| # Matter Linux Energy Gateway Example |
| |
| The Energy Gateway app is intended to act as a `CommodityPrice` and |
| `Electrical Grid Conditions` cluster server that can share the current |
| electrical price of energy and grid conditions (how many Grams of CO2 per kWh) |
| to Energy Smart Appliances (ESAs). |
| |
| This is primarily intended as an example reference application. |
| |
| This document describes how to build and run CHIP Linux Energy Gateway Example |
| on Raspberry Pi. This doc is tested on **Ubuntu for Raspberry Pi Server 24.04 |
| LTS (aarch64)**. |
| |
| To cross-compile this example on x64 host and run on **NXP i.MX 8M Mini** |
| **EVK**, see the associated |
| [README document](../../../docs/platforms/nxp/nxp_imx8m_linux_examples.md) for |
| details. |
| |
| <hr> |
| |
| - [Matter Linux Energy Gateway Example](#matter-linux-energy-gateway-example) |
| - [Building](#building) |
| - [Commandline arguments](#commandline-arguments) |
| - [Running the Complete Example on Raspberry Pi 4](#running-the-complete-example-on-raspberry-pi-4) |
| - [Device Tracing](#device-tracing) |
| - [Python Test Cases](#python-test-cases) |
| - [Running the test cases:](#running-the-test-cases) |
| - [MATTER-REPL Interaction](#matter-repl-interaction) |
| - [Building matter-repl:](#building-matter-repl) |
| - [Activating python virtual env](#activating-python-virtual-env) |
| - [Interacting with matter-repl and the example app](#interacting-with-matter-repl-and-the-example-app) |
| - [CommodityPrice cluster](#commodityprice-cluster) |
| - [ElectricalGridConditions cluster](#electricalgridconditions-cluster) |
| |
| <hr> |
| |
| ## Building |
| |
| - Install tool chain |
| |
| ```bash |
| sudo apt-get install git gcc g++ python pkg-config libssl-dev libdbus-1-dev libglib2.0-dev ninja-build python3-venv python3-dev unzip |
| ``` |
| |
| - Build the example application: |
| |
| ```bash |
| cd ~/connectedhomeip/examples/energy-gateway-app/linux |
| git submodule update --init |
| source third_party/connectedhomeip/scripts/activate.sh |
| gn gen out/debug |
| ninja -C out/debug |
| ``` |
| |
| - To delete generated executable, libraries and object files use: |
| |
| ```bash |
| cd ~/connectedhomeip/examples/energy-gateway-app/linux |
| rm -rf out |
| ``` |
| |
| ## Commandline arguments |
| |
| - `--wifi` |
| |
| Enables WiFi management feature. Required for WiFi commissioning. |
| |
| - `--thread` |
| |
| Enables Thread management feature, requires ot-br-posix dbus daemon running. |
| Required for Thread commissioning. |
| |
| - `--ble-controller <selector>` |
| |
| Use the specific Bluetooth controller for BLE advertisement and connections. |
| For details on controller selection refer to |
| [Linux BLE Settings](/platforms/linux/ble_settings.md). |
| |
| ## Running the Complete Example on Raspberry Pi 4 |
| |
| - Prerequisites |
| |
| 1. A Raspberry Pi 4 board |
| 2. A USB Bluetooth Dongle, Ubuntu desktop will send Bluetooth advertisement, |
| which will block CHIP from connecting via BLE. On Ubuntu server, you need |
| to install `pi-bluetooth` via APT. |
| 3. Ubuntu 24.04 or newer image for ARM64 platform. |
| |
| - Building |
| |
| Follow [Building](#building) section of this document. |
| |
| - Running |
| |
| - [Optional] Plug USB Bluetooth dongle |
| |
| - Plug USB Bluetooth dongle and find its bluetooth controller selector |
| as described in |
| [Linux BLE Settings](/platforms/linux/ble_settings.md). |
| |
| - Run Linux Energy Gateway Example App |
| |
| ```bash |
| cd ~/connectedhomeip/examples/energy-gateway-app/linux |
| sudo out/debug/chip-energy-gateway-app --ble-controller [bluetooth controller number] |
| # In this example, the device we want to use is hci1 |
| sudo out/debug/chip-energy-gateway-app --ble-controller 1 |
| ``` |
| |
| - Test the device using ChipDeviceController on your laptop / workstation |
| etc. |
| |
| ## Device Tracing |
| |
| Device tracing is available to analyze the device performance. To turn on |
| tracing, build with RPC enabled. See [Building with RPC enabled](#building). |
| |
| Obtain tracing json file. |
| |
| ```bash |
| {PIGWEED_REPO}/pw_trace_tokenized/py/pw_trace_tokenized/get_trace.py -s localhost:33000 \ |
| -o {OUTPUT_FILE} -t {ELF_FILE} {PIGWEED_REPO}/pw_trace_tokenized/pw_trace_protos/trace_rpc.proto |
| ``` |
| |
| ## Python Test Cases |
| |
| When you want to test this cluster you can use matter-repl or chip-tool by hand. |
| MATTER-REPL is slightly easier to interact with when dealing with some of the |
| complex structures. |
| |
| There are several test scripts provided for Commodity Price cluster (in |
| [src/python_testing](/src/python_testing)): |
| |
| - `TC_SEPR_2_1`: This validates the primary functionality |
| - \*`TC_SEPR_2_2`: This validates GetDetailedPriceRequest command |
| - \*`TC_SEPR_2_3`: This validates the FORECASTING feature and |
| GetDetailedForecastRequest command (NOTE requires TCP support - see below) |
| |
| There are several test scripts provided for Electrical Grid Conditions cluster |
| (in [src/python_testing](/src/python_testing)): |
| |
| - `TC_EGC_2_1`: This validates the primary functionality |
| - \*`TC_EGC_2_2`: This validates that when the CurrentConditions attribute |
| changes, an event is sent |
| - \*`TC_EGC_2_3`: This validates the FORECASTING feature using test event to |
| simulate data |
| |
| `*` - These scripts require the use of Test Event Triggers via the |
| GeneralDiagnostics cluster on Endpoint 0. This requires an `enableKey` (16 |
| bytes) and a set of reserved int64_t test event trigger codes. |
| |
| **NOTE: that some non Linux platforms may not support TCP (for large messages). |
| This means that the GetDetailedForecastRequest() command will not be supported |
| on these platforms.** |
| |
| Once the application is built you also need to tell it at runtime what the |
| chosen enable key is using the `--enable-key` command line option. |
| |
| ```bash |
| ./chip-energy-gateway-app --enable-key 000102030405060708090a0b0c0d0e0f |
| ``` |
| |
| ### Running the test cases: |
| |
| From the top-level of the connectedhomeip repo type: |
| |
| Start the chip-energy-gateway-app: |
| |
| ```bash |
| rm -f /tmp/chip_*; out/debug/chip-energy-gateway-app --enable-key 000102030405060708090a0b0c0d0e0f |
| ``` |
| |
| Then run the test: |
| |
| ```bash |
| python src/python_testing/TC_SEPR_2_1.py --endpoint 1 -m on-network -n 1234 -p 20202021 -d 3840 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f |
| ``` |
| |
| - Note that the `--endpoint 1` must be used with the example, since the SEPR |
| cluster is on endpoint 1. The `--hex-arg enableKey:<key>` value must match |
| the `--enable-key <key>` used on chip-energy-gateway-app args. |
| |
| The chip-energy-gateway-app will need to be stopped before running each test |
| script as each test commissions the chip-energy-gateway-app in the first step. |
| That is also why the `/tmp/chip_*` files are deleted before running |
| chip-energy-gateway-app as this is where the app stores the matter persistent |
| data (e.g. fabric info). |
| |
| ## MATTER-REPL Interaction |
| |
| - See matter-repl documentation in: |
| - [Working with Python CHIP Controller](../../../docs/development_controllers/matter-repl/python_chip_controller_building.md) |
| - [Matter_REPL_Intro](https://github.com/project-chip/connectedhomeip/blob/master/docs/development_controllers/matter-repl/Matter_REPL_Intro.ipynb) |
| |
| ### Building matter-repl: |
| |
| ```bash |
| ./build_python.sh -i out/python |
| ``` |
| |
| ### Activating python virtual env |
| |
| - You need to repeat this step each time you start a new shell. |
| |
| ```bash |
| source out/python/bin/activate |
| ``` |
| |
| ### Interacting with matter-repl and the example app |
| |
| - Step 1: Launch the example app in shell 1 |
| |
| ```bash |
| ./chip-energy-gateway-app --enable-key 000102030405060708090a0b0c0d0e0f |
| ``` |
| |
| - Step 2: Launch matter-repl in shell 2 (where you have previously run |
| `source out/python/bin/activate`) |
| |
| ```bash |
| matter-repl |
| ``` |
| |
| - Step 3: (In matter-repl) Commissioning OnNetwork |
| |
| ```python |
| await devCtrl.CommissionOnNetwork(200,20202021) # Commission with NodeID 200 |
| Out[1]: 200 |
| ``` |
| |
| #### CommodityPrice cluster |
| |
| This allows you to get current and forecast energy prices. |
| |
| - Step 4: (In matter-repl) Read `Commodity Price` attributes |
| |
| ```python |
| # Read from NodeID 200, Endpoint 1, all attributes on CommodityPrice cluster |
| await devCtrl.ReadAttribute(200,[(1, chip.clusters.CommodityPrice)]) |
| ``` |
| |
| The response in the default app is a null `CurrentPrice` and an empty |
| `PriceForecast` attribute: |
| |
| ``` |
| Out[11]: |
| |
| { |
| │ 1: { |
| │ │ <class 'chip.clusters.Objects.CommodityPrice'>: { |
| │ │ │ <class 'chip.clusters.Attribute.DataVersion'>: 3672963490, |
| │ │ │ <class 'chip.clusters.Objects.CommodityPrice.Attributes.AcceptedCommandList'>: [ |
| │ │ │ │ 0, |
| │ │ │ │ 2 |
| │ │ │ ], |
| │ │ │ <class 'chip.clusters.Objects.CommodityPrice.Attributes.Currency'>: CurrencyStruct( |
| │ │ │ │ currency=826, |
| │ │ │ │ decimalPoints=5 |
| │ │ │ ), |
| │ │ │ <class 'chip.clusters.Objects.CommodityPrice.Attributes.GeneratedCommandList'>: [ |
| │ │ │ │ 1, |
| │ │ │ │ 3 |
| │ │ │ ], |
| │ │ │ <class 'chip.clusters.Objects.CommodityPrice.Attributes.AttributeList'>: [ |
| │ │ │ │ 0, |
| │ │ │ │ 1, |
| │ │ │ │ 2, |
| │ │ │ │ 3, |
| │ │ │ │ 65532, |
| │ │ │ │ 65533, |
| │ │ │ │ 65528, |
| │ │ │ │ 65529, |
| │ │ │ │ 65531 |
| │ │ │ ], |
| │ │ │ <class 'chip.clusters.Objects.CommodityPrice.Attributes.TariffUnit'>: <TariffUnitEnum.kKWh: 0>, |
| │ │ │ <class 'chip.clusters.Objects.CommodityPrice.Attributes.PriceForecast'>: [], |
| │ │ │ <class 'chip.clusters.Objects.CommodityPrice.Attributes.ClusterRevision'>: 4, |
| │ │ │ <class 'chip.clusters.Objects.CommodityPrice.Attributes.CurrentPrice'>: Null, |
| │ │ │ <class 'chip.clusters.Objects.CommodityPrice.Attributes.FeatureMap'>: 1 |
| │ │ } |
| │ } |
| ``` |
| |
| - Step 5: (In matter-repl) Using TestEvent trigger |
| `eventTrigger=0x0095000000000000` we can generate a test `CurrentPrice` with |
| sample data |
| |
| ```python |
| # Send a test event trigger NodeID 200, Endpoint 0, with eventTrigger=0x0095000000000000 |
| await devCtrl.SendCommand(200, 0, chip.clusters.GeneralDiagnostics.Commands.TestEventTrigger(enableKey=bytes([b for b in range(16)]), eventTrigger=0x0095000000000000)) |
| ``` |
| |
| - Step 6: (In matter-repl) Re-Read `CurrentPrice` attribute (see the values |
| have changed) |
| |
| ``` |
| await devCtrl.ReadAttribute(200,[(1,chip.clusters.CommodityPrice.Attributes.CurrentPrice)]) |
| Out[18]: |
| |
| { |
| │ 1: { |
| │ │ <class 'chip.clusters.Objects.CommodityPrice'>: { |
| │ │ │ <class 'chip.clusters.Attribute.DataVersion'>: 3672963491, |
| │ │ │ <class 'chip.clusters.Objects.CommodityPrice.Attributes.CurrentPrice'>: CommodityPriceStruct( |
| │ │ │ │ periodStart=799150761, |
| │ │ │ │ periodEnd=799152561, |
| │ │ │ │ price=15916, |
| │ │ │ │ priceLevel=3, |
| │ │ │ │ description=None, |
| │ │ │ │ components=None |
| │ │ │ ) |
| │ │ } |
| │ } |
| } |
| ``` |
| |
| **NOTE: that the description and components are not included in the attribute |
| READ.** |
| |
| To get these we need to use the GetDetailedPriceRequest command: This takes a |
| `details` bitmap which requests the type of detail to be returned: |
| |
| - b0 = Description |
| - b1 = Components |
| |
| i.e. |
| |
| - details = 1 (Description ONLY) |
| - details = 2 (Components ONLY) |
| - details = 3 (Description & Components) |
| |
| - Step 7: (In matter-repl) Send `GetDetailedPriceRequest()` |
| |
| ``` |
| await devCtrl.SendCommand(200, 1, chip.clusters.CommodityPrice.Commands.GetDetailedPriceRequest(3)) |
| Out[15]: |
| |
| GetDetailedPriceResponse( |
| │ currentPrice=CommodityPriceStruct( |
| │ │ periodStart=799150761, |
| │ │ periodEnd=799152561, |
| │ │ price=15916, |
| │ │ priceLevel=3, |
| │ │ description='Medium', |
| │ │ components=[ |
| │ │ │ CommodityPriceComponentStruct( |
| │ │ │ │ price=15120, |
| │ │ │ │ source=<TariffPriceTypeEnum.kStandard: 0>, |
| │ │ │ │ description='ExVAT', |
| │ │ │ │ tariffComponentID=None |
| │ │ │ ), |
| │ │ │ CommodityPriceComponentStruct( |
| │ │ │ │ price=795, |
| │ │ │ │ source=<TariffPriceTypeEnum.kStandard: 0>, |
| │ │ │ │ description='VAT', |
| │ │ │ │ tariffComponentID=None |
| │ │ │ ) |
| │ │ ] |
| │ ) |
| ) |
| ``` |
| |
| - Step 8: (In matter-repl) Using TestEvent trigger |
| `eventTrigger=0x0095000000000001` we can generate a test `PriceForecast` |
| containing the price values for the next few hours |
| |
| ```python |
| # Send a test event trigger NodeID 200, Endpoint 0, with eventTrigger=0x0095000000000001 |
| await devCtrl.SendCommand(200, 0, chip.clusters.GeneralDiagnostics.Commands.TestEventTrigger(enableKey=bytes([b for b in range(16)]), eventTrigger=0x0095000000000001)) |
| ``` |
| |
| - Step 9: (In matter-repl) Read `PriceForecast` attributes (see the values |
| have changed) |
| |
| ``` |
| await devCtrl.ReadAttribute(200,[(1,chip.clusters.CommodityPrice.Attributes.PriceForecast)]) |
| Out[21]: |
| |
| { |
| │ 1: { |
| │ │ <class 'chip.clusters.Objects.CommodityPrice'>: { |
| │ │ │ <class 'chip.clusters.Attribute.DataVersion'>: 3672963492, |
| │ │ │ <class 'chip.clusters.Objects.CommodityPrice.Attributes.PriceForecast'>: [ |
| │ │ │ │ CommodityPriceStruct( |
| │ │ │ │ │ periodStart=799152701, |
| │ │ │ │ │ periodEnd=799154500, |
| │ │ │ │ │ price=27935, |
| │ │ │ │ │ priceLevel=3, |
| │ │ │ │ │ description=None, |
| │ │ │ │ │ components=None |
| │ │ │ │ ), |
| │ │ │ │ CommodityPriceStruct( |
| │ │ │ │ │ periodStart=799154501, |
| │ │ │ │ │ periodEnd=799156300, |
| │ │ │ │ │ price=23687, |
| │ │ │ │ │ priceLevel=2, |
| │ │ │ │ │ description=None, |
| │ │ │ │ │ components=None |
| │ │ │ │ ), |
| │ │ │ │ CommodityPriceStruct( |
| │ │ │ │ │ periodStart=799156301, |
| │ │ │ │ │ periodEnd=799158100, |
| │ │ │ │ │ price=18636, |
| │ │ │ │ │ priceLevel=2, |
| │ │ │ │ │ description=None, |
| │ │ │ │ │ components=None |
| │ │ │ │ ), |
| │ │ │ │ CommodityPriceStruct( |
| │ │ │ │ │ periodStart=799158101, |
| │ │ │ │ │ periodEnd=799159900, |
| │ │ │ │ │ price=8889, |
| │ │ │ │ │ priceLevel=1, |
| │ │ │ │ │ description=None, |
| │ │ │ │ │ components=None |
| │ │ │ │ ), |
| ... |
| │ │ │ │ CommodityPriceStruct( |
| │ │ │ │ │ periodStart=799251701, |
| │ │ │ │ │ periodEnd=799253500, |
| │ │ │ │ │ price=24450, |
| │ │ │ │ │ priceLevel=3, |
| │ │ │ │ │ description=None, |
| │ │ │ │ │ components=None |
| │ │ │ │ ) |
| │ │ │ ] |
| │ │ } |
| │ } |
| } |
| ``` |
| |
| **NOTE: that the description and components are not included in the attribute |
| READ.** |
| |
| To get these we need to use the GetDetailedForecastRequest command (**USES |
| TCP**): |
| |
| This takes a `details` bitmap which requests the type of detail to be returned: |
| |
| b0 = Description b1 = Components |
| |
| i.e. details = 1 (Description ONLY) details = 2 (Components ONLY) details = 3 |
| (Description & Components) |
| |
| - Step 10: (In matter-repl) Send `GetDetailedForecastRequest()` |
| - Step 10a: First we need to ensure we connect with TCP (only needed once): |
| |
| ```python |
| dev = await devCtrl.GetConnectedDevice(200, allowPASE=False, timeoutMs=1000, payloadCapability=chip.ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) |
| ``` |
| |
| - Step 10b: Send the `GetDetailedForecastRequest()` command: |
| |
| ``` |
| await devCtrl.SendCommand(200, 1, chip.clusters.CommodityPrice.Commands.GetDetailedForecastRequest(3)) |
| Out[24]: |
| |
| GetDetailedForecastResponse( |
| │ priceForecast=[ |
| │ │ CommodityPriceStruct( |
| │ │ │ periodStart=799152701, |
| │ │ │ periodEnd=799154500, |
| │ │ │ price=27935, |
| │ │ │ priceLevel=3, |
| │ │ │ description='High', |
| │ │ │ components=[ |
| │ │ │ │ CommodityPriceComponentStruct( |
| │ │ │ │ │ price=26538, |
| │ │ │ │ │ source=<TariffPriceTypeEnum.kStandard: 0>, |
| │ │ │ │ │ description='ExVAT', |
| │ │ │ │ │ tariffComponentID=None |
| │ │ │ │ ), |
| │ │ │ │ CommodityPriceComponentStruct( |
| │ │ │ │ │ price=1396, |
| │ │ │ │ │ source=<TariffPriceTypeEnum.kStandard: 0>, |
| │ │ │ │ │ description='VAT', |
| │ │ │ │ │ tariffComponentID=None |
| │ │ │ │ ) |
| │ │ │ ] |
| │ │ ), |
| │ │ CommodityPriceStruct( |
| │ │ │ periodStart=799154501, |
| │ │ │ periodEnd=799156300, |
| │ │ │ price=23687, |
| │ │ │ priceLevel=2, |
| │ │ │ description='Medium', |
| │ │ │ components=[ |
| │ │ │ │ CommodityPriceComponentStruct( |
| │ │ │ │ │ price=22502, |
| │ │ │ │ │ source=<TariffPriceTypeEnum.kStandard: 0>, |
| │ │ │ │ │ description='ExVAT', |
| │ │ │ │ │ tariffComponentID=None |
| │ │ │ │ ), |
| │ │ │ │ CommodityPriceComponentStruct( |
| │ │ │ │ │ price=1184, |
| │ │ │ │ │ source=<TariffPriceTypeEnum.kStandard: 0>, |
| │ │ │ │ │ description='VAT', |
| │ │ │ │ │ tariffComponentID=None |
| │ │ │ │ ) |
| │ │ │ ] |
| │ │ ), |
| ... |
| │ │ CommodityPriceStruct( |
| │ │ │ periodStart=799251701, |
| │ │ │ periodEnd=799253500, |
| │ │ │ price=24450, |
| │ │ │ priceLevel=3, |
| │ │ │ description='High', |
| │ │ │ components=[ |
| │ │ │ │ CommodityPriceComponentStruct( |
| │ │ │ │ │ price=23227, |
| │ │ │ │ │ source=<TariffPriceTypeEnum.kStandard: 0>, |
| │ │ │ │ │ description='ExVAT', |
| │ │ │ │ │ tariffComponentID=None |
| │ │ │ │ ), |
| │ │ │ │ CommodityPriceComponentStruct( |
| │ │ │ │ │ price=1222, |
| │ │ │ │ │ source=<TariffPriceTypeEnum.kStandard: 0>, |
| │ │ │ │ │ description='VAT', |
| │ │ │ │ │ tariffComponentID=None |
| │ │ │ │ ) |
| │ │ │ ] |
| │ │ ) |
| │ ] |
| ) |
| |
| ``` |
| |
| #### ElectricalGridConditions cluster |
| |
| This allows you to get current and forecast electrical grid conditions. This |
| assumes you have already commissioned the app (see above). |
| |
| - Step 1: (In matter-repl) Read `Electrical Grid Conditions` attributes |
| |
| ``` |
| # Read from NodeID 200, Endpoint 1, all attributes on ElectricalGridConditions cluster |
| await devCtrl.ReadAttribute(200,[(1, chip.clusters.ElectricalGridConditions)]) |
| Out[2]: |
| |
| { |
| │ 1: { |
| │ │ <class 'chip.clusters.Objects.ElectricalGridConditions'>: { |
| │ │ │ <class 'chip.clusters.Attribute.DataVersion'>: 2998541776, |
| │ │ │ <class 'chip.clusters.Objects.ElectricalGridConditions.Attributes.LocalGenerationAvailable'>: True, |
| │ │ │ <class 'chip.clusters.Objects.ElectricalGridConditions.Attributes.ClusterRevision'>: 1, |
| │ │ │ <class 'chip.clusters.Objects.ElectricalGridConditions.Attributes.ForecastConditions'>: [], |
| │ │ │ <class 'chip.clusters.Objects.ElectricalGridConditions.Attributes.AcceptedCommandList'>: [], |
| │ │ │ <class 'chip.clusters.Objects.ElectricalGridConditions.Attributes.FeatureMap'>: 1, |
| │ │ │ <class 'chip.clusters.Objects.ElectricalGridConditions.Attributes.CurrentConditions'>: Null, |
| │ │ │ <class 'chip.clusters.Objects.ElectricalGridConditions.Attributes.GeneratedCommandList'>: [], |
| │ │ │ <class 'chip.clusters.Objects.ElectricalGridConditions.Attributes.AttributeList'>: [ |
| │ │ │ │ 0, |
| │ │ │ │ 1, |
| │ │ │ │ 2, |
| │ │ │ │ 65532, |
| │ │ │ │ 65533, |
| │ │ │ │ 65528, |
| │ │ │ │ 65529, |
| │ │ │ │ 65531 |
| │ │ │ ] |
| │ │ } |
| │ } |
| } |
| ``` |
| |
| The response in the default app is a null `CurrentConditions` and an empty |
| `ForecastConditions` attribute. |
| |
| - Step 2: (In matter-repl) Using TestEvent trigger |
| `eventTrigger=0x00A0000000000000` we can generate a test `CurrentConditions` |
| with sample data |
| |
| ```python |
| # Send a test event trigger NodeID 200, Endpoint 0, with eventTrigger=0x00A0000000000000 |
| await devCtrl.SendCommand(200, 0, chip.clusters.GeneralDiagnostics.Commands.TestEventTrigger(enableKey=bytes([b for b in range(16)]), eventTrigger=0x00A0000000000000)) |
| ``` |
| |
| - Step 3: (In matter-repl) Re-Read `CurrentConditions` attribute (see the |
| values have changed) |
| |
| ``` |
| await devCtrl.ReadAttribute(200,[(1, chip.clusters.ElectricalGridConditions.Attributes.CurrentConditions)]) |
| Out[7]: |
| |
| { |
| │ 1: { |
| │ │ <class 'chip.clusters.Objects.ElectricalGridConditions'>: { |
| │ │ │ <class 'chip.clusters.Attribute.DataVersion'>: 488127616, |
| │ │ │ <class 'chip.clusters.Objects.ElectricalGridConditions.Attributes.CurrentConditions'>: ElectricalGridConditionsStruct( |
| │ │ │ │ periodStart=799154050, |
| │ │ │ │ periodEnd=799155850, |
| │ │ │ │ gridCarbonIntensity=230, |
| │ │ │ │ gridCarbonLevel=<ThreeLevelEnum.kMedium: 1>, |
| │ │ │ │ localCarbonIntensity=0, |
| │ │ │ │ localCarbonLevel=<ThreeLevelEnum.kLow: 0> |
| │ │ │ ) |
| │ │ } |
| │ } |
| } |
| ``` |
| |
| - Step 4: (In matter-repl) Using TestEvent trigger |
| `eventTrigger=0x00A0000000000001` we can generate a test |
| `ForecastConditions` with sample data |
| |
| ```python |
| # Send a test event trigger NodeID 200, Endpoint 0, with eventTrigger=0x00A0000000000001 |
| await devCtrl.SendCommand(200, 0, chip.clusters.GeneralDiagnostics.Commands.TestEventTrigger(enableKey=bytes([b for b in range(16)]), eventTrigger=0x00A0000000000001)) |
| ``` |
| |
| - Step 5: (In matter-repl) Re-Read `ForecastConditions` attribute (see the |
| values have changed) |
| |
| ``` |
| await devCtrl.ReadAttribute(200,[(1, chip.clusters.ElectricalGridConditions.Attributes.ForecastConditions)]) |
| Out[9]: |
| |
| { |
| │ 1: { |
| │ │ <class 'chip.clusters.Objects.ElectricalGridConditions'>: { |
| │ │ │ <class 'chip.clusters.Attribute.DataVersion'>: 488127617, |
| │ │ │ <class 'chip.clusters.Objects.ElectricalGridConditions.Attributes.ForecastConditions'>: [ |
| │ │ │ │ ElectricalGridConditionsStruct( |
| │ │ │ │ │ periodStart=799154301, |
| │ │ │ │ │ periodEnd=799156100, |
| │ │ │ │ │ gridCarbonIntensity=18, |
| │ │ │ │ │ gridCarbonLevel=<ThreeLevelEnum.kLow: 0>, |
| │ │ │ │ │ localCarbonIntensity=18, |
| │ │ │ │ │ localCarbonLevel=<ThreeLevelEnum.kLow: 0> |
| │ │ │ │ ), |
| │ │ │ │ ElectricalGridConditionsStruct( |
| │ │ │ │ │ periodStart=799156101, |
| │ │ │ │ │ periodEnd=799157900, |
| │ │ │ │ │ gridCarbonIntensity=399, |
| │ │ │ │ │ gridCarbonLevel=<ThreeLevelEnum.kHigh: 2>, |
| │ │ │ │ │ localCarbonIntensity=399, |
| │ │ │ │ │ localCarbonLevel=<ThreeLevelEnum.kHigh: 2> |
| │ │ │ │ ), |
| │ │ │ │ ElectricalGridConditionsStruct( |
| │ │ │ │ │ periodStart=799157901, |
| │ │ │ │ │ periodEnd=799159700, |
| │ │ │ │ │ gridCarbonIntensity=165, |
| │ │ │ │ │ gridCarbonLevel=<ThreeLevelEnum.kMedium: 1>, |
| │ │ │ │ │ localCarbonIntensity=165, |
| │ │ │ │ │ localCarbonLevel=<ThreeLevelEnum.kMedium: 1> |
| │ │ │ │ ), |
| ... |
| │ │ │ │ ElectricalGridConditionsStruct( |
| │ │ │ │ │ periodStart=799238901, |
| │ │ │ │ │ periodEnd=799240700, |
| │ │ │ │ │ gridCarbonIntensity=130, |
| │ │ │ │ │ gridCarbonLevel=<ThreeLevelEnum.kMedium: 1>, |
| │ │ │ │ │ localCarbonIntensity=130, |
| │ │ │ │ │ localCarbonLevel=<ThreeLevelEnum.kMedium: 1> |
| │ │ │ │ ) |
| │ │ │ ] |
| │ │ } |
| │ } |
| } |
| ``` |