From 5b5b7f30cc21c52ebd0545102c27eaf3010f2e4c Mon Sep 17 00:00:00 2001 From: Jerry Johns Date: Fri, 28 Jan 2022 16:39:08 -0800 Subject: [PATCH] Python REPL: Persistent Storage, Multi Fabric, JupyterLab Support, (#13715) --- .github/.wordlist.txt | 20 + Matter - Multi Fabric Commissioning.ipynb | 823 ++++ Matter - REPL Basics.ipynb | 1139 +++++ docs/guides/matter-repl.md | 165 + .../guides/repl/Matter - Access Control.ipynb | 885 ++++ .../repl/Matter - Basic Interactions.ipynb | 4247 +++++++++++++++++ .../Matter - Multi Fabric Commissioning.ipynb | 1186 +++++ docs/guides/repl/Matter - REPL Intro.ipynb | 1154 +++++ src/controller/CHIPDeviceController.cpp | 4 + src/controller/CHIPDeviceController.h | 2 + src/controller/CHIPDeviceControllerFactory.h | 16 + .../ExampleOperationalCredentialsIssuer.cpp | 63 +- .../ExampleOperationalCredentialsIssuer.h | 11 + .../OperationalCredentialsDelegate.h | 2 +- src/controller/python/BUILD.gn | 3 + .../ChipDeviceController-ScriptBinding.cpp | 120 +- .../ChipDeviceController-StorageDelegate.cpp | 44 + .../ChipDeviceController-StorageDelegate.h | 37 +- src/controller/python/OpCredsBinding.cpp | 186 + src/controller/python/build-chip-wheel.py | 4 +- src/controller/python/chip-device-ctrl.py | 53 +- src/controller/python/chip-repl.py | 30 +- .../python/chip/ChipCommissionableNodeCtrl.py | 4 +- src/controller/python/chip/ChipDeviceCtrl.py | 176 +- src/controller/python/chip/ChipReplStartup.py | 75 +- src/controller/python/chip/ChipStack.py | 30 +- src/controller/python/chip/FabricAdmin.py | 209 + .../python/chip/clusters/Attribute.py | 16 +- .../python/chip/clusters/Command.py | 16 +- .../python/chip/clusters/attribute.cpp | 12 +- .../python/chip/storage/__init__.py | 158 + .../python/test/test_scripts/base.py | 78 +- .../test/test_scripts/mobile-device-test.py | 11 +- 33 files changed, 10803 insertions(+), 176 deletions(-) create mode 100644 Matter - Multi Fabric Commissioning.ipynb create mode 100644 Matter - REPL Basics.ipynb create mode 100644 docs/guides/matter-repl.md create mode 100644 docs/guides/repl/Matter - Access Control.ipynb create mode 100644 docs/guides/repl/Matter - Basic Interactions.ipynb create mode 100644 docs/guides/repl/Matter - Multi Fabric Commissioning.ipynb create mode 100644 docs/guides/repl/Matter - REPL Intro.ipynb create mode 100644 src/controller/python/OpCredsBinding.cpp create mode 100644 src/controller/python/chip/FabricAdmin.py create mode 100644 src/controller/python/chip/storage/__init__.py diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index d000fb5474ddff..36036b8e4072db 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -80,6 +80,7 @@ ATWC AudioOutput auth autoconnect +autocompletion autocrlf autogenerated automake @@ -228,6 +229,7 @@ ContentAppPlatform ContentApp's ContentLaunch ContentLauncher +continuousHinting contrib controllee conv @@ -272,6 +274,7 @@ DCL DCMAKE DCONFIG debianutils +deepnote DEDEDEDE DelayedActionTime demangle @@ -481,6 +484,7 @@ href HTTPS HW iaszone +ibb ICA ICMP IDF @@ -521,6 +525,9 @@ ipp iptables iputils IPv +ipykernel +ipynb +IPython ISCAN itemName iterable @@ -535,6 +542,9 @@ jre js json JTAG +Jupyter +jupyter +jupyterlab KA Kconfig KeypadInput @@ -543,6 +553,7 @@ kNodeIdNotSpecified knownissues KVS LabelList +launchable LAUNCHXL ldflags LEDs @@ -584,6 +595,7 @@ LockingState loopback LowPower LPC +LSP LTE LTS LwIP @@ -839,6 +851,7 @@ ReadConfigValue readelf readfds README +readthedocs Reag rebase recommand @@ -852,6 +865,8 @@ Rendez RendezvousInformation RendezvousParameters RendezVousTest +REPL +repl repo req Requestor @@ -883,6 +898,7 @@ RunMain runtime rw RXD +sandboxed sbin scalability scalable @@ -915,6 +931,7 @@ SetUpPINCode SetupQRCode sexualized SHA +showDocumentation shubhamdp SIGINT SiLabs @@ -949,6 +966,7 @@ StartScan stderr stdout sterm +storagepath str strcpy su @@ -1076,6 +1094,7 @@ venv Verifier Verifiers VID +virtualenv visualstudio vlatest VLEDs @@ -1133,6 +1152,7 @@ YNJV Yocto yoctoproject YourFolder +yWsC zapt zaptool ZCL diff --git a/Matter - Multi Fabric Commissioning.ipynb b/Matter - Multi Fabric Commissioning.ipynb new file mode 100644 index 00000000000000..c7f92aa331d5f6 --- /dev/null +++ b/Matter - Multi Fabric Commissioning.ipynb @@ -0,0 +1,823 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e8b2f5eb", + "metadata": {}, + "source": [ + "# Multi Fabric Commissioning\n", + "\n", + "_This notebook walks through a flow that sets up two separate commissioners on two different fabrics and commissions a target device onto those fabrics._" + ] + }, + { + "cell_type": "markdown", + "id": "99ce2877", + "metadata": {}, + "source": [ + "### Imports\n", + "\n", + "Let's first begin by setting up by importing some key modules that are needed to make it easier for us to interact with the Matter stack." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "52b40db6", + "metadata": {}, + "outputs": [], + "source": [ + "from rich import print\n", + "from rich.pretty import pprint\n", + "from rich import inspect\n", + "import logging\n", + "import chip\n", + "import chip.logging\n", + "from chip import ChipDeviceCtrl\n", + "import chip.clusters as Clusters\n", + "from chip.ChipReplStartup import *\n", + "from chip.ChipStack import *\n", + "import subprocess, sys" + ] + }, + { + "cell_type": "markdown", + "id": "78e14359", + "metadata": {}, + "source": [ + "### Initialization\n", + "\n", + "Next, let's initialize the REPL environment and the Matter Stack." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "e3057f9d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
──────────────────────────────────────── Matter REPL ────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m──────────────────────────────────────── \u001b[0mMatter REPL\u001b[92m ────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "            \n",
+       "    \n",
+       "            Welcome to the Matter Python REPL!\n",
+       "    \n",
+       "            For help, please type matterhelp()\n",
+       "    \n",
+       "            To get more information on a particular object/class, you can pass\n",
+       "            that into matterhelp() as well.\n",
+       "    \n",
+       "            \n",
+       "
\n" + ], + "text/plain": [ + "\n", + " \n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m Welcome to the Matter Python REPL!\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m For help, please type \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m To get more information on a particular object/class, you can pass\u001b[0m\n", + "\u001b[1;34m that into \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\u001b[1;34m as well.\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m \u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
─────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m─────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ReplInit()\n", + "chipStack = ChipStack()" + ] + }, + { + "cell_type": "markdown", + "id": "9cb06305", + "metadata": {}, + "source": [ + "### Launch Server\n", + "\n", + "Let's launch an instance of the `chip-all-clusters-app`." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "52ccd8c6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
<subprocess.Popen object at 0x10d12db50>\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m<\u001b[0m\u001b[1;95msubprocess.Popen\u001b[0m\u001b[39m object at \u001b[0m\u001b[1;36m0x10d12db50\u001b[0m\u001b[1m>\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "subprocess.Popen(['killall', 'chip-all-clusters-app'])" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "1a8022e6", + "metadata": {}, + "outputs": [], + "source": [ + "process = subprocess.Popen('./out/debug/chip-all-clusters-app', stdout=subprocess.DEVNULL)" + ] + }, + { + "cell_type": "markdown", + "id": "c22ea8ee", + "metadata": {}, + "source": [ + "### Create Controller on Fabric A" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "5e964fe3", + "metadata": {}, + "outputs": [], + "source": [ + "devCtrl = ChipDeviceCtrl.ChipDeviceController(controllerNodeId=1)" + ] + }, + { + "cell_type": "markdown", + "id": "b33dec2e", + "metadata": {}, + "source": [ + "### Commission Target" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "e98d8157", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2021-12-29 15:02:03 johnsj-macbookpro1.roam.corp.google.com chip.CTL[86631] ERROR Unable to find country code, defaulting to WW\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Established CASE with Device\n" + ] + }, + { + "data": { + "text/html": [ + "
True\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[3;92mTrue\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Node address has been updated\n", + "Commissioning complete\n" + ] + } + ], + "source": [ + "devCtrl.CommissionIP(b'127.0.0.1', 20202021, 1)" + ] + }, + { + "cell_type": "markdown", + "id": "820fcede", + "metadata": {}, + "source": [ + "### Read out the Fabric List to validate" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "6802862a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.OperationalCredentials'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'>: [\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x040\\xa5d\\x8eX4]\\xa1\\xe18\\x04\\x9b\\xf2E\\x8eh\\x13dwQ\\xd9\\x19\\xa5\\xe4\\x88h\\xe5q\\xacPCtY\\xb9\\xcc\\x94KQ\\xa85\\xfa(\\x07\\x80q+\\xa6\\x9a%\\x8d\\x1f\\xf4MJ\\xa0\\x9e[\\xafW0\"\\x82\\xf4\\xbb',\n",
+       "│   │   │   │   │   vendorId=27424,\n",
+       "│   │   │   │   │   fabricId=3,\n",
+       "│   │   │   │   │   nodeId=1,\n",
+       "│   │   │   │   │   label=''\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.SupportedFabrics'>: 16,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.CommissionedFabrics'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.TrustedRootCertificates'>: [\n",
+       "│   │   │   │   b'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x03\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x03\\x18$\\x07\\x01$\\x08\\x010\\tA\\x040\\xa5d\\x8eX4]\\xa1\\xe18\\x04\\x9b\\xf2E\\x8eh\\x13dwQ\\xd9\\x19\\xa5\\xe4\\x88h\\xe5q\\xacPCtY\\xb9\\xcc\\x94KQ\\xa85\\xfa(\\x07\\x80q+\\xa6\\x9a%\\x8d\\x1f\\xf4MJ\\xa0\\x9e[\\xafW0\"\\x82\\xf4\\xbb7\\n5\\x01)\\x01\\x18$\\x02`0\\x04\\x14j\\xf4P\\xfa\\x1dE\\xff28AZ\\xc9\\x05]u=\\x07X\\x91\\\\0\\x05\\x14j\\xf4P\\xfa\\x1dE\\xff28AZ\\xc9\\x05]u=\\x07X\\x91\\\\\\x180\\x0b@\\xbc@\\xe6\\xa9\\xc1\\xecjP!\\xb1N\\xc6_\\xe1k\\xaf\\xc2\\xc1~\\xb5\\xa38\\xb3\\x19\\t\\xbd\\xbd\\x96\\xfcV\\xb6\\x07\\xfe\\xec\\xc8q\"\\x9b\\xadX\\xdfg\\xfb\\xbaW\\x90(\\xfe\\xeb\\x14oqeV\\x119\\x06\\xae)Q\\x0e+G\\x89\\x18'\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.CurrentFabricIndex'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.ClusterRevision'>: 1\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x040\\xa5d\\x8eX4\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\xa1\\xe18\\x04\\x9b\\xf2E\\x8eh\\x13dwQ\\xd9\\x19\\xa5\\xe4\\x88h\\xe5q\\xacPCtY\\xb9\\xcc\\x94KQ\\xa85\\xfa\u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\x07\\x80q+\\xa6\\x9a%\\x8d\\x1f\\xf4MJ\\xa0\\x9e\u001b[0m\u001b[32m[\u001b[0m\u001b[32m\\xafW0\"\\x82\\xf4\\xbb'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m=\u001b[1;36m27424\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m=\u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.SupportedFabrics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m16\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.CommissionedFabrics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.TrustedRootCertificates'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x03\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x03\\x18$\\x07\\x01$\\x08\\x010\\tA\\x040\\xa5d\\x8eX4\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\xa1\\xe18\\x04\\x9b\\xf2E\\x8eh\\x13dwQ\\xd9\\x19\\xa5\\xe4\\x88h\\xe5q\\xacPCtY\\xb9\\xcc\\x94KQ\\xa85\\xfa\u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\x07\\x80q+\\xa6\\x9a%\\x8d\\x1f\\xf4MJ\\xa0\\x9e\u001b[0m\u001b[32m[\u001b[0m\u001b[32m\\xafW0\"\\x82\\xf4\\xbb7\\n5\\x01\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\x01\\x18$\\x02`0\\x04\\x14j\\xf4P\\xfa\\x1dE\\xff28AZ\\xc9\\x05\u001b[0m\u001b[32m]\u001b[0m\u001b[32mu\u001b[0m\u001b[32m=\\x07X\\x91\\\\0\\x05\\x14j\\xf4P\\xfa\\x1dE\\xff28AZ\\xc9\\x05\u001b[0m\u001b[32m]\u001b[0m\u001b[32mu\u001b[0m\u001b[32m=\\x07X\\x91\\\\\\x180\\x0b@\\xbc@\\xe6\\xa9\\xc1\\xecjP!\\xb1N\\xc6_\\xe1k\\xaf\\xc2\\xc1~\\xb5\\xa38\\xb3\\x19\\t\\xbd\\xbd\\x96\\xfcV\\xb6\\x07\\xfe\\xec\\xc8q\"\\x9b\\xadX\\xdfg\\xfb\\xbaW\\x90\u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\xfe\\xeb\\x14oqeV\\x119\\x06\\xae\u001b[0m\u001b[32m)\u001b[0m\u001b[32mQ\\x0e+G\\x89\\x18'\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.CurrentFabricIndex'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(1, [(Clusters.OperationalCredentials)])" + ] + }, + { + "cell_type": "markdown", + "id": "dbade62b", + "metadata": {}, + "source": [ + "Note that the `FabricsList` contains just a single item with a `fabriIndex` of 1, and a `fabricId` of 1." + ] + }, + { + "cell_type": "markdown", + "id": "7326ae6a", + "metadata": {}, + "source": [ + "### Create Controller on Fabric B" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a975776b", + "metadata": {}, + "outputs": [], + "source": [ + "devCtrl2 = ChipDeviceCtrl.ChipDeviceController(controllerNodeId=30)" + ] + }, + { + "cell_type": "markdown", + "id": "72b857b3", + "metadata": {}, + "source": [ + "### Open Commissioning Window\n", + "\n", + "The target right now doesn't accept commissioning requests. So let's go ahead and open the commissioning window to permit the second controller on Fabric B to commission the target. This request has to originate from the 1st controller." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "f4fca3f4", + "metadata": {}, + "outputs": [], + "source": [ + "await devCtrl.SendCommand(1, 0, Clusters.AdministratorCommissioning.Commands.OpenBasicCommissioningWindow(100))" + ] + }, + { + "cell_type": "markdown", + "id": "b7b2215e", + "metadata": {}, + "source": [ + "### Commission Target on Fabric B" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "41255a44", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2021-12-28 23:33:17 johnsj-macbookpro1.roam.corp.google.com chip.CTL[86631] ERROR Unable to find country code, defaulting to WW\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Established CASE with Device\n" + ] + }, + { + "data": { + "text/html": [ + "
True\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[3;92mTrue\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Node address has been updated\n", + "Commissioning complete\n" + ] + } + ], + "source": [ + "devCtrl2.CommissionIP(b'127.0.0.1', 20202021, 1)" + ] + }, + { + "cell_type": "markdown", + "id": "b17289ff", + "metadata": {}, + "source": [ + "### Read out the Fabric List to validate" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "903cb0fd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.AccessControl'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.AccessControl.Attributes.Acl'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.AccessControl.Attributes.Extension'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.AccessControl.Attributes.ClusterRevision'>: 1\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl.Attributes.Acl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl.Attributes.Extension'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl2.ReadAttribute(1, [(Clusters.AccessControl)])" + ] + }, + { + "cell_type": "markdown", + "id": "ebf71c37", + "metadata": {}, + "source": [ + "Note that the FabricsList contains two items now!" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "cf9e453e", + "metadata": {}, + "outputs": [ + { + "ename": "ChipStackError", + "evalue": "Chip Stack Error 11", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mChipStackError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/nq/rnhbb96s3sl9n9lrzgx40tfw008537/T/ipykernel_12727/1832887926.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ms\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mawait\u001b[0m \u001b[0mdevCtrl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mReadAttribute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mClusters\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mLevelControl\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m4\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m~/work/devel/ext-git/connectedhomeip-2/out/python_env/lib/python3.8/site-packages/chip/ChipDeviceCtrl.py\u001b[0m in \u001b[0;36mReadAttribute\u001b[0;34m(self, nodeid, attributes, returnClusterObject, reportInterval)\u001b[0m\n\u001b[1;32m 524\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mres\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 525\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_ChipStack\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mErrorToException\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 526\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;32mawait\u001b[0m \u001b[0mfuture\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 527\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 528\u001b[0m async def ReadEvent(self, nodeid: int, events: typing.List[typing.Union[\n", + "\u001b[0;31mChipStackError\u001b[0m: Chip Stack Error 11" + ] + } + ], + "source": [ + "s = await devCtrl.ReadAttribute(1, [(Clusters.LevelControl)], True, (0, 4))" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "713c1139-e0a2-469e-a471-593955a1b354", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
<Subscription (Id=13932082784090111118)>\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m<\u001b[0m\u001b[1;95mSubscription\u001b[0m\u001b[39m \u001b[0m\u001b[1;39m(\u001b[0m\u001b[33mId\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m13932082784090111118\u001b[0m\u001b[1;39m)\u001b[0m\u001b[1m>\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "s" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "a92d3e5d-ff49-455e-8e8e-fd96ef258eb3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "1: {\n",
+       "│   │   <class 'chip.clusters.Objects.LevelControl'>: LevelControl(\n",
+       "│   │   │   currentLevel=0,\n",
+       "│   │   │   remainingTime=0,\n",
+       "│   │   │   minLevel=0,\n",
+       "│   │   │   maxLevel=255,\n",
+       "│   │   │   currentFrequency=0,\n",
+       "│   │   │   minFrequency=0,\n",
+       "│   │   │   maxFrequency=0,\n",
+       "│   │   │   options=0,\n",
+       "│   │   │   onOffTransitionTime=0,\n",
+       "│   │   │   onLevel=254,\n",
+       "│   │   │   onTransitionTime=0,\n",
+       "│   │   │   offTransitionTime=0,\n",
+       "│   │   │   defaultMoveRate=0,\n",
+       "│   │   │   startUpCurrentLevel=0,\n",
+       "│   │   │   attributeList=None,\n",
+       "│   │   │   featureMap=None,\n",
+       "│   │   │   clusterRevision=3\n",
+       "│   │   )\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m1\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mLevelControl\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcurrentLevel\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mremainingTime\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mminLevel\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mmaxLevel\u001b[0m=\u001b[1;36m255\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcurrentFrequency\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mminFrequency\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mmaxFrequency\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moptions\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33monOffTransitionTime\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33monLevel\u001b[0m=\u001b[1;36m254\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33monTransitionTime\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moffTransitionTime\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mdefaultMoveRate\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mstartUpCurrentLevel\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mattributeList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mfeatureMap\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclusterRevision\u001b[0m=\u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "s.GetAttributes()" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "88032327-5acd-4d2f-892b-72dc41959ec0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attribute Changed:\n" + ] + }, + { + "data": { + "text/html": [ + "
{\n",
+       "'Endpoint': 1,\n",
+       "'Attribute': <class 'chip.clusters.Objects.OnOff.Attributes.OnTime'>,\n",
+       "'Value': 0\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Endpoint'\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Attribute'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnTime'\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Value'\u001b[0m: \u001b[1;36m0\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attribute Changed:\n" + ] + }, + { + "data": { + "text/html": [ + "
{\n",
+       "'Endpoint': 1,\n",
+       "'Attribute': <class 'chip.clusters.Objects.OnOff.Attributes.OnOff'>,\n",
+       "'Value': False\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Endpoint'\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Attribute'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnOff'\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Value'\u001b[0m: \u001b[3;91mFalse\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attribute Changed:\n" + ] + }, + { + "data": { + "text/html": [ + "
{\n",
+       "'Endpoint': 1,\n",
+       "'Attribute': <class 'chip.clusters.Objects.OnOff.Attributes.OnTime'>,\n",
+       "'Value': 0\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Endpoint'\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Attribute'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnTime'\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Value'\u001b[0m: \u001b[1;36m0\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attribute Changed:\n" + ] + }, + { + "data": { + "text/html": [ + "
{\n",
+       "'Endpoint': 1,\n",
+       "'Attribute': <class 'chip.clusters.Objects.OnOff.Attributes.OnOff'>,\n",
+       "'Value': False\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Endpoint'\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Attribute'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnOff'\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Value'\u001b[0m: \u001b[3;91mFalse\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.SendCommand(1, 1, Clusters.OnOff.Commands.Off())" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "87046a41-08ff-4de2-9a9b-400922280bd6", + "metadata": {}, + "outputs": [], + "source": [ + "await devCtrl.SendCommand(1, 1, Clusters.OnOff.Commands.On())" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "7957fc03-e91a-4a07-8b08-cc1e86e595c3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attribute Changed:\n" + ] + }, + { + "data": { + "text/html": [ + "
{\n",
+       "'Endpoint': 1,\n",
+       "'Attribute': <class 'chip.clusters.Objects.LevelControl.Attributes.CurrentLevel'>,\n",
+       "'Value': 1\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Endpoint'\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Attribute'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.CurrentLevel'\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Value'\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attribute Changed:\n" + ] + }, + { + "data": { + "text/html": [ + "
{\n",
+       "'Endpoint': 1,\n",
+       "'Attribute': <class 'chip.clusters.Objects.LevelControl.Attributes.CurrentLevel'>,\n",
+       "'Value': 100\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Endpoint'\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Attribute'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.CurrentLevel'\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Value'\u001b[0m: \u001b[1;36m100\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.SendCommand(1, 1, Clusters.LevelControl.Commands.MoveToLevel(100, 10, 0, 0))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cefa5cae-67f4-49a9-a4c1-285f315c51e2", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "matter-env", + "language": "python", + "name": "matter-env" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2+chromium.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Matter - REPL Basics.ipynb b/Matter - REPL Basics.ipynb new file mode 100644 index 00000000000000..1928f888710ea3 --- /dev/null +++ b/Matter - REPL Basics.ipynb @@ -0,0 +1,1139 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e8b2f5eb", + "metadata": {}, + "source": [ + "# Interaction Model Examples\n", + "\n", + "This notebook walks through the various interactions that can be initiated from the REPL towards a target using the Matter Interaction Model (IM) and Data Model (DM)." + ] + }, + { + "cell_type": "markdown", + "id": "99ce2877", + "metadata": {}, + "source": [ + "## Imports\n", + "\n", + "Let's first begin by setting up by importing some key modules that are needed to make it easier for us to interact with the Matter stack." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "52b40db6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
──────────────────────────────────────── Matter REPL ────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m──────────────────────────────────────── \u001b[0mMatter REPL\u001b[92m ────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "            \n",
+       "    \n",
+       "            Welcome to the Matter Python REPL!\n",
+       "    \n",
+       "            For help, please type matterhelp()\n",
+       "    \n",
+       "            To get more information on a particular object/class, you can pass\n",
+       "            that into matterhelp() as well.\n",
+       "    \n",
+       "            \n",
+       "
\n" + ], + "text/plain": [ + "\n", + " \n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m Welcome to the Matter Python REPL!\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m For help, please type \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m To get more information on a particular object/class, you can pass\u001b[0m\n", + "\u001b[1;34m that into \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\u001b[1;34m as well.\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m \u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
─────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m─────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-18 14:07:57 johnsj-macbookpro1.roam.corp.google.com root[52410] CRITICAL Loading configuration from /tmp/repl-storage.json...\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading CHIP DLL...\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Restoring FabricAdmin from storage to manage FabricId 1, FabricIndex 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mRestoring FabricAdmin from storage to manage FabricId \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m, FabricIndex \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 1(1)\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "Fabric Admins have been loaded and are available at fabricAdmins\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[34mFabric Admins have been loaded and are available at \u001b[0m\u001b[31mfabricAdmins\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Creating default device controller on fabric 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mCreating default device controller on fabric \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Allocating new controller with FabricId: 1(1), NodeId: 1\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "Default CHIP Device Controller has been initialized to manage fabricAdmins[0], and is \n",
+       "available as devCtrl\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n", + "\u001b[34mDefault CHIP Device Controller has been initialized to manage \u001b[0m\u001b[1;31mfabricAdmins\u001b[0m\u001b[1;31m[\u001b[0m\u001b[1;31m0\u001b[0m\u001b[1;31m]\u001b[0m\u001b[1;34m, and is \u001b[0m\n", + "\u001b[1;34mavailable as \u001b[0m\u001b[1;31mdevCtrl\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from rich import print\n", + "from rich.pretty import pprint\n", + "from rich import inspect\n", + "import logging\n", + "import chip\n", + "import chip.logging\n", + "from chip import ChipDeviceCtrl\n", + "import chip.clusters as Clusters\n", + "from chip.ChipReplStartup import *\n", + "from chip.ChipStack import *\n", + "import subprocess, sys" + ] + }, + { + "cell_type": "markdown", + "id": "78e14359", + "metadata": {}, + "source": [ + "## Initialization\n", + "\n", + "Next, let's initialize the REPL environment and the Matter Stack." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e3057f9d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
──────────────────────────────────────── Matter REPL ────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m──────────────────────────────────────── \u001b[0mMatter REPL\u001b[92m ────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "            \n",
+       "    \n",
+       "            Welcome to the Matter Python REPL!\n",
+       "    \n",
+       "            For help, please type matterhelp()\n",
+       "    \n",
+       "            To get more information on a particular object/class, you can pass\n",
+       "            that into matterhelp() as well.\n",
+       "    \n",
+       "            \n",
+       "
\n" + ], + "text/plain": [ + "\n", + " \n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m Welcome to the Matter Python REPL!\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m For help, please type \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m To get more information on a particular object/class, you can pass\u001b[0m\n", + "\u001b[1;34m that into \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\u001b[1;34m as well.\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m \u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
─────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m─────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ReplInit()\n", + "chipStack = ChipStack()\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "9cb06305", + "metadata": {}, + "source": [ + "## Launch Server\n", + "\n", + "Let's launch an instance of the `chip-all-clusters-app`." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "52ccd8c6", + "metadata": {}, + "outputs": [], + "source": [ + "subprocess.Popen(['pkill', '-f', 'chip-all-clusters-app'])\n", + "process = subprocess.Popen('./out/debug/chip-all-clusters-app', stdout=subprocess.DEVNULL)" + ] + }, + { + "cell_type": "markdown", + "id": "b33dec2e", + "metadata": {}, + "source": [ + "### Commission Target\n", + "\n", + "Commission the target with a NodeId of 1." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "5e964fe3", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-02 21:25:51 johnsj-macbookpro1.roam.corp.google.com chip.CTL[93727] ERROR Unable to find country code, defaulting to WW\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Established CASE with Device\n", + "Node address has been updated\n", + "Commissioning complete\n" + ] + }, + { + "data": { + "text/html": [ + "
True\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[3;92mTrue\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "devCtrl = ChipDeviceCtrl.ChipDeviceController(controllerNodeId=1)\n", + "devCtrl.CommissionIP(b'127.0.0.1', 20202021, 1)" + ] + }, + { + "cell_type": "markdown", + "id": "c22ea8ee", + "metadata": { + "tags": [] + }, + "source": [ + "## Invoke Commands" + ] + }, + { + "cell_type": "markdown", + "id": "4c94d599-e243-43de-8abe-bb4d9b1f52d4", + "metadata": {}, + "source": [ + "### Basic Command (Success Response)" + ] + }, + { + "cell_type": "markdown", + "id": "52e6e92e-0bc6-45f2-9b6b-74d43ba3048c", + "metadata": {}, + "source": [ + "Let's send a basic command to turn on/off the light on Endpoint 1." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "bed38512-91f8-4d4e-b6e1-b30749137bbd", + "metadata": {}, + "outputs": [], + "source": [ + "await devCtrl.SendCommand(1, 1, Clusters.OnOff.Commands.On())" + ] + }, + { + "cell_type": "markdown", + "id": "b1c0fe3c-95da-4980-9b9b-2a5ab602af44", + "metadata": {}, + "source": [ + "The receipt of a successful status response will result in the command just returning successfully. Otherwise, an exception will be thrown." + ] + }, + { + "cell_type": "markdown", + "id": "80c604b9-f6dc-4ec5-91e8-a6e806c821a6", + "metadata": {}, + "source": [ + "### Basic Command (Failure Response)" + ] + }, + { + "cell_type": "markdown", + "id": "753f5a54-4a75-41ed-a7c0-99c8cca8b6de", + "metadata": { + "tags": [] + }, + "source": [ + "If we send the same command to an invalid endpoint, an exception is thrown:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "2935f13b-ca16-4f9c-b320-8896c8465278", + "metadata": {}, + "outputs": [ + { + "ename": "InteractionModelError", + "evalue": "InteractionModelError: Failure (0x1)", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mInteractionModelError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/nq/rnhbb96s3sl9n9lrzgx40tfw008537/T/ipykernel_93727/18655580.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mawait\u001b[0m \u001b[0mdevCtrl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSendCommand\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mClusters\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mOnOff\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCommands\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mOn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m~/work/devel/ext-git/connectedhomeip-2/out/python_env/lib/python3.8/site-packages/chip/ChipDeviceCtrl.py\u001b[0m in \u001b[0;36mSendCommand\u001b[0;34m(self, nodeid, endpoint, payload, responseType)\u001b[0m\n\u001b[1;32m 420\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mres\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 421\u001b[0m \u001b[0mfuture\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_exception\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_ChipStack\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mErrorToException\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 422\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;32mawait\u001b[0m \u001b[0mfuture\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 423\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 424\u001b[0m \u001b[0;32masync\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mWriteAttribute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnodeid\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mattributes\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mtyping\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mList\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mtyping\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTuple\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mint\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mClusterObjects\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mClusterAttributeDescriptor\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mInteractionModelError\u001b[0m: InteractionModelError: Failure (0x1)" + ] + } + ], + "source": [ + "await devCtrl.SendCommand(1, 100, Clusters.OnOff.Commands.On())" + ] + }, + { + "cell_type": "markdown", + "id": "5296f2bc-5e9d-4b06-a7c1-f247ebe5eac2", + "metadata": {}, + "source": [ + "### Basic Command (Data Response)" + ] + }, + { + "cell_type": "markdown", + "id": "bb196da4-5162-4c4b-ae64-ef1d23a04eb9", + "metadata": { + "tags": [] + }, + "source": [ + "Here's an example of a command that sends back a data response, and how that is presented:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "33f34d12-79f4-4230-836b-2e66ea839440", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "TestListInt8UReverseResponse(\n",
+       "arg1=[\n",
+       "│   │   7,\n",
+       "│   │   5,\n",
+       "│   │   3,\n",
+       "│   │   1\n",
+       "]\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1;35mTestListInt8UReverseResponse\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33marg1\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m7\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m5\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.SendCommand(1, 1, Clusters.TestCluster.Commands.TestListInt8UReverseRequest([1, 3, 5, 7]))" + ] + }, + { + "cell_type": "markdown", + "id": "820fcede", + "metadata": { + "tags": [] + }, + "source": [ + "### Read out the Fabric List to validate" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "765fe963-80a6-41f6-a569-df5d71c6822c", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.OperationalCredentials'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'>: [\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04b\\xeeV\\x80\\x01\\xee\\xab1\\x0f|\\x01\\xc1\\xaf5\\x14\\xf0\\x18\\x8f\\xa2\\xa3\\xa8\\x8b \\x0c\\x8c\\xd5\\xb0\\xf6]BN\\rS=\\xa4U\\xeb\\xf5\\x82\\xbbdKU\\xc8\\xe9\\x16\\xeao}\\xcc\\xce<\\xbf^\\xd5\\xa5\\x06,L\\x93\\x1dX\\xc5\\xfc',\n",
+       "│   │   │   │   │   vendorId=26464,\n",
+       "│   │   │   │   │   fabricId=1,\n",
+       "│   │   │   │   │   nodeId=1,\n",
+       "│   │   │   │   │   label=''\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.SupportedFabrics'>: 16,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.CommissionedFabrics'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.TrustedRootCertificates'>: [\n",
+       "│   │   │   │   b'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04b\\xeeV\\x80\\x01\\xee\\xab1\\x0f|\\x01\\xc1\\xaf5\\x14\\xf0\\x18\\x8f\\xa2\\xa3\\xa8\\x8b \\x0c\\x8c\\xd5\\xb0\\xf6]BN\\rS=\\xa4U\\xeb\\xf5\\x82\\xbbdKU\\xc8\\xe9\\x16\\xeao}\\xcc\\xce<\\xbf^\\xd5\\xa5\\x06,L\\x93\\x1dX\\xc5\\xfc7\\n5\\x01)\\x01\\x18$\\x02`0\\x04\\x14q9\\x96)~h\\xbc\\x04:\\xc5\\x12\\xeb\\xa8\\x16y\\xd4\\xb2C\\xba\\xf50\\x05\\x14q9\\x96)~h\\xbc\\x04:\\xc5\\x12\\xeb\\xa8\\x16y\\xd4\\xb2C\\xba\\xf5\\x180\\x0b@\\x13K\\x909\\xd6\\xf2\\xbb\\x1c\\\\R/E\\xe7\\x00y\\xbf^d8\\x05\\x89\\x8c\\xbeK\\x14O\\xac\\x8c\\xd44\\x93\\n\\xb1\\xe6k\\xa7\\x9c\\xdc\\xc5\\xffR,\\xcc\\xb5\\xc4\\x84\\x01\\x92\\x9d.\\x9b\\xda\\x0f\\x1d\\xa2\\xccEz-\\x13\\x05\\x12\\x1d\\xcb\\x18'\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.CurrentFabricIndex'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.ClusterRevision'>: 1\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x04b\\xeeV\\x80\\x01\\xee\\xab1\\x0f|\\x01\\xc1\\xaf5\\x14\\xf0\\x18\\x8f\\xa2\\xa3\\xa8\\x8b \\x0c\\x8c\\xd5\\xb0\\xf6\u001b[0m\u001b[32m]\u001b[0m\u001b[32mBN\\\u001b[0m\u001b[32mrS\u001b[0m\u001b[32m=\\xa4U\\xeb\\xf5\\x82\\xbbdKU\\xc8\\xe9\\x16\\xeao\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xcc\\xce\u001b[0m\u001b[32m<\u001b[0m\u001b[32m\\xbf^\\xd5\\xa5\\x06,L\\x93\\x1dX\\xc5\\xfc'\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m26464\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m\u001b[39m=\u001b[0m\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;39m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;39m]\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[39m\u001b[0m: \u001b[1;36m16\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.CommissionedFabrics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.TrustedRootCertificates'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04b\\xeeV\\x80\\x01\\xee\\xab1\\x0f|\\x01\\xc1\\xaf5\\x14\\xf0\\x18\\x8f\\xa2\\xa3\\xa8\\x8b \\x0c\\x8c\\xd5\\xb0\\xf6\u001b[0m\u001b[32m]\u001b[0m\u001b[32mBN\\\u001b[0m\u001b[32mrS\u001b[0m\u001b[32m=\\xa4U\\xeb\\xf5\\x82\\xbbdKU\\xc8\\xe9\\x16\\xeao\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xcc\\xce\u001b[0m\u001b[32m<\u001b[0m\u001b[32m\\xbf^\\xd5\\xa5\\x06,L\\x93\\x1dX\\xc5\\xfc7\\n5\\x01\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\x01\\x18$\\x02`0\\x04\\x14q9\\x96\u001b[0m\u001b[32m)\u001b[0m\u001b[32m~h\\xbc\\x04:\\xc5\\x12\\xeb\\xa8\\x16y\\xd4\\xb2C\\xba\\xf50\\x05\\x14q9\\x96\u001b[0m\u001b[32m)\u001b[0m\u001b[32m~h\\xbc\\x04:\\xc5\\x12\\xeb\\xa8\\x16y\\xd4\\xb2C\\xba\\xf5\\x180\\x0b@\\x13K\\x909\\xd6\\xf2\\xbb\\x1c\\\\R/E\\xe7\\x00y\\xbf^d8\\x05\\x89\\x8c\\xbeK\\x14O\\xac\\x8c\\xd44\\x93\\n\\xb1\\xe6k\\xa7\\x9c\\xdc\\xc5\\xffR,\\xcc\\xb5\\xc4\\x84\\x01\\x92\\x9d.\\x9b\\xda\\x0f\\x1d\\xa2\\xccEz-\\x13\\x05\\x12\\x1d\\xcb\\x18'\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;39m]\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[39m\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(1, [(Clusters.OperationalCredentials)])" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "6802862a", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.Descriptor'>: Descriptor(\n",
+       "│   │   │   deviceList=[\n",
+       "│   │   │   │   DeviceType(\n",
+       "│   │   │   │   │   type=22,\n",
+       "│   │   │   │   │   revision=1\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   serverList=[\n",
+       "│   │   │   │   3,\n",
+       "│   │   │   │   4,\n",
+       "│   │   │   │   29,\n",
+       "│   │   │   │   30,\n",
+       "│   │   │   │   31,\n",
+       "│   │   │   │   40,\n",
+       "│   │   │   │   41,\n",
+       "│   │   │   │   42,\n",
+       "│   │   │   │   46,\n",
+       "│   │   │   │   48,\n",
+       "│   │   │   │   49,\n",
+       "│   │   │   │   50,\n",
+       "│   │   │   │   51,\n",
+       "│   │   │   │   52,\n",
+       "│   │   │   │   53,\n",
+       "│   │   │   │   54,\n",
+       "│   │   │   │   55,\n",
+       "│   │   │   │   60,\n",
+       "│   │   │   │   62,\n",
+       "│   │   │   │   63,\n",
+       "│   │   │   │   64,\n",
+       "│   │   │   │   65,\n",
+       "│   │   │   │   1029\n",
+       "│   │   │   ],\n",
+       "│   │   │   clientList=[],\n",
+       "│   │   │   partsList=[\n",
+       "│   │   │   │   1,\n",
+       "│   │   │   │   2\n",
+       "│   │   │   ],\n",
+       "│   │   │   attributeList=None,\n",
+       "│   │   │   featureMap=None,\n",
+       "│   │   │   clusterRevision=1\n",
+       "│   │   )\n",
+       "},\n",
+       "1: {\n",
+       "│   │   <class 'chip.clusters.Objects.Descriptor'>: Descriptor(\n",
+       "│   │   │   deviceList=[\n",
+       "│   │   │   │   DeviceType(\n",
+       "│   │   │   │   │   type=22,\n",
+       "│   │   │   │   │   revision=1\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   serverList=[\n",
+       "│   │   │   │   3,\n",
+       "│   │   │   │   4,\n",
+       "│   │   │   │   5,\n",
+       "│   │   │   │   6,\n",
+       "│   │   │   │   7,\n",
+       "│   │   │   │   8,\n",
+       "│   │   │   │   15,\n",
+       "│   │   │   │   29,\n",
+       "│   │   │   │   30,\n",
+       "│   │   │   │   37,\n",
+       "│   │   │   │   47,\n",
+       "│   │   │   │   57,\n",
+       "│   │   │   │   59,\n",
+       "│   │   │   │   64,\n",
+       "│   │   │   │   65,\n",
+       "│   │   │   │   69,\n",
+       "│   │   │   │   80,\n",
+       "│   │   │   │   257,\n",
+       "│   │   │   │   258,\n",
+       "│   │   │   │   259,\n",
+       "│   │   │   │   512,\n",
+       "│   │   │   │   513,\n",
+       "│   │   │   │   516,\n",
+       "│   │   │   │   768,\n",
+       "│   │   │   │   1024,\n",
+       "│   │   │   │   1026,\n",
+       "│   │   │   │   1027,\n",
+       "│   │   │   │   1028,\n",
+       "│   │   │   │   1029,\n",
+       "│   │   │   │   1030,\n",
+       "│   │   │   │   1280,\n",
+       "│   │   │   │   1283,\n",
+       "│   │   │   │   1284,\n",
+       "│   │   │   │   1285,\n",
+       "│   │   │   │   1286,\n",
+       "│   │   │   │   1287,\n",
+       "│   │   │   │   1288,\n",
+       "│   │   │   │   1289,\n",
+       "│   │   │   │   1290,\n",
+       "│   │   │   │   1291,\n",
+       "│   │   │   │   1292,\n",
+       "│   │   │   │   1293,\n",
+       "│   │   │   │   1294,\n",
+       "│   │   │   │   1295,\n",
+       "│   │   │   │   2820\n",
+       "│   │   │   ],\n",
+       "│   │   │   clientList=[],\n",
+       "│   │   │   partsList=[],\n",
+       "│   │   │   attributeList=None,\n",
+       "│   │   │   featureMap=None,\n",
+       "│   │   │   clusterRevision=1\n",
+       "│   │   )\n",
+       "},\n",
+       "2: {\n",
+       "│   │   <class 'chip.clusters.Objects.Descriptor'>: Descriptor(\n",
+       "│   │   │   deviceList=[\n",
+       "│   │   │   │   DeviceType(\n",
+       "│   │   │   │   │   type=22,\n",
+       "│   │   │   │   │   revision=1\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   serverList=[\n",
+       "│   │   │   │   4,\n",
+       "│   │   │   │   6,\n",
+       "│   │   │   │   29,\n",
+       "│   │   │   │   1030\n",
+       "│   │   │   ],\n",
+       "│   │   │   clientList=[],\n",
+       "│   │   │   partsList=[],\n",
+       "│   │   │   attributeList=None,\n",
+       "│   │   │   featureMap=None,\n",
+       "│   │   │   clusterRevision=1\n",
+       "│   │   )\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mdeviceList\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mDeviceType\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[1;36m22\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mserverList\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m29\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m30\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m31\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m40\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m41\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m42\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m46\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m48\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m49\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m50\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m51\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m52\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m53\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m54\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m55\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m60\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m62\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m63\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m64\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m65\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1029\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclientList\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mpartsList\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mattributeList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mfeatureMap\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclusterRevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m1\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mdeviceList\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mDeviceType\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[1;36m22\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mserverList\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m5\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m6\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m7\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m8\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m15\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m29\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m30\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m37\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m47\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m57\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m59\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m64\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m65\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m69\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m80\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m257\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m258\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m259\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m512\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m513\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m516\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m768\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1024\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1026\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1027\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1028\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1029\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1030\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1280\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1283\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1284\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1285\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1286\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1287\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1288\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1289\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1290\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1291\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1292\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1293\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1294\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1295\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m2820\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclientList\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mpartsList\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mattributeList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mfeatureMap\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclusterRevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m2\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mdeviceList\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mDeviceType\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[1;36m22\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mserverList\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m6\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m29\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1030\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclientList\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mpartsList\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mattributeList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mfeatureMap\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclusterRevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(1, [(Clusters.Descriptor)], True)" + ] + }, + { + "cell_type": "markdown", + "id": "dbade62b", + "metadata": {}, + "source": [ + "Note that the `FabricsList` contains just a single item with a `fabriIndex` of 1, and a `fabricId` of 1." + ] + }, + { + "cell_type": "markdown", + "id": "7326ae6a", + "metadata": { + "tags": [] + }, + "source": [ + "### Create Controller on Fabric B" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "a975776b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "[\n",
+       "1,\n",
+       "2,\n",
+       "3,\n",
+       "4\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m4\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "a = [1, 2, 3, 4]\n", + "a" + ] + }, + { + "cell_type": "markdown", + "id": "72b857b3", + "metadata": {}, + "source": [ + "### Open Commissioning Window\n", + "\n", + "The target right now doesn't accept commissioning requests. So let's go ahead and open the commissioning window to permit the second controller on Fabric B to commission the target. This request has to originate from the 1st controller." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f4fca3f4", + "metadata": {}, + "outputs": [], + "source": [ + "await devCtrl.SendCommand(1, 0, Clusters.AdministratorCommissioning.Commands.OpenBasicCommissioningWindow(100))" + ] + }, + { + "cell_type": "markdown", + "id": "b7b2215e", + "metadata": {}, + "source": [ + "### Commission Target on Fabric B" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "41255a44", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2021-12-30 21:35:59 johnsj-macbookpro1.roam.corp.google.com chip.CTL[58883] ERROR Unable to find country code, defaulting to WW\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Established CASE with Device\n" + ] + }, + { + "data": { + "text/html": [ + "
True\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[3;92mTrue\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Node address has been updated\n", + "Commissioning complete\n" + ] + } + ], + "source": [ + "devCtrl2.CommissionIP(b'127.0.0.1', 20202021, 1)" + ] + }, + { + "cell_type": "markdown", + "id": "b17289ff", + "metadata": {}, + "source": [ + "### Read out the Fabric List to validate" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "903cb0fd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.OperationalCredentials'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'>: [\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04b\\xeeV\\x80\\x01\\xee\\xab1\\x0f|\\x01\\xc1\\xaf5\\x14\\xf0\\x18\\x8f\\xa2\\xa3\\xa8\\x8b \\x0c\\x8c\\xd5\\xb0\\xf6]BN\\rS=\\xa4U\\xeb\\xf5\\x82\\xbbdKU\\xc8\\xe9\\x16\\xeao}\\xcc\\xce<\\xbf^\\xd5\\xa5\\x06,L\\x93\\x1dX\\xc5\\xfc',\n",
+       "│   │   │   │   │   vendorId=26464,\n",
+       "│   │   │   │   │   fabricId=1,\n",
+       "│   │   │   │   │   nodeId=1,\n",
+       "│   │   │   │   │   label=''\n",
+       "│   │   │   │   ),\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=2,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04G+A\\xc6\\x15\\xb0\\xa6\\x1e\\xb2_J\\x8e\\xb1b\\xc6\\x16\\xcd\\xa8\\xe63\\x98\\xb8\\x7fr\\x9a\\xfe\\x01#\\xe0\\x8fw4\\xc1[\\x17\\xd1\\x81.\\xa0\\r\\x90\\xef|\\xf2\\xe3\\xe3\\xf6\\x82\\x91@U\\x90N\\xbd\\xdb\\xb2 h\\r\\x10w\\xf69\\x93',\n",
+       "│   │   │   │   │   vendorId=26464,\n",
+       "│   │   │   │   │   fabricId=2,\n",
+       "│   │   │   │   │   nodeId=1,\n",
+       "│   │   │   │   │   label=''\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.SupportedFabrics'>: 16,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.CommissionedFabrics'>: 2,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.TrustedRootCertificates'>: [\n",
+       "│   │   │   │   b'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04b\\xeeV\\x80\\x01\\xee\\xab1\\x0f|\\x01\\xc1\\xaf5\\x14\\xf0\\x18\\x8f\\xa2\\xa3\\xa8\\x8b \\x0c\\x8c\\xd5\\xb0\\xf6]BN\\rS=\\xa4U\\xeb\\xf5\\x82\\xbbdKU\\xc8\\xe9\\x16\\xeao}\\xcc\\xce<\\xbf^\\xd5\\xa5\\x06,L\\x93\\x1dX\\xc5\\xfc7\\n5\\x01)\\x01\\x18$\\x02`0\\x04\\x14q9\\x96)~h\\xbc\\x04:\\xc5\\x12\\xeb\\xa8\\x16y\\xd4\\xb2C\\xba\\xf50\\x05\\x14q9\\x96)~h\\xbc\\x04:\\xc5\\x12\\xeb\\xa8\\x16y\\xd4\\xb2C\\xba\\xf5\\x180\\x0b@\\x13K\\x909\\xd6\\xf2\\xbb\\x1c\\\\R/E\\xe7\\x00y\\xbf^d8\\x05\\x89\\x8c\\xbeK\\x14O\\xac\\x8c\\xd44\\x93\\n\\xb1\\xe6k\\xa7\\x9c\\xdc\\xc5\\xffR,\\xcc\\xb5\\xc4\\x84\\x01\\x92\\x9d.\\x9b\\xda\\x0f\\x1d\\xa2\\xccEz-\\x13\\x05\\x12\\x1d\\xcb\\x18',\n",
+       "│   │   │   │   b'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x02\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x02\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04G+A\\xc6\\x15\\xb0\\xa6\\x1e\\xb2_J\\x8e\\xb1b\\xc6\\x16\\xcd\\xa8\\xe63\\x98\\xb8\\x7fr\\x9a\\xfe\\x01#\\xe0\\x8fw4\\xc1[\\x17\\xd1\\x81.\\xa0\\r\\x90\\xef|\\xf2\\xe3\\xe3\\xf6\\x82\\x91@U\\x90N\\xbd\\xdb\\xb2 h\\r\\x10w\\xf69\\x937\\n5\\x01)\\x01\\x18$\\x02`0\\x04\\x14\\xc6\\xb8;\\xbf\"u\\xb8f\"\\x99\\x10\\xc5o\\xdf\\xc4(\\x1b\\xbd\\xeeh0\\x05\\x14\\xc6\\xb8;\\xbf\"u\\xb8f\"\\x99\\x10\\xc5o\\xdf\\xc4(\\x1b\\xbd\\xeeh\\x180\\x0b@\\tQ;Y\\xb6\\x82I[\\x85k\\xfdot\\xb6\\x98\\x04\\x1d\\xf9SJ\\xf74\\xfa\\xbc\\xa1OWM\\xef\\xec\\xcf|\\xad[\\x17\\xd5/\\xa9\\xbb\\xb4\\xbc\\xb1\\xafa\\x06\\xdb\\xcd]E\\xdf\\x84\\xcf\\xb6\\x10\\xd9\\xc7\\xf5l\\xef\\x96K6\\xbd\\xa5\\x18'\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.CurrentFabricIndex'>: 2,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.ClusterRevision'>: 1\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x04b\\xeeV\\x80\\x01\\xee\\xab1\\x0f|\\x01\\xc1\\xaf5\\x14\\xf0\\x18\\x8f\\xa2\\xa3\\xa8\\x8b \\x0c\\x8c\\xd5\\xb0\\xf6\u001b[0m\u001b[32m]\u001b[0m\u001b[32mBN\\\u001b[0m\u001b[32mrS\u001b[0m\u001b[32m=\\xa4U\\xeb\\xf5\\x82\\xbbdKU\\xc8\\xe9\\x16\\xeao\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xcc\\xce\u001b[0m\u001b[32m<\u001b[0m\u001b[32m\\xbf^\\xd5\\xa5\\x06,L\\x93\\x1dX\\xc5\\xfc'\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m26464\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m\u001b[39m=\u001b[0m\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;39m)\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1;39m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m\u001b[39m=\u001b[0m\u001b[32mb\u001b[0m\u001b[32m'\\x04G+A\\xc6\\x15\\xb0\\xa6\\x1e\\xb2_J\\x8e\\xb1b\\xc6\\x16\\xcd\\xa8\\xe63\\x98\\xb8\\x7fr\\x9a\\xfe\\x01#\\xe0\\x8fw4\\xc1\u001b[0m\u001b[32m[\u001b[0m\u001b[32m\\x17\\xd1\\x81.\\xa0\\r\\x90\\xef|\\xf2\\xe3\\xe3\\xf6\\x82\\x91@U\\x90N\\xbd\\xdb\\xb2 h\\r\\x10w\\xf69\\x93'\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m26464\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m2\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m\u001b[39m=\u001b[0m\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;39m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;39m]\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[39m\u001b[0m: \u001b[1;36m16\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.CommissionedFabrics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.TrustedRootCertificates'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04b\\xeeV\\x80\\x01\\xee\\xab1\\x0f|\\x01\\xc1\\xaf5\\x14\\xf0\\x18\\x8f\\xa2\\xa3\\xa8\\x8b \\x0c\\x8c\\xd5\\xb0\\xf6\u001b[0m\u001b[32m]\u001b[0m\u001b[32mBN\\\u001b[0m\u001b[32mrS\u001b[0m\u001b[32m=\\xa4U\\xeb\\xf5\\x82\\xbbdKU\\xc8\\xe9\\x16\\xeao\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xcc\\xce\u001b[0m\u001b[32m<\u001b[0m\u001b[32m\\xbf^\\xd5\\xa5\\x06,L\\x93\\x1dX\\xc5\\xfc7\\n5\\x01\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\x01\\x18$\\x02`0\\x04\\x14q9\\x96\u001b[0m\u001b[32m)\u001b[0m\u001b[32m~h\\xbc\\x04:\\xc5\\x12\\xeb\\xa8\\x16y\\xd4\\xb2C\\xba\\xf50\\x05\\x14q9\\x96\u001b[0m\u001b[32m)\u001b[0m\u001b[32m~h\\xbc\\x04:\\xc5\\x12\\xeb\\xa8\\x16y\\xd4\\xb2C\\xba\\xf5\\x180\\x0b@\\x13K\\x909\\xd6\\xf2\\xbb\\x1c\\\\R/E\\xe7\\x00y\\xbf^d8\\x05\\x89\\x8c\\xbeK\\x14O\\xac\\x8c\\xd44\\x93\\n\\xb1\\xe6k\\xa7\\x9c\\xdc\\xc5\\xffR,\\xcc\\xb5\\xc4\\x84\\x01\\x92\\x9d.\\x9b\\xda\\x0f\\x1d\\xa2\\xccEz-\\x13\\x05\\x12\\x1d\\xcb\\x18'\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x02\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x02\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04G+A\\xc6\\x15\\xb0\\xa6\\x1e\\xb2_J\\x8e\\xb1b\\xc6\\x16\\xcd\\xa8\\xe63\\x98\\xb8\\x7fr\\x9a\\xfe\\x01#\\xe0\\x8fw4\\xc1\u001b[0m\u001b[32m[\u001b[0m\u001b[32m\\x17\\xd1\\x81.\\xa0\\r\\x90\\xef|\\xf2\\xe3\\xe3\\xf6\\x82\\x91@U\\x90N\\xbd\\xdb\\xb2 h\\r\\x10w\\xf69\\x937\\n5\\x01\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\x01\\x18$\\x02`0\\x04\\x14\\xc6\\xb8;\\xbf\"u\\xb8f\"\\x99\\x10\\xc5o\\xdf\\xc4\u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\x1b\\xbd\\xeeh0\\x05\\x14\\xc6\\xb8;\\xbf\"u\\xb8f\"\\x99\\x10\\xc5o\\xdf\\xc4\u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\x1b\\xbd\\xeeh\\x180\\x0b@\\tQ;Y\\xb6\\x82I\u001b[0m\u001b[32m[\u001b[0m\u001b[32m\\x85k\\xfdot\\xb6\\x98\\x04\\x1d\\xf9SJ\\xf74\\xfa\\xbc\\xa1OWM\\xef\\xec\\xcf|\\xad\u001b[0m\u001b[32m[\u001b[0m\u001b[32m\\x17\\xd5/\\xa9\\xbb\\xb4\\xbc\\xb1\\xafa\\x06\\xdb\\xcd\u001b[0m\u001b[32m]\u001b[0m\u001b[32mE\\xdf\\x84\\xcf\\xb6\\x10\\xd9\\xc7\\xf5l\\xef\\x96K6\\xbd\\xa5\\x18'\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;39m]\u001b[0m\u001b[39m,\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[39m\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl2.ReadAttribute(1, [(Clusters.OperationalCredentials)])" + ] + }, + { + "cell_type": "markdown", + "id": "ebf71c37", + "metadata": {}, + "source": [ + "Note that the FabricsList contains two items now!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "matter-env-2", + "language": "python", + "name": "matter-env-2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2+chromium.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/guides/matter-repl.md b/docs/guides/matter-repl.md new file mode 100644 index 00000000000000..c9a6aa86ce1684 --- /dev/null +++ b/docs/guides/matter-repl.md @@ -0,0 +1,165 @@ +# Matter Python REPL + +The Matter Python REPL is a native IPython shell environment loaded with a +Python-wrapped version of the C++ Matter stack to permit interacting as a +controller to other Matter-compliant devices. + +You can interact with the REPL in a one of three ways: + +1. Through an IPython shell built from source +2. Through a locally built 'REPL Playground', which is a Jupyter Lab environment + that supports launching both a native IPython shell as well as Guide + Notebooks. +3. Through a cloud-hosted REPL Playground that has pre-built versions of the + REPL that can be interacted with through a browser. + +This guide provides instructions on how to utilize its various features. + +### + +## Source files + +You can find source files of the Python CHIP Controller tool in the +`src/controller/python` directory. + +The tool uses the generic CHIP Device Controller library, available in the +`src/controller` directory. + +## Building + +Please follow the instructions +[here](./python_chip_controller_building.md#building) to build the Python +virtual environment. + +## Launching the REPL + +1. Activate the Python virtual environment: + + ``` + source out/python_env/bin/activate + ``` + +2. Launch the REPL. + + ``` + sudo out/python_env/bin/chip-repl + ``` + +> By default, the REPL points to `/tmp/repl-storage.json` for persistent +> storage. You can over-ride that location by passing in `--storagepath ` +> to the above invocation. + +## REPL Playground + +The REPL playground is a Jupyter Lab instance that allows you to interact with +the REPL from a web browser (or a Jupyter Notebook client of your choice!). It +contains the entire REPL encapsulated as an IPython kernel. + +### Locally Hosted + +The locally hosted version requires you to follow the build instructions below +to initially setup your Python environment. + +Then: + +1. Install + [Jupyter Lab](https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html) + (not within the virtualenv!) + +``` +pip3 install jupyterlab ipykernel +``` + +2. Install the [Python LSP](https://github.com/jupyter-lsp/jupyterlab-lsp) + extension for better code autocompletion in the playground. + +``` +pip3 install jupyterlab-lsp +pip3 install python-lsp-server +``` + +3. Every virtual env needs to be installed as a 'kernel' in Jupyter Lab. To do + so, activate the virtual env and run: + +``` +python -m ipykernel install +``` + +4. Navigate to the SDK root folder and launch Jupyter Lab (not from within + virtual env!) + +``` +jupyter-lab +``` + +This will automatically launch the playground on your browser. + +5. (Optional) To enable live code completions, in the Jupyter Lab Interface, go + to "Settings" → "Advanced Settings Editor" → "Code Completion". In the "User + Preferences" section, add the following: + +``` +{ + "continuousHinting": true, + "showDocumentation": true, + "theme": 'material' +} +``` + +Now, when you type, it should auto complete functions/objects/etc. + +For more details, go to the +[Python LSP](https://github.com/jupyter-lsp/jupyterlab-lsp) page. + +### Cloud Hosted + +A pre-built version of the REPL playground is made available through the cloud. +This is ideal if you're new to the REPL and want to try it out without having to +follow the build and launch instructions below. You can also use this to +prototype various bits of logic in Python as well as interact with +all-clusters-app from a browser. + +The playground can be accessed [here](http://35.236.121.59/). + +> **NOTE:** You have to create a user ID when accessing the above for the first +> time (password can be blank). That creates a sandboxed environment for you to +> play in. There-after, you'll always be re-directed straight to the Jupyter Lab +> landing page. + +> **NOTE:** The sandbox is temporary. After an hour of inactivity, the sandbox +> is deleted and your saved contents will be lost. + +For more information on Jupyter Lab, check out +[these](https://jupyterlab.readthedocs.io/en/stable/user/interface.html) docs. + +### IPython REPL + +Going through the above isn't terribly useful, since all you'll be able to do is +launch the REPL environment itself through the IPython shell. + +To launch the IPython REPL, launch "matter-env" from the "Console" tab in the +Launcher. + +### Guide Notebooks + +A number of Jupyter Notebooks have been written that serve as both guides for +interacting with the REPL _as well as_ being launchable directly into the +cloud-hosted playground. + +The following icon is present at the top of applicable guides that can be +launched into the playground: + + +drawing + +

+ +## Guides + +[REPL Basics](https://deepnote.com/viewer/github/project-chip/connectedhomeip/blob/master/docs/guides/repl/Matter%20-%20REPL%20Intro.ipynb) + +[Using the IM](https://deepnote.com/viewer/github/project-chip/connectedhomeip/blob/master/docs/guides/repl/Matter%20-%20Basic%20Interactions.ipynb) + +[Multi Fabric Commissioning](https://deepnote.com/viewer/github/project-chip/connectedhomeip/blob/master/docs/guides/repl/Matter%20-%20Multi%20Fabric%20Commissioning.ipynb) + +[Access Control](https://deepnote.com/viewer/github/project-chip/connectedhomeip/blob/master/docs/guides/repl/Matter%20-%20Access%20Control.ipynb) diff --git a/docs/guides/repl/Matter - Access Control.ipynb b/docs/guides/repl/Matter - Access Control.ipynb new file mode 100644 index 00000000000000..ac4534af86376e --- /dev/null +++ b/docs/guides/repl/Matter - Access Control.ipynb @@ -0,0 +1,885 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e8b2f5eb", + "metadata": { + "tags": [] + }, + "source": [ + "# Access Control\n", + "\n", + "\n", + "\"drawing\"\n", + "\n", + "

\n", + "\n", + "This document explains how to use Access Control in Matter, and will be updated as development proceeds." + ] + }, + { + "cell_type": "markdown", + "id": "2dce5632", + "metadata": {}, + "source": [ + "## What Does and Doesn’t Work Right Now?\n", + "\n", + "Briefly, you can read and write the entire ACL attribute in the all-clusters-app, but Access Control isn’t yet turned on, so it won’t affect interactions. There’s almost no error checking when writing the ACL attribute (e.g. ensuring subjects match auth mode, only your fabric can be written, etc.) so exercise caution for now." + ] + }, + { + "cell_type": "markdown", + "id": "99ce2877", + "metadata": { + "tags": [] + }, + "source": [ + "## Initialization\n", + "\n", + "Let's first begin by setting up by importing some key modules that are needed to make it easier for us to interact with the Matter stack.\n", + "\n", + "> **NOTE**: _This is not needed if you launch the REPL from the command-line._" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "bad327b7-c78a-4c46-b224-077fe7539ee1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
──────────────────────────────────────── Matter REPL ────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m──────────────────────────────────────── \u001b[0mMatter REPL\u001b[92m ────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "            \n",
+       "    \n",
+       "            Welcome to the Matter Python REPL!\n",
+       "    \n",
+       "            For help, please type matterhelp()\n",
+       "    \n",
+       "            To get more information on a particular object/class, you can pass\n",
+       "            that into matterhelp() as well.\n",
+       "    \n",
+       "            \n",
+       "
\n" + ], + "text/plain": [ + "\n", + " \n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m Welcome to the Matter Python REPL!\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m For help, please type \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m To get more information on a particular object/class, you can pass\u001b[0m\n", + "\u001b[1;34m that into \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\u001b[1;34m as well.\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m \u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
─────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m─────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-25 16:59:51 johnsj-macbookpro1.roam.corp.google.com root[28183] CRITICAL Loading configuration from /tmp/repl-storage.json...\n", + "2022-01-25 16:59:51 johnsj-macbookpro1.roam.corp.google.com chip.DL[28183] ERROR MAC is not known, using a default.\n", + "2022-01-25 16:59:51 johnsj-macbookpro1.roam.corp.google.com chip.DL[28183] ERROR Register (kDNSServiceErr_NameConflict)\n", + "2022-01-25 16:59:51 johnsj-macbookpro1.roam.corp.google.com chip.DIS[28183] ERROR Failed to advertise unprovisioned commissionable node: ../../src/platform/Darwin/DnssdImpl.cpp:302: CHIP Error 0x000000AC: Internal error\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Restoring FabricAdmin from storage to manage FabricId 1, FabricIndex 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mRestoring FabricAdmin from storage to manage FabricId \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m, FabricIndex \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 1(1)\n" + ] + }, + { + "data": { + "text/html": [ + "
Restoring FabricAdmin from storage to manage FabricId 2, FabricIndex 2...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mRestoring FabricAdmin from storage to manage FabricId \u001b[0m\u001b[1;38;5;129m2\u001b[0m\u001b[38;5;129m, FabricIndex \u001b[0m\u001b[1;38;5;129m2\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 2(2)\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "Fabric Admins have been loaded and are available at fabricAdmins\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[34mFabric Admins have been loaded and are available at \u001b[0m\u001b[31mfabricAdmins\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Creating default device controller on fabric 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mCreating default device controller on fabric \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Allocating new controller with FabricId: 1(1), NodeId: 1\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "Default CHIP Device Controller has been initialized to manage fabricAdmins[0], and is \n",
+       "available as devCtrl\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n", + "\u001b[34mDefault CHIP Device Controller has been initialized to manage \u001b[0m\u001b[1;31mfabricAdmins\u001b[0m\u001b[1;31m[\u001b[0m\u001b[1;31m0\u001b[0m\u001b[1;31m]\u001b[0m\u001b[1;34m, and is \u001b[0m\n", + "\u001b[1;34mavailable as \u001b[0m\u001b[1;31mdevCtrl\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import chip.native\n", + "import pkgutil\n", + "module = pkgutil.get_loader('chip.ChipReplStartup')\n", + "%run {module.path}" + ] + }, + { + "cell_type": "markdown", + "id": "7a082d33-bebd-4b34-b8e3-df59ed429c54", + "metadata": {}, + "source": [ + "## Commission and Setup Server" + ] + }, + { + "cell_type": "markdown", + "id": "9cb06305", + "metadata": {}, + "source": [ + "### Launch Server\n", + "\n", + "Let's launch an instance of the `chip-all-clusters-app`." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "52ccd8c6", + "metadata": {}, + "outputs": [], + "source": [ + "import time, os\n", + "import subprocess\n", + "subprocess.Popen(['pkill', '-f', 'chip-all-clusters-app'])\n", + "time.sleep(1)\n", + "\n", + "# So that the all-clusters-app won't boot with stale prior state. \n", + "subprocess.Popen(['rm', '-rf', '/tmp/chip_*'])\n", + "time.sleep(1)\n", + "\n", + "# The location of the all-clusters-app in the cloud playground is one level higher - adjust for this by testing for file presence.\n", + "if (os.path.isfile('../../../out/debug/chip-all-clusters-app')):\n", + " appPath = '../../../out/debug/chip-all-clusters-app'\n", + "else:\n", + " appPath = '../../../../out/debug/chip-all-clusters-app'\n", + " \n", + "process = subprocess.Popen(appPath, stdout=subprocess.DEVNULL)\n", + "time.sleep(1)" + ] + }, + { + "cell_type": "markdown", + "id": "b33dec2e", + "metadata": {}, + "source": [ + "### Commission Target\n", + "\n", + "Commission the target with a NodeId of 1." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "5e964fe3", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-25 16:59:54 johnsj-macbookpro1.roam.corp.google.com chip.CTL[28183] ERROR Unable to find country code, defaulting to WW\n", + "2022-01-25 16:59:54 johnsj-macbookpro1.roam.corp.google.com chip.SC[28183] ERROR The device does not support GetClock_RealTimeMS() API. This will eventually result in CASE session setup failures.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Node address has been updated\n", + "Commissioning complete\n" + ] + }, + { + "data": { + "text/html": [ + "
True\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[3;92mTrue\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "devCtrl.CommissionIP(b'127.0.0.1', 20202021, 2)" + ] + }, + { + "cell_type": "markdown", + "id": "c22ea8ee", + "metadata": { + "tags": [] + }, + "source": [ + "## Bootstrap ACLs" + ] + }, + { + "cell_type": "markdown", + "id": "372ae9a4", + "metadata": {}, + "source": [ + "(For now) normally after commissioning there would be at least a single admin entry, but currently the ACL will be empty, so add that entry manually. This step will be removed later when it’s no longer necessary." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "058504b3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.OperationalCredentials'>: OperationalCredentials(\n",
+       "│   │   │   NOCs=[\n",
+       "│   │   │   │   NOCStruct(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   noc=b'\\x150\\x01\\x01\\x01$\\x02\\x017\\x03$\\x13\\x01$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x11\\x02$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04\\x19\\x1ef\\xaa\\x8d_A\\x19\\x9f\\xee\\xa1\\x1fn\\x82\\xb6}(\\xd6\\x00\\'\\xeb\\x80Y\\xf9\\xd7\\xa8\\xbe\\x98\\xce\\xba4v\\xa0\\xa0\\xa9\\xbaUO)?\\xbb\\xe0\\xa4\\x12r\\x0cb\\xe0\\xc8\\xa7r\\xe3\\xd5\\x8e\\x159\\xc6\\xaf\\xc8\\xbc\\xb4\\x8b\\xf9E7\\n5\\x01(\\x01\\x18$\\x02\\x016\\x03\\x04\\x02\\x04\\x01\\x180\\x04\\x14\\x1f\\x87b\\xe9`2\\x03C{o`\\x9e\\x14\\xe3\\x8c\\x0b\\x83\\xcd\\x10Z0\\x05\\x14p\\xfc\\xf9\\nFI\\xba9\\xb6SH\\xcb\\xd0meg\\n\\t\\\\=\\x180\\x0b@\\xd3\\x03x<\\x0f\\xdc\\xceBl\\x01\\xfb[Kly+\\xd4\\xab\\xa08\\xd3f \\xa5\\xb9\\xb4aP\\xce|\\xee\"to\\x17\\xc1m\\xcfQ\\x10pq=7\\r\\xf6\\xe4\\x89+\\xcb\\x98\\xa9\\x176T\\x82\\x83\\x8d\\x04#\\xa2\\xd3\\xf2\\xb6\\x18',\n",
+       "│   │   │   │   │   icac=b'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x13\\x01$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04,\\x0c\\x82d\\xa8\\xd8-o\\x860Q\\xeb\\x8d\\x87\\xe6x\\x9e\\x0b\\xf8\\xc91\\xa9\\xc5\\x01nxB\\x17h\\xbc\\x98]\\xc9&\\x19\\x9f\\xde\\x97&\\x80M\\xca\\x8b\\xa1\\xa0g\\xfd\\xae}\\x12\\x8a\\x98\\x08\\x86k\\xc7=\\xc3\\xea\\x0e\\xb0\\xf0p\\x057\\n5\\x01)\\x01\\x18$\\x02`0\\x04\\x14p\\xfc\\xf9\\nFI\\xba9\\xb6SH\\xcb\\xd0meg\\n\\t\\\\=0\\x05\\x14~\\xf0\\n\\'\\'\\x89\\xc26\\xa8\\xdaz\\xbeCv\\xb2\\x7fn\\xca^\\xb5\\x180\\x0b@\\x11\\xa5\\xf9\\x80\\x1a\\x9c\\xe5\\xbf\\x1e\\xb3\\n\\x83\\x0eW6!\\x0f\\xb0,\\xa7\\xdb\\xb0\\xe3B\\xdc\\\\\\xec\\xbb\\x02\\xc2\\x04\\xd9\\x0c\\xa7\\xdfj\\x1a\\x15]\\x18\\x08\\xdfFz%)b\\xfa\\x9b\\xca\\x99\\xccY\\x01\\xa7}\\xf1|\\xe6\\xfe\\xf0*\\x10W\\x18'\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   fabricsList=[\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04\\xa2\\x88}\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x98',\n",
+       "│   │   │   │   │   vendorId=31968,\n",
+       "│   │   │   │   │   fabricId=1,\n",
+       "│   │   │   │   │   nodeId=2,\n",
+       "│   │   │   │   │   label=''\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   supportedFabrics=16,\n",
+       "│   │   │   commissionedFabrics=1,\n",
+       "│   │   │   trustedRootCertificates=[\n",
+       "│   │   │   │   b'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04\\xa2\\x88}\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x987\\n5\\x01)\\x01\\x18$\\x02`0\\x04\\x14~\\xf0\\n\\'\\'\\x89\\xc26\\xa8\\xdaz\\xbeCv\\xb2\\x7fn\\xca^\\xb50\\x05\\x14~\\xf0\\n\\'\\'\\x89\\xc26\\xa8\\xdaz\\xbeCv\\xb2\\x7fn\\xca^\\xb5\\x180\\x0b@3;\\xd5n\\xa0\\xb1O\\xecI:\\x9cM\\xf4u\\x12a\\x96\\x1d\\x13\\x19\\xa4D\\xb3v&_o.(\\xcbs\\xeb\\xc0\\xc4\\xb80\\xc2\\xecF4\\xfbV\\'\\xf7X\\xe2A\\xaa\\xa5l\\r5\\xba\\xbd\\xa4I&C\\xff\\xed\\xd8\\xa8_\\x06\\x18'\n",
+       "│   │   │   ],\n",
+       "│   │   │   currentFabricIndex=1,\n",
+       "│   │   │   attributeList=None,\n",
+       "│   │   │   featureMap=None,\n",
+       "│   │   │   clusterRevision=1\n",
+       "│   │   )\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mOperationalCredentials\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mNOCs\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mNOCStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnoc\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x150\\x01\\x01\\x01$\\x02\\x017\\x03$\\x13\\x01$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x11\\x02$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04\\x19\\x1ef\\xaa\\x8d_A\\x19\\x9f\\xee\\xa1\\x1fn\\x82\\xb6\u001b[0m\u001b[32m}\u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\xd6\\x00\\'\\xeb\\x80Y\\xf9\\xd7\\xa8\\xbe\\x98\\xce\\xba4v\\xa0\\xa0\\xa9\\xbaUO\u001b[0m\u001b[32m)\u001b[0m\u001b[32m?\\xbb\\xe0\\xa4\\x12r\\x0cb\\xe0\\xc8\\xa7r\\xe3\\xd5\\x8e\\x159\\xc6\\xaf\\xc8\\xbc\\xb4\\x8b\\xf9E7\\n5\\x01\u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\x01\\x18$\\x02\\x016\\x03\\x04\\x02\\x04\\x01\\x180\\x04\\x14\\x1f\\x87b\\xe9`2\\x03C\u001b[0m\u001b[32m{\u001b[0m\u001b[32mo`\\x9e\\x14\\xe3\\x8c\\x0b\\x83\\xcd\\x10Z0\\x05\\x14p\\xfc\\xf9\\nFI\\xba9\\xb6SH\\xcb\\xd0meg\\n\\t\\\\=\\x180\\x0b@\\xd3\\x03x<\\x0f\\xdc\\xceBl\\x01\\xfb\u001b[0m\u001b[32m[\u001b[0m\u001b[32mKly+\\xd4\\xab\\xa08\\xd3f \\xa5\\xb9\\xb4aP\\xce|\\xee\"to\\x17\\xc1m\\xcfQ\\\u001b[0m\u001b[32mx10pq\u001b[0m\u001b[32m=\u001b[0m\u001b[32m7\u001b[0m\u001b[32m\\r\\xf6\\xe4\\x89+\\xcb\\x98\\xa9\\x176T\\x82\\x83\\x8d\\x04#\\xa2\\xd3\\xf2\\xb6\\x18'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33micac\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x13\\x01$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04,\\x0c\\x82d\\xa8\\xd8-o\\x860Q\\xeb\\x8d\\x87\\xe6x\\x9e\\x0b\\xf8\\xc91\\xa9\\xc5\\x01nxB\\x17h\\xbc\\x98\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\xc9&\\x19\\x9f\\xde\\x97&\\x80M\\xca\\x8b\\xa1\\xa0g\\xfd\\xae\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\x12\\x8a\\x98\\x08\\x86k\\\u001b[0m\u001b[32mxc7\u001b[0m\u001b[32m=\\xc3\\xea\\x0e\\xb0\\xf0p\\x057\\n5\\x01\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\x01\\x18$\\x02`0\\x04\\x14p\\xfc\\xf9\\nFI\\xba9\\xb6SH\\xcb\\xd0meg\\n\\t\\\\=0\\x05\\x14~\\xf0\\n\\'\\'\\x89\\xc26\\xa8\\xdaz\\xbeCv\\xb2\\x7fn\\xca^\\xb5\\x180\\x0b@\\x11\\xa5\\xf9\\x80\\x1a\\x9c\\xe5\\xbf\\x1e\\xb3\\n\\x83\\x0eW6!\\x0f\\xb0,\\xa7\\xdb\\xb0\\xe3B\\xdc\\\\\\xec\\xbb\\x02\\xc2\\x04\\xd9\\x0c\\xa7\\xdfj\\x1a\\x15\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\x18\\x08\\xdfFz%\u001b[0m\u001b[32m)\u001b[0m\u001b[32mb\\xfa\\x9b\\xca\\x99\\xccY\\x01\\xa7\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xf1|\\xe6\\xfe\\xf0*\\x10W\\x18'\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mfabricsList\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x04\\xa2\\x88\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x98'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m=\u001b[1;36m31968\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33msupportedFabrics\u001b[0m=\u001b[1;36m16\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcommissionedFabrics\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mtrustedRootCertificates\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04\\xa2\\x88\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x987\\n5\\x01\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\x01\\x18$\\x02`0\\x04\\x14~\\xf0\\n\\'\\'\\x89\\xc26\\xa8\\xdaz\\xbeCv\\xb2\\x7fn\\xca^\\xb50\\x05\\x14~\\xf0\\n\\'\\'\\x89\\xc26\\xa8\\xdaz\\xbeCv\\xb2\\x7fn\\xca^\\xb5\\x180\\x0b@3;\\xd5n\\xa0\\xb1O\\xecI:\\x9cM\\xf4u\\x12a\\x96\\x1d\\x13\\x19\\xa4D\\xb3v&_o.\u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\xcbs\\xeb\\xc0\\xc4\\xb80\\xc2\\xecF4\\xfbV\\'\\xf7X\\xe2A\\xaa\\xa5l\\r5\\xba\\xbd\\xa4I&C\\xff\\xed\\xd8\\xa8_\\x06\\x18'\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcurrentFabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mattributeList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mfeatureMap\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclusterRevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(2, [ (0, Clusters.OperationalCredentials)], True)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "af2d1fd0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "[\n",
+       "AccessControlEntry(\n",
+       "│   │   fabricIndex=1,\n",
+       "│   │   privilege=<Privilege.kAdminister: 5>,\n",
+       "│   │   authMode=<AuthMode.kCase: 2>,\n",
+       "│   │   subjects=[\n",
+       "│   │   │   1\n",
+       "│   │   ],\n",
+       "│   │   targets=Null\n",
+       ")\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;35mAccessControlEntry\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mprivilege\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mPrivilege.kAdminister:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m5\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mauthMode\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mAuthMode.kCase:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33msubjects\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mtargets\u001b[0m=\u001b[35mNull\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "acl = [ Clusters.AccessControl.Structs.AccessControlEntry(\n", + " fabricIndex = 1,\n", + " privilege = Clusters.AccessControl.Enums.Privilege.kAdminister,\n", + " authMode = Clusters.AccessControl.Enums.AuthMode.kCase,\n", + " subjects = [ 1 ] ) \n", + "]\n", + "\n", + "acl" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "bfb94ff7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "[\n",
+       "AttributeStatus(\n",
+       "│   │   Path=AttributePath(\n",
+       "│   │   │   EndpointId=0,\n",
+       "│   │   │   ClusterId=31,\n",
+       "│   │   │   AttributeId=0\n",
+       "│   │   ),\n",
+       "│   │   Status=<Status.Success: 0>\n",
+       ")\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;35mAttributeStatus\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mPath\u001b[0m=\u001b[1;35mAttributePath\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mEndpointId\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mClusterId\u001b[0m=\u001b[1;36m31\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mAttributeId\u001b[0m=\u001b[1;36m0\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mStatus\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mStatus.Success:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.WriteAttribute(2, [ (0, Clusters.AccessControl.Attributes.Acl( acl ) ) ] )" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "5ab2bffe", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.AccessControl'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.AccessControl.Attributes.Acl'>: [\n",
+       "│   │   │   │   AccessControlEntry(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   privilege=<Privilege.kAdminister: 5>,\n",
+       "│   │   │   │   │   authMode=<AuthMode.kCase: 2>,\n",
+       "│   │   │   │   │   subjects=[\n",
+       "│   │   │   │   │   │   1\n",
+       "│   │   │   │   │   ],\n",
+       "│   │   │   │   │   targets=Null\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ]\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl.Attributes.Acl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mAccessControlEntry\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mprivilege\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mPrivilege.kAdminister:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m5\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mauthMode\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mAuthMode.kCase:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33msubjects\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtargets\u001b[0m=\u001b[35mNull\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "data = await devCtrl.ReadAttribute(2, [ (0, Clusters.AccessControl.Attributes.Acl) ] )\n", + "data" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ae25b644-abc6-4de6-b098-5fbde2409dc4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "[\n",
+       "AccessControlEntry(\n",
+       "│   │   fabricIndex=1,\n",
+       "│   │   privilege=<Privilege.kAdminister: 5>,\n",
+       "│   │   authMode=<AuthMode.kCase: 2>,\n",
+       "│   │   subjects=[\n",
+       "│   │   │   1\n",
+       "│   │   ],\n",
+       "│   │   targets=Null\n",
+       ")\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;35mAccessControlEntry\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mprivilege\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mPrivilege.kAdminister:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m5\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mauthMode\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mAuthMode.kCase:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33msubjects\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mtargets\u001b[0m=\u001b[35mNull\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "acl = data[0][chip.clusters.Objects.AccessControl][chip.clusters.Objects.AccessControl.Attributes.Acl]\n", + "acl" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "605f44c4-6abe-4a7b-87e4-9b1e677f9cfe", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "[\n",
+       "AccessControlEntry(\n",
+       "│   │   fabricIndex=1,\n",
+       "│   │   privilege=<Privilege.kAdminister: 5>,\n",
+       "│   │   authMode=<AuthMode.kCase: 2>,\n",
+       "│   │   subjects=[\n",
+       "│   │   │   1\n",
+       "│   │   ],\n",
+       "│   │   targets=Null\n",
+       "),\n",
+       "AccessControlEntry(\n",
+       "│   │   fabricIndex=1,\n",
+       "│   │   privilege=<Privilege.kOperate: 3>,\n",
+       "│   │   authMode=<AuthMode.kCase: 2>,\n",
+       "│   │   subjects=Null,\n",
+       "│   │   targets=[\n",
+       "│   │   │   Target(\n",
+       "│   │   │   │   cluster=Null,\n",
+       "│   │   │   │   endpoint=1,\n",
+       "│   │   │   │   deviceType=Null\n",
+       "│   │   │   )\n",
+       "│   │   ]\n",
+       ")\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;35mAccessControlEntry\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mprivilege\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mPrivilege.kAdminister:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m5\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mauthMode\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mAuthMode.kCase:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33msubjects\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mtargets\u001b[0m=\u001b[35mNull\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;35mAccessControlEntry\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mprivilege\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mPrivilege.kOperate:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mauthMode\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mAuthMode.kCase:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33msubjects\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mtargets\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;35mTarget\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mcluster\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mendpoint\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mdeviceType\u001b[0m=\u001b[35mNull\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "acl.append(Clusters.AccessControl.Structs.AccessControlEntry(\n", + " fabricIndex = 1,\n", + " privilege = Clusters.AccessControl.Enums.Privilege.kOperate,\n", + " authMode = Clusters.AccessControl.Enums.AuthMode.kCase,\n", + " targets = [ Clusters.AccessControl.Structs.Target(\n", + " endpoint = 1,\n", + " ) ] ) )\n", + "acl" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "66cce24d-c1d4-434c-ab1a-d391b1b8e660", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "[\n",
+       "AttributeStatus(\n",
+       "│   │   Path=AttributePath(\n",
+       "│   │   │   EndpointId=0,\n",
+       "│   │   │   ClusterId=31,\n",
+       "│   │   │   AttributeId=0\n",
+       "│   │   ),\n",
+       "│   │   Status=<Status.Success: 0>\n",
+       ")\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;35mAttributeStatus\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mPath\u001b[0m=\u001b[1;35mAttributePath\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mEndpointId\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mClusterId\u001b[0m=\u001b[1;36m31\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mAttributeId\u001b[0m=\u001b[1;36m0\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mStatus\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mStatus.Success:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.WriteAttribute(2, [ (0, Clusters.AccessControl.Attributes.Acl( acl ) ) ] )" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "64f7f5e3-64d1-4b2b-a777-e07f5ef86681", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.AccessControl'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.AccessControl.Attributes.Acl'>: [\n",
+       "│   │   │   │   AccessControlEntry(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   privilege=<Privilege.kAdminister: 5>,\n",
+       "│   │   │   │   │   authMode=<AuthMode.kCase: 2>,\n",
+       "│   │   │   │   │   subjects=[\n",
+       "│   │   │   │   │   │   1\n",
+       "│   │   │   │   │   ],\n",
+       "│   │   │   │   │   targets=Null\n",
+       "│   │   │   │   ),\n",
+       "│   │   │   │   AccessControlEntry(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   privilege=<Privilege.kOperate: 3>,\n",
+       "│   │   │   │   │   authMode=<AuthMode.kCase: 2>,\n",
+       "│   │   │   │   │   subjects=Null,\n",
+       "│   │   │   │   │   targets=[\n",
+       "│   │   │   │   │   │   Target(\n",
+       "│   │   │   │   │   │   │   cluster=Null,\n",
+       "│   │   │   │   │   │   │   endpoint=1,\n",
+       "│   │   │   │   │   │   │   deviceType=Null\n",
+       "│   │   │   │   │   │   )\n",
+       "│   │   │   │   │   ]\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ]\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl.Attributes.Acl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mAccessControlEntry\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mprivilege\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mPrivilege.kAdminister:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m5\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mauthMode\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mAuthMode.kCase:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33msubjects\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtargets\u001b[0m=\u001b[35mNull\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mAccessControlEntry\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mprivilege\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mPrivilege.kOperate:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mauthMode\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mAuthMode.kCase:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33msubjects\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtargets\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1;35mTarget\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mcluster\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mendpoint\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ │ │ \u001b[0m\u001b[33mdeviceType\u001b[0m=\u001b[35mNull\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(2, [ (0, Clusters.AccessControl.Attributes.Acl ) ] )" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "matter-env", + "language": "python", + "name": "matter-env" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2+chromium.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/guides/repl/Matter - Basic Interactions.ipynb b/docs/guides/repl/Matter - Basic Interactions.ipynb new file mode 100644 index 00000000000000..4d4e77a18312f2 --- /dev/null +++ b/docs/guides/repl/Matter - Basic Interactions.ipynb @@ -0,0 +1,4247 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e8b2f5eb", + "metadata": { + "tags": [] + }, + "source": [ + "# Interaction Model Examples\n", + "\n", + "\n", + "\"drawing\"\n", + "\n", + "

\n", + "\n", + "This walks through the various interactions that can be initiated from the REPL towards a target using the Matter Interaction Model (IM) and Data Model (DM)." + ] + }, + { + "cell_type": "markdown", + "id": "99ce2877", + "metadata": { + "tags": [] + }, + "source": [ + "## Initialization\n", + "\n", + "Let's first begin by setting up by importing some key modules that are needed to make it easier for us to interact with the Matter stack.\n", + "\n", + "`ChipReplStartup.py` is run within the global namespace. This results in all of its imports being made available here.\n", + "\n", + "> **NOTE**: _This is not needed if you launch the REPL from the command-line._" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "bad327b7-c78a-4c46-b224-077fe7539ee1", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
──────────────────────────────────────── Matter REPL ────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m──────────────────────────────────────── \u001b[0mMatter REPL\u001b[92m ────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "            \n",
+       "    \n",
+       "            Welcome to the Matter Python REPL!\n",
+       "    \n",
+       "            For help, please type matterhelp()\n",
+       "    \n",
+       "            To get more information on a particular object/class, you can pass\n",
+       "            that into matterhelp() as well.\n",
+       "    \n",
+       "            \n",
+       "
\n" + ], + "text/plain": [ + "\n", + " \n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m Welcome to the Matter Python REPL!\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m For help, please type \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m To get more information on a particular object/class, you can pass\u001b[0m\n", + "\u001b[1;34m that into \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\u001b[1;34m as well.\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m \u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
─────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m─────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-25 16:58:28 johnsj-macbookpro1.roam.corp.google.com root[27801] CRITICAL Loading configuration from /tmp/repl-storage.json...\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Restoring FabricAdmin from storage to manage FabricId 1, FabricIndex 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mRestoring FabricAdmin from storage to manage FabricId \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m, FabricIndex \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 1(1)\n" + ] + }, + { + "data": { + "text/html": [ + "
Restoring FabricAdmin from storage to manage FabricId 2, FabricIndex 2...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mRestoring FabricAdmin from storage to manage FabricId \u001b[0m\u001b[1;38;5;129m2\u001b[0m\u001b[38;5;129m, FabricIndex \u001b[0m\u001b[1;38;5;129m2\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 2(2)\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "Fabric Admins have been loaded and are available at fabricAdmins\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[34mFabric Admins have been loaded and are available at \u001b[0m\u001b[31mfabricAdmins\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Creating default device controller on fabric 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mCreating default device controller on fabric \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Allocating new controller with FabricId: 1(1), NodeId: 1\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "Default CHIP Device Controller has been initialized to manage fabricAdmins[0], and is \n",
+       "available as devCtrl\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n", + "\u001b[34mDefault CHIP Device Controller has been initialized to manage \u001b[0m\u001b[1;31mfabricAdmins\u001b[0m\u001b[1;31m[\u001b[0m\u001b[1;31m0\u001b[0m\u001b[1;31m]\u001b[0m\u001b[1;34m, and is \u001b[0m\n", + "\u001b[1;34mavailable as \u001b[0m\u001b[1;31mdevCtrl\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import chip.native\n", + "import pkgutil\n", + "module = pkgutil.get_loader('chip.ChipReplStartup')\n", + "%run {module.path}" + ] + }, + { + "cell_type": "markdown", + "id": "047c4785-bb5f-41bd-9fce-5e8a7442f227", + "metadata": {}, + "source": [ + "## Cluster Elements\n", + "\n", + "The Interaction Model uses data model types that refer not just to the various base types defines in the spec, but types that correspond to structs/commands/events/attributes defined in each cluster specification. The cluster-specific types are referred to as 'cluster objects'. These are represented as Python dataclasses, with each field in the respective object equivalently named as a member within the dataclass.\n", + "\n", + "### Namespaces\n", + "\n", + "Objects in clusters are organized into namespaces. All clusters can be found under the `Clusters` namespace, with the appropriate cluster in upper camel case within that. (e.g `Clusters.TestCluster`).\n", + "\n", + "Within that, `Commands`, `Structs` and `Attributes` delimit the respective types in the cluster.\n", + "\n", + "_Example Struct:_" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "043ade5d-6f01-4cbc-8d60-57d605946ada", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "SimpleStruct(\n",
+       "a=20,\n",
+       "b=True,\n",
+       "c=<SimpleEnum.kValueA: 1>,\n",
+       "d=b'1234',\n",
+       "e=30,\n",
+       "f=0,\n",
+       "g=23.234,\n",
+       "h=0.0\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1;35mSimpleStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33ma\u001b[0m=\u001b[1;36m20\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mb\u001b[0m=\u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mc\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kValueA:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33md\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'1234'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33me\u001b[0m=\u001b[1;36m30\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mf\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mg\u001b[0m=\u001b[1;36m23\u001b[0m\u001b[1;36m.234\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mh\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "v = Clusters.TestCluster.Structs.SimpleStruct()\n", + "v.a = 20\n", + "v.b = True\n", + "v.c = Clusters.TestCluster.Enums.SimpleEnum.kValueA\n", + "v.d = b'1234'\n", + "v.e = 30\n", + "v.g = 23.234\n", + "\n", + "v" + ] + }, + { + "cell_type": "markdown", + "id": "62b3ca42-c2d2-4252-8683-47b0c1a1319d", + "metadata": {}, + "source": [ + "_Example Command:_" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "d52b1adc-7723-4be8-80c0-f7f262398d39", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "TestAddArguments(\n",
+       "arg1=0,\n",
+       "arg2=0\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1;35mTestAddArguments\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33marg1\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33marg2\u001b[0m=\u001b[1;36m0\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "Clusters.TestCluster.Commands.TestAddArguments()" + ] + }, + { + "cell_type": "markdown", + "id": "ae69ad3b-7dd5-4ef2-9ba3-5944c0c2c2bf", + "metadata": {}, + "source": [ + "To get more information about the fields in these objects and their types, run:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "c55de6c7-da4e-488e-bafb-32781ee088a8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
╭──────── <class 'chip.clusters.Objects.TestCluster.Commands.TestAddArguments'> ─────────╮\n",
+       " def TestCluster.Commands.TestAddArguments(arg1: 'uint' = 0, arg2: 'uint' = 0) -> None: \n",
+       "                                                                                        \n",
+       " TestAddArguments(arg1: 'uint' = 0, arg2: 'uint' = 0)                                   \n",
+       "                                                                                        \n",
+       "                  arg1 = 0                                                              \n",
+       "                  arg2 = 0                                                              \n",
+       "            cluster_id = 1295                                                           \n",
+       "            command_id = 4                                                              \n",
+       "            descriptor = ClusterObjectDescriptor(                                       \n",
+       "                             Fields=[                                                   \n",
+       "                                 ClusterObjectFieldDescriptor(                          \n",
+       "                                     Label='arg1',                                      \n",
+       "                                     Tag=0,                                             \n",
+       "                                     Type=<class 'chip.tlv.uint'>                       \n",
+       "                                 ),                                                     \n",
+       "                                 ClusterObjectFieldDescriptor(                          \n",
+       "                                     Label='arg2',                                      \n",
+       "                                     Tag=1,                                             \n",
+       "                                     Type=<class 'chip.tlv.uint'>                       \n",
+       "                                 )                                                      \n",
+       "                             ]                                                          \n",
+       "                         )                                                              \n",
+       "             is_client = True                                                           \n",
+       " must_use_timed_invoke = False                                                          \n",
+       "              FromDict = def FromDict(data: dict):                                      \n",
+       "               FromTLV = def FromTLV(data: bytes):                                      \n",
+       "                 ToTLV = def ToTLV(self):                                               \n",
+       "╰────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[34m╭─\u001b[0m\u001b[34m─────── \u001b[0m\u001b[1;34m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Commands.TestAddArguments'\u001b[0m\u001b[1;34m>\u001b[0m\u001b[34m ────────\u001b[0m\u001b[34m─╮\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;96mdef \u001b[0m\u001b[1;31mTestCluster.Commands.TestAddArguments\u001b[0m\u001b[1m(\u001b[0marg1: \u001b[32m'uint'\u001b[0m = \u001b[1;36m0\u001b[0m, arg2: \u001b[32m'uint'\u001b[0m = \u001b[1;36m0\u001b[0m\u001b[1m)\u001b[0m -> \u001b[3;35mNone\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;35mTestAddArguments\u001b[0m\u001b[1;36m(\u001b[0m\u001b[36marg1: \u001b[0m\u001b[32m'uint'\u001b[0m\u001b[36m = \u001b[0m\u001b[1;36m0\u001b[0m\u001b[36m, arg2: \u001b[0m\u001b[32m'uint'\u001b[0m\u001b[36m = \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;36m)\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33marg1\u001b[0m = \u001b[1;36m0\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33marg2\u001b[0m = \u001b[1;36m0\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mcluster_id\u001b[0m = \u001b[1;36m1295\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mcommand_id\u001b[0m = \u001b[1;36m4\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mdescriptor\u001b[0m = \u001b[1;35mClusterObjectDescriptor\u001b[0m\u001b[1m(\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[33mFields\u001b[0m=\u001b[1m[\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;35mClusterObjectFieldDescriptor\u001b[0m\u001b[1m(\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[33mLabel\u001b[0m=\u001b[32m'arg1'\u001b[0m, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[33mTag\u001b[0m=\u001b[1;36m0\u001b[0m, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[33mType\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.tlv.uint'\u001b[0m\u001b[1m>\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1m)\u001b[0m, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;35mClusterObjectFieldDescriptor\u001b[0m\u001b[1m(\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[33mLabel\u001b[0m=\u001b[32m'arg2'\u001b[0m, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[33mTag\u001b[0m=\u001b[1;36m1\u001b[0m, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[33mType\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.tlv.uint'\u001b[0m\u001b[1m>\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1m)\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1m]\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1m)\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mis_client\u001b[0m = \u001b[3;92mTrue\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mmust_use_timed_invoke\u001b[0m = \u001b[3;91mFalse\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mFromDict\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mFromDict\u001b[0m\u001b[1m(\u001b[0mdata: dict\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mFromTLV\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mFromTLV\u001b[0m\u001b[1m(\u001b[0mdata: bytes\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mToTLV\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mToTLV\u001b[0m\u001b[1m(\u001b[0mself\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m╰────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "matterhelp(Clusters.TestCluster.Commands.TestAddArguments)" + ] + }, + { + "cell_type": "markdown", + "id": "c7724d12-2a35-49f1-bb9f-ee010200b1aa", + "metadata": {}, + "source": [ + "### Nullable Fields\n", + "\n", + "For fields that are nullable, they are represented as a `Typing.Union[Nullable, ...]`. This means that it can either be a `Nullable` type or the underlying type of the field.\n", + "\n", + "When nullable, a field can either take on the value of the native type, or a value of `NullValue`." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "eb2563ac-0315-45ed-9984-308d4376ca94", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "NullablesAndOptionalsStruct(\n",
+       "nullableInt=Null,\n",
+       "optionalInt=None,\n",
+       "nullableOptionalInt=None,\n",
+       "nullableString=Null,\n",
+       "optionalString=None,\n",
+       "nullableOptionalString=None,\n",
+       "nullableStruct=Null,\n",
+       "optionalStruct=None,\n",
+       "nullableOptionalStruct=None,\n",
+       "nullableList=Null,\n",
+       "optionalList=None,\n",
+       "nullableOptionalList=None\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1;35mNullablesAndOptionalsStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mnullableInt\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33moptionalInt\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mnullableOptionalInt\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mnullableString\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33moptionalString\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mnullableOptionalString\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mnullableStruct\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33moptionalStruct\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mnullableOptionalStruct\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mnullableList\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33moptionalList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mnullableOptionalList\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "a = Clusters.TestCluster.Structs.NullablesAndOptionalsStruct()\n", + "a.nullableInt = Clusters.Types.NullValue\n", + "a" + ] + }, + { + "cell_type": "markdown", + "id": "0786dd6b-df15-4cf4-b0a9-0578f040bd27", + "metadata": {}, + "source": [ + "### Optional Fields\n", + "\n", + "If a field is optional, it is represented in the typing hints as a `Typing.Union[NoneType, ...]`. An optional field that isn't present has a value of `None`." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "75de30fc-666c-4610-9d86-25fb9d0e4f82", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
None\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[3;35mNone\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print(a.nullableOptionalInt)" + ] + }, + { + "cell_type": "markdown", + "id": "ee702b80-6f93-4627-8f9e-c97ebaa41de6", + "metadata": {}, + "source": [ + "### Defaults\n", + "\n", + "Upon construction of a cluster object, the fields within that object are automatically initialized to type specific defaults as specified in the data model specification:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "677ce9b4-99f3-4c0e-8f78-d123eb3190b5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "SimpleStruct(\n",
+       "a=0,\n",
+       "b=False,\n",
+       "c=0,\n",
+       "d=b'',\n",
+       "e='',\n",
+       "f=0,\n",
+       "g=0.0,\n",
+       "h=0.0\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1;35mSimpleStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33ma\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mb\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mc\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33md\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33me\u001b[0m=\u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mf\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mg\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mh\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "Clusters.TestCluster.Structs.SimpleStruct()" + ] + }, + { + "cell_type": "markdown", + "id": "322ebc15-ae5d-4e84-bb66-a5d77d1e04c6", + "metadata": { + "jp-MarkdownHeadingCollapsed": true, + "tags": [] + }, + "source": [ + "## IM Interactions\n", + "\n", + "This section will walk through the various types of IM Interactions that are possible in the REPL." + ] + }, + { + "cell_type": "markdown", + "id": "7a082d33-bebd-4b34-b8e3-df59ed429c54", + "metadata": { + "tags": [] + }, + "source": [ + "### Commission and Setup Server" + ] + }, + { + "cell_type": "markdown", + "id": "4f458209-bfd4-4682-acac-5faadeecd97a", + "metadata": { + "tags": [] + }, + "source": [ + "#### Launch Server\n", + "\n", + "Let's launch an instance of the `chip-all-clusters-app`.\n", + "\n", + "> NOTE: If you're interacting with real devices, this step can be skipped." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "52ccd8c6", + "metadata": {}, + "outputs": [], + "source": [ + "import time, os\n", + "import subprocess\n", + "\n", + "# So that the all-clusters-app won't boot with stale prior state. \n", + "subprocess.Popen(['rm', '-rf', '/tmp/chip_*'])\n", + "time.sleep(1)\n", + "\n", + "subprocess.Popen(['pkill', '-f', 'chip-all-clusters-app'])\n", + "time.sleep(1)\n", + "\n", + "# The location of the all-clusters-app in the cloud playground is one level higher - adjust for this by testing for file presence.\n", + "if (os.path.isfile('../../../out/debug/chip-all-clusters-app')):\n", + " appPath = '../../../out/debug/chip-all-clusters-app'\n", + "else:\n", + " appPath = '../../../../out/debug/chip-all-clusters-app'\n", + " \n", + "process = subprocess.Popen(appPath, stdout=subprocess.DEVNULL)\n", + "time.sleep(1)" + ] + }, + { + "cell_type": "markdown", + "id": "b33dec2e", + "metadata": {}, + "source": [ + "#### Commission Target (Locally Launched App)\n", + "\n", + "Commission the target with a NodeId of 1." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "5e964fe3", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-25 16:58:31 johnsj-macbookpro1.roam.corp.google.com chip.CTL[27801] ERROR Unable to find country code, defaulting to WW\n", + "2022-01-25 16:58:31 johnsj-macbookpro1.roam.corp.google.com chip.SC[27801] ERROR The device does not support GetClock_RealTimeMS() API. This will eventually result in CASE session setup failures.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Node address has been updated\n", + "Commissioning complete\n" + ] + }, + { + "data": { + "text/html": [ + "
True\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[3;92mTrue\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "devCtrl.CommissionIP(b'127.0.0.1', 20202021, 2)" + ] + }, + { + "cell_type": "markdown", + "id": "46c82aa0-d99b-4073-ad22-0ce260ba025a", + "metadata": { + "tags": [] + }, + "source": [ + "#### Commission Target (BLE + Thread)\n", + "\n", + "To commission a Thread-based target over BLE, ensure your BLE stack is up on your host and available as `hci0` on Linux. You can confirm this by running `hciconfig -a`. You'll also need Thread credentials to join the Thread network.\n", + "\n", + "> NOTE: MacOS Monterey is currently not supported due to issues with its BLE stack." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a1e762ad-b272-4a9c-959c-6fc1543d9631", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "devCtrl.CommissionThreadBle(3840, 20202021, 2, b'\\x01\\x03\\xff')" + ] + }, + { + "cell_type": "markdown", + "id": "bd93c3f0-651a-4e66-9d35-613b009e98cb", + "metadata": { + "tags": [] + }, + "source": [ + "#### Commission Target (BLE + WiFi)\n", + "\n", + "To commission a Wifi-based target over BLE, ensure your BLE stack is up on your host and available as `hci0` on Linux. You can confirm this by running `hciconfig -a`. You'll also need Wifi credentials to join the Thread network.\n", + "\n", + "> NOTE: MacOS Monterey is currently not supported due to issues with its BLE stack." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b552280-8586-4b5d-acde-c7806e882f23", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "devCtrl.CommissionWiFi(3840, 20202021, 2, 'MyWifiSsid', 'MyWifiPassword')" + ] + }, + { + "cell_type": "markdown", + "id": "c22ea8ee", + "metadata": { + "tags": [] + }, + "source": [ + "### Invoke Interaction" + ] + }, + { + "cell_type": "markdown", + "id": "4c94d599-e243-43de-8abe-bb4d9b1f52d4", + "metadata": {}, + "source": [ + "#### Basic Command (Success Response)" + ] + }, + { + "cell_type": "markdown", + "id": "52e6e92e-0bc6-45f2-9b6b-74d43ba3048c", + "metadata": {}, + "source": [ + "Let's send a basic command to turn on/off the light on Endpoint 1." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "bed38512-91f8-4d4e-b6e1-b30749137bbd", + "metadata": {}, + "outputs": [], + "source": [ + "await devCtrl.SendCommand(2, 1, Clusters.OnOff.Commands.On())" + ] + }, + { + "cell_type": "markdown", + "id": "b1c0fe3c-95da-4980-9b9b-2a5ab602af44", + "metadata": {}, + "source": [ + "The receipt of a successful status response will result in the command just returning successfully. Otherwise, an exception will be thrown." + ] + }, + { + "cell_type": "markdown", + "id": "80c604b9-f6dc-4ec5-91e8-a6e806c821a6", + "metadata": {}, + "source": [ + "#### Basic Command (Failure Response)" + ] + }, + { + "cell_type": "markdown", + "id": "753f5a54-4a75-41ed-a7c0-99c8cca8b6de", + "metadata": { + "tags": [] + }, + "source": [ + "If we send the same command to an invalid endpoint, an exception is thrown. If an IM status code was received from the server, a `InteractionModelError` is thrown containing the IM status code:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "2935f13b-ca16-4f9c-b320-8896c8465278", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
InteractionModelError(<Status.Failure: 1>)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mInteractionModelError\u001b[0m\u001b[1m(\u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mStatus.Failure:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "try:\n", + " await devCtrl.SendCommand(2, 100, Clusters.OnOff.Commands.On())\n", + "except Exception as e:\n", + " pprint(e)" + ] + }, + { + "cell_type": "markdown", + "id": "5296f2bc-5e9d-4b06-a7c1-f247ebe5eac2", + "metadata": {}, + "source": [ + "#### Basic Command (Data Response)" + ] + }, + { + "cell_type": "markdown", + "id": "bb196da4-5162-4c4b-ae64-ef1d23a04eb9", + "metadata": { + "tags": [] + }, + "source": [ + "Here's an example of a command that sends back a data response, and how that is presented:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "33f34d12-79f4-4230-836b-2e66ea839440", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "TestListInt8UReverseResponse(\n",
+       "arg1=[\n",
+       "│   │   7,\n",
+       "│   │   5,\n",
+       "│   │   3,\n",
+       "│   │   1\n",
+       "]\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1;35mTestListInt8UReverseResponse\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33marg1\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m7\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m5\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.SendCommand(2, 1, Clusters.TestCluster.Commands.TestListInt8UReverseRequest([1, 3, 5, 7]))" + ] + }, + { + "cell_type": "markdown", + "id": "a513295e-c44f-4deb-aa36-8b404c91e95e", + "metadata": {}, + "source": [ + "### Read Interaction\n", + "\n", + "The `ReadAttribute` method on the `DeviceController` class can be used to read attributes from a target. The NodeId of the target is the first argument, followed by a list of paths that are expressed as cluster object namespaces to the respective slices of the data that is requested.\n", + "\n", + "By default, the data is returned as a dictionary, with the top-level item representing the endpoint, then the cluster and the attribute. The latter two keys are expressed using cluster object namespaces." + ] + }, + { + "cell_type": "markdown", + "id": "493dae62-f9fe-40b6-9c3d-0584e9c1893f", + "metadata": {}, + "source": [ + "#### Read 1 attribute:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "7167af96-43b1-4524-8712-592e3ede6114", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "1: {\n",
+       "│   │   <class 'chip.clusters.Objects.TestCluster'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int16u'>: 0\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m1\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "a = await devCtrl.ReadAttribute(2, [Clusters.TestCluster.Attributes.Int16u])\n", + "a" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "b6c3bf1f-3247-4f8d-ac42-1b5ebc59cb44", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "<class 'chip.clusters.Objects.TestCluster.Attributes.Int16u'>: 0\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "a[1][Clusters.TestCluster]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "a2cafa5e-6c0e-42b9-bac0-8a1770306718", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
0\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;36m0\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "a[1][Clusters.TestCluster][Clusters.TestCluster.Attributes.Int16u]" + ] + }, + { + "cell_type": "markdown", + "id": "49f5a4f5-9d0e-4678-a4b1-9b00cf5518c1", + "metadata": { + "tags": [] + }, + "source": [ + "#### Read 2 attributes:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "8e2cb85c-9fa4-4f2e-bd71-aea54988274d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "1: {\n",
+       "│   │   <class 'chip.clusters.Objects.TestCluster'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Boolean'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int16u'>: 0\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m1\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Boolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(2, [Clusters.TestCluster.Attributes.Int16u, Clusters.TestCluster.Attributes.Boolean])" + ] + }, + { + "cell_type": "markdown", + "id": "b276df34-e38b-4a1e-a104-7f0e71842a75", + "metadata": {}, + "source": [ + "#### Read the entirety of a cluster on an endpoint:\n", + "\n", + "The path is represented as tuple of (endpoint, cluster)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "043cb3ac-3346-45f1-bcd3-803ea33dc3c0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "1: {\n",
+       "│   │   <class 'chip.clusters.Objects.OnOff'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnOff'>: True,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'>: True,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.FeatureMap'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'>: 4\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m1\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m4\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(2, [(1, Clusters.OnOff)])" + ] + }, + { + "cell_type": "markdown", + "id": "07a9e227-4f53-42a9-8fb0-5da32515dc9f", + "metadata": {}, + "source": [ + "#### Read the entirety of a cluster across all endpoints:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "15d7a880-9ddd-4619-9e42-3fd8895d80e1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "1: {\n",
+       "│   │   <class 'chip.clusters.Objects.OnOff'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnOff'>: True,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'>: True,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.FeatureMap'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'>: 4\n",
+       "│   │   }\n",
+       "},\n",
+       "2: {\n",
+       "│   │   <class 'chip.clusters.Objects.OnOff'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnOff'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'>: True,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.FeatureMap'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'>: 4\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m1\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m4\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m2\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m4\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(2, [Clusters.OnOff])" + ] + }, + { + "cell_type": "markdown", + "id": "8d2403ba-91f1-4b59-b5ce-68ccc175f8ea", + "metadata": {}, + "source": [ + "#### Read an endpoint:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "accb9351-c8e0-4a4e-86d9-784b35903144", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "2: {\n",
+       "│   │   <class 'chip.clusters.Objects.Groups'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Groups.Attributes.NameSupport'>: 128,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Groups.Attributes.ClusterRevision'>: 3\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.OnOff'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnOff'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'>: True,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.FeatureMap'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'>: 4\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Descriptor'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.DeviceList'>: [\n",
+       "│   │   │   │   DeviceType(\n",
+       "│   │   │   │   │   type=256,\n",
+       "│   │   │   │   │   revision=1\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ServerList'>: [\n",
+       "│   │   │   │   4,\n",
+       "│   │   │   │   6,\n",
+       "│   │   │   │   29,\n",
+       "│   │   │   │   1030\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ClientList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.PartsList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.OccupancySensing'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.Occupancy'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorType'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorTypeBitmap'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.ClusterRevision'>: 2\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m2\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups.Attributes.NameSupport'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m128\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m4\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.DeviceList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mDeviceType\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[1;36m256\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ServerList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m6\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m29\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1030\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ClientList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.PartsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.Occupancy'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorTypeBitmap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(2, [2])" + ] + }, + { + "cell_type": "markdown", + "id": "8aad8fef-66d7-4320-ba3c-47b481d66960", + "metadata": {}, + "source": [ + "#### Read the entire node:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "6fff453d-59a4-4dba-878f-1c65c7b1958b", + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-25 16:58:32 johnsj-macbookpro1.roam.corp.google.com root[27801] ERROR For path: Endpoint = 0, Attribute = , got IM Error: InteractionModelError: UnsupportedRead (0x8f)\n", + "2022-01-25 16:58:32 johnsj-macbookpro1.roam.corp.google.com root[27801] ERROR For path: Endpoint = 1, Attribute = , got IM Error: InteractionModelError: UnsupportedRead (0x8f)\n", + "2022-01-25 16:58:32 johnsj-macbookpro1.roam.corp.google.com root[27801] ERROR For path: Endpoint = 1, Attribute = , got IM Error: InteractionModelError: InvalidDataType (0x8d)\n", + "2022-01-25 16:58:32 johnsj-macbookpro1.roam.corp.google.com root[27801] ERROR For path: Endpoint = 1, Attribute = , got IM Error: InteractionModelError: Failure (0x1)\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.Identify'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Identify.Attributes.IdentifyTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Identify.Attributes.IdentifyType'>: 2,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Identify.Attributes.ClusterRevision'>: 2\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Groups'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Groups.Attributes.NameSupport'>: 128,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Groups.Attributes.ClusterRevision'>: 3\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Descriptor'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.DeviceList'>: [\n",
+       "│   │   │   │   DeviceType(\n",
+       "│   │   │   │   │   type=22,\n",
+       "│   │   │   │   │   revision=1\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ServerList'>: [\n",
+       "│   │   │   │   3,\n",
+       "│   │   │   │   4,\n",
+       "│   │   │   │   29,\n",
+       "│   │   │   │   30,\n",
+       "│   │   │   │   31,\n",
+       "│   │   │   │   40,\n",
+       "│   │   │   │   42,\n",
+       "│   │   │   │   43,\n",
+       "│   │   │   │   44,\n",
+       "│   │   │   │   46,\n",
+       "│   │   │   │   48,\n",
+       "│   │   │   │   49,\n",
+       "│   │   │   │   50,\n",
+       "│   │   │   │   51,\n",
+       "│   │   │   │   52,\n",
+       "│   │   │   │   53,\n",
+       "│   │   │   │   54,\n",
+       "│   │   │   │   55,\n",
+       "│   │   │   │   60,\n",
+       "│   │   │   │   62,\n",
+       "│   │   │   │   63,\n",
+       "│   │   │   │   64,\n",
+       "│   │   │   │   65,\n",
+       "│   │   │   │   1029\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ClientList'>: [\n",
+       "│   │   │   │   41\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.PartsList'>: [\n",
+       "│   │   │   │   1,\n",
+       "│   │   │   │   2\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Binding'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Binding.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.AccessControl'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.AccessControl.Attributes.Acl'>: [\n",
+       "│   │   │   │   AccessControlEntry(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   privilege=<Privilege.kAdminister: 5>,\n",
+       "│   │   │   │   │   authMode=<AuthMode.kCase: 2>,\n",
+       "│   │   │   │   │   subjects=[\n",
+       "│   │   │   │   │   │   1\n",
+       "│   │   │   │   │   ],\n",
+       "│   │   │   │   │   targets=Null\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.AccessControl.Attributes.Extension'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.AccessControl.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Basic'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.InteractionModelVersion'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.VendorName'>: 'TEST_VENDOR',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.VendorID'>: 9050,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.ProductName'>: 'TEST_PRODUCT',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.ProductID'>: 65279,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.NodeLabel'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.Location'>: 'XX',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.HardwareVersion'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.HardwareVersionString'>: 'TEST_VERSION',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.SoftwareVersion'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.SoftwareVersionString'>: 'prerelease',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.ManufacturingDate'>: '20210614123456ZZ',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.PartNumber'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.ProductURL'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.ProductLabel'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.SerialNumber'>: 'TEST_SN',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.LocalConfigDisabled'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.Reachable'>: True,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.UniqueID'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.Basic.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.OtaSoftwareUpdateRequestor'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OtaSoftwareUpdateRequestor.Attributes.DefaultOtaProviders'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.OtaSoftwareUpdateRequestor.Attributes.UpdatePossible'>: True,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OtaSoftwareUpdateRequestor.Attributes.UpdateState'>: <OTAUpdateStateEnum.kUnknown: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OtaSoftwareUpdateRequestor.Attributes.UpdateStateProgress'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OtaSoftwareUpdateRequestor.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.LocalizationConfiguration'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.LocalizationConfiguration.Attributes.ActiveLocale'>: 'en-US',\n",
+       "│   │   │   <class 'chip.clusters.Objects.LocalizationConfiguration.Attributes.SupportedLocales'>: [\n",
+       "│   │   │   │   'Test',\n",
+       "│   │   │   │   'en-US',\n",
+       "│   │   │   │   'de-DE',\n",
+       "│   │   │   │   'fr-FR',\n",
+       "│   │   │   │   'en-GB',\n",
+       "│   │   │   │   'es-ES',\n",
+       "│   │   │   │   'zh-CN',\n",
+       "│   │   │   │   'it-IT',\n",
+       "│   │   │   │   'ja-JP'\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.LocalizationConfiguration.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.TimeFormatLocalization'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.TimeFormatLocalization.Attributes.HourFormat'>: <HourFormat.k12hr: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TimeFormatLocalization.Attributes.ActiveCalendarType'>: <CalendarType.kBuddhist: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TimeFormatLocalization.Attributes.SupportedCalendarTypes'>: [\n",
+       "│   │   │   │   <CalendarType.kBuddhist: 0>,\n",
+       "│   │   │   │   <CalendarType.kChinese: 1>,\n",
+       "│   │   │   │   <CalendarType.kCoptic: 2>,\n",
+       "│   │   │   │   <CalendarType.kEthiopian: 3>,\n",
+       "│   │   │   │   <CalendarType.kGregorian: 4>,\n",
+       "│   │   │   │   <CalendarType.kHebrew: 5>,\n",
+       "│   │   │   │   <CalendarType.kIndian: 6>,\n",
+       "│   │   │   │   <CalendarType.kIslamic: 7>,\n",
+       "│   │   │   │   <CalendarType.kJapanese: 8>,\n",
+       "│   │   │   │   <CalendarType.kKorean: 9>,\n",
+       "│   │   │   │   <CalendarType.kPersian: 10>,\n",
+       "│   │   │   │   <CalendarType.kTaiwanese: 11>\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.TimeFormatLocalization.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.PowerSourceConfiguration'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSourceConfiguration.Attributes.Sources'>: [\n",
+       "│   │   │   │   1\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSourceConfiguration.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.GeneralCommissioning'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralCommissioning.Attributes.Breadcrumb'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralCommissioning.Attributes.BasicCommissioningInfoList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralCommissioning.Attributes.RegulatoryConfig'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralCommissioning.Attributes.LocationCapability'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralCommissioning.Attributes.FeatureMap'>: 6,\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralCommissioning.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.NetworkCommissioning'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.MaxNetworks'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.Networks'>: ValueDecodeFailure(\n",
+       "│   │   │   │   TLVValue=None,\n",
+       "│   │   │   │   Reason=InteractionModelError(<Status.UnsupportedRead: 143>)\n",
+       "│   │   │   ),\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.ScanMaxTimeSeconds'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.ConnectMaxTimeSeconds'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.InterfaceEnabled'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.LastNetworkingStatus'>: <NetworkCommissioningStatus.kSuccess: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.LastNetworkID'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.LastConnectErrorValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.FeatureMap'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.GeneralDiagnostics'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralDiagnostics.Attributes.NetworkInterfaces'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralDiagnostics.Attributes.RebootCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralDiagnostics.Attributes.UpTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralDiagnostics.Attributes.TotalOperationalHours'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralDiagnostics.Attributes.BootReasons'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralDiagnostics.Attributes.ActiveHardwareFaults'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralDiagnostics.Attributes.ActiveRadioFaults'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralDiagnostics.Attributes.ActiveNetworkFaults'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.GeneralDiagnostics.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.SoftwareDiagnostics'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.SoftwareDiagnostics.Attributes.ThreadMetrics'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.SoftwareDiagnostics.Attributes.CurrentHeapFree'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.SoftwareDiagnostics.Attributes.CurrentHeapUsed'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.SoftwareDiagnostics.Attributes.CurrentHeapHighWatermark'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.SoftwareDiagnostics.Attributes.FeatureMap'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.SoftwareDiagnostics.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.Channel'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RoutingRole'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.NetworkName'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.PanId'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ExtendedPanId'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.MeshLocalPrefix'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.OverrunCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.NeighborTableList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RouteTableList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.PartitionId'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.Weighting'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.DataVersion'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.StableDataVersion'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.LeaderRouterId'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.DetachedRoleCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ChildRoleCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RouterRoleCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.LeaderRoleCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.AttachAttemptCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.PartitionIdChangeCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.BetterPartitionAttachAttemptCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ParentChangeCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxTotalCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxUnicastCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxBroadcastCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxAckRequestedCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxAckedCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxNoAckRequestedCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxDataCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxDataPollCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxBeaconCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxBeaconRequestCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxOtherCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxRetryCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxDirectMaxRetryExpiryCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxIndirectMaxRetryExpiryCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxErrCcaCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxErrAbortCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxErrBusyChannelCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxTotalCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxUnicastCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxBroadcastCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxDataCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxDataPollCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxBeaconCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxBeaconRequestCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxOtherCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxAddressFilteredCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxDestAddrFilteredCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxDuplicatedCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrNoFrameCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrUnknownNeighborCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrInvalidSrcAddrCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrSecCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrFcsCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrOtherCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ActiveTimestamp'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.PendingTimestamp'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.Delay'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.SecurityPolicy'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ChannelMask'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.OperationalDatasetComponents'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ActiveNetworkFaultsList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.FeatureMap'>: 15,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.Bssid'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.SecurityType'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.WiFiVersion'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.ChannelNumber'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.Rssi'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.BeaconLostCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.BeaconRxCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.PacketMulticastRxCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.PacketMulticastTxCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.PacketUnicastRxCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.PacketUnicastTxCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.CurrentMaxRate'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.OverrunCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.FeatureMap'>: 3,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.PHYRate'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.FullDuplex'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.PacketRxCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.PacketTxCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.TxErrCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.CollisionCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.OverrunCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.CarrierDetect'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.TimeSinceReset'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.FeatureMap'>: 3,\n",
+       "│   │   │   <class 'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.AdministratorCommissioning'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.AdministratorCommissioning.Attributes.WindowStatus'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.AdministratorCommissioning.Attributes.AdminFabricIndex'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.AdministratorCommissioning.Attributes.AdminVendorId'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.AdministratorCommissioning.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.OperationalCredentials'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.NOCs'>: [\n",
+       "│   │   │   │   NOCStruct(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   noc=b'\\x150\\x01\\x01\\x01$\\x02\\x017\\x03$\\x13\\x01$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x11\\x02$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04\\xbc8\\x9d2\\xe7\\xe6\\x0f\\x12\\xcb\\x0fYb\\x8f\\xa6zc\\xa1\\xb2y\\x18\\xc3~\\x98\\xee\\xa9r\\xd3\\x18\\xe9@\\xf9\\x17B\\xa6\\xed\\x11\\x92\\xc2\\xe2k&\\x88m\\r^`\\x10\\xc3|\\xdd\\xb4)\\r\\x11\\xcc\\xd1p\\x9bwN)H)\\x187\\n5\\x01(\\x01\\x18$\\x02\\x016\\x03\\x04\\x02\\x04\\x01\\x180\\x04\\x14B8k q\\xd8Lv\\x85^A;\\xceyC\\xa4\\xe9|\\xc1\\x120\\x05\\x14\\x8d\\xe3\\xb8\\x08&j\\xd4\\xa5\\xd5\\x1c\\xb5\\x83]\\xa5-\\x97jG\\xdb\\x87\\x180\\x0b@4\\n\\xcd\\x15+\\xa9n}s\\xbb$u\\x12\\xec\"B\\x00\\x98\\x1fD\\xd4\\xb7\\xcc\\xbb\\xd3\\x17*\\xfa\\xd3\\x8atX]\\xca\\xec\\xaf:[$o|\\xc6\"z\\x15\\xb4d\\x144\\x11i\\xa4\\xaa7\\xce\\x9f\\xc5l\\x11\\xe7I\\x87L\\x88\\x18',\n",
+       "│   │   │   │   │   icac=b'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x13\\x01$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04\\xf2\\xc0\\x10\\xe9=c\\x9e\\xed.\\xaaQj\\x0ca\\xd8\\x1f\\xfb:\\xf2\\x92$\\x04hc><\\xb2\\xc9R>\\xfe\\x1f\\x121\\xf2\\xaf5 \\xc4\\r\\xd3=\\xd0\\xae\\xbe\\xb4\\x85\\x8dI\\xfa`Z\\xaeI\\xfe*>\\xb1\\x88:,Rs\\xb57\\n5\\x01)\\x01\\x18$\\x02`0\\x04\\x14\\x8d\\xe3\\xb8\\x08&j\\xd4\\xa5\\xd5\\x1c\\xb5\\x83]\\xa5-\\x97jG\\xdb\\x870\\x05\\x14\\xd0\\xb8\\x11\\xcc\\x07\\x01\\xfd<\\xb1\\xc3\\x9a\\xc3\\xc4\\xb1\\xa8\\xa1\\x9al\\xa6\\xd5\\x180\\x0b@\\x91\\x1cY!4-\\\\\\xc1hC[q\\xa8\\x85\\x00\\xa7\\xdd\\xd8\\x1fAM\\xca-6\\xf5 \\x89\\x85k\\x05;\\x15\\xd0\\x83A>D\\xe9\\x9e\\xc1]\\xbb\\xcd\\x8c\\x83\\xbbm\\xab\\xf9\\x8a\\xdb\\x9df\\x11\\x05\\x98hC\\x8f\\xcd\\xad\\n7\\x9e\\x18'\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'>: [\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04\\x1b$\\xfe8s\\x9d\\xcdJ\\xb8\\tN\\xfd\\x16\\xb2\\xbf\\xecn\\x00\\xfd\\x93\\xfa\\xc8`\\x89M\\x14\\xe8RB\\x9f\\xc0\\x9f\\x05\\\\dfX\\xd7\\xa8\\xc3\\x05\\x05#52/\\xfe\\xc3\\x1c\\xa1\\xa7\\xa8\\x0cF\\xa2S\\xa2\\xf5\\xfe\\xd8\\x9fQ\\x0b\\xfa',\n",
+       "│   │   │   │   │   vendorId=60064,\n",
+       "│   │   │   │   │   fabricId=1,\n",
+       "│   │   │   │   │   nodeId=2,\n",
+       "│   │   │   │   │   label=''\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.SupportedFabrics'>: 16,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.CommissionedFabrics'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.TrustedRootCertificates'>: [\n",
+       "│   │   │   │   b'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04\\x1b$\\xfe8s\\x9d\\xcdJ\\xb8\\tN\\xfd\\x16\\xb2\\xbf\\xecn\\x00\\xfd\\x93\\xfa\\xc8`\\x89M\\x14\\xe8RB\\x9f\\xc0\\x9f\\x05\\\\dfX\\xd7\\xa8\\xc3\\x05\\x05#52/\\xfe\\xc3\\x1c\\xa1\\xa7\\xa8\\x0cF\\xa2S\\xa2\\xf5\\xfe\\xd8\\x9fQ\\x0b\\xfa7\\n5\\x01)\\x01\\x18$\\x02`0\\x04\\x14\\xd0\\xb8\\x11\\xcc\\x07\\x01\\xfd<\\xb1\\xc3\\x9a\\xc3\\xc4\\xb1\\xa8\\xa1\\x9al\\xa6\\xd50\\x05\\x14\\xd0\\xb8\\x11\\xcc\\x07\\x01\\xfd<\\xb1\\xc3\\x9a\\xc3\\xc4\\xb1\\xa8\\xa1\\x9al\\xa6\\xd5\\x180\\x0b@J\\xa5\\xdb\\xec9\\xd3i\\xbf\\xa84\\xbc(r\\xfb\\xf9\\x95X\\x00\\xf1\\x1f\\xd5#\\x14x\\xbeT}\\xda\\xe1\\x15\\x94\\x92\\xdb\\xc8\\xccI0\\xc5\\xe2\\x1ev0h\\x10N\\xdd\\x8b\\xd7\\x94\\x90]\\xd4\\x8f\\x08>\\x8b\\xc8j\\x05\\xbeb\\xed\\xd5\\xe0\\x18'\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.CurrentFabricIndex'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.GroupKeyManagement'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.GroupKeyManagement.Attributes.GroupKeyMap'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.GroupKeyManagement.Attributes.GroupTable'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.GroupKeyManagement.Attributes.MaxGroupsPerFabric'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.GroupKeyManagement.Attributes.MaxGroupKeysPerFabric'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.GroupKeyManagement.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.FixedLabel'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.FixedLabel.Attributes.LabelList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.FixedLabel.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.UserLabel'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.UserLabel.Attributes.LabelList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.UserLabel.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.RelativeHumidityMeasurement'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MinMeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MaxMeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.ClusterRevision'>: 2\n",
+       "│   │   }\n",
+       "},\n",
+       "1: {\n",
+       "│   │   <class 'chip.clusters.Objects.Identify'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Identify.Attributes.IdentifyTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Identify.Attributes.IdentifyType'>: 2,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Identify.Attributes.ClusterRevision'>: 2\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Groups'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Groups.Attributes.NameSupport'>: 128,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Groups.Attributes.ClusterRevision'>: 3\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Scenes'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Scenes.Attributes.SceneCount'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Scenes.Attributes.CurrentScene'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Scenes.Attributes.CurrentGroup'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Scenes.Attributes.SceneValid'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Scenes.Attributes.NameSupport'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Scenes.Attributes.ClusterRevision'>: 3\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.OnOff'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnOff'>: True,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'>: True,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.FeatureMap'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'>: 4\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.OnOffSwitchConfiguration'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOffSwitchConfiguration.Attributes.SwitchType'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOffSwitchConfiguration.Attributes.SwitchActions'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOffSwitchConfiguration.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.LevelControl'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.CurrentLevel'>: 254,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.RemainingTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.MinLevel'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.MaxLevel'>: 254,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.CurrentFrequency'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.MinFrequency'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.MaxFrequency'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.Options'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.OnOffTransitionTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.OnLevel'>: 254,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.OnTransitionTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.OffTransitionTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.DefaultMoveRate'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.StartUpCurrentLevel'>: Null,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.FeatureMap'>: 3,\n",
+       "│   │   │   <class 'chip.clusters.Objects.LevelControl.Attributes.ClusterRevision'>: 5\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.BinaryInputBasic'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.BinaryInputBasic.Attributes.OutOfService'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.BinaryInputBasic.Attributes.PresentValue'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.BinaryInputBasic.Attributes.StatusFlags'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.BinaryInputBasic.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Descriptor'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.DeviceList'>: [\n",
+       "│   │   │   │   DeviceType(\n",
+       "│   │   │   │   │   type=256,\n",
+       "│   │   │   │   │   revision=1\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ServerList'>: [\n",
+       "│   │   │   │   3,\n",
+       "│   │   │   │   4,\n",
+       "│   │   │   │   5,\n",
+       "│   │   │   │   6,\n",
+       "│   │   │   │   7,\n",
+       "│   │   │   │   8,\n",
+       "│   │   │   │   15,\n",
+       "│   │   │   │   29,\n",
+       "│   │   │   │   30,\n",
+       "│   │   │   │   37,\n",
+       "│   │   │   │   47,\n",
+       "│   │   │   │   49,\n",
+       "│   │   │   │   57,\n",
+       "│   │   │   │   59,\n",
+       "│   │   │   │   64,\n",
+       "│   │   │   │   65,\n",
+       "│   │   │   │   69,\n",
+       "│   │   │   │   80,\n",
+       "│   │   │   │   257,\n",
+       "│   │   │   │   258,\n",
+       "│   │   │   │   259,\n",
+       "│   │   │   │   512,\n",
+       "│   │   │   │   513,\n",
+       "│   │   │   │   516,\n",
+       "│   │   │   │   768,\n",
+       "│   │   │   │   1024,\n",
+       "│   │   │   │   1026,\n",
+       "│   │   │   │   1027,\n",
+       "│   │   │   │   1028,\n",
+       "│   │   │   │   1029,\n",
+       "│   │   │   │   1030,\n",
+       "│   │   │   │   1280,\n",
+       "│   │   │   │   1283,\n",
+       "│   │   │   │   1284,\n",
+       "│   │   │   │   1285,\n",
+       "│   │   │   │   1286,\n",
+       "│   │   │   │   1287,\n",
+       "│   │   │   │   1288,\n",
+       "│   │   │   │   1289,\n",
+       "│   │   │   │   1290,\n",
+       "│   │   │   │   1291,\n",
+       "│   │   │   │   1292,\n",
+       "│   │   │   │   1293,\n",
+       "│   │   │   │   1294,\n",
+       "│   │   │   │   1295,\n",
+       "│   │   │   │   2820\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ClientList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.PartsList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Binding'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Binding.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.BridgedActions'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.BridgedActions.Attributes.ActionList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.BridgedActions.Attributes.EndpointList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.BridgedActions.Attributes.SetupUrl'>: 'https://example.com',\n",
+       "│   │   │   <class 'chip.clusters.Objects.BridgedActions.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.PowerSource'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSource.Attributes.Status'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSource.Attributes.Order'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSource.Attributes.Description'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSource.Attributes.BatteryVoltage'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSource.Attributes.BatteryPercentRemaining'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSource.Attributes.BatteryTimeRemaining'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSource.Attributes.BatteryChargeLevel'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSource.Attributes.ActiveBatteryFaults'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSource.Attributes.BatteryChargeState'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSource.Attributes.FeatureMap'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PowerSource.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.NetworkCommissioning'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.MaxNetworks'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.Networks'>: ValueDecodeFailure(\n",
+       "│   │   │   │   TLVValue=None,\n",
+       "│   │   │   │   Reason=InteractionModelError(<Status.UnsupportedRead: 143>)\n",
+       "│   │   │   ),\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.ScanMaxTimeSeconds'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.ConnectMaxTimeSeconds'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.InterfaceEnabled'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.LastNetworkingStatus'>: <NetworkCommissioningStatus.kSuccess: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.LastNetworkID'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.LastConnectErrorValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.FeatureMap'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.NetworkCommissioning.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.BridgedDeviceBasic'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.BridgedDeviceBasic.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Switch'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Switch.Attributes.NumberOfPositions'>: 2,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Switch.Attributes.CurrentPosition'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Switch.Attributes.MultiPressMax'>: 2,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Switch.Attributes.FeatureMap'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Switch.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.FixedLabel'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.FixedLabel.Attributes.LabelList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.FixedLabel.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.UserLabel'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.UserLabel.Attributes.LabelList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.UserLabel.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.BooleanState'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.BooleanState.Attributes.StateValue'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.BooleanState.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.ModeSelect'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.ModeSelect.Attributes.CurrentMode'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ModeSelect.Attributes.SupportedModes'>: [\n",
+       "│   │   │   │   ModeOptionStruct(\n",
+       "│   │   │   │   │   label='Black',\n",
+       "│   │   │   │   │   mode=0,\n",
+       "│   │   │   │   │   semanticTag=0\n",
+       "│   │   │   │   ),\n",
+       "│   │   │   │   ModeOptionStruct(\n",
+       "│   │   │   │   │   label='Cappuccino',\n",
+       "│   │   │   │   │   mode=4,\n",
+       "│   │   │   │   │   semanticTag=0\n",
+       "│   │   │   │   ),\n",
+       "│   │   │   │   ModeOptionStruct(\n",
+       "│   │   │   │   │   label='Espresso',\n",
+       "│   │   │   │   │   mode=7,\n",
+       "│   │   │   │   │   semanticTag=0\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.ModeSelect.Attributes.OnMode'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ModeSelect.Attributes.StartUpMode'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ModeSelect.Attributes.Description'>: 'Coffee',\n",
+       "│   │   │   <class 'chip.clusters.Objects.ModeSelect.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.DoorLock'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.LockState'>: <DlLockState.kUnlocked: 2>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.LockType'>: <DlLockType.kDeadBolt: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.ActuatorEnabled'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.DoorState'>: <DlDoorState.kDoorOpen: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.DoorOpenEvents'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.DoorClosedEvents'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.OpenPeriod'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.NumberOfTotalUsersSupported'>: 10,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.NumberOfPINUsersSupported'>: 10,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.NumberOfWeekDaySchedulesSupportedPerUser'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.NumberOfYearDaySchedulesSupportedPerUser'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.NumberOfHolidaySchedulesSupported'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.MaxPINCodeLength'>: 6,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.MinPINCodeLength'>: 6,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.CredentialRulesSupport'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.Language'>: 'en',\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.AutoRelockTime'>: 96,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.SoundVolume'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.OperatingMode'>: <DlOperatingMode.kNormal: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.SupportedOperatingModes'>: 65526,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.DefaultConfigurationRegister'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.EnableOneTouchLocking'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.EnableInsideStatusLED'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.EnablePrivacyModeButton'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.WrongCodeEntryLimit'>: 3,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.UserCodeTemporaryDisableTime'>: 10,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.RequirePINforRemoteOperation'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.DoorLock.Attributes.ClusterRevision'>: 3\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.WindowCovering'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.Type'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionLift'>: 32767,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionTilt'>: 32767,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.ConfigStatus'>: 3,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionLiftPercentage'>: 50,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionTiltPercentage'>: 50,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.OperationalStatus'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.TargetPositionLiftPercent100ths'>: 500,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.TargetPositionTiltPercent100ths'>: 500,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.EndProductType'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionLiftPercent100ths'>: 500,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionTiltPercent100ths'>: 500,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.InstalledOpenLimitLift'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.InstalledClosedLimitLift'>: 65535,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.InstalledOpenLimitTilt'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.InstalledClosedLimitTilt'>: 65535,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.Mode'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.SafetyStatus'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.FeatureMap'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.WindowCovering.Attributes.ClusterRevision'>: 5\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.BarrierControl'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.BarrierControl.Attributes.BarrierMovingState'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.BarrierControl.Attributes.BarrierSafetyStatus'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.BarrierControl.Attributes.BarrierCapabilities'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.BarrierControl.Attributes.BarrierPosition'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.BarrierControl.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxPressure'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxSpeed'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxFlow'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MinConstPressure'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxConstPressure'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MinCompPressure'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxCompPressure'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MinConstSpeed'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxConstSpeed'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MinConstFlow'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxConstFlow'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MinConstTemp'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxConstTemp'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.PumpStatus'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.EffectiveOperationMode'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.EffectiveControlMode'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.Capacity'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.Speed'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.LifetimeRunningHours'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.Power'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.LifetimeEnergyConsumed'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.OperationMode'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.ControlMode'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.AlarmMask'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.FeatureMap'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Thermostat'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.LocalTemperature'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.AbsMinHeatSetpointLimit'>: 700,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.AbsMaxHeatSetpointLimit'>: 3000,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.AbsMinCoolSetpointLimit'>: 1600,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.AbsMaxCoolSetpointLimit'>: 3200,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.OccupiedCoolingSetpoint'>: 2600,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.OccupiedHeatingSetpoint'>: 2000,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.MinHeatSetpointLimit'>: 700,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.MaxHeatSetpointLimit'>: 3000,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.MinCoolSetpointLimit'>: 1600,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.MaxCoolSetpointLimit'>: 3200,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.MinSetpointDeadBand'>: 25,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.ControlSequenceOfOperation'>: 4,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.SystemMode'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.StartOfWeek'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.NumberOfWeeklyTransitions'>: 7,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.NumberOfDailyTransitions'>: 4,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.FeatureMap'>: 11,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Thermostat.Attributes.ClusterRevision'>: 3\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.ThermostatUserInterfaceConfiguration'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThermostatUserInterfaceConfiguration.Attributes.TemperatureDisplayMode'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThermostatUserInterfaceConfiguration.Attributes.KeypadLockout'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThermostatUserInterfaceConfiguration.Attributes.ScheduleProgrammingVisibility'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ThermostatUserInterfaceConfiguration.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.ColorControl'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.CurrentHue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.CurrentSaturation'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.RemainingTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.CurrentX'>: 24939,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.CurrentY'>: 24701,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.DriftCompensation'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.CompensationText'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorTemperature'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorMode'>: 2,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorControlOptions'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.NumberOfPrimaries'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary1X'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary1Y'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary1Intensity'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary2X'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary2Y'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary2Intensity'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary3X'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary3Y'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary3Intensity'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary4X'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary4Y'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary4Intensity'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary5X'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary5Y'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary5Intensity'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary6X'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary6Y'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.Primary6Intensity'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.WhitePointX'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.WhitePointY'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorPointRX'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorPointRY'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorPointRIntensity'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorPointGX'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorPointGY'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorPointGIntensity'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorPointBX'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorPointBY'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorPointBIntensity'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.EnhancedCurrentHue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.EnhancedColorMode'>: 2,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorLoopActive'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorLoopDirection'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorLoopTime'>: 25,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorLoopStartEnhancedHue'>: 8960,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorLoopStoredEnhancedHue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorCapabilities'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorTempPhysicalMin'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ColorTempPhysicalMax'>: 65279,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.CoupleColorTempToLevelMinMireds'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.StartUpColorTemperatureMireds'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ColorControl.Attributes.ClusterRevision'>: 3\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.IlluminanceMeasurement'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.IlluminanceMeasurement.Attributes.MeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.IlluminanceMeasurement.Attributes.MinMeasuredValue'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.IlluminanceMeasurement.Attributes.MaxMeasuredValue'>: 65534,\n",
+       "│   │   │   <class 'chip.clusters.Objects.IlluminanceMeasurement.Attributes.Tolerance'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.IlluminanceMeasurement.Attributes.LightSensorType'>: Null,\n",
+       "│   │   │   <class 'chip.clusters.Objects.IlluminanceMeasurement.Attributes.ClusterRevision'>: 2\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.TemperatureMeasurement'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.TemperatureMeasurement.Attributes.MeasuredValue'>: -32768,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TemperatureMeasurement.Attributes.MinMeasuredValue'>: -32768,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TemperatureMeasurement.Attributes.MaxMeasuredValue'>: -32768,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TemperatureMeasurement.Attributes.Tolerance'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TemperatureMeasurement.Attributes.ClusterRevision'>: 3\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.PressureMeasurement'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.PressureMeasurement.Attributes.MeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PressureMeasurement.Attributes.MinMeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PressureMeasurement.Attributes.MaxMeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.PressureMeasurement.Attributes.ClusterRevision'>: 2\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.FlowMeasurement'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.FlowMeasurement.Attributes.MeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.FlowMeasurement.Attributes.MinMeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.FlowMeasurement.Attributes.MaxMeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.FlowMeasurement.Attributes.Tolerance'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.FlowMeasurement.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.RelativeHumidityMeasurement'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MinMeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MaxMeasuredValue'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.Tolerance'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.ClusterRevision'>: 2\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.OccupancySensing'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.Occupancy'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorType'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorTypeBitmap'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.ClusterRevision'>: 2\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.IasZone'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.IasZone.Attributes.ZoneState'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.IasZone.Attributes.ZoneType'>: 541,\n",
+       "│   │   │   <class 'chip.clusters.Objects.IasZone.Attributes.ZoneStatus'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.IasZone.Attributes.IasCieAddress'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.IasZone.Attributes.ZoneId'>: 255,\n",
+       "│   │   │   <class 'chip.clusters.Objects.IasZone.Attributes.ClusterRevision'>: 2\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.WakeOnLan'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.WakeOnLan.Attributes.WakeOnLanMacAddress'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.WakeOnLan.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Channel'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Channel.Attributes.ChannelList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Channel.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.TargetNavigator'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.TargetNavigator.Attributes.TargetNavigatorList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.TargetNavigator.Attributes.CurrentNavigatorTarget'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TargetNavigator.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.MediaPlayback'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.MediaPlayback.Attributes.PlaybackState'>: <PlaybackStateEnum.kPlaying: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.MediaPlayback.Attributes.StartTime'>: 255,\n",
+       "│   │   │   <class 'chip.clusters.Objects.MediaPlayback.Attributes.Duration'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.MediaPlayback.Attributes.PlaybackSpeed'>: 0.0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.MediaPlayback.Attributes.SeekRangeEnd'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.MediaPlayback.Attributes.SeekRangeStart'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.MediaPlayback.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.MediaInput'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.MediaInput.Attributes.MediaInputList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.MediaInput.Attributes.CurrentMediaInput'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.MediaInput.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.LowPower'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.LowPower.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.KeypadInput'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.KeypadInput.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.ContentLauncher'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.ContentLauncher.Attributes.AcceptHeaderList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.ContentLauncher.Attributes.SupportedStreamingProtocols'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ContentLauncher.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.AudioOutput'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.AudioOutput.Attributes.AudioOutputList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.AudioOutput.Attributes.CurrentAudioOutput'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.AudioOutput.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.ApplicationLauncher'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.ApplicationLauncher.Attributes.ApplicationLauncherList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.ApplicationLauncher.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.ApplicationBasic'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.ApplicationBasic.Attributes.VendorName'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.ApplicationBasic.Attributes.VendorId'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ApplicationBasic.Attributes.ApplicationName'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.ApplicationBasic.Attributes.ProductId'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ApplicationBasic.Attributes.ApplicationStatus'>: <ApplicationStatusEnum.kStopped: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ApplicationBasic.Attributes.ApplicationVersion'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.ApplicationBasic.Attributes.AllowedVendorList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.ApplicationBasic.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.AccountLogin'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.AccountLogin.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.TestCluster'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Boolean'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Bitmap8'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Bitmap16'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Bitmap32'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Bitmap64'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int8u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int16u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int24u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int32u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int40u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int48u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int56u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int64u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int8s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int16s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int24s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int32s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int40s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int48s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int56s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int64s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Enum8'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Enum16'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.FloatSingle'>: 0.0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.FloatDouble'>: 0.0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.OctetString'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListInt8u'>: [\n",
+       "│   │   │   │   0,\n",
+       "│   │   │   │   0,\n",
+       "│   │   │   │   0,\n",
+       "│   │   │   │   0\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListOctetString'>: [\n",
+       "│   │   │   │   b'',\n",
+       "│   │   │   │   b'',\n",
+       "│   │   │   │   b'',\n",
+       "│   │   │   │   b''\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListStructOctetString'>: [\n",
+       "│   │   │   │   TestListStructOctet(\n",
+       "│   │   │   │   │   fabricIndex=0,\n",
+       "│   │   │   │   │   operationalCert=b''\n",
+       "│   │   │   │   ),\n",
+       "│   │   │   │   TestListStructOctet(\n",
+       "│   │   │   │   │   fabricIndex=0,\n",
+       "│   │   │   │   │   operationalCert=b''\n",
+       "│   │   │   │   ),\n",
+       "│   │   │   │   TestListStructOctet(\n",
+       "│   │   │   │   │   fabricIndex=0,\n",
+       "│   │   │   │   │   operationalCert=b''\n",
+       "│   │   │   │   ),\n",
+       "│   │   │   │   TestListStructOctet(\n",
+       "│   │   │   │   │   fabricIndex=0,\n",
+       "│   │   │   │   │   operationalCert=b''\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.LongOctetString'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.CharString'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.LongCharString'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.EpochUs'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.EpochS'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.VendorId'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListNullablesAndOptionalsStruct'>: [\n",
+       "│   │   │   │   NullablesAndOptionalsStruct(\n",
+       "│   │   │   │   │   nullableInt=Null,\n",
+       "│   │   │   │   │   optionalInt=None,\n",
+       "│   │   │   │   │   nullableOptionalInt=None,\n",
+       "│   │   │   │   │   nullableString=Null,\n",
+       "│   │   │   │   │   optionalString=None,\n",
+       "│   │   │   │   │   nullableOptionalString=None,\n",
+       "│   │   │   │   │   nullableStruct=Null,\n",
+       "│   │   │   │   │   optionalStruct=None,\n",
+       "│   │   │   │   │   nullableOptionalStruct=None,\n",
+       "│   │   │   │   │   nullableList=Null,\n",
+       "│   │   │   │   │   optionalList=None,\n",
+       "│   │   │   │   │   nullableOptionalList=None\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.EnumAttr'>: <SimpleEnum.kUnspecified: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.StructAttr'>: SimpleStruct(\n",
+       "│   │   │   │   a=0,\n",
+       "│   │   │   │   b=False,\n",
+       "│   │   │   │   c=<SimpleEnum.kUnspecified: 0>,\n",
+       "│   │   │   │   d=b'',\n",
+       "│   │   │   │   e='',\n",
+       "│   │   │   │   f=0,\n",
+       "│   │   │   │   g=0.0,\n",
+       "│   │   │   │   h=0.0\n",
+       "│   │   │   ),\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt8u'>: 70,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt8s'>: -20,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt16u'>: 200,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt16s'>: -100,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListLongOctetString'>: [\n",
+       "│   │   │   │   b'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',\n",
+       "│   │   │   │   b'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',\n",
+       "│   │   │   │   b'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',\n",
+       "│   │   │   │   b'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ListFabricScoped'>: [\n",
+       "│   │   │   │   TestFabricScoped(\n",
+       "│   │   │   │   │   fabricIndex=1\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.TimedWriteBoolean'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.GeneralErrorBoolean'>: ValueDecodeFailure(\n",
+       "│   │   │   │   TLVValue=None,\n",
+       "│   │   │   │   Reason=InteractionModelError(<Status.InvalidDataType: 141>)\n",
+       "│   │   │   ),\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ClusterErrorBoolean'>: ValueDecodeFailure(\n",
+       "│   │   │   │   TLVValue=None,\n",
+       "│   │   │   │   Reason=InteractionModelError(<Status.Failure: 1>)\n",
+       "│   │   │   ),\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableBoolean'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap8'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap16'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap32'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap64'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt8u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt16u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt24u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt32u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt40u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt48u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt56u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt64u'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt8s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt16s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt24s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt32s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt40s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt48s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt56s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableInt64s'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableEnum8'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableEnum16'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableFloatSingle'>: 0.0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableFloatDouble'>: 0.0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableOctetString'>: b'',\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableCharString'>: '',\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableEnumAttr'>: <SimpleEnum.kUnspecified: 0>,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableStruct'>: Null,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt8u'>: 70,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt8s'>: -20,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt16u'>: 200,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt16s'>: -100,\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.ElectricalMeasurement'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.MeasurementType'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.TotalActivePower'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsVoltage'>: 65535,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsVoltageMin'>: 32768,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsVoltageMax'>: 32768,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsCurrent'>: 65535,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsCurrentMin'>: 65535,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsCurrentMax'>: 65535,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.ActivePower'>: -1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.ActivePowerMin'>: -1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.ActivePowerMax'>: -1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.ElectricalMeasurement.Attributes.ClusterRevision'>: 3\n",
+       "│   │   }\n",
+       "},\n",
+       "2: {\n",
+       "│   │   <class 'chip.clusters.Objects.Groups'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Groups.Attributes.NameSupport'>: 128,\n",
+       "│   │   │   <class 'chip.clusters.Objects.Groups.Attributes.ClusterRevision'>: 3\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.OnOff'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnOff'>: False,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'>: True,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OnTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.FeatureMap'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'>: 4\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.Descriptor'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.DeviceList'>: [\n",
+       "│   │   │   │   DeviceType(\n",
+       "│   │   │   │   │   type=256,\n",
+       "│   │   │   │   │   revision=1\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ServerList'>: [\n",
+       "│   │   │   │   4,\n",
+       "│   │   │   │   6,\n",
+       "│   │   │   │   29,\n",
+       "│   │   │   │   1030\n",
+       "│   │   │   ],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ClientList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.PartsList'>: [],\n",
+       "│   │   │   <class 'chip.clusters.Objects.Descriptor.Attributes.ClusterRevision'>: 1\n",
+       "│   │   },\n",
+       "│   │   <class 'chip.clusters.Objects.OccupancySensing'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.Occupancy'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorType'>: 0,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorTypeBitmap'>: 1,\n",
+       "│   │   │   <class 'chip.clusters.Objects.OccupancySensing.Attributes.ClusterRevision'>: 2\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Identify'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Identify.Attributes.IdentifyTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Identify.Attributes.IdentifyType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Identify.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups.Attributes.NameSupport'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m128\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.DeviceList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mDeviceType\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[1;36m22\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ServerList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m29\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m30\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m31\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m40\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m42\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m43\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m44\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m46\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m48\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m49\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m50\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m51\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m52\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m53\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m54\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m55\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m60\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m62\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m63\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m64\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m65\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1029\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ClientList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m41\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.PartsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Binding'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Binding.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl.Attributes.Acl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mAccessControlEntry\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mprivilege\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mPrivilege.kAdminister:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m5\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mauthMode\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mAuthMode.kCase:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33msubjects\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ │ \u001b[0m\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtargets\u001b[0m=\u001b[35mNull\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl.Attributes.Extension'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccessControl.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.InteractionModelVersion'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.VendorName'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m'TEST_VENDOR'\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.VendorID'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m9050\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.ProductName'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m'TEST_PRODUCT'\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.ProductID'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m65279\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.NodeLabel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.Location'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m'XX'\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.HardwareVersion'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.HardwareVersionString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m'TEST_VERSION'\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.SoftwareVersion'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.SoftwareVersionString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m'prerelease'\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.ManufacturingDate'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m'20210614123456ZZ'\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.PartNumber'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.ProductURL'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.ProductLabel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.SerialNumber'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m'TEST_SN'\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.LocalConfigDisabled'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.Reachable'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.UniqueID'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Basic.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OtaSoftwareUpdateRequestor'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OtaSoftwareUpdateRequestor.Attributes.DefaultOtaProviders'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OtaSoftwareUpdateRequestor.Attributes.UpdatePossible'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OtaSoftwareUpdateRequestor.Attributes.UpdateState'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mOTAUpdateStateEnum.kUnknown:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OtaSoftwareUpdateRequestor.Attributes.UpdateStateProgress'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OtaSoftwareUpdateRequestor.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LocalizationConfiguration'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LocalizationConfiguration.Attributes.ActiveLocale'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m'en-US'\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LocalizationConfiguration.Attributes.SupportedLocales'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Test'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'en-US'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'de-DE'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'fr-FR'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'en-GB'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'es-ES'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'zh-CN'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'it-IT'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'ja-JP'\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LocalizationConfiguration.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TimeFormatLocalization'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TimeFormatLocalization.Attributes.HourFormat'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mHourFormat.k12hr:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TimeFormatLocalization.Attributes.ActiveCalendarType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kBuddhist:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TimeFormatLocalization.Attributes.SupportedCalendarTypes'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kBuddhist:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kChinese:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kCoptic:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kEthiopian:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m3\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kGregorian:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m4\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kHebrew:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m5\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kIndian:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m6\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kIslamic:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m7\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kJapanese:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m8\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kKorean:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m9\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kPersian:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m10\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mCalendarType.kTaiwanese:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m11\u001b[0m\u001b[1m>\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TimeFormatLocalization.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSourceConfiguration'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSourceConfiguration.Attributes.Sources'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSourceConfiguration.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralCommissioning'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralCommissioning.Attributes.Breadcrumb'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralCommissioning.Attributes.BasicCommissioningInfoList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralCommissioning.Attributes.RegulatoryConfig'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralCommissioning.Attributes.LocationCapability'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralCommissioning.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m6\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralCommissioning.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.MaxNetworks'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.Networks'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mValueDecodeFailure\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mTLVValue\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mReason\u001b[0m=\u001b[1;35mInteractionModelError\u001b[0m\u001b[1m(\u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mStatus.UnsupportedRead:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m143\u001b[0m\u001b[1m>\u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.ScanMaxTimeSeconds'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.ConnectMaxTimeSeconds'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.InterfaceEnabled'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.LastNetworkingStatus'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mNetworkCommissioningStatus.kSuccess:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.LastNetworkID'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.LastConnectErrorValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralDiagnostics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralDiagnostics.Attributes.NetworkInterfaces'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralDiagnostics.Attributes.RebootCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralDiagnostics.Attributes.UpTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralDiagnostics.Attributes.TotalOperationalHours'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralDiagnostics.Attributes.BootReasons'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralDiagnostics.Attributes.ActiveHardwareFaults'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralDiagnostics.Attributes.ActiveRadioFaults'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralDiagnostics.Attributes.ActiveNetworkFaults'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GeneralDiagnostics.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.SoftwareDiagnostics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.SoftwareDiagnostics.Attributes.ThreadMetrics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.SoftwareDiagnostics.Attributes.CurrentHeapFree'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.SoftwareDiagnostics.Attributes.CurrentHeapUsed'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.SoftwareDiagnostics.Attributes.CurrentHeapHighWatermark'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.SoftwareDiagnostics.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.SoftwareDiagnostics.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.Channel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RoutingRole'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.NetworkName'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.PanId'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ExtendedPanId'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.MeshLocalPrefix'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.OverrunCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.NeighborTableList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RouteTableList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.PartitionId'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.Weighting'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.DataVersion'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.StableDataVersion'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.LeaderRouterId'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.DetachedRoleCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ChildRoleCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RouterRoleCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.LeaderRoleCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.AttachAttemptCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.PartitionIdChangeCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.BetterPartitionAttachAttemptCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ParentChangeCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxTotalCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxUnicastCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxBroadcastCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxAckRequestedCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxAckedCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxNoAckRequestedCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxDataCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxDataPollCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxBeaconCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxBeaconRequestCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxOtherCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxRetryCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxDirectMaxRetryExpiryCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxIndirectMaxRetryExpiryCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxErrCcaCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxErrAbortCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.TxErrBusyChannelCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxTotalCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxUnicastCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxBroadcastCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxDataCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxDataPollCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxBeaconCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxBeaconRequestCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxOtherCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxAddressFilteredCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxDestAddrFilteredCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxDuplicatedCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrNoFrameCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrUnknownNeighborCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrInvalidSrcAddrCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrSecCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrFcsCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.RxErrOtherCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ActiveTimestamp'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.PendingTimestamp'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.Delay'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.SecurityPolicy'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ChannelMask'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.OperationalDatasetComponents'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ActiveNetworkFaultsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m15\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThreadNetworkDiagnostics.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.Bssid'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.SecurityType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.WiFiVersion'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.ChannelNumber'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.Rssi'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.BeaconLostCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.BeaconRxCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.PacketMulticastRxCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.PacketMulticastTxCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.PacketUnicastRxCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.PacketUnicastTxCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.CurrentMaxRate'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.OverrunCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WiFiNetworkDiagnostics.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.PHYRate'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.FullDuplex'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.PacketRxCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.PacketTxCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.TxErrCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.CollisionCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.OverrunCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.CarrierDetect'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.TimeSinceReset'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.EthernetNetworkDiagnostics.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AdministratorCommissioning'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AdministratorCommissioning.Attributes.WindowStatus'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AdministratorCommissioning.Attributes.AdminFabricIndex'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AdministratorCommissioning.Attributes.AdminVendorId'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AdministratorCommissioning.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.NOCs'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mNOCStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnoc\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x150\\x01\\x01\\x01$\\x02\\x017\\x03$\\x13\\x01$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x11\\x02$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04\\xbc8\\x9d2\\xe7\\xe6\\x0f\\x12\\xcb\\x0fYb\\x8f\\xa6zc\\xa1\\xb2y\\x18\\xc3~\\x98\\xee\\xa9r\\xd3\\x18\\xe9@\\xf9\\x17B\\xa6\\xed\\x11\\x92\\xc2\\xe2k&\\x88m\\r^`\\x10\\xc3|\\xdd\\xb4\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\r\\x11\\xcc\\xd1p\\x9bwN\u001b[0m\u001b[32m)\u001b[0m\u001b[32mH\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\x187\\n5\\x01\u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\x01\\x18$\\x02\\x016\\x03\\x04\\x02\\x04\\x01\\x180\\x04\\x14B8k q\\xd8Lv\\x85^A;\\xceyC\\xa4\\xe9|\\xc1\\x120\\x05\\x14\\x8d\\xe3\\xb8\\x08&j\\xd4\\xa5\\xd5\\x1c\\xb5\\x83\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\xa5-\\x97jG\\xdb\\x87\\x180\\x0b@4\\n\\xcd\\x15+\\xa9n\u001b[0m\u001b[32m}\u001b[0m\u001b[32ms\\xbb$u\\x12\\xec\"B\\x00\\x98\\x1fD\\xd4\\xb7\\xcc\\xbb\\xd3\\x17*\\xfa\\xd3\\x8atX\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\xca\\xec\\xaf:\u001b[0m\u001b[32m[\u001b[0m\u001b[32m$o|\\xc6\"z\\x15\\xb4d\\x144\\x11i\\xa4\\xaa7\\xce\\x9f\\xc5l\\x11\\xe7I\\x87L\\x88\\x18'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33micac\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x13\\x01$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04\\xf2\\xc0\\x10\\\u001b[0m\u001b[32mxe9\u001b[0m\u001b[32m=\u001b[0m\u001b[32mc\u001b[0m\u001b[32m\\x9e\\xed.\\xaaQj\\x0ca\\xd8\\x1f\\xfb:\\xf2\\x92$\\x04hc>\u001b[0m\u001b[32m<\u001b[0m\u001b[32m\\xb2\\xc9R\u001b[0m\u001b[32m>\u001b[0m\u001b[32m\\xfe\\x1f\\x121\\xf2\\xaf5 \\xc4\\r\\\u001b[0m\u001b[32mxd3\u001b[0m\u001b[32m=\\xd0\\xae\\xbe\\xb4\\x85\\x8dI\\xfa`Z\\xaeI\\xfe*>\\xb1\\x88:,Rs\\xb57\\n5\\x01\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\x01\\x18$\\x02`0\\x04\\x14\\x8d\\xe3\\xb8\\x08&j\\xd4\\xa5\\xd5\\x1c\\xb5\\x83\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\xa5-\\x97jG\\xdb\\x870\\x05\\x14\\xd0\\xb8\\x11\\xcc\\x07\\x01\\xfd\u001b[0m\u001b[32m<\u001b[0m\u001b[32m\\xb1\\xc3\\x9a\\xc3\\xc4\\xb1\\xa8\\xa1\\x9al\\xa6\\xd5\\x180\\x0b@\\x91\\x1cY!4-\\\\\\xc1hC\u001b[0m\u001b[32m[\u001b[0m\u001b[32mq\\xa8\\x85\\x00\\xa7\\xdd\\xd8\\x1fAM\\xca-6\\xf5 \\x89\\x85k\\x05;\\x15\\xd0\\x83A\u001b[0m\u001b[32m>\u001b[0m\u001b[32mD\\xe9\\x9e\\xc1\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\xbb\\xcd\\x8c\\x83\\xbbm\\xab\\xf9\\x8a\\xdb\\x9df\\x11\\x05\\x98hC\\x8f\\xcd\\xad\\n7\\x9e\\x18'\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x04\\x1b$\\xfe8s\\x9d\\xcdJ\\xb8\\tN\\xfd\\x16\\xb2\\xbf\\xecn\\x00\\xfd\\x93\\xfa\\xc8`\\x89M\\x14\\xe8RB\\x9f\\xc0\\x9f\\x05\\\\dfX\\xd7\\xa8\\xc3\\x05\\x05#52/\\xfe\\xc3\\x1c\\xa1\\xa7\\xa8\\x0cF\\xa2S\\xa2\\xf5\\xfe\\xd8\\x9fQ\\x0b\\xfa'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m=\u001b[1;36m60064\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.SupportedFabrics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m16\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.CommissionedFabrics'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.TrustedRootCertificates'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb'\\x150\\x01\\x01\\x00$\\x02\\x017\\x03$\\x14\\x00$\\x15\\x01\\x18&\\x04\\x80\"\\x81\\'&\\x05\\x80%M:7\\x06$\\x14\\x00$\\x15\\x01\\x18$\\x07\\x01$\\x08\\x010\\tA\\x04\\x1b$\\xfe8s\\x9d\\xcdJ\\xb8\\tN\\xfd\\x16\\xb2\\xbf\\xecn\\x00\\xfd\\x93\\xfa\\xc8`\\x89M\\x14\\xe8RB\\x9f\\xc0\\x9f\\x05\\\\dfX\\xd7\\xa8\\xc3\\x05\\x05#52/\\xfe\\xc3\\x1c\\xa1\\xa7\\xa8\\x0cF\\xa2S\\xa2\\xf5\\xfe\\xd8\\x9fQ\\x0b\\xfa7\\n5\\x01\u001b[0m\u001b[32m)\u001b[0m\u001b[32m\\x01\\x18$\\x02`0\\x04\\x14\\xd0\\xb8\\x11\\xcc\\x07\\x01\\xfd\u001b[0m\u001b[32m<\u001b[0m\u001b[32m\\xb1\\xc3\\x9a\\xc3\\xc4\\xb1\\xa8\\xa1\\x9al\\xa6\\xd50\\x05\\x14\\xd0\\xb8\\x11\\xcc\\x07\\x01\\xfd<\\xb1\\xc3\\x9a\\xc3\\xc4\\xb1\\xa8\\xa1\\x9al\\xa6\\xd5\\x180\\x0b@J\\xa5\\xdb\\xec9\\xd3i\\xbf\\xa84\\xbc\u001b[0m\u001b[32m(\u001b[0m\u001b[32mr\\xfb\\xf9\\x95X\\x00\\xf1\\x1f\\xd5#\\x14x\\xbeT\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xda\\xe1\\x15\\x94\\x92\\xdb\\xc8\\xccI0\\xc5\\xe2\\x1ev0h\\x10N\\xdd\\x8b\\xd7\\x94\\x90\u001b[0m\u001b[32m]\u001b[0m\u001b[32m\\xd4\\x8f\\x08\u001b[0m\u001b[32m>\u001b[0m\u001b[32m\\x8b\\xc8j\\x05\\xbeb\\xed\\xd5\\xe0\\x18'\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.CurrentFabricIndex'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GroupKeyManagement'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GroupKeyManagement.Attributes.GroupKeyMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GroupKeyManagement.Attributes.GroupTable'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GroupKeyManagement.Attributes.MaxGroupsPerFabric'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GroupKeyManagement.Attributes.MaxGroupKeysPerFabric'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.GroupKeyManagement.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FixedLabel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FixedLabel.Attributes.LabelList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FixedLabel.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UserLabel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UserLabel.Attributes.LabelList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UserLabel.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.RelativeHumidityMeasurement'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MinMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MaxMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m1\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Identify'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Identify.Attributes.IdentifyTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Identify.Attributes.IdentifyType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Identify.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups.Attributes.NameSupport'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m128\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Scenes'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Scenes.Attributes.SceneCount'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Scenes.Attributes.CurrentScene'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Scenes.Attributes.CurrentGroup'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Scenes.Attributes.SceneValid'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Scenes.Attributes.NameSupport'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Scenes.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m4\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOffSwitchConfiguration'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOffSwitchConfiguration.Attributes.SwitchType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOffSwitchConfiguration.Attributes.SwitchActions'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOffSwitchConfiguration.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.CurrentLevel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m254\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.RemainingTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.MinLevel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.MaxLevel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m254\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.CurrentFrequency'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.MinFrequency'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.MaxFrequency'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.Options'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.OnOffTransitionTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.OnLevel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m254\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.OnTransitionTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.OffTransitionTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.DefaultMoveRate'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.StartUpCurrentLevel'\u001b[0m\u001b[1m>\u001b[0m: Null,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LevelControl.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m5\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BinaryInputBasic'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BinaryInputBasic.Attributes.OutOfService'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BinaryInputBasic.Attributes.PresentValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BinaryInputBasic.Attributes.StatusFlags'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BinaryInputBasic.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.DeviceList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mDeviceType\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[1;36m256\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ServerList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m5\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m6\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m7\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m8\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m15\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m29\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m30\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m37\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m47\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m49\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m57\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m59\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m64\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m65\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m69\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m80\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m257\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m258\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m259\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m512\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m513\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m516\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m768\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1024\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1026\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1027\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1028\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1029\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1030\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1280\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1283\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1284\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1285\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1286\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1287\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1288\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1289\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1290\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1291\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1292\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1293\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1294\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1295\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m2820\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ClientList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.PartsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Binding'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Binding.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BridgedActions'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BridgedActions.Attributes.ActionList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BridgedActions.Attributes.EndpointList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BridgedActions.Attributes.SetupUrl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m'https://example.com'\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BridgedActions.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource.Attributes.Status'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource.Attributes.Order'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource.Attributes.Description'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource.Attributes.BatteryVoltage'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource.Attributes.BatteryPercentRemaining'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource.Attributes.BatteryTimeRemaining'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource.Attributes.BatteryChargeLevel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource.Attributes.ActiveBatteryFaults'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource.Attributes.BatteryChargeState'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PowerSource.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.MaxNetworks'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.Networks'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mValueDecodeFailure\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mTLVValue\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mReason\u001b[0m=\u001b[1;35mInteractionModelError\u001b[0m\u001b[1m(\u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mStatus.UnsupportedRead:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m143\u001b[0m\u001b[1m>\u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.ScanMaxTimeSeconds'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.ConnectMaxTimeSeconds'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.InterfaceEnabled'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.LastNetworkingStatus'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mNetworkCommissioningStatus.kSuccess:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.LastNetworkID'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.LastConnectErrorValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.NetworkCommissioning.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BridgedDeviceBasic'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BridgedDeviceBasic.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Switch'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Switch.Attributes.NumberOfPositions'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Switch.Attributes.CurrentPosition'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Switch.Attributes.MultiPressMax'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Switch.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Switch.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FixedLabel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FixedLabel.Attributes.LabelList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FixedLabel.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UserLabel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UserLabel.Attributes.LabelList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.UserLabel.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BooleanState'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BooleanState.Attributes.StateValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BooleanState.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ModeSelect'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ModeSelect.Attributes.CurrentMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ModeSelect.Attributes.SupportedModes'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mModeOptionStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m'Black'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mmode\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33msemanticTag\u001b[0m=\u001b[1;36m0\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mModeOptionStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m'Cappuccino'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mmode\u001b[0m=\u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33msemanticTag\u001b[0m=\u001b[1;36m0\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mModeOptionStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m'Espresso'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mmode\u001b[0m=\u001b[1;36m7\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33msemanticTag\u001b[0m=\u001b[1;36m0\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ModeSelect.Attributes.OnMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ModeSelect.Attributes.StartUpMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ModeSelect.Attributes.Description'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m'Coffee'\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ModeSelect.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.LockState'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mDlLockState.kUnlocked:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m2\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.LockType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mDlLockType.kDeadBolt:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.ActuatorEnabled'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.DoorState'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mDlDoorState.kDoorOpen:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.DoorOpenEvents'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.DoorClosedEvents'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.OpenPeriod'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.NumberOfTotalUsersSupported'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m10\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.NumberOfPINUsersSupported'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m10\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.NumberOfWeekDaySchedulesSupportedPerUser'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.NumberOfYearDaySchedulesSupportedPerUser'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.NumberOfHolidaySchedulesSupported'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.MaxPINCodeLength'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m6\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.MinPINCodeLength'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m6\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.CredentialRulesSupport'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.Language'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m'en'\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.AutoRelockTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m96\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.SoundVolume'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.OperatingMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mDlOperatingMode.kNormal:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.SupportedOperatingModes'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m65526\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.DefaultConfigurationRegister'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.EnableOneTouchLocking'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.EnableInsideStatusLED'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.EnablePrivacyModeButton'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.WrongCodeEntryLimit'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.UserCodeTemporaryDisableTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m10\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.RequirePINforRemoteOperation'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.DoorLock.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.Type'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionLift'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m32767\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionTilt'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m32767\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.ConfigStatus'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionLiftPercentage'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m50\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionTiltPercentage'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m50\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.OperationalStatus'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.TargetPositionLiftPercent100ths'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m500\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.TargetPositionTiltPercent100ths'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m500\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.EndProductType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionLiftPercent100ths'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m500\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.CurrentPositionTiltPercent100ths'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m500\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.InstalledOpenLimitLift'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.InstalledClosedLimitLift'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m65535\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.InstalledOpenLimitTilt'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.InstalledClosedLimitTilt'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m65535\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.Mode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.SafetyStatus'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WindowCovering.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m5\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BarrierControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BarrierControl.Attributes.BarrierMovingState'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BarrierControl.Attributes.BarrierSafetyStatus'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BarrierControl.Attributes.BarrierCapabilities'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BarrierControl.Attributes.BarrierPosition'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.BarrierControl.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxPressure'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxSpeed'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxFlow'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MinConstPressure'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxConstPressure'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MinCompPressure'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxCompPressure'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MinConstSpeed'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxConstSpeed'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MinConstFlow'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxConstFlow'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MinConstTemp'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.MaxConstTemp'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.PumpStatus'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.EffectiveOperationMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.EffectiveControlMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.Capacity'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.Speed'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.LifetimeRunningHours'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.Power'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.LifetimeEnergyConsumed'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.OperationMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.ControlMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.AlarmMask'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PumpConfigurationAndControl.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.LocalTemperature'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.AbsMinHeatSetpointLimit'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m700\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.AbsMaxHeatSetpointLimit'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3000\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.AbsMinCoolSetpointLimit'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1600\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.AbsMaxCoolSetpointLimit'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3200\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.OccupiedCoolingSetpoint'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2600\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.OccupiedHeatingSetpoint'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2000\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.MinHeatSetpointLimit'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m700\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.MaxHeatSetpointLimit'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3000\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.MinCoolSetpointLimit'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1600\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.MaxCoolSetpointLimit'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3200\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.MinSetpointDeadBand'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m25\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.ControlSequenceOfOperation'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.SystemMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.StartOfWeek'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.NumberOfWeeklyTransitions'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m7\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.NumberOfDailyTransitions'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m11\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Thermostat.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThermostatUserInterfaceConfiguration'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThermostatUserInterfaceConfiguration.Attributes.TemperatureDisplayMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThermostatUserInterfaceConfiguration.Attributes.KeypadLockout'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThermostatUserInterfaceConfiguration.Attributes.ScheduleProgrammingVisibility'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ThermostatUserInterfaceConfiguration.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.CurrentHue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.CurrentSaturation'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.RemainingTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.CurrentX'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m24939\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.CurrentY'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m24701\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.DriftCompensation'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.CompensationText'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorTemperature'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorControlOptions'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.NumberOfPrimaries'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary1X'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary1Y'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary1Intensity'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary2X'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary2Y'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary2Intensity'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary3X'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary3Y'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary3Intensity'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary4X'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary4Y'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary4Intensity'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary5X'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary5Y'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary5Intensity'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary6X'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary6Y'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.Primary6Intensity'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.WhitePointX'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.WhitePointY'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorPointRX'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorPointRY'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorPointRIntensity'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorPointGX'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorPointGY'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorPointGIntensity'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorPointBX'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorPointBY'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorPointBIntensity'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.EnhancedCurrentHue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.EnhancedColorMode'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorLoopActive'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorLoopDirection'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorLoopTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m25\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorLoopStartEnhancedHue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m8960\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorLoopStoredEnhancedHue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorCapabilities'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorTempPhysicalMin'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ColorTempPhysicalMax'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m65279\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.CoupleColorTempToLevelMinMireds'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.StartUpColorTemperatureMireds'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ColorControl.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IlluminanceMeasurement'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IlluminanceMeasurement.Attributes.MeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IlluminanceMeasurement.Attributes.MinMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IlluminanceMeasurement.Attributes.MaxMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m65534\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IlluminanceMeasurement.Attributes.Tolerance'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IlluminanceMeasurement.Attributes.LightSensorType'\u001b[0m\u001b[1m>\u001b[0m: Null,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IlluminanceMeasurement.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TemperatureMeasurement'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TemperatureMeasurement.Attributes.MeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-32768\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TemperatureMeasurement.Attributes.MinMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-32768\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TemperatureMeasurement.Attributes.MaxMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-32768\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TemperatureMeasurement.Attributes.Tolerance'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TemperatureMeasurement.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PressureMeasurement'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PressureMeasurement.Attributes.MeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PressureMeasurement.Attributes.MinMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PressureMeasurement.Attributes.MaxMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.PressureMeasurement.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FlowMeasurement'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FlowMeasurement.Attributes.MeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FlowMeasurement.Attributes.MinMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FlowMeasurement.Attributes.MaxMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FlowMeasurement.Attributes.Tolerance'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.FlowMeasurement.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.RelativeHumidityMeasurement'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MinMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.MaxMeasuredValue'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.Tolerance'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.RelativeHumidityMeasurement.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.Occupancy'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorTypeBitmap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IasZone'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IasZone.Attributes.ZoneState'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IasZone.Attributes.ZoneType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m541\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IasZone.Attributes.ZoneStatus'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IasZone.Attributes.IasCieAddress'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IasZone.Attributes.ZoneId'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m255\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.IasZone.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WakeOnLan'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WakeOnLan.Attributes.WakeOnLanMacAddress'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.WakeOnLan.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Channel'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Channel.Attributes.ChannelList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Channel.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TargetNavigator'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TargetNavigator.Attributes.TargetNavigatorList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TargetNavigator.Attributes.CurrentNavigatorTarget'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TargetNavigator.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaPlayback'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaPlayback.Attributes.PlaybackState'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mPlaybackStateEnum.kPlaying:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaPlayback.Attributes.StartTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m255\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaPlayback.Attributes.Duration'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaPlayback.Attributes.PlaybackSpeed'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaPlayback.Attributes.SeekRangeEnd'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaPlayback.Attributes.SeekRangeStart'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaPlayback.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaInput'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaInput.Attributes.MediaInputList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaInput.Attributes.CurrentMediaInput'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.MediaInput.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LowPower'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.LowPower.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.KeypadInput'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.KeypadInput.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ContentLauncher'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ContentLauncher.Attributes.AcceptHeaderList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ContentLauncher.Attributes.SupportedStreamingProtocols'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ContentLauncher.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AudioOutput'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AudioOutput.Attributes.AudioOutputList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AudioOutput.Attributes.CurrentAudioOutput'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AudioOutput.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationLauncher'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationLauncher.Attributes.ApplicationLauncherList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationLauncher.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationBasic'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationBasic.Attributes.VendorName'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationBasic.Attributes.VendorId'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationBasic.Attributes.ApplicationName'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationBasic.Attributes.ProductId'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationBasic.Attributes.ApplicationStatus'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mApplicationStatusEnum.kStopped:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationBasic.Attributes.ApplicationVersion'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationBasic.Attributes.AllowedVendorList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ApplicationBasic.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccountLogin'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.AccountLogin.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Boolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Bitmap8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Bitmap16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Bitmap32'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Bitmap64'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int24u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int32u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int40u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int48u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int56u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int64u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int24s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int32s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int40s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int48s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int56s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int64s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Enum8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Enum16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.FloatSingle'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.FloatDouble'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.OctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m0\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb''\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListStructOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mTestListStructOctet\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33moperationalCert\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mTestListStructOctet\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33moperationalCert\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mTestListStructOctet\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33moperationalCert\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mTestListStructOctet\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33moperationalCert\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.LongOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.CharString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.LongCharString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.EpochUs'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.EpochS'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.VendorId'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListNullablesAndOptionalsStruct'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mNullablesAndOptionalsStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnullableInt\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33moptionalInt\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnullableOptionalInt\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnullableString\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33moptionalString\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnullableOptionalString\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnullableStruct\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33moptionalStruct\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnullableOptionalStruct\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnullableList\u001b[0m=\u001b[35mNull\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33moptionalList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnullableOptionalList\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.EnumAttr'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.StructAttr'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mSimpleStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33ma\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mb\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mc\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33md\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33me\u001b[0m=\u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mf\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mg\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mh\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m70\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-20\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m200\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.RangeRestrictedInt16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-100\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListLongOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32mb'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ListFabricScoped'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mTestFabricScoped\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.TimedWriteBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.GeneralErrorBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mValueDecodeFailure\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mTLVValue\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mReason\u001b[0m=\u001b[1;35mInteractionModelError\u001b[0m\u001b[1m(\u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mStatus.InvalidDataType:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m141\u001b[0m\u001b[1m>\u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ClusterErrorBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mValueDecodeFailure\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mTLVValue\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mReason\u001b[0m=\u001b[1;35mInteractionModelError\u001b[0m\u001b[1m(\u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mStatus.Failure:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableBoolean'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap32'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableBitmap64'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt24u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt32u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt40u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt48u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt56u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt64u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt24s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt32s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt40s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt48s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt56s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableInt64s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableEnum8'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableEnum16'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableFloatSingle'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableFloatDouble'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableOctetString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32mb''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableCharString'\u001b[0m\u001b[1m>\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableEnumAttr'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableStruct'\u001b[0m\u001b[1m>\u001b[0m: Null,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt8u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m70\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt8s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-20\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m200\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.NullableRangeRestrictedInt16s'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-100\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.MeasurementType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.TotalActivePower'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsVoltage'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m65535\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsVoltageMin'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m32768\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsVoltageMax'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m32768\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsCurrent'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m65535\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsCurrentMin'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m65535\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.RmsCurrentMax'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m65535\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.ActivePower'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.ActivePowerMin'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.ActivePowerMax'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m-1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.ElectricalMeasurement.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m2\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups.Attributes.NameSupport'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m128\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'\u001b[0m\u001b[1m>\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.StartUpOnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.FeatureMap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m4\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.DeviceList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mDeviceType\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[1;36m256\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ServerList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m6\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m29\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1030\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ClientList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.PartsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.Occupancy'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorType'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.OccupancySensorTypeBitmap'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing.Attributes.ClusterRevision'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(2, [('*')])" + ] + }, + { + "cell_type": "markdown", + "id": "7209813d-81d8-4f4c-8d4a-73a69569c86d", + "metadata": {}, + "source": [ + "#### Alternative 'Cluster' View\n", + "\n", + "The above encapsulates each attribute as a 'cluster-object' key within the top-level cluster instance. Instead, an alternative view each attribute is represented as a field in the object can be retrieved by passing in `True` to the third argument:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "b46b9c2a-30c9-48e9-84ce-fe261cc10a5f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "2: {\n",
+       "│   │   <class 'chip.clusters.Objects.Groups'>: Groups(\n",
+       "│   │   │   nameSupport=128,\n",
+       "│   │   │   attributeList=None,\n",
+       "│   │   │   featureMap=None,\n",
+       "│   │   │   clusterRevision=3\n",
+       "│   │   ),\n",
+       "│   │   <class 'chip.clusters.Objects.OnOff'>: OnOff(\n",
+       "│   │   │   onOff=False,\n",
+       "│   │   │   globalSceneControl=True,\n",
+       "│   │   │   onTime=0,\n",
+       "│   │   │   offWaitTime=0,\n",
+       "│   │   │   startUpOnOff=0,\n",
+       "│   │   │   attributeList=None,\n",
+       "│   │   │   featureMap=0,\n",
+       "│   │   │   clusterRevision=4\n",
+       "│   │   ),\n",
+       "│   │   <class 'chip.clusters.Objects.Descriptor'>: Descriptor(\n",
+       "│   │   │   deviceList=[\n",
+       "│   │   │   │   DeviceType(\n",
+       "│   │   │   │   │   type=256,\n",
+       "│   │   │   │   │   revision=1\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ],\n",
+       "│   │   │   serverList=[\n",
+       "│   │   │   │   4,\n",
+       "│   │   │   │   6,\n",
+       "│   │   │   │   29,\n",
+       "│   │   │   │   1030\n",
+       "│   │   │   ],\n",
+       "│   │   │   clientList=[],\n",
+       "│   │   │   partsList=[],\n",
+       "│   │   │   attributeList=None,\n",
+       "│   │   │   featureMap=None,\n",
+       "│   │   │   clusterRevision=1\n",
+       "│   │   ),\n",
+       "│   │   <class 'chip.clusters.Objects.OccupancySensing'>: OccupancySensing(\n",
+       "│   │   │   occupancy=0,\n",
+       "│   │   │   occupancySensorType=0,\n",
+       "│   │   │   occupancySensorTypeBitmap=1,\n",
+       "│   │   │   pirOccupiedToUnoccupiedDelay=None,\n",
+       "│   │   │   pirUnoccupiedToOccupiedDelay=None,\n",
+       "│   │   │   pirUnoccupiedToOccupiedThreshold=None,\n",
+       "│   │   │   ultrasonicOccupiedToUnoccupiedDelay=None,\n",
+       "│   │   │   ultrasonicUnoccupiedToOccupiedDelay=None,\n",
+       "│   │   │   ultrasonicUnoccupiedToOccupiedThreshold=None,\n",
+       "│   │   │   physicalContactOccupiedToUnoccupiedDelay=None,\n",
+       "│   │   │   physicalContactUnoccupiedToOccupiedDelay=None,\n",
+       "│   │   │   physicalContactUnoccupiedToOccupiedThreshold=None,\n",
+       "│   │   │   attributeList=None,\n",
+       "│   │   │   featureMap=None,\n",
+       "│   │   │   clusterRevision=2\n",
+       "│   │   )\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m2\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Groups'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mGroups\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mnameSupport\u001b[0m=\u001b[1;36m128\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mattributeList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mfeatureMap\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclusterRevision\u001b[0m=\u001b[1;36m3\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mOnOff\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33monOff\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mglobalSceneControl\u001b[0m=\u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33monTime\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moffWaitTime\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mstartUpOnOff\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mattributeList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mfeatureMap\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclusterRevision\u001b[0m=\u001b[1;36m4\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.Descriptor'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mdeviceList\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mDeviceType\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[1;36m256\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mserverList\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m6\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m29\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;36m1030\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclientList\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mpartsList\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mattributeList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mfeatureMap\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclusterRevision\u001b[0m=\u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OccupancySensing'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mOccupancySensing\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moccupancy\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moccupancySensorType\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moccupancySensorTypeBitmap\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mpirOccupiedToUnoccupiedDelay\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mpirUnoccupiedToOccupiedDelay\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mpirUnoccupiedToOccupiedThreshold\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33multrasonicOccupiedToUnoccupiedDelay\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33multrasonicUnoccupiedToOccupiedDelay\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33multrasonicUnoccupiedToOccupiedThreshold\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mphysicalContactOccupiedToUnoccupiedDelay\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mphysicalContactUnoccupiedToOccupiedDelay\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mphysicalContactUnoccupiedToOccupiedThreshold\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mattributeList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mfeatureMap\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclusterRevision\u001b[0m=\u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(2, [2], True)" + ] + }, + { + "cell_type": "markdown", + "id": "1e852897-ce10-4885-bd84-b1aa060b9b6c", + "metadata": {}, + "source": [ + "#### Read Events:\n", + "\n", + "A `ReadEvents` API exists that behaves similarly to the `ReadAttributes` API. It permits the same degrees of wildcard expression as its counterpart and follows the same format for expressing all wildcard permutations." + ] + }, + { + "cell_type": "markdown", + "id": "11f23767-c8a8-4ecd-8d38-023b3872eceb", + "metadata": {}, + "source": [ + "#### Read all events:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "5ef28449-1262-4b06-9984-4a2f9c409450", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "[\n",
+       "EventReadResult(\n",
+       "│   │   Header=EventHeader(\n",
+       "│   │   │   EndpointId=1,\n",
+       "│   │   │   Event=None,\n",
+       "│   │   │   EventNumber=0,\n",
+       "│   │   │   Priority=<EventPriority.DEBUG: 1>,\n",
+       "│   │   │   Timestamp=<EventTimestampType.SYSTEM: 0>,\n",
+       "│   │   │   TimestampType=None\n",
+       "│   │   ),\n",
+       "│   │   Status=<Status.Success: 0>,\n",
+       "│   │   Data=TestEvent(\n",
+       "│   │   │   arg1=0,\n",
+       "│   │   │   arg2=<SimpleEnum.kUnspecified: 0>,\n",
+       "│   │   │   arg3=False,\n",
+       "│   │   │   arg4=SimpleStruct(\n",
+       "│   │   │   │   a=0,\n",
+       "│   │   │   │   b=False,\n",
+       "│   │   │   │   c=<SimpleEnum.kUnspecified: 0>,\n",
+       "│   │   │   │   d=b'',\n",
+       "│   │   │   │   e='',\n",
+       "│   │   │   │   f=0,\n",
+       "│   │   │   │   g=0.0,\n",
+       "│   │   │   │   h=0.0\n",
+       "│   │   │   ),\n",
+       "│   │   │   arg5=[],\n",
+       "│   │   │   arg6=[]\n",
+       "│   │   )\n",
+       ")\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;35mEventReadResult\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mHeader\u001b[0m=\u001b[1;35mEventHeader\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mEndpointId\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mEvent\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mEventNumber\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mPriority\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mEventPriority.DEBUG:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mTimestamp\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mEventTimestampType.SYSTEM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mTimestampType\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mStatus\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mStatus.Success:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mData\u001b[0m=\u001b[1;35mTestEvent\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg1\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg2\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg3\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg4\u001b[0m=\u001b[1;35mSimpleStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33ma\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mb\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mc\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33md\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33me\u001b[0m=\u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mf\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mg\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mh\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg5\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg6\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Force an event to get emitted.\n", + "await devCtrl.SendCommand(2, 1, Clusters.TestCluster.Commands.TestEmitTestEventRequest())\n", + "\n", + "await devCtrl.ReadEvent(2, [('*')])" + ] + }, + { + "cell_type": "markdown", + "id": "b93ee082-2a7f-47db-8c92-e7accc216086", + "metadata": {}, + "source": [ + "### Subscription Interaction\n", + "\n", + "To subscribe to a Node, the same `ReadAttributes` API is used to trigger a subscription, with a valid `reportInterval` tuple passed in being used as a way to indicate the request to create a subscription." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "921b58f7-cdfb-436f-813a-412cbf7a018d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
<Subscription (Id=6469889299346410316)>\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m<\u001b[0m\u001b[1;95mSubscription\u001b[0m\u001b[39m \u001b[0m\u001b[1;39m(\u001b[0m\u001b[33mId\u001b[0m\u001b[39m=\u001b[0m\u001b[1;36m6469889299346410316\u001b[0m\u001b[1;39m)\u001b[0m\u001b[1m>\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "reportingTimingParams = (0, 2) # MinInterval = 0s, MaxInterval = 2s\n", + "subscription = await devCtrl.ReadAttribute(2, [(2, Clusters.OnOff)], True, reportingTimingParams)\n", + "subscription" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "ebd8f6aa-cf7b-4396-a83a-ad2fdacad1ae", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "2: {\n",
+       "│   │   <class 'chip.clusters.Objects.OnOff'>: OnOff(\n",
+       "│   │   │   onOff=False,\n",
+       "│   │   │   globalSceneControl=True,\n",
+       "│   │   │   onTime=0,\n",
+       "│   │   │   offWaitTime=0,\n",
+       "│   │   │   startUpOnOff=0,\n",
+       "│   │   │   attributeList=None,\n",
+       "│   │   │   featureMap=0,\n",
+       "│   │   │   clusterRevision=4\n",
+       "│   │   )\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m2\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;35mOnOff\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33monOff\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mglobalSceneControl\u001b[0m=\u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33monTime\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33moffWaitTime\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mstartUpOnOff\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mattributeList\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mfeatureMap\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mclusterRevision\u001b[0m=\u001b[1;36m4\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "subscription.GetAttributes()" + ] + }, + { + "cell_type": "markdown", + "id": "866329a7-7757-4a5d-b7b0-4d70a86b65b0", + "metadata": {}, + "source": [ + "#### Trigger Report\n", + "\n", + "To trigger a report, let's alter the state of the on/off switch on EP1. That should trigger the generation of a set of attribute reports.\n", + "\n", + "The `SubscriptionTransaction` object returned by `ReadAttribute` permits installing a callback that is invoked on any attribute report. A default callback is installed above that just dumps out the attribute data." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "b0d34116-6c9b-4aee-a8a0-f92091654b4c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attribute Changed:\n" + ] + }, + { + "data": { + "text/html": [ + "
{\n",
+       "'Endpoint': 2,\n",
+       "'Attribute': <class 'chip.clusters.Objects.OnOff.Attributes.OnOff'>,\n",
+       "'Value': True\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Endpoint'\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Attribute'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnOff'\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Value'\u001b[0m: \u001b[3;92mTrue\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attribute Changed:\n" + ] + }, + { + "data": { + "text/html": [ + "
{\n",
+       "'Endpoint': 2,\n",
+       "'Attribute': <class 'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'>,\n",
+       "'Value': True\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Endpoint'\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Attribute'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.GlobalSceneControl'\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Value'\u001b[0m: \u001b[3;92mTrue\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attribute Changed:\n" + ] + }, + { + "data": { + "text/html": [ + "
{\n",
+       "'Endpoint': 2,\n",
+       "'Attribute': <class 'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'>,\n",
+       "'Value': 0\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Endpoint'\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Attribute'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OffWaitTime'\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Value'\u001b[0m: \u001b[1;36m0\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.SendCommand(2, 2, Clusters.OnOff.Commands.On())\n", + "time.sleep(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "eb712364-4311-4bcb-91a4-2e9f26b825a1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attribute Changed:\n" + ] + }, + { + "data": { + "text/html": [ + "
{\n",
+       "'Endpoint': 2,\n",
+       "'Attribute': <class 'chip.clusters.Objects.OnOff.Attributes.OnOff'>,\n",
+       "'Value': False\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Endpoint'\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Attribute'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnOff'\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Value'\u001b[0m: \u001b[3;91mFalse\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Attribute Changed:\n" + ] + }, + { + "data": { + "text/html": [ + "
{\n",
+       "'Endpoint': 2,\n",
+       "'Attribute': <class 'chip.clusters.Objects.OnOff.Attributes.OnTime'>,\n",
+       "'Value': 0\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Endpoint'\u001b[0m: \u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Attribute'\u001b[0m: \u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OnOff.Attributes.OnTime'\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'Value'\u001b[0m: \u001b[1;36m0\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.SendCommand(2, 2, Clusters.OnOff.Commands.Off())\n", + "time.sleep(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "50aa8d53-0fe3-4489-badd-3db9f78ea210", + "metadata": {}, + "outputs": [], + "source": [ + "subscription.Shutdown()" + ] + }, + { + "cell_type": "markdown", + "id": "dad3f8bf-431e-496f-b2a7-6e675e3d3ee2", + "metadata": {}, + "source": [ + "#### Subscribe to Events" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "7db20b08-fed9-46f6-ab46-9e69c82a87fb", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "reportingTimingParams = (0, 2) # MinInterval = 0s, MaxInterval = 2s\n", + "subscription = await devCtrl.ReadEvent(2, [()], reportingTimingParams)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "d8599eec-b1e1-4936-aea2-11c2a015a7a7", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "[\n",
+       "EventReadResult(\n",
+       "│   │   Header=EventHeader(\n",
+       "│   │   │   EndpointId=1,\n",
+       "│   │   │   Event=None,\n",
+       "│   │   │   EventNumber=0,\n",
+       "│   │   │   Priority=<EventPriority.DEBUG: 1>,\n",
+       "│   │   │   Timestamp=<EventTimestampType.SYSTEM: 0>,\n",
+       "│   │   │   TimestampType=None\n",
+       "│   │   ),\n",
+       "│   │   Status=<Status.Success: 0>,\n",
+       "│   │   Data=TestEvent(\n",
+       "│   │   │   arg1=0,\n",
+       "│   │   │   arg2=<SimpleEnum.kUnspecified: 0>,\n",
+       "│   │   │   arg3=False,\n",
+       "│   │   │   arg4=SimpleStruct(\n",
+       "│   │   │   │   a=0,\n",
+       "│   │   │   │   b=False,\n",
+       "│   │   │   │   c=<SimpleEnum.kUnspecified: 0>,\n",
+       "│   │   │   │   d=b'',\n",
+       "│   │   │   │   e='',\n",
+       "│   │   │   │   f=0,\n",
+       "│   │   │   │   g=0.0,\n",
+       "│   │   │   │   h=0.0\n",
+       "│   │   │   ),\n",
+       "│   │   │   arg5=[],\n",
+       "│   │   │   arg6=[]\n",
+       "│   │   )\n",
+       ")\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;35mEventReadResult\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mHeader\u001b[0m=\u001b[1;35mEventHeader\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mEndpointId\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mEvent\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mEventNumber\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mPriority\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mEventPriority.DEBUG:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mTimestamp\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mEventTimestampType.SYSTEM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mTimestampType\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mStatus\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mStatus.Success:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mData\u001b[0m=\u001b[1;35mTestEvent\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg1\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg2\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg3\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg4\u001b[0m=\u001b[1;35mSimpleStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33ma\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mb\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mc\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33md\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33me\u001b[0m=\u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mf\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mg\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mh\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg5\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33marg6\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "subscription.GetEvents()" + ] + }, + { + "cell_type": "markdown", + "id": "4ff2d257-ea1b-4957-97ed-fd6518740218", + "metadata": {}, + "source": [ + "### Trigger Event\n", + "\n", + "Force an event to get emitted, which after a short while, should generate a report and trigger the print out of the received event:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "93cb4c17-b3c7-4462-b448-397171458416", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Received Event:\n" + ] + }, + { + "data": { + "text/html": [ + "
EventReadResult(\n",
+       "Header=EventHeader(\n",
+       "│   │   EndpointId=1,\n",
+       "│   │   Event=None,\n",
+       "│   │   EventNumber=1,\n",
+       "│   │   Priority=<EventPriority.DEBUG: 1>,\n",
+       "│   │   Timestamp=<EventTimestampType.SYSTEM: 0>,\n",
+       "│   │   TimestampType=None\n",
+       "),\n",
+       "Status=<Status.Success: 0>,\n",
+       "Data=TestEvent(\n",
+       "│   │   arg1=0,\n",
+       "│   │   arg2=<SimpleEnum.kUnspecified: 0>,\n",
+       "│   │   arg3=False,\n",
+       "│   │   arg4=SimpleStruct(\n",
+       "│   │   │   a=0,\n",
+       "│   │   │   b=False,\n",
+       "│   │   │   c=<SimpleEnum.kUnspecified: 0>,\n",
+       "│   │   │   d=b'',\n",
+       "│   │   │   e='',\n",
+       "│   │   │   f=0,\n",
+       "│   │   │   g=0.0,\n",
+       "│   │   │   h=0.0\n",
+       "│   │   ),\n",
+       "│   │   arg5=[],\n",
+       "│   │   arg6=[]\n",
+       ")\n",
+       ")\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1;35mEventReadResult\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mHeader\u001b[0m=\u001b[1;35mEventHeader\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mEndpointId\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mEvent\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mEventNumber\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mPriority\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mEventPriority.DEBUG:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mTimestamp\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mEventTimestampType.SYSTEM:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mTimestampType\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mStatus\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mStatus.Success:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mData\u001b[0m=\u001b[1;35mTestEvent\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33marg1\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33marg2\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33marg3\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33marg4\u001b[0m=\u001b[1;35mSimpleStruct\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33ma\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mb\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mc\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mSimpleEnum.kUnspecified:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33md\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33me\u001b[0m=\u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mf\u001b[0m=\u001b[1;36m0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mg\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mh\u001b[0m=\u001b[1;36m0\u001b[0m\u001b[1;36m.0\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33marg5\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33marg6\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.SendCommand(2, 1, Clusters.TestCluster.Commands.TestEmitTestEventRequest())\n", + "time.sleep(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "6e294da6-1e71-444d-952b-0e1d3b8268b6", + "metadata": {}, + "outputs": [], + "source": [ + "subscription.Shutdown()" + ] + }, + { + "cell_type": "markdown", + "id": "e2b7e2ea-497f-40e7-86c5-198ad1a80950", + "metadata": {}, + "source": [ + "### Write Interaction\n", + "\n", + "To write attribute data, the `WriteAttribute` API can be used. It requires a NodeId and a list of cluster object encapsulated data for the attribute being written." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "95c78192-d895-4784-b8e6-4f8884bb1f92", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "[\n",
+       "AttributeStatus(\n",
+       "│   │   Path=AttributePath(\n",
+       "│   │   │   EndpointId=1,\n",
+       "│   │   │   ClusterId=1295,\n",
+       "│   │   │   AttributeId=6\n",
+       "│   │   ),\n",
+       "│   │   Status=<Status.Success: 0>\n",
+       ")\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;35mAttributeStatus\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mPath\u001b[0m=\u001b[1;35mAttributePath\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mEndpointId\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mClusterId\u001b[0m=\u001b[1;36m1295\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mAttributeId\u001b[0m=\u001b[1;36m6\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[33mStatus\u001b[0m=\u001b[1m<\u001b[0m\u001b[1;95mStatus.Success:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m0\u001b[0m\u001b[1m>\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.WriteAttribute(2, [ (1, Clusters.TestCluster.Attributes.Int16u(2)) ])" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "69fcf8e6-a49e-471e-9169-14c4fee88f2e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "1: {\n",
+       "│   │   <class 'chip.clusters.Objects.TestCluster'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.TestCluster.Attributes.Int16u'>: 2\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m1\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.TestCluster.Attributes.Int16u'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(2, [ (1, Clusters.TestCluster.Attributes.Int16u) ])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "matter-env", + "language": "python", + "name": "matter-env" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2+chromium.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/guides/repl/Matter - Multi Fabric Commissioning.ipynb b/docs/guides/repl/Matter - Multi Fabric Commissioning.ipynb new file mode 100644 index 00000000000000..231d7c66df48e1 --- /dev/null +++ b/docs/guides/repl/Matter - Multi Fabric Commissioning.ipynb @@ -0,0 +1,1186 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7953092e-e313-4fb5-82ab-ce1d42f4c1a9", + "metadata": { + "tags": [] + }, + "source": [ + "# Multi Fabric - Commissioning and Interactions\n", + "\n", + "\n", + "\"drawing\"\n", + "\n", + "

\n", + "\n", + "This walks through creating multiple controllers on multiple fabrics, using those controllers to commission a target onto those fabrics and finally, interacting with them using the interaction model." + ] + }, + { + "cell_type": "markdown", + "id": "c8aae2cc-41fa-4101-a744-c725be5f034c", + "metadata": {}, + "source": [ + "## FabricAdmins and Controllers\n", + "\n", + "The `FabricAdmin` class (present in the `chip.FabricAdmin` package) is responsible for adminstering a fabric. It houses the Fabric ID and Index, as well as an RCAC and ICAC that provides the certificate material grounding that fabric.\n", + "\n", + "The `FabricAdmin` can be used to vend `ChipDeviceController` objects that represent a controller instance with a specific identity grounded in the admin's fabric. This controller can then be used to commission and interact with devices." + ] + }, + { + "cell_type": "markdown", + "id": "7f2e9f8d-eb79-494f-adac-efefdba7165f", + "metadata": {}, + "source": [ + "## Clear Persisted Storage\n", + "\n", + "Let's clear out our persisted storage (if one exists) to start from a clean slate." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b351b723-9849-430d-ad4e-f699897416d1", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import os, subprocess\n", + "\n", + "if os.path.isfile('/tmp/repl-storage.json'):\n", + " os.remove('/tmp/repl-storage.json')\n", + "\n", + "# So that the all-clusters-app won't boot with stale prior state. \n", + "subprocess.Popen(['rm', '-rf', '/tmp/chip_*'])" + ] + }, + { + "cell_type": "markdown", + "id": "f50759eb-3511-4312-9cfd-7431dcb9366a", + "metadata": { + "tags": [] + }, + "source": [ + "## Initialization\n", + "\n", + "Let's first begin by setting up by importing some key modules that are needed to make it easier for us to interact with the Matter stack.\n", + "\n", + "`ChipReplStartup.py` is run within the global namespace. This results in all of its imports being made available here.\n", + "\n", + "> **NOTE**: _This is not needed if you launch the REPL from the command-line._" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "72f25a72-0b7e-41d5-a9ef-18af8a54ec39", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
──────────────────────────────────────── Matter REPL ────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m──────────────────────────────────────── \u001b[0mMatter REPL\u001b[92m ────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "            \n",
+       "    \n",
+       "            Welcome to the Matter Python REPL!\n",
+       "    \n",
+       "            For help, please type matterhelp()\n",
+       "    \n",
+       "            To get more information on a particular object/class, you can pass\n",
+       "            that into matterhelp() as well.\n",
+       "    \n",
+       "            \n",
+       "
\n" + ], + "text/plain": [ + "\n", + " \n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m Welcome to the Matter Python REPL!\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m For help, please type \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m To get more information on a particular object/class, you can pass\u001b[0m\n", + "\u001b[1;34m that into \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\u001b[1;34m as well.\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m \u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
─────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m─────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-25 16:58:57 johnsj-macbookpro1.roam.corp.google.com root[27921] ERROR [Errno 2] No such file or directory: '/tmp/repl-storage.json'\n", + "2022-01-25 16:58:57 johnsj-macbookpro1.roam.corp.google.com root[27921] WARNING Could not load configuration from /tmp/repl-storage.json - resetting configuration...\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "No previous fabric admins discovered in persistent storage - creating a new one...\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[38;5;129mNo previous fabric admins discovered in persistent storage - creating a new one\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 1(1)\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Creating default device controller on fabric 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mCreating default device controller on fabric \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Allocating new controller with FabricId: 1(1), NodeId: 1\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "Default CHIP Device Controller has been initialized to manage fabricAdmins[0], and is \n",
+       "available as devCtrl\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n", + "\u001b[34mDefault CHIP Device Controller has been initialized to manage \u001b[0m\u001b[1;31mfabricAdmins\u001b[0m\u001b[1;31m[\u001b[0m\u001b[1;31m0\u001b[0m\u001b[1;31m]\u001b[0m\u001b[1;34m, and is \u001b[0m\n", + "\u001b[1;34mavailable as \u001b[0m\u001b[1;31mdevCtrl\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import chip.native\n", + "import pkgutil\n", + "module = pkgutil.get_loader('chip.ChipReplStartup')\n", + "%run {module.path}" + ] + }, + { + "cell_type": "markdown", + "id": "d79775d7-2ebb-4d05-9f2f-c7859802dc98", + "metadata": {}, + "source": [ + "At startup, the REPL will attempt to find any previously configured fabrics stored in persisted storage. If it can't find any (as is the case here), it will construct a default `FabricAdmin` object on Fabric 1 (Index 1) as well as construct a device controller (`devCtrl`) on that fabric." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "030ecc69-bad4-476f-95d5-cb593597cad6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "[\n",
+       "<chip.FabricAdmin.FabricAdmin object at 0x10a68dee0>\n",
+       "]\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mchip.FabricAdmin.FabricAdmin\u001b[0m\u001b[39m object at \u001b[0m\u001b[1;36m0x10a68dee0\u001b[0m\u001b[1m>\u001b[0m\n", + "\u001b[1m]\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fabricAdmins" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a5c5b564-2d16-4790-8659-a7f7f304df98", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
<chip.ChipDeviceCtrl.ChipDeviceController object at 0x10a6c6040>\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m<\u001b[0m\u001b[1;95mchip.ChipDeviceCtrl.ChipDeviceController\u001b[0m\u001b[39m object at \u001b[0m\u001b[1;36m0x10a6c6040\u001b[0m\u001b[1m>\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "devCtrl" + ] + }, + { + "cell_type": "markdown", + "id": "b793def3-10ff-4f86-a84a-fce81b7a86a4", + "metadata": {}, + "source": [ + "### Commission onto Fabric 1" + ] + }, + { + "cell_type": "markdown", + "id": "a84a90a5-726f-4634-a148-3860ba3ba0fc", + "metadata": {}, + "source": [ + "#### Launch Server\n", + "\n", + "Let's launch an instance of the `chip-all-clusters-app`." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "b8b08b57-61a7-4c3e-8acc-cf4d78a67f55", + "metadata": {}, + "outputs": [], + "source": [ + "import time, os\n", + "import subprocess\n", + "subprocess.Popen(['pkill', '-f', 'chip-all-clusters-app'])\n", + "time.sleep(1)\n", + "\n", + "# The location of the all-clusters-app in the cloud playground is one level higher - adjust for this by testing for file presence.\n", + "if (os.path.isfile('../../../out/debug/chip-all-clusters-app')):\n", + " appPath = '../../../out/debug/chip-all-clusters-app'\n", + "else:\n", + " appPath = '../../../../out/debug/chip-all-clusters-app'\n", + " \n", + "process = subprocess.Popen(appPath, stdout=subprocess.DEVNULL)\n", + "time.sleep(1)" + ] + }, + { + "cell_type": "markdown", + "id": "cdbc86a0-24ca-4d1b-85f6-1d812a190817", + "metadata": {}, + "source": [ + "#### Commission Target\n", + "\n", + "Commission the target onto Fabric 1 using the default device controller instance with a NodeId of 1." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "cde97ce7-6478-45fd-b985-103b09d8dfa9", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-25 16:59:00 johnsj-macbookpro1.roam.corp.google.com chip.CTL[27921] ERROR Unable to find country code, defaulting to WW\n", + "2022-01-25 16:59:00 johnsj-macbookpro1.roam.corp.google.com chip.SC[27921] ERROR The device does not support GetClock_RealTimeMS() API. This will eventually result in CASE session setup failures.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Node address has been updated\n", + "Commissioning complete\n" + ] + }, + { + "data": { + "text/html": [ + "
True\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[3;92mTrue\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "devCtrl.CommissionIP(b'127.0.0.1', 20202021, 2)" + ] + }, + { + "cell_type": "markdown", + "id": "c24fea58-d8a3-4352-a3b6-716340da74e5", + "metadata": {}, + "source": [ + "### Read OpCreds Cluster\n", + "\n", + "Read out the OpCreds cluster to confirm membership into Fabric 1." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "830e3421-45a6-435f-9617-bbf34f7c3fe0", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.OperationalCredentials'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'>: [\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04\\xa2\\x88}\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x98',\n",
+       "│   │   │   │   │   vendorId=27168,\n",
+       "│   │   │   │   │   fabricId=1,\n",
+       "│   │   │   │   │   nodeId=2,\n",
+       "│   │   │   │   │   label=''\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ]\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x04\\xa2\\x88\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x98'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m=\u001b[1;36m27168\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.ReadAttribute(2, [(Clusters.OperationalCredentials.Attributes.FabricsList)], fabricFiltered=False)" + ] + }, + { + "cell_type": "markdown", + "id": "77c0c2a1-3014-4dc5-8d42-5a3459ed311a", + "metadata": {}, + "source": [ + "### Commission onto Fabric 2" + ] + }, + { + "cell_type": "markdown", + "id": "965a5fbf-5762-4432-93f9-47782c5ee050", + "metadata": {}, + "source": [ + "#### Create new FabricAdmin" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "9f7d6810-6d8e-47c9-8795-b4bc8777e963", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 2(2)\n" + ] + } + ], + "source": [ + "import chip.FabricAdmin as FabricAdmin\n", + "fabric2 = FabricAdmin.FabricAdmin(fabricId = 2, fabricIndex = 2)" + ] + }, + { + "cell_type": "markdown", + "id": "73477a0d-f80f-4973-b34b-fe31b55cb5e1", + "metadata": {}, + "source": [ + "Here's a brief peek at the JSON data that is in the persisted storage file." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "f211c5be-665b-4630-9570-a44a6f17f358", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "'repl-config': {\n",
+       "│   │   'fabricAdmins': {\n",
+       "│   │   │   '1': {\n",
+       "│   │   │   │   'fabricId': 1\n",
+       "│   │   │   },\n",
+       "│   │   │   '2': {\n",
+       "│   │   │   │   'fabricId': 2\n",
+       "│   │   │   }\n",
+       "│   │   }\n",
+       "},\n",
+       "'sdk-config': {\n",
+       "│   │   'ExampleOpCredsCAKey1': 'BKKIfb3b1LxeVaPOZveSvqdYO0W4LVkSXiTgG1P5mo+sdmr6ISZtNgDj0YVvG55Iq0M/2OwIbEi1WB86dbD7apgpj13h8fueMKMfErM65jMAsAPBcPEhnVc3JJ6m7K4Qq0ORAwBgAABhAAAAAAAAAA==',\n",
+       "│   │   'ExampleOpCredsICAKey1': 'BCwMgmSo2C1vhjBR642H5nieC/jJManFAW54QhdovJhdySYZn96XJoBNyouhoGf9rn0SipgIhmvHPcPqDrDwcAXiQyB87caIuz5DJ3v7KHHLquGmdv5pNpZ4IhqDomt/2kORAwBgAABhAAAAAAAAAA==',\n",
+       "│   │   'ExampleCAIntermediateCert1': 'MIIB2TCCAYCgAwIBAgIBADAKBggqhkjOPQQDAjBEMSAwHgYKKwYBBAGConwBBAwQMDAwMDAwMDAwMDAwMDAwMDEgMB4GCisGAQQBgqJ8AQUMEDAwMDAwMDAwMDAwMDAwMDEwHhcNMjEwMTAxMDAwMDAwWhcNMzAxMjMwMDAwMDAwWjBEMSAwHgYKKwYBBAGConwBAwwQMDAwMDAwMDAwMDAwMDAwMTEgMB4GCisGAQQBgqJ8AQUMEDAwMDAwMDAwMDAwMDAwMDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQsDIJkqNgtb4YwUeuNh+Z4ngv4yTGpxQFueEIXaLyYXckmGZ/elyaATcqLoaBn/a59EoqYCIZrxz3D6g6w8HAFo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcPz5CkZJujm2U0jL0G1lZwoJXD0wHwYDVR0jBBgwFoAUfvAKJyeJwjao2nq+Q3ayf27KXrUwCgYIKoZIzj0EAwIDRwAwRAIgEaX5gBqc5b8eswqDDlc2IQ+wLKfbsONC3FzsuwLCBNkCIAyn32oaFV0YCN9GeiUpYvqbypnMWQGnffF85v7wKhBX',\n",
+       "│   │   'ExampleCARootCert1': 'MIIB2jCCAYCgAwIBAgIBADAKBggqhkjOPQQDAjBEMSAwHgYKKwYBBAGConwBBAwQMDAwMDAwMDAwMDAwMDAwMDEgMB4GCisGAQQBgqJ8AQUMEDAwMDAwMDAwMDAwMDAwMDEwHhcNMjEwMTAxMDAwMDAwWhcNMzAxMjMwMDAwMDAwWjBEMSAwHgYKKwYBBAGConwBBAwQMDAwMDAwMDAwMDAwMDAwMDEgMB4GCisGAQQBgqJ8AQUMEDAwMDAwMDAwMDAwMDAwMDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASiiH2929S8XlWjzmb3kr6nWDtFuC1ZEl4k4BtT+ZqPrHZq+iEmbTYA49GFbxueSKtDP9jsCGxItVgfOnWw+2qYo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfvAKJyeJwjao2nq+Q3ayf27KXrUwHwYDVR0jBBgwFoAUfvAKJyeJwjao2nq+Q3ayf27KXrUwCgYIKoZIzj0EAwIDSAAwRQIgMzvVbqCxT+xJOpxN9HUSYZYdExmkRLN2Jl9vLijLc+sCIQDAxLgwwuxGNPtWJ/dY4kGqpWwNNbq9pEkmQ//t2KhfBg==',\n",
+       "│   │   'ExampleOpCredsCAKey2': 'BJ1gkAlp0ZrmBkQiko2ces/p86N1qCB30y+tdT5HrWEBqgPh6SVNnZfe5ZMjzJZFp/J1K+7MSDF7QeAgKrQYwcAcV1G9fnqw9anHoj+EW2k9xqw0b4bWXE9f2xKfWWb/ykCSAwBgAABhAAAAAAAAAA==',\n",
+       "│   │   'ExampleOpCredsICAKey2': 'BMktytxSOcWsbMcZ6WrjsODvTRKcLWZjo8bt8CDUqfhoHLFqrmahTQnH4rY8gjRpKRBw/Yw2YpEodcaLyC1V+cC2VvZrLqLVW8uRNPkVxcojVHAXYAGCRp6CW4kQ+zBtNUCSAwBgAABhAAAAAAAAAA=='\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'repl-config'\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'fabricAdmins'\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'1'\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'fabricId'\u001b[0m: \u001b[1;36m1\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[32m'2'\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'fabricId'\u001b[0m: \u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'sdk-config'\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'ExampleOpCredsCAKey1'\u001b[0m: \u001b[32m'BKKIfb3b1LxeVaPOZveSvqdYO0W4LVkSXiTgG1P5mo+sdmr6ISZtNgDj0YVvG55Iq0M/2OwIbEi1WB86dbD7apgpj13h8fueMKMf\u001b[0m\u001b[32mErM65jMAsAPBcPEhnVc3JJ6m7K4Qq0ORAwBgAABhAAAAAAAAAA\u001b[0m\u001b[32m=='\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'ExampleOpCredsICAKey1'\u001b[0m: \u001b[32m'BCwMgmSo2C1vhjBR642H5nieC/jJManFAW54QhdovJhdySYZn96XJoBNyouhoGf9rn0SipgIhmvHPcPqDrDwcAXiQyB87caIuz5DJ3v7KHHLquGmdv5pNpZ4IhqDomt/\u001b[0m\u001b[32m2kORAwBgAABhAAAAAAAAAA\u001b[0m\u001b[32m=='\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'ExampleCAIntermediateCert1'\u001b[0m: \u001b[32m'MIIB2TCCAYCgAwIBAgIBADAKBggqhkjOPQQDAjBEMSAwHgYKKwYBBAGConwBBAwQMDAwMDAwMDAwMDAwMDAwMDEgMB4GCisGAQQBgqJ8AQUMEDAwMDAwMDAwMDAwMDAwMDEwHhcNMjEwMTAxMDAwMDAwWhcNMzAxMjMwMDAwMDAwWjBEMSAwHgYKKwYBBAGConwBAwwQMDAwMDAwMDAwMDAwMDAwMTEgMB4GCisGAQQBgqJ8AQUMEDAwMDAwMDAwMDAwMDAwMDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQsDIJkqNgtb4YwUeuNh+Z4ngv4yTGpxQFueEIXaLyYXckmGZ/elyaATcqLoaBn/a59EoqYCIZrxz3D6g6w8HAFo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcPz5CkZJujm2U0jL0G1lZwoJXD0wHwYDVR0jBBgwFoAUfvAKJyeJwjao2nq+Q3ayf27KXrUwCgYIKoZIzj0EAwIDRwAwRAIgEaX5gBqc5b8eswqDDlc2IQ+wLKfbsONC3FzsuwLCBNkCIAyn32oaFV0YCN9GeiUpYvqbypnMWQGnffF85v7wKhBX'\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'ExampleCARootCert1'\u001b[0m: \u001b[32m'MIIB2jCCAYCgAwIBAgIBADAKBggqhkjOPQQDAjBEMSAwHgYKKwYBBAGConwBBAwQMDAwMDAwMDAwMDAwMDAwMDEgMB4GCisGAQQBgqJ8AQUMEDAwMDAwMDAwMDAwMDAwMDEwHhcNMjEwMTAxMDAwMDAwWhcNMzAxMjMwMDAwMDAwWjBEMSAwHgYKKwYBBAGConwBBAwQMDAwMDAwMDAwMDAwMDAwMDEgMB4GCisGAQQBgqJ8AQUMEDAwMDAwMDAwMDAwMDAwMDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASiiH2929S8XlWjzmb3kr6nWDtFuC1ZEl4k4BtT+ZqPrHZq+iEmbTYA49GFbxueSKtDP9jsCGxItVgfOnWw+2qYo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfvAKJyeJwjao2nq+Q3ayf27KXrUwHwYDVR0jBBgwFoAUfvAKJyeJwjao2nq+Q3ayf27KXrUwCgYIKoZIzj0EAwIDSAAwRQIgMzvVbqCxT+xJOpxN9HUSYZYdExmkRLN2Jl9vLijLc+sCIQDAxLgwwuxGNPtWJ/dY4kGqpWwNNbq9pEkmQ//\u001b[0m\u001b[32mt2KhfBg\u001b[0m\u001b[32m=='\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'ExampleOpCredsCAKey2'\u001b[0m: \u001b[32m'BJ1gkAlp0ZrmBkQiko2ces/p86N1qCB30y+tdT5HrWEBqgPh6SVNnZfe5ZMjzJZFp/J1K+7MSDF7QeAgKrQYwcAcV1G9fnqw9anHoj+EW2k9xqw0b4bWXE9f2xKfWWb/\u001b[0m\u001b[32mykCSAwBgAABhAAAAAAAAAA\u001b[0m\u001b[32m=='\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'ExampleOpCredsICAKey2'\u001b[0m: \u001b[32m'BMktytxSOcWsbMcZ6WrjsODvTRKcLWZjo8bt8CDUqfhoHLFqrmahTQnH4rY8gjRpKRBw/Yw2YpEodcaLyC1V+cC2VvZrLqLVW8uRNPkVxcojVHAXYAGCRp6CW4kQ+\u001b[0m\u001b[32mzBtNUCSAwBgAABhAAAAAAAAAA\u001b[0m\u001b[32m=='\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "builtins.chipStack.GetStorageManager().jsonData" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "15bb2c3e-9051-421c-8769-4a59e4b2fc73", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Allocating new controller with FabricId: 2(2), NodeId: 1\n" + ] + } + ], + "source": [ + "devCtrl2 = fabric2.NewController()" + ] + }, + { + "cell_type": "markdown", + "id": "9da4943c-ffff-42e1-a369-f36f89423ed6", + "metadata": {}, + "source": [ + "#### Open Commissioning Window" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "7902ab28-3c74-4717-8522-f6c4a17c5efe", + "metadata": {}, + "outputs": [], + "source": [ + "await devCtrl.SendCommand(2, 0, Clusters.AdministratorCommissioning.Commands.OpenBasicCommissioningWindow(100))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "1c57c8ff-5ae9-4fdd-9fb8-4eda0e297db2", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-25 16:59:00 johnsj-macbookpro1.roam.corp.google.com chip.CTL[27921] ERROR Unable to find country code, defaulting to WW\n", + "2022-01-25 16:59:00 johnsj-macbookpro1.roam.corp.google.com chip.SC[27921] ERROR The device does not support GetClock_RealTimeMS() API. This will eventually result in CASE session setup failures.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Node address has been updated\n", + "Commissioning complete\n" + ] + }, + { + "data": { + "text/html": [ + "
True\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[3;92mTrue\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "devCtrl2.CommissionIP(b'127.0.0.1', 20202021, 2)" + ] + }, + { + "cell_type": "markdown", + "id": "d55534a4-a926-42da-8b80-a9b3408324dc", + "metadata": {}, + "source": [ + "### Read OpCreds Cluster\n", + "\n", + "Read out the OpCreds cluster to confirm membership into Fabric 2." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "0c087a70-d852-4329-958d-d91a1bdbffaf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.OperationalCredentials'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'>: [\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04\\xa2\\x88}\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x98',\n",
+       "│   │   │   │   │   vendorId=27168,\n",
+       "│   │   │   │   │   fabricId=1,\n",
+       "│   │   │   │   │   nodeId=2,\n",
+       "│   │   │   │   │   label=''\n",
+       "│   │   │   │   ),\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=2,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04\\x9d`\\x90\\ti\\xd1\\x9a\\xe6\\x06D\"\\x92\\x8d\\x9cz\\xcf\\xe9\\xf3\\xa3u\\xa8 w\\xd3/\\xadu>G\\xada\\x01\\xaa\\x03\\xe1\\xe9%M\\x9d\\x97\\xde\\xe5\\x93#\\xcc\\x96E\\xa7\\xf2u+\\xee\\xccH1{A\\xe0 *\\xb4\\x18\\xc1\\xc0',\n",
+       "│   │   │   │   │   vendorId=28544,\n",
+       "│   │   │   │   │   fabricId=2,\n",
+       "│   │   │   │   │   nodeId=2,\n",
+       "│   │   │   │   │   label=''\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ]\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x04\\xa2\\x88\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x98'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m=\u001b[1;36m27168\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x04\\x9d`\\x90\\ti\\xd1\\x9a\\xe6\\x06D\"\\x92\\x8d\\x9cz\\xcf\\xe9\\xf3\\xa3u\\xa8 w\\xd3/\\xadu>G\\xada\\x01\\xaa\\x03\\xe1\\xe9%M\\x9d\\x97\\xde\\xe5\\x93#\\xcc\\x96E\\xa7\\xf2u+\\xee\\xccH1\u001b[0m\u001b[32m{\u001b[0m\u001b[32mA\\xe0 *\\xb4\\x18\\xc1\\xc0'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m=\u001b[1;36m28544\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl2.ReadAttribute(2, [(Clusters.OperationalCredentials.Attributes.FabricsList)], fabricFiltered=False)" + ] + }, + { + "cell_type": "markdown", + "id": "b5cbbd20-1609-4fe1-a17e-8027b0ba1334", + "metadata": { + "tags": [] + }, + "source": [ + "## Relaunch REPL\n", + "\n", + "Let's simulate re-launching the REPL to show-case the capabilities of the persistence storage and its mechanics." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "d44f5ab8-c59f-4fdb-9a26-081f6799c512", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
──────────────────────────────────────── Matter REPL ────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m──────────────────────────────────────── \u001b[0mMatter REPL\u001b[92m ────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "            \n",
+       "    \n",
+       "            Welcome to the Matter Python REPL!\n",
+       "    \n",
+       "            For help, please type matterhelp()\n",
+       "    \n",
+       "            To get more information on a particular object/class, you can pass\n",
+       "            that into matterhelp() as well.\n",
+       "    \n",
+       "            \n",
+       "
\n" + ], + "text/plain": [ + "\n", + " \n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m Welcome to the Matter Python REPL!\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m For help, please type \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m To get more information on a particular object/class, you can pass\u001b[0m\n", + "\u001b[1;34m that into \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\u001b[1;34m as well.\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m \u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
─────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m─────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Restoring FabricAdmin from storage to manage FabricId 1, FabricIndex 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mRestoring FabricAdmin from storage to manage FabricId \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m, FabricIndex \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 1(1)\n" + ] + }, + { + "data": { + "text/html": [ + "
Restoring FabricAdmin from storage to manage FabricId 2, FabricIndex 2...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mRestoring FabricAdmin from storage to manage FabricId \u001b[0m\u001b[1;38;5;129m2\u001b[0m\u001b[38;5;129m, FabricIndex \u001b[0m\u001b[1;38;5;129m2\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 2(2)\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "Fabric Admins have been loaded and are available at fabricAdmins\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[34mFabric Admins have been loaded and are available at \u001b[0m\u001b[31mfabricAdmins\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Creating default device controller on fabric 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mCreating default device controller on fabric \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Allocating new controller with FabricId: 1(1), NodeId: 1\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "Default CHIP Device Controller has been initialized to manage fabricAdmins[0], and is \n",
+       "available as devCtrl\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n", + "\u001b[34mDefault CHIP Device Controller has been initialized to manage \u001b[0m\u001b[1;31mfabricAdmins\u001b[0m\u001b[1;31m[\u001b[0m\u001b[1;31m0\u001b[0m\u001b[1;31m]\u001b[0m\u001b[1;34m, and is \u001b[0m\n", + "\u001b[1;34mavailable as \u001b[0m\u001b[1;31mdevCtrl\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import chip.native\n", + "import pkgutil\n", + "module = pkgutil.get_loader('chip.ChipReplStartup')\n", + "%run {module.path}" + ] + }, + { + "cell_type": "markdown", + "id": "2a619893-da3f-4651-bc9f-a2276906fc71", + "metadata": {}, + "source": [ + "The REPL has now loaded the two fabrics that were created in the previous session into the `fabricAdmins` variable. It has also created a default controller on the first fabric in that list (Fabric 1) as `devCtrl`." + ] + }, + { + "cell_type": "markdown", + "id": "1f97206d-2b2f-4ae2-8814-5c756b514ca1", + "metadata": { + "tags": [] + }, + "source": [ + "### Establish CASE and Read OpCreds\n", + "\n", + "To prove that we do indeed have two distinct fabrics and controllers on each fabric, let's go ahead and update the label of each fabric. To do so, you'd need to succcessfully establish a CASE session through a controller on the respective fabric, and call the 'UpdateLabel' command.\n", + "\n", + "Underneath the covers, each device controller will do operational discovery of the NodeId being read and establish a CASE session before issuing the IM interaction." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "45ee5838-b1e9-4ba8-b804-c3efc9d352d0", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-25 16:59:00 johnsj-macbookpro1.roam.corp.google.com chip.SC[27921] ERROR The device does not support GetClock_RealTimeMS() API. This will eventually result in CASE session setup failures.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Node address has been updated\n", + "Established CASE with Device\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.OperationalCredentials'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'>: [\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04\\xa2\\x88}\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x98',\n",
+       "│   │   │   │   │   vendorId=27168,\n",
+       "│   │   │   │   │   fabricId=1,\n",
+       "│   │   │   │   │   nodeId=2,\n",
+       "│   │   │   │   │   label='Fabric1Label'\n",
+       "│   │   │   │   ),\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=2,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04\\x9d`\\x90\\ti\\xd1\\x9a\\xe6\\x06D\"\\x92\\x8d\\x9cz\\xcf\\xe9\\xf3\\xa3u\\xa8 w\\xd3/\\xadu>G\\xada\\x01\\xaa\\x03\\xe1\\xe9%M\\x9d\\x97\\xde\\xe5\\x93#\\xcc\\x96E\\xa7\\xf2u+\\xee\\xccH1{A\\xe0 *\\xb4\\x18\\xc1\\xc0',\n",
+       "│   │   │   │   │   vendorId=28544,\n",
+       "│   │   │   │   │   fabricId=2,\n",
+       "│   │   │   │   │   nodeId=2,\n",
+       "│   │   │   │   │   label=''\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ]\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x04\\xa2\\x88\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x98'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m=\u001b[1;36m27168\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m'Fabric1Label'\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x04\\x9d`\\x90\\ti\\xd1\\x9a\\xe6\\x06D\"\\x92\\x8d\\x9cz\\xcf\\xe9\\xf3\\xa3u\\xa8 w\\xd3/\\xadu>G\\xada\\x01\\xaa\\x03\\xe1\\xe9%M\\x9d\\x97\\xde\\xe5\\x93#\\xcc\\x96E\\xa7\\xf2u+\\xee\\xccH1\u001b[0m\u001b[32m{\u001b[0m\u001b[32mA\\xe0 *\\xb4\\x18\\xc1\\xc0'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m=\u001b[1;36m28544\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m''\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "await devCtrl.SendCommand(2, 0, Clusters.OperationalCredentials.Commands.UpdateFabricLabel(\"Fabric1Label\"))\n", + "await devCtrl.ReadAttribute(2, [(Clusters.OperationalCredentials.Attributes.FabricsList)], fabricFiltered=False)" + ] + }, + { + "cell_type": "markdown", + "id": "ea5d9a2b-78b2-4bb9-843e-97d26b1c0f90", + "metadata": { + "tags": [] + }, + "source": [ + "Instantiate a controller on fabric 2 and use it to read out the op creds from that fabric." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "5d88cb17-bdda-418f-94ca-83d746c162b0", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-25 16:59:00 johnsj-macbookpro1.roam.corp.google.com chip.SC[27921] ERROR The device does not support GetClock_RealTimeMS() API. This will eventually result in CASE session setup failures.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Allocating new controller with FabricId: 2(2), NodeId: 1\n", + "Node address has been updated\n", + "Established CASE with Device\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "{\n",
+       "0: {\n",
+       "│   │   <class 'chip.clusters.Objects.OperationalCredentials'>: {\n",
+       "│   │   │   <class 'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'>: [\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=1,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04\\xa2\\x88}\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x98',\n",
+       "│   │   │   │   │   vendorId=27168,\n",
+       "│   │   │   │   │   fabricId=1,\n",
+       "│   │   │   │   │   nodeId=2,\n",
+       "│   │   │   │   │   label='Fabric1Label'\n",
+       "│   │   │   │   ),\n",
+       "│   │   │   │   FabricDescriptor(\n",
+       "│   │   │   │   │   fabricIndex=2,\n",
+       "│   │   │   │   │   rootPublicKey=b'\\x04\\x9d`\\x90\\ti\\xd1\\x9a\\xe6\\x06D\"\\x92\\x8d\\x9cz\\xcf\\xe9\\xf3\\xa3u\\xa8 w\\xd3/\\xadu>G\\xada\\x01\\xaa\\x03\\xe1\\xe9%M\\x9d\\x97\\xde\\xe5\\x93#\\xcc\\x96E\\xa7\\xf2u+\\xee\\xccH1{A\\xe0 *\\xb4\\x18\\xc1\\xc0',\n",
+       "│   │   │   │   │   vendorId=28544,\n",
+       "│   │   │   │   │   fabricId=2,\n",
+       "│   │   │   │   │   nodeId=2,\n",
+       "│   │   │   │   │   label='Fabric2Label'\n",
+       "│   │   │   │   )\n",
+       "│   │   │   ]\n",
+       "│   │   }\n",
+       "}\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1;36m0\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.clusters.Objects.OperationalCredentials.Attributes.FabricsList'\u001b[0m\u001b[1m>\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x04\\xa2\\x88\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\\xbd\\xdb\\xd4\\xbc^U\\xa3\\xcef\\xf7\\x92\\xbe\\xa7X;E\\xb8-Y\\x12^$\\xe0\\x1bS\\xf9\\x9a\\x8f\\xacvj\\xfa!&m6\\x00\\xe3\\xd1\\x85o\\x1b\\x9eH\\xabC?\\xd8\\xec\\x08lH\\xb5X\\x1f:u\\xb0\\xfbj\\x98'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m=\u001b[1;36m27168\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m=\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m'Fabric1Label'\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1;35mFabricDescriptor\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricIndex\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mrootPublicKey\u001b[0m=\u001b[32mb\u001b[0m\u001b[32m'\\x04\\x9d`\\x90\\ti\\xd1\\x9a\\xe6\\x06D\"\\x92\\x8d\\x9cz\\xcf\\xe9\\xf3\\xa3u\\xa8 w\\xd3/\\xadu>G\\xada\\x01\\xaa\\x03\\xe1\\xe9%M\\x9d\\x97\\xde\\xe5\\x93#\\xcc\\x96E\\xa7\\xf2u+\\xee\\xccH1\u001b[0m\u001b[32m{\u001b[0m\u001b[32mA\\xe0 *\\xb4\\x18\\xc1\\xc0'\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mvendorId\u001b[0m=\u001b[1;36m28544\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mfabricId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mnodeId\u001b[0m=\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[33mlabel\u001b[0m=\u001b[32m'Fabric2Label'\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "devCtrl2 = fabricAdmins[1].NewController()\n", + "await devCtrl2.SendCommand(2, 0, Clusters.OperationalCredentials.Commands.UpdateFabricLabel(\"Fabric2Label\"))\n", + "await devCtrl2.ReadAttribute(2, [(Clusters.OperationalCredentials.Attributes.FabricsList)], fabricFiltered=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "4ecb4ab4-bb7a-4941-8080-34783028fce0", + "metadata": {}, + "outputs": [], + "source": [ + "devCtrl2.Shutdown()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "matter-env", + "language": "python", + "name": "matter-env" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2+chromium.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/guides/repl/Matter - REPL Intro.ipynb b/docs/guides/repl/Matter - REPL Intro.ipynb new file mode 100644 index 00000000000000..83cc3ad8efadec --- /dev/null +++ b/docs/guides/repl/Matter - REPL Intro.ipynb @@ -0,0 +1,1154 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "9cd8236c-1a11-4d08-aad3-d1744d1b26e3", + "metadata": {}, + "source": [ + "# REPL Basics\n", + "\n", + "\n", + "\"drawing\"\n", + "\n", + "

\n", + "\n", + "This goes over the basics of interacting with the REPL." + ] + }, + { + "cell_type": "markdown", + "id": "7b7f651c-2e64-4d0e-aa93-1a01d093c946", + "metadata": { + "tags": [] + }, + "source": [ + "## Initialization\n", + "\n", + "Let's first begin by setting up by importing some key modules that are needed to make it easier for us to interact with the Matter stack.\n", + "\n", + "`ChipReplStartup.py` is run within the global namespace. This results in all of its imports being made available here.\n", + "\n", + "> **NOTE**: _This is not needed if you launch the REPL from the command-line._" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "cdffbe57-bd09-41db-a624-cbfcd65c6eae", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
──────────────────────────────────────── Matter REPL ────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m──────────────────────────────────────── \u001b[0mMatter REPL\u001b[92m ────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "            \n",
+       "    \n",
+       "            Welcome to the Matter Python REPL!\n",
+       "    \n",
+       "            For help, please type matterhelp()\n",
+       "    \n",
+       "            To get more information on a particular object/class, you can pass\n",
+       "            that into matterhelp() as well.\n",
+       "    \n",
+       "            \n",
+       "
\n" + ], + "text/plain": [ + "\n", + " \n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m Welcome to the Matter Python REPL!\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m For help, please type \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m To get more information on a particular object/class, you can pass\u001b[0m\n", + "\u001b[1;34m that into \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\u001b[1;34m as well.\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m \u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
─────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m─────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2022-01-25 16:57:54 johnsj-macbookpro1.roam.corp.google.com root[27642] CRITICAL Loading configuration from /tmp/repl-storage.json...\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Restoring FabricAdmin from storage to manage FabricId 1, FabricIndex 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mRestoring FabricAdmin from storage to manage FabricId \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m, FabricIndex \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 1(1)\n" + ] + }, + { + "data": { + "text/html": [ + "
Restoring FabricAdmin from storage to manage FabricId 2, FabricIndex 2...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mRestoring FabricAdmin from storage to manage FabricId \u001b[0m\u001b[1;38;5;129m2\u001b[0m\u001b[38;5;129m, FabricIndex \u001b[0m\u001b[1;38;5;129m2\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 2(2)\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "Fabric Admins have been loaded and are available at fabricAdmins\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[34mFabric Admins have been loaded and are available at \u001b[0m\u001b[31mfabricAdmins\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Creating default device controller on fabric 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mCreating default device controller on fabric \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Allocating new controller with FabricId: 1(1), NodeId: 1\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "Default CHIP Device Controller has been initialized to manage fabricAdmins[0], and is \n",
+       "available as devCtrl\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n", + "\u001b[34mDefault CHIP Device Controller has been initialized to manage \u001b[0m\u001b[1;31mfabricAdmins\u001b[0m\u001b[1;31m[\u001b[0m\u001b[1;31m0\u001b[0m\u001b[1;31m]\u001b[0m\u001b[1;34m, and is \u001b[0m\n", + "\u001b[1;34mavailable as \u001b[0m\u001b[1;31mdevCtrl\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import chip.native\n", + "import pkgutil\n", + "module = pkgutil.get_loader('chip.ChipReplStartup')\n", + "%run {module.path}" + ] + }, + { + "cell_type": "markdown", + "id": "49a01315-6cac-4f8a-830d-adb5b7b9fc27", + "metadata": {}, + "source": [ + "## Persistent Storage\n", + "\n", + "> NOTE: By default, the REPL points to `/tmp/repl-storage.json` for its persistent storage. To change that location, you can pass that in directly as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "c05b4b22-f6b1-4669-9358-98b0fe9a9136", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
──────────────────────────────────────── Matter REPL ────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m──────────────────────────────────────── \u001b[0mMatter REPL\u001b[92m ────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "            \n",
+       "    \n",
+       "            Welcome to the Matter Python REPL!\n",
+       "    \n",
+       "            For help, please type matterhelp()\n",
+       "    \n",
+       "            To get more information on a particular object/class, you can pass\n",
+       "            that into matterhelp() as well.\n",
+       "    \n",
+       "            \n",
+       "
\n" + ], + "text/plain": [ + "\n", + " \n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m Welcome to the Matter Python REPL!\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m For help, please type \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m To get more information on a particular object/class, you can pass\u001b[0m\n", + "\u001b[1;34m that into \u001b[0m\u001b[1;32mmatterhelp\u001b[0m\u001b[1;32m(\u001b[0m\u001b[1;32m)\u001b[0m\u001b[1;34m as well.\u001b[0m\n", + "\u001b[1;34m \u001b[0m\n", + "\u001b[1;34m \u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
─────────────────────────────────────────────────────────────────────────────────────────────\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[92m─────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Restoring FabricAdmin from storage to manage FabricId 1, FabricIndex 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mRestoring FabricAdmin from storage to manage FabricId \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m, FabricIndex \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 1(1)\n" + ] + }, + { + "data": { + "text/html": [ + "
Restoring FabricAdmin from storage to manage FabricId 2, FabricIndex 2...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mRestoring FabricAdmin from storage to manage FabricId \u001b[0m\u001b[1;38;5;129m2\u001b[0m\u001b[38;5;129m, FabricIndex \u001b[0m\u001b[1;38;5;129m2\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "New FabricAdmin: FabricId: 2(2)\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "Fabric Admins have been loaded and are available at fabricAdmins\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\u001b[34mFabric Admins have been loaded and are available at \u001b[0m\u001b[31mfabricAdmins\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
Creating default device controller on fabric 1...\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[38;5;129mCreating default device controller on fabric \u001b[0m\u001b[1;38;5;129m1\u001b[0m\u001b[38;5;129m...\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Allocating new controller with FabricId: 1(1), NodeId: 1\n" + ] + }, + { + "data": { + "text/html": [ + "
\n",
+       "\n",
+       "Default CHIP Device Controller has been initialized to manage fabricAdmins[0], and is \n",
+       "available as devCtrl\n",
+       "
\n" + ], + "text/plain": [ + "\n", + "\n", + "\u001b[34mDefault CHIP Device Controller has been initialized to manage \u001b[0m\u001b[1;31mfabricAdmins\u001b[0m\u001b[1;31m[\u001b[0m\u001b[1;31m0\u001b[0m\u001b[1;31m]\u001b[0m\u001b[1;34m, and is \u001b[0m\n", + "\u001b[1;34mavailable as \u001b[0m\u001b[1;31mdevCtrl\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import chip.native\n", + "import pkgutil\n", + "module = pkgutil.get_loader('chip.ChipReplStartup')\n", + "%run {module.path} --storagepath /tmp/repl.json" + ] + }, + { + "cell_type": "markdown", + "id": "04152051-9b58-4a12-a92c-a01db33e38ad", + "metadata": {}, + "source": [ + "## Help\n", + "\n", + "To get help for the various classes and their respective methods, run:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "b36f41dd-d5e2-447e-a9a4-f1eab7d92bec", + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
╭─────────────────── <class 'chip.ChipDeviceCtrl.ChipDeviceController'> ────────────────────╮\n",
+       " ╭───────────────────────────────────────────────────────────────────────────────────────╮ \n",
+       "  <chip.ChipDeviceCtrl.ChipDeviceController object at 0x1143b3910>                       \n",
+       " ╰───────────────────────────────────────────────────────────────────────────────────────╯ \n",
+       "                                                                                           \n",
+       "                                activeList = {                                             \n",
+       "                                                 <chip.ChipDeviceCtrl.ChipDeviceController \n",
+       "                                             object at 0x1143b3910>                        \n",
+       "                                             }                                             \n",
+       "                                   devCtrl = c_void_p(140320379576320)                     \n",
+       "                                  isActive = True                                          \n",
+       "                                     state = <DCState.IDLE: 1>                             \n",
+       "        cbHandleCommissioningCompleteFunct = def cbHandleCommissioningCompleteFunct(...)   \n",
+       "          cbHandleKeyExchangeCompleteFunct = def cbHandleKeyExchangeCompleteFunct(...)     \n",
+       "                 cbOnAddressUpdateComplete = def cbOnAddressUpdateComplete(...)            \n",
+       "                             CheckIsActive = def CheckIsActive():                          \n",
+       "                        CloseBLEConnection = def CloseBLEConnection():                     \n",
+       "                              CloseSession = def CloseSession(nodeid):                     \n",
+       "                                Commission = def Commission(nodeid):                       \n",
+       "                              CommissionIP = def CommissionIP(ipaddr, setupPinCode,        \n",
+       "                                             nodeid):                                      \n",
+       "                                ConnectBLE = def ConnectBLE(discriminator, setupPinCode,   \n",
+       "                                             nodeid):                                      \n",
+       "                                ConnectBle = def ConnectBle(bleConnection):                \n",
+       "                  DiscoverAllCommissioning = def DiscoverAllCommissioning():               \n",
+       " DiscoverCommissionableNodesCommissioningEn… def                                           \n",
+       "                                           = DiscoverCommissionableNodesCommissioningEnab… \n",
+       "     DiscoverCommissionableNodesDeviceType = def                                           \n",
+       "                                             DiscoverCommissionableNodesDeviceType(device… \n",
+       " DiscoverCommissionableNodesLongDiscriminat… def                                           \n",
+       "                                           = DiscoverCommissionableNodesLongDiscriminator \n",
+       " DiscoverCommissionableNodesShortDiscrimina… def                                           \n",
+       "                                           = DiscoverCommissionableNodesShortDiscriminato… \n",
+       "         DiscoverCommissionableNodesVendor = def                                           \n",
+       "                                             DiscoverCommissionableNodesVendor(vendor):    \n",
+       "                    EstablishPASESessionIP = def EstablishPASESessionIP(ipaddr,            \n",
+       "                                             setupPinCode, nodeid):                        \n",
+       "                         GetAddressAndPort = def GetAddressAndPort(nodeid):                \n",
+       "                         GetClusterHandler = def GetClusterHandler():                      \n",
+       "                     GetCompressedFabricId = def GetCompressedFabricId():                  \n",
+       "                    GetConnectedDeviceSync = def GetConnectedDeviceSync(nodeid):           \n",
+       "                               GetFabricId = def GetFabricId():                            \n",
+       "                  GetIPForDiscoveredDevice = def GetIPForDiscoveredDevice(idx, addrStr,    \n",
+       "                                             length):                                      \n",
+       "                              GetLogFilter = def GetLogFilter():                           \n",
+       "                               IsConnected = def IsConnected():                            \n",
+       "                   OpenCommissioningWindow = def OpenCommissioningWindow(nodeid, timeout,  \n",
+       "                                             iteration, discriminator, option):            \n",
+       "                               ParseQRCode = def ParseQRCode(qrCode, output):              \n",
+       "                    PrintDiscoveredDevices = def PrintDiscoveredDevices():                 \n",
+       "                             ReadAttribute = def ReadAttribute(nodeid: int, attributes:    \n",
+       "                                             List[Union[NoneType, Tuple[int],              \n",
+       "                                             Tuple[Type[chip.clusters.ClusterObjects.Clus… \n",
+       "                                             Tuple[Type[chip.clusters.ClusterObjects.Clus… \n",
+       "                                             Tuple[int,                                    \n",
+       "                                             Type[chip.clusters.ClusterObjects.Cluster]],  \n",
+       "                                             Tuple[int,                                    \n",
+       "                                             Type[chip.clusters.ClusterObjects.ClusterAtt… \n",
+       "                                             returnClusterObject: bool = False,            \n",
+       "                                             reportInterval: Tuple[int, int] = None,       \n",
+       "                                             fabricFiltered: bool = True):                 \n",
+       "                                             Read a list of attributes from a target node  \n",
+       "                                                                                           \n",
+       "                                             nodeId: Target's Node ID                      \n",
+       "                                             attributes: A list of tuples of varying types \n",
+       "                                             depending on the type of read being           \n",
+       "                                             requested:                                    \n",
+       "                                                 (endpoint, Clusters.ClusterA.AttributeA): \n",
+       "                                             Endpoint = specific,    Cluster = specific,   \n",
+       "                                             Attribute = specific                          \n",
+       "                                                 (endpoint, Clusters.ClusterA):            \n",
+       "                                             Endpoint = specific,    Cluster = specific,   \n",
+       "                                             Attribute = *                                 \n",
+       "                                                 (Clusters.ClusterA.AttributeA):           \n",
+       "                                             Endpoint = *,           Cluster = specific,   \n",
+       "                                             Attribute = specific                          \n",
+       "                                                 endpoint:                                 \n",
+       "                                             Endpoint = specific,    Cluster = *,          \n",
+       "                                             Attribute = *                                 \n",
+       "                                                 Clusters.ClusterA:                        \n",
+       "                                             Endpoint = *,           Cluster = specific,   \n",
+       "                                             Attribute = *                                 \n",
+       "                                                 '*' or ():                                \n",
+       "                                             Endpoint = *,           Cluster = *,          \n",
+       "                                             Attribute = *                                 \n",
+       "                                                                                           \n",
+       "                                                 The cluster and attributes specified      \n",
+       "                                             above are to be selected from the generated   \n",
+       "                                             cluster objects.                              \n",
+       "                                                                                           \n",
+       "                                                 e.g.                                      \n",
+       "                                                     ReadAttribute(1, [ 1 ] ) -- case 4    \n",
+       "                                             above.                                        \n",
+       "                                                     ReadAttribute(1, [ Clusters.Basic ] ) \n",
+       "                                             -- case 5 above.                              \n",
+       "                                                     ReadAttribute(1, [ (1,                \n",
+       "                                             Clusters.Basic.Attributes.Location ] ) --     \n",
+       "                                             case 1 above.                                 \n",
+       "                                                                                           \n",
+       "                                             returnClusterObject: This returns the data as \n",
+       "                                             consolidated cluster objects, with all        \n",
+       "                                             attributes for a cluster inside               \n",
+       "                                                                  a single cluster-wide    \n",
+       "                                             cluster object.                               \n",
+       "                                                                                           \n",
+       "                                             reportInterval: A tuple of two int-s for      \n",
+       "                                             (MinIntervalFloor, MaxIntervalCeiling). Used  \n",
+       "                                             by establishing subscriptions.                \n",
+       "                                                 When not provided, a read request will be \n",
+       "                                             sent.                                         \n",
+       "                                 ReadEvent = def ReadEvent(nodeid: int, events:            \n",
+       "                                             List[Union[NoneType, Tuple[int],              \n",
+       "                                             Tuple[Type[chip.clusters.ClusterObjects.Clus… \n",
+       "                                             Tuple[Type[chip.clusters.ClusterObjects.Clus… \n",
+       "                                             Tuple[int,                                    \n",
+       "                                             Type[chip.clusters.ClusterObjects.Cluster]],  \n",
+       "                                             Tuple[int,                                    \n",
+       "                                             Type[chip.clusters.ClusterObjects.ClusterEve… \n",
+       "                                             reportInterval: Tuple[int, int] = None):      \n",
+       "                                             Read a list of events from a target node      \n",
+       "                                                                                           \n",
+       "                                             nodeId: Target's Node ID                      \n",
+       "                                             events: A list of tuples of varying types     \n",
+       "                                             depending on the type of read being           \n",
+       "                                             requested:                                    \n",
+       "                                                 (endpoint, Clusters.ClusterA.EventA):     \n",
+       "                                             Endpoint = specific,    Cluster = specific,   \n",
+       "                                             Event = specific                              \n",
+       "                                                 (endpoint, Clusters.ClusterA):            \n",
+       "                                             Endpoint = specific,    Cluster = specific,   \n",
+       "                                             Event = *                                     \n",
+       "                                                 (Clusters.ClusterA.EventA):               \n",
+       "                                             Endpoint = *,           Cluster = specific,   \n",
+       "                                             Event = specific                              \n",
+       "                                                 endpoint:                                 \n",
+       "                                             Endpoint = specific,    Cluster = *,          \n",
+       "                                             Event = *                                     \n",
+       "                                                 Clusters.ClusterA:                        \n",
+       "                                             Endpoint = *,           Cluster = specific,   \n",
+       "                                             Event = *                                     \n",
+       "                                                 '*' or ():                                \n",
+       "                                             Endpoint = *,           Cluster = *,          \n",
+       "                                             Event = *                                     \n",
+       "                                                                                           \n",
+       "                                             The cluster and events specified above are to \n",
+       "                                             be selected from the generated cluster        \n",
+       "                                             objects.                                      \n",
+       "                                                                                           \n",
+       "                                             e.g.                                          \n",
+       "                                                 ReadEvent(1, [ 1 ] ) -- case 4 above.     \n",
+       "                                                 ReadEvent(1, [ Clusters.Basic ] ) -- case \n",
+       "                                             5 above.                                      \n",
+       "                                                 ReadEvent(1, [ (1,                        \n",
+       "                                             Clusters.Basic.Events.Location ] ) -- case 1  \n",
+       "                                             above.                                        \n",
+       "                                                                                           \n",
+       "                                             reportInterval: A tuple of two int-s for      \n",
+       "                                             (MinIntervalFloor, MaxIntervalCeiling). Used  \n",
+       "                                             by establishing subscriptions.                \n",
+       "                                                 When not provided, a read request will be \n",
+       "                                             sent.                                         \n",
+       "                               ResolveNode = def ResolveNode(nodeid):                      \n",
+       "                               SendCommand = def SendCommand(nodeid: int, endpoint: int,   \n",
+       "                                             payload:                                      \n",
+       "                                             chip.clusters.ClusterObjects.ClusterCommand,  \n",
+       "                                             responseType=None, timedRequestTimeoutMs: int \n",
+       "                                             = None):                                      \n",
+       "                                             Send a cluster-object encapsulated command to \n",
+       "                                             a node and get returned a future that can be  \n",
+       "                                             awaited upon to receive the response.         \n",
+       "                                             If a valid responseType is passed in, that    \n",
+       "                                             will be used to deserialize the object. If    \n",
+       "                                             not, the type will be automatically deduced   \n",
+       "                                             from the metadata received over the wire.     \n",
+       "                                                                                           \n",
+       "                                             timedWriteTimeoutMs: Timeout for a timed      \n",
+       "                                             invoke request. Omit or set to 'None' to      \n",
+       "                                             indicate a non-timed request.                 \n",
+       "                             SetBlockingCB = def SetBlockingCB(blockingCB):                \n",
+       "                              SetLogFilter = def SetLogFilter(category):                   \n",
+       "               SetThreadOperationalDataset = def                                           \n",
+       "                                             SetThreadOperationalDataset(threadOperationa… \n",
+       "                        SetWiFiCredentials = def SetWiFiCredentials(ssid, credentials):    \n",
+       "                                  Shutdown = def Shutdown():                               \n",
+       "                                             Shuts down this controller and reclaims any   \n",
+       "                                             used resources, including the bound           \n",
+       "                                             C++ constructor instance in the SDK.          \n",
+       "                               ShutdownAll = def ShutdownAll(...) Shut down all active     \n",
+       "                                             controllers and reclaim any used resources.   \n",
+       "                            WriteAttribute = def WriteAttribute(nodeid: int, attributes:   \n",
+       "                                             List[Tuple[int,                               \n",
+       "                                             chip.clusters.ClusterObjects.ClusterAttribut… \n",
+       "                                             timedRequestTimeoutMs: int = None):           \n",
+       "                                             Write a list of attributes on a target node.  \n",
+       "                                                                                           \n",
+       "                                             nodeId: Target's Node ID                      \n",
+       "                                             timedWriteTimeoutMs: Timeout for a timed      \n",
+       "                                             write request. Omit or set to 'None' to       \n",
+       "                                             indicate a non-timed request.                 \n",
+       "                                             attributes: A list of tuples of type          \n",
+       "                                             (endpoint, cluster-object):                   \n",
+       "                                                                                           \n",
+       "                                             E.g                                           \n",
+       "                                                 (1,                                       \n",
+       "                                             Clusters.TestCluster.Attributes.XYZAttribute \n",
+       "                                             -- Write 'hello' to the XYZ attribute on the  \n",
+       "                                             test cluster to endpoint 1                    \n",
+       "                          ZCLAttributeList = def ZCLAttributeList():                       \n",
+       "                            ZCLCommandList = def ZCLCommandList():                         \n",
+       "                          ZCLReadAttribute = def ZCLReadAttribute(cluster, attribute,      \n",
+       "                                             nodeid, endpoint, groupid, blocking=True):    \n",
+       "                                   ZCLSend = def ZCLSend(cluster, command, nodeid,         \n",
+       "                                             endpoint, groupid, args, blocking=False):     \n",
+       "                     ZCLSubscribeAttribute = def ZCLSubscribeAttribute(cluster, attribute, \n",
+       "                                             nodeid, endpoint, minInterval, maxInterval,   \n",
+       "                                             blocking=True):                               \n",
+       "                         ZCLWriteAttribute = def ZCLWriteAttribute(cluster: str,           \n",
+       "                                             attribute: str, nodeid, endpoint, groupid,    \n",
+       "                                             value, blocking=True):                        \n",
+       "╰───────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[34m╭─\u001b[0m\u001b[34m────────────────── \u001b[0m\u001b[1;34m<\u001b[0m\u001b[1;95mclass\u001b[0m\u001b[39m \u001b[0m\u001b[32m'chip.ChipDeviceCtrl.ChipDeviceController'\u001b[0m\u001b[1;34m>\u001b[0m\u001b[34m ───────────────────\u001b[0m\u001b[34m─╮\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[32m╭───────────────────────────────────────────────────────────────────────────────────────╮\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[32m│\u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mchip.ChipDeviceCtrl.ChipDeviceController\u001b[0m\u001b[39m object at \u001b[0m\u001b[1;36m0x1143b3910\u001b[0m\u001b[1m>\u001b[0m \u001b[32m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[32m╰───────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mactiveList\u001b[0m = \u001b[1m{\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1m<\u001b[0m\u001b[1;95mchip.ChipDeviceCtrl.ChipDeviceController\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[39mobject at \u001b[0m\u001b[1;36m0x1143b3910\u001b[0m\u001b[1m>\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1m}\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mdevCtrl\u001b[0m = \u001b[1;35mc_void_p\u001b[0m\u001b[1m(\u001b[0m\u001b[1;36m140320379576320\u001b[0m\u001b[1m)\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33misActive\u001b[0m = \u001b[3;92mTrue\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mstate\u001b[0m = \u001b[1m<\u001b[0m\u001b[1;95mDCState.IDLE:\u001b[0m\u001b[39m \u001b[0m\u001b[1;36m1\u001b[0m\u001b[1m>\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mcbHandleCommissioningCompleteFunct\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mcbHandleCommissioningCompleteFunct\u001b[0m\u001b[1m(\u001b[0m\u001b[33m...\u001b[0m\u001b[1m)\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mcbHandleKeyExchangeCompleteFunct\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mcbHandleKeyExchangeCompleteFunct\u001b[0m\u001b[1m(\u001b[0m\u001b[33m...\u001b[0m\u001b[1m)\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mcbOnAddressUpdateComplete\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mcbOnAddressUpdateComplete\u001b[0m\u001b[1m(\u001b[0m\u001b[33m...\u001b[0m\u001b[1m)\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mCheckIsActive\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mCheckIsActive\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mCloseBLEConnection\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mCloseBLEConnection\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mCloseSession\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mCloseSession\u001b[0m\u001b[1m(\u001b[0mnodeid\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mCommission\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mCommission\u001b[0m\u001b[1m(\u001b[0mnodeid\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mCommissionIP\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mCommissionIP\u001b[0m\u001b[1m(\u001b[0mipaddr, setupPinCode, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m nodeid\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mConnectBLE\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mConnectBLE\u001b[0m\u001b[1m(\u001b[0mdiscriminator, setupPinCode, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m nodeid\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mConnectBle\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mConnectBle\u001b[0m\u001b[1m(\u001b[0mbleConnection\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mDiscoverAllCommissioning\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mDiscoverAllCommissioning\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mDiscoverCommissionableNodesCommissioningEn…\u001b[0m \u001b[3;96mdef \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m = \u001b[1;31mDiscoverCommissionableNodesCommissioningEnab…\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mDiscoverCommissionableNodesDeviceType\u001b[0m = \u001b[3;96mdef \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;31mDiscoverCommissionableNodesDeviceType\u001b[0m\u001b[1m(\u001b[0mdevice… \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mDiscoverCommissionableNodesLongDiscriminat…\u001b[0m \u001b[3;96mdef \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m = \u001b[1;31mDiscoverCommissionableNodesLongDiscriminator\u001b[0m\u001b[1m…\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mDiscoverCommissionableNodesShortDiscrimina…\u001b[0m \u001b[3;96mdef \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m = \u001b[1;31mDiscoverCommissionableNodesShortDiscriminato…\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mDiscoverCommissionableNodesVendor\u001b[0m = \u001b[3;96mdef \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;31mDiscoverCommissionableNodesVendor\u001b[0m\u001b[1m(\u001b[0mvendor\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mEstablishPASESessionIP\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mEstablishPASESessionIP\u001b[0m\u001b[1m(\u001b[0mipaddr, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m setupPinCode, nodeid\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mGetAddressAndPort\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mGetAddressAndPort\u001b[0m\u001b[1m(\u001b[0mnodeid\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mGetClusterHandler\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mGetClusterHandler\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mGetCompressedFabricId\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mGetCompressedFabricId\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mGetConnectedDeviceSync\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mGetConnectedDeviceSync\u001b[0m\u001b[1m(\u001b[0mnodeid\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mGetFabricId\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mGetFabricId\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mGetIPForDiscoveredDevice\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mGetIPForDiscoveredDevice\u001b[0m\u001b[1m(\u001b[0midx, addrStr, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m length\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mGetLogFilter\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mGetLogFilter\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mIsConnected\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mIsConnected\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mOpenCommissioningWindow\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mOpenCommissioningWindow\u001b[0m\u001b[1m(\u001b[0mnodeid, timeout, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m iteration, discriminator, option\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mParseQRCode\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mParseQRCode\u001b[0m\u001b[1m(\u001b[0mqrCode, output\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mPrintDiscoveredDevices\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mPrintDiscoveredDevices\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mReadAttribute\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mReadAttribute\u001b[0m\u001b[1m(\u001b[0mnodeid: int, attributes: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m List\u001b[1m[\u001b[0mUnion\u001b[1m[\u001b[0mNoneType, Tuple\u001b[1m[\u001b[0mint\u001b[1m]\u001b[0m, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Tuple\u001b[1m[\u001b[0mType\u001b[1m[\u001b[0mchip.clusters.ClusterObjects.Clus… \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Tuple\u001b[1m[\u001b[0mType\u001b[1m[\u001b[0mchip.clusters.ClusterObjects.Clus… \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Tuple\u001b[1m[\u001b[0mint, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Type\u001b[1m[\u001b[0mchip.clusters.ClusterObjects.Cluster\u001b[1m]\u001b[0m\u001b[1m]\u001b[0m, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Tuple\u001b[1m[\u001b[0mint, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Type\u001b[1m[\u001b[0mchip.clusters.ClusterObjects.ClusterAtt… \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m returnClusterObject: bool = \u001b[3;91mFalse\u001b[0m, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m reportInterval: Tuple\u001b[1m[\u001b[0mint, int\u001b[1m]\u001b[0m = \u001b[3;35mNone\u001b[0m, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m fabricFiltered: bool = \u001b[3;92mTrue\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mRead a list of attributes from a target node\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mnodeId: Target's Node ID\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mattributes: A list of tuples of varying types\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mdepending on the type of read being \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mrequested:\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2m(\u001b[0m\u001b[2mendpoint, Clusters.ClusterA.AttributeA\u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m:\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = specific, Cluster = specific, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mAttribute = specific\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2m(\u001b[0m\u001b[2mendpoint, Clusters.ClusterA\u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m: \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = specific, Cluster = specific, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mAttribute = *\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2m(\u001b[0m\u001b[2mClusters.ClusterA.AttributeA\u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m: \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = *, Cluster = specific, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mAttribute = specific\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m endpoint: \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = specific, Cluster = *, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mAttribute = *\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m Clusters.ClusterA: \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = *, Cluster = specific, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mAttribute = *\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[2;32m'*'\u001b[0m\u001b[2m or \u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m: \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = *, Cluster = *, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mAttribute = *\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m The cluster and attributes specified \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mabove are to be selected from the generated \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mcluster objects.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m e.g.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2;35mReadAttribute\u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m, \u001b[0m\u001b[1;2m[\u001b[0m\u001b[2m \u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m \u001b[0m\u001b[1;2m]\u001b[0m\u001b[2m \u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m -- case \u001b[0m\u001b[1;2;36m4\u001b[0m\u001b[2m \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mabove.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2;35mReadAttribute\u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m, \u001b[0m\u001b[1;2m[\u001b[0m\u001b[2m Clusters.Basic \u001b[0m\u001b[1;2m]\u001b[0m\u001b[2m \u001b[0m\u001b[1;2m)\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m-- case \u001b[0m\u001b[1;2;36m5\u001b[0m\u001b[2m above.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2;35mReadAttribute\u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m, \u001b[0m\u001b[1;2m[\u001b[0m\u001b[2m \u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mClusters.Basic.Attributes.Location \u001b[0m\u001b[1;2m]\u001b[0m\u001b[2m \u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m -- \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mcase \u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m above.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mreturnClusterObject: This returns the data as\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mconsolidated cluster objects, with all \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mattributes for a cluster inside\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m a single cluster-wide \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mcluster object.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mreportInterval: A tuple of two int-s for \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;2m(\u001b[0m\u001b[2mMinIntervalFloor, MaxIntervalCeiling\u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m. Used \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mby establishing subscriptions.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m When not provided, a read request will be\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2msent.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mReadEvent\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mReadEvent\u001b[0m\u001b[1m(\u001b[0mnodeid: int, events: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m List\u001b[1m[\u001b[0mUnion\u001b[1m[\u001b[0mNoneType, Tuple\u001b[1m[\u001b[0mint\u001b[1m]\u001b[0m, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Tuple\u001b[1m[\u001b[0mType\u001b[1m[\u001b[0mchip.clusters.ClusterObjects.Clus… \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Tuple\u001b[1m[\u001b[0mType\u001b[1m[\u001b[0mchip.clusters.ClusterObjects.Clus… \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Tuple\u001b[1m[\u001b[0mint, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Type\u001b[1m[\u001b[0mchip.clusters.ClusterObjects.Cluster\u001b[1m]\u001b[0m\u001b[1m]\u001b[0m, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Tuple\u001b[1m[\u001b[0mint, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m Type\u001b[1m[\u001b[0mchip.clusters.ClusterObjects.ClusterEve… \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m reportInterval: Tuple\u001b[1m[\u001b[0mint, int\u001b[1m]\u001b[0m = \u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mRead a list of events from a target node\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mnodeId: Target's Node ID\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mevents: A list of tuples of varying types \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mdepending on the type of read being \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mrequested:\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2m(\u001b[0m\u001b[2mendpoint, Clusters.ClusterA.EventA\u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m: \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = specific, Cluster = specific, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEvent = specific\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2m(\u001b[0m\u001b[2mendpoint, Clusters.ClusterA\u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m: \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = specific, Cluster = specific, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEvent = *\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2m(\u001b[0m\u001b[2mClusters.ClusterA.EventA\u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m: \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = *, Cluster = specific, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEvent = specific\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m endpoint: \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = specific, Cluster = *, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEvent = *\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m Clusters.ClusterA: \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = *, Cluster = specific, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEvent = *\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[2;32m'*'\u001b[0m\u001b[2m or \u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m: \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEndpoint = *, Cluster = *, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mEvent = *\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mThe cluster and events specified above are to\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mbe selected from the generated cluster \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mobjects.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2me.g.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2;35mReadEvent\u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m, \u001b[0m\u001b[1;2m[\u001b[0m\u001b[2m \u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m \u001b[0m\u001b[1;2m]\u001b[0m\u001b[2m \u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m -- case \u001b[0m\u001b[1;2;36m4\u001b[0m\u001b[2m above.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2;35mReadEvent\u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m, \u001b[0m\u001b[1;2m[\u001b[0m\u001b[2m Clusters.Basic \u001b[0m\u001b[1;2m]\u001b[0m\u001b[2m \u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m -- case\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;2;36m5\u001b[0m\u001b[2m above.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2;35mReadEvent\u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m, \u001b[0m\u001b[1;2m[\u001b[0m\u001b[2m \u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mClusters.Basic.Events.Location \u001b[0m\u001b[1;2m]\u001b[0m\u001b[2m \u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m -- case \u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mabove.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mreportInterval: A tuple of two int-s for \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;2m(\u001b[0m\u001b[2mMinIntervalFloor, MaxIntervalCeiling\u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m. Used \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mby establishing subscriptions.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m When not provided, a read request will be\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2msent.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mResolveNode\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mResolveNode\u001b[0m\u001b[1m(\u001b[0mnodeid\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mSendCommand\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mSendCommand\u001b[0m\u001b[1m(\u001b[0mnodeid: int, endpoint: int, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m payload: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m chip.clusters.ClusterObjects.ClusterCommand, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[33mresponseType\u001b[0m=\u001b[3;35mNone\u001b[0m, timedRequestTimeoutMs: int \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m = \u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mSend a cluster-object encapsulated command to\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2ma node and get returned a future that can be \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mawaited upon to receive the response.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mIf a valid responseType is passed in, that \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mwill be used to deserialize the object. If \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mnot, the type will be automatically deduced\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mfrom the metadata received over the wire.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mtimedWriteTimeoutMs: Timeout for a timed \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2minvoke request. Omit or set to \u001b[0m\u001b[2;32m'None'\u001b[0m\u001b[2m to \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mindicate a non-timed request.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mSetBlockingCB\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mSetBlockingCB\u001b[0m\u001b[1m(\u001b[0mblockingCB\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mSetLogFilter\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mSetLogFilter\u001b[0m\u001b[1m(\u001b[0mcategory\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mSetThreadOperationalDataset\u001b[0m = \u001b[3;96mdef \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;31mSetThreadOperationalDataset\u001b[0m\u001b[1m(\u001b[0mthreadOperationa… \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mSetWiFiCredentials\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mSetWiFiCredentials\u001b[0m\u001b[1m(\u001b[0mssid, credentials\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mShutdown\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mShutdown\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mShuts down this controller and reclaims any \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mused resources, including the bound\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mC++ constructor instance in the SDK.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mShutdownAll\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mShutdownAll\u001b[0m\u001b[1m(\u001b[0m\u001b[33m...\u001b[0m\u001b[1m)\u001b[0m \u001b[2mShut down all active \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mcontrollers and reclaim any used resources.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mWriteAttribute\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mWriteAttribute\u001b[0m\u001b[1m(\u001b[0mnodeid: int, attributes: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m List\u001b[1m[\u001b[0mTuple\u001b[1m[\u001b[0mint, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m chip.clusters.ClusterObjects.ClusterAttribut… \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m timedRequestTimeoutMs: int = \u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mWrite a list of attributes on a target node.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mnodeId: Target's Node ID\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mtimedWriteTimeoutMs: Timeout for a timed \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mwrite request. Omit or set to \u001b[0m\u001b[2;32m'None'\u001b[0m\u001b[2m to \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mindicate a non-timed request.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mattributes: A list of tuples of type \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;2m(\u001b[0m\u001b[2mendpoint, cluster-object\u001b[0m\u001b[1;2m)\u001b[0m\u001b[2m:\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mE.g\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m \u001b[0m\u001b[1;2m(\u001b[0m\u001b[1;2;36m1\u001b[0m\u001b[2m, \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;2;35mClusters.TestCluster.Attributes.XYZAttribute\u001b[0m\u001b[1;2m…\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2m-- Write \u001b[0m\u001b[2;32m'hello'\u001b[0m\u001b[2m to the XYZ attribute on the \u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[2mtest cluster to endpoint \u001b[0m\u001b[1;2;36m1\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mZCLAttributeList\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mZCLAttributeList\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mZCLCommandList\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mZCLCommandList\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mZCLReadAttribute\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mZCLReadAttribute\u001b[0m\u001b[1m(\u001b[0mcluster, attribute, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m nodeid, endpoint, groupid, \u001b[33mblocking\u001b[0m=\u001b[3;92mTrue\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mZCLSend\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mZCLSend\u001b[0m\u001b[1m(\u001b[0mcluster, command, nodeid, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m endpoint, groupid, args, \u001b[33mblocking\u001b[0m=\u001b[3;91mFalse\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mZCLSubscribeAttribute\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mZCLSubscribeAttribute\u001b[0m\u001b[1m(\u001b[0mcluster, attribute, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m nodeid, endpoint, minInterval, maxInterval, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[33mblocking\u001b[0m=\u001b[3;92mTrue\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;33mZCLWriteAttribute\u001b[0m = \u001b[3;96mdef \u001b[0m\u001b[1;31mZCLWriteAttribute\u001b[0m\u001b[1m(\u001b[0mcluster: str, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m attribute: str, nodeid, endpoint, groupid, \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m value, \u001b[33mblocking\u001b[0m=\u001b[3;92mTrue\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m╰───────────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
╭─────────── <function mattersetlog at 0x115ea1670> ───────────╮\n",
+       " def mattersetlog(level):                                     \n",
+       "                                                              \n",
+       " 35 attribute(s) not shown. Run inspect(inspect) for options. \n",
+       "╰──────────────────────────────────────────────────────────────╯\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[34m╭─\u001b[0m\u001b[34m────────── \u001b[0m\u001b[1;34m<\u001b[0m\u001b[1;95mfunction\u001b[0m\u001b[39m mattersetlog at \u001b[0m\u001b[1;36m0x115ea1670\u001b[0m\u001b[1;34m>\u001b[0m\u001b[34m ──────────\u001b[0m\u001b[34m─╮\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;96mdef \u001b[0m\u001b[1;31mmattersetlog\u001b[0m\u001b[1m(\u001b[0mlevel\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;36m35\u001b[0m\u001b[3m attribute(s) not shown.\u001b[0m Run \u001b[1;35minspect\u001b[0m\u001b[1m(\u001b[0minspect\u001b[1m)\u001b[0m for options. \u001b[34m│\u001b[0m\n", + "\u001b[34m╰──────────────────────────────────────────────────────────────╯\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
╭───────────────── <function mattersetdebug at 0x115ea1700> ──────────────────╮\n",
+       " def mattersetdebug(enableDebugMode: bool = True):                           \n",
+       "                                                                             \n",
+       " Enables debug mode that is utilized by some Matter modules                  \n",
+       " to better facilitate debugging of failures (e.g throwing exceptions instead \n",
+       " of returning well-formatted results).                                       \n",
+       "                                                                             \n",
+       " 35 attribute(s) not shown. Run inspect(inspect) for options.                \n",
+       "╰─────────────────────────────────────────────────────────────────────────────╯\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[34m╭─\u001b[0m\u001b[34m──────────────── \u001b[0m\u001b[1;34m<\u001b[0m\u001b[1;95mfunction\u001b[0m\u001b[39m mattersetdebug at \u001b[0m\u001b[1;36m0x115ea1700\u001b[0m\u001b[1;34m>\u001b[0m\u001b[34m ─────────────────\u001b[0m\u001b[34m─╮\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[3;96mdef \u001b[0m\u001b[1;31mmattersetdebug\u001b[0m\u001b[1m(\u001b[0menableDebugMode: bool = \u001b[3;92mTrue\u001b[0m\u001b[1m)\u001b[0m: \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[36mEnables debug mode that is utilized by some Matter modules\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[36mto better facilitate debugging of failures \u001b[0m\u001b[1;36m(\u001b[0m\u001b[36me.g throwing exceptions instead\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[36mof returning well-formatted results\u001b[0m\u001b[1;36m)\u001b[0m\u001b[36m.\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[34m│\u001b[0m\n", + "\u001b[34m│\u001b[0m \u001b[1;36m35\u001b[0m\u001b[3m attribute(s) not shown.\u001b[0m Run \u001b[1;35minspect\u001b[0m\u001b[1m(\u001b[0minspect\u001b[1m)\u001b[0m for options. \u001b[34m│\u001b[0m\n", + "\u001b[34m╰─────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "matterhelp()" + ] + }, + { + "cell_type": "markdown", + "id": "17536445-9ca7-4bcb-9a1b-752d08858442", + "metadata": {}, + "source": [ + "To get help on a specific method in that class, you can pass that in as an argument:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "537404ad-cf20-4ce8-9cd6-037c397339ee", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
╭─ <bound method ChipDeviceController.SendCommand of <chip.ChipDeviceCtrl.ChipDeviceControl─╮\n",
+       " def ChipDeviceController.SendCommand(nodeid: int, endpoint: int, payload:                 \n",
+       " chip.clusters.ClusterObjects.ClusterCommand, responseType=None, timedRequestTimeoutMs:    \n",
+       " int = None):                                                                              \n",
+       "                                                                                           \n",
+       " Send a cluster-object encapsulated command to a node and get returned a future that can   \n",
+       " be awaited upon to receive the response.                                                  \n",
+       " If a valid responseType is passed in, that will be used to deserialize the object. If     \n",
+       " not, the type will be automatically deduced                                               \n",
+       " from the metadata received over the wire.                                                 \n",
+       "                                                                                           \n",
+       " timedWriteTimeoutMs: Timeout for a timed invoke request. Omit or set to 'None' to         \n",
+       " indicate a non-timed request.                                                             \n",
+       "                                                                                           \n",
+       " 27 attribute(s) not shown. Run inspect(inspect) for options.                              \n",
+       "╰───────────────────────────────────────────────────────────────────────────────────────────╯\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[34m╭─\u001b[0m\u001b[34m \u001b[0m\u001b[1;34m<\u001b[0m\u001b[1;95mbound\u001b[0m\u001b[39m method ChipDeviceController.SendCommand of \n", + "{\n", + "'value': [\n", + "│ │ 1,\n", + "│ │ 2,\n", + "│ │ 3,\n", + "│ │ 4,\n", + "│ │ [\n", + "│ │ │ 1,\n", + "│ │ │ 2\n", + "│ │ ]\n", + "]\n", + "}\n", + "\n" + ], + "text/plain": [ + "\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'value'\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m2\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m3\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;36m1\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;36m2\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[1m}\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "a = {'value': [1, 2, 3, 4, [1, 2]]}\n", + "a" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "matter-env", + "language": "python", + "name": "matter-env" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.2+chromium.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 98bcce0ca2622f..6c433f6b7afdf1 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -716,6 +716,8 @@ CHIP_ERROR DeviceCommissioner::Shutdown() ChipLogDetail(Controller, "Shutting down the commissioner"); + mSystemState->SessionMgr()->UnregisterRecoveryDelegate(*this); + #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable if (mUdcTransportMgr != nullptr) { @@ -934,6 +936,7 @@ CHIP_ERROR DeviceCommissioner::Commission(NodeId remoteDeviceId, CommissioningPa ChipLogError(Controller, "Invalid device for commissioning " ChipLogFormatX64, ChipLogValueX64(remoteDeviceId)); return CHIP_ERROR_INCORRECT_STATE; } + if (mCommissioningStage != CommissioningStage::kSecurePairing) { ChipLogError(Controller, "Commissioning already in progress - not restarting"); @@ -1452,6 +1455,7 @@ void DeviceCommissioner::OnSessionEstablishmentTimeoutCallback(System::Layer * a { static_cast(aAppState)->OnSessionEstablishmentTimeout(); } + #if CHIP_DEVICE_CONFIG_ENABLE_DNSSD CHIP_ERROR DeviceCommissioner::DiscoverCommissionableNodes(Dnssd::DiscoveryFilter filter) { diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index b89a66ade8b0f8..71946f3d8e5427 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -350,6 +350,8 @@ class DLL_EXPORT DeviceController : public SessionRecoveryDelegate, void ReleaseOperationalDevice(NodeId remoteDeviceId); + OperationalCredentialsDelegate * GetOperationalCredentialsDelegate() { return mOperationalCredentialsDelegate; } + protected: enum class State { diff --git a/src/controller/CHIPDeviceControllerFactory.h b/src/controller/CHIPDeviceControllerFactory.h index fcc44fd5bf6c77..9d49eeefa36283 100644 --- a/src/controller/CHIPDeviceControllerFactory.h +++ b/src/controller/CHIPDeviceControllerFactory.h @@ -106,6 +106,22 @@ class DeviceControllerFactory DeviceControllerFactory(DeviceControllerFactory const &) = delete; void operator=(DeviceControllerFactory const &) = delete; + // + // Some clients do not prefer a complete shutdown of the stack being initiated if + // all device controllers have ceased to exist. To avoid that, this method has been + // created to permit retention of the underlying system state to avoid that. + // + void RetainSystemState() { (void) mSystemState->Retain(); } + + // + // To initiate shutdown of the stack upon termination of all resident controllers in the + // system, invoke this method to decrement the refcount on the system state and consequently, + // shut-down the stack. + // + // This should only be invoked if a matching call to RetainSystemState() was called prior. + // + void ReleaseSystemState() { mSystemState->Release(); } + private: DeviceControllerFactory(){}; void PopulateInitParams(ControllerInitParams & controllerParams, const SetupParams & params); diff --git a/src/controller/ExampleOperationalCredentialsIssuer.cpp b/src/controller/ExampleOperationalCredentialsIssuer.cpp index 3b1db1077c92dd..3d2530ddc3f61e 100644 --- a/src/controller/ExampleOperationalCredentialsIssuer.cpp +++ b/src/controller/ExampleOperationalCredentialsIssuer.cpp @@ -32,6 +32,7 @@ namespace Controller { constexpr const char kOperationalCredentialsIssuerKeypairStorage[] = "ExampleOpCredsCAKey"; constexpr const char kOperationalCredentialsIntermediateIssuerKeypairStorage[] = "ExampleOpCredsICAKey"; constexpr const char kOperationalCredentialsRootCertificateStorage[] = "ExampleCARootCert"; +constexpr const char kOperationalCredentialsIntermediateCertificateStorage[] = "ExampleCAIntermediateCert"; using namespace Credentials; using namespace Crypto; @@ -41,6 +42,7 @@ CHIP_ERROR ExampleOperationalCredentialsIssuer::Initialize(PersistentStorageDele { using namespace ASN1; ASN1UniversalTime effectiveTime; + CHIP_ERROR err; // Initializing the default start validity to start of 2021. The default validity duration is 10 years. CHIP_ZERO_AT(effectiveTime); @@ -52,14 +54,19 @@ CHIP_ERROR ExampleOperationalCredentialsIssuer::Initialize(PersistentStorageDele Crypto::P256SerializedKeypair serializedKey; uint16_t keySize = static_cast(sizeof(serializedKey)); - if (storage.SyncGetKeyValue(kOperationalCredentialsIssuerKeypairStorage, &serializedKey, keySize) != CHIP_NO_ERROR) + PERSISTENT_KEY_OP(mIndex, kOperationalCredentialsIssuerKeypairStorage, key, + err = storage.SyncGetKeyValue(key, &serializedKey, keySize)); + + if (err != CHIP_NO_ERROR) { // Storage doesn't have an existing keypair. Let's create one and add it to the storage. ReturnErrorOnFailure(mIssuer.Initialize()); ReturnErrorOnFailure(mIssuer.Serialize(serializedKey)); keySize = static_cast(sizeof(serializedKey)); - ReturnErrorOnFailure(storage.SyncSetKeyValue(kOperationalCredentialsIssuerKeypairStorage, &serializedKey, keySize)); + + PERSISTENT_KEY_OP(mIndex, kOperationalCredentialsIssuerKeypairStorage, key, + ReturnErrorOnFailure(storage.SyncSetKeyValue(key, &serializedKey, keySize))); } else { @@ -69,15 +76,19 @@ CHIP_ERROR ExampleOperationalCredentialsIssuer::Initialize(PersistentStorageDele keySize = static_cast(sizeof(serializedKey)); - if (storage.SyncGetKeyValue(kOperationalCredentialsIntermediateIssuerKeypairStorage, &serializedKey, keySize) != CHIP_NO_ERROR) + PERSISTENT_KEY_OP(mIndex, kOperationalCredentialsIntermediateIssuerKeypairStorage, key, + err = storage.SyncGetKeyValue(key, &serializedKey, keySize)); + + if (err != CHIP_NO_ERROR) { // Storage doesn't have an existing keypair. Let's create one and add it to the storage. ReturnErrorOnFailure(mIntermediateIssuer.Initialize()); ReturnErrorOnFailure(mIntermediateIssuer.Serialize(serializedKey)); keySize = static_cast(sizeof(serializedKey)); - ReturnErrorOnFailure( - storage.SyncSetKeyValue(kOperationalCredentialsIntermediateIssuerKeypairStorage, &serializedKey, keySize)); + + PERSISTENT_KEY_OP(mIndex, kOperationalCredentialsIntermediateIssuerKeypairStorage, key, + ReturnErrorOnFailure(storage.SyncSetKeyValue(key, &serializedKey, keySize))); } else { @@ -110,28 +121,44 @@ CHIP_ERROR ExampleOperationalCredentialsIssuer::GenerateNOCChainAfterValidation( X509CertRequestParams noc_request = { 1, mNow, mNow + mValidity, noc_dn, icac_dn }; ReturnErrorOnFailure(NewNodeOperationalX509Cert(noc_request, pubkey, mIntermediateIssuer, noc)); - ChipLogProgress(Controller, "Generating ICAC"); - X509CertRequestParams icac_request = { 0, mNow, mNow + mValidity, icac_dn, rcac_dn }; - ReturnErrorOnFailure(NewICAX509Cert(icac_request, mIntermediateIssuer.Pubkey(), mIssuer, icac)); + uint16_t icacBufLen = static_cast(std::min(icac.size(), static_cast(UINT16_MAX))); + CHIP_ERROR err = CHIP_NO_ERROR; + PERSISTENT_KEY_OP(mIndex, kOperationalCredentialsIntermediateCertificateStorage, key, + err = mStorage->SyncGetKeyValue(key, icac.data(), icacBufLen)); + if (err == CHIP_NO_ERROR) + { + // Found root certificate in the storage. + icac.reduce_size(icacBufLen); + } + else + { + ChipLogProgress(Controller, "Generating ICAC"); + X509CertRequestParams icac_request = { 0, mNow, mNow + mValidity, icac_dn, rcac_dn }; + ReturnErrorOnFailure(NewICAX509Cert(icac_request, mIntermediateIssuer.Pubkey(), mIssuer, icac)); + + VerifyOrReturnError(CanCastTo(icac.size()), CHIP_ERROR_INTERNAL); + PERSISTENT_KEY_OP(mIndex, kOperationalCredentialsIntermediateCertificateStorage, key, + err = mStorage->SyncSetKeyValue(key, icac.data(), static_cast(icac.size()))); + } uint16_t rcacBufLen = static_cast(std::min(rcac.size(), static_cast(UINT16_MAX))); - CHIP_ERROR err = CHIP_NO_ERROR; - PERSISTENT_KEY_OP(fabricId, kOperationalCredentialsRootCertificateStorage, key, + PERSISTENT_KEY_OP(mIndex, kOperationalCredentialsRootCertificateStorage, key, err = mStorage->SyncGetKeyValue(key, rcac.data(), rcacBufLen)); if (err == CHIP_NO_ERROR) { // Found root certificate in the storage. rcac.reduce_size(rcacBufLen); - return CHIP_NO_ERROR; } + else + { + ChipLogProgress(Controller, "Generating RCAC"); + X509CertRequestParams rcac_request = { 0, mNow, mNow + mValidity, rcac_dn, rcac_dn }; + ReturnErrorOnFailure(NewRootX509Cert(rcac_request, mIssuer, rcac)); - ChipLogProgress(Controller, "Generating RCAC"); - X509CertRequestParams rcac_request = { 0, mNow, mNow + mValidity, rcac_dn, rcac_dn }; - ReturnErrorOnFailure(NewRootX509Cert(rcac_request, mIssuer, rcac)); - - VerifyOrReturnError(CanCastTo(rcac.size()), CHIP_ERROR_INTERNAL); - PERSISTENT_KEY_OP(fabricId, kOperationalCredentialsRootCertificateStorage, key, - err = mStorage->SyncSetKeyValue(key, rcac.data(), static_cast(rcac.size()))); + VerifyOrReturnError(CanCastTo(rcac.size()), CHIP_ERROR_INTERNAL); + PERSISTENT_KEY_OP(mIndex, kOperationalCredentialsRootCertificateStorage, key, + err = mStorage->SyncSetKeyValue(key, rcac.data(), static_cast(rcac.size()))); + } return err; } diff --git a/src/controller/ExampleOperationalCredentialsIssuer.h b/src/controller/ExampleOperationalCredentialsIssuer.h index c196b2e954b5b3..ce0ef0456cd83d 100644 --- a/src/controller/ExampleOperationalCredentialsIssuer.h +++ b/src/controller/ExampleOperationalCredentialsIssuer.h @@ -42,6 +42,16 @@ namespace Controller { class DLL_EXPORT ExampleOperationalCredentialsIssuer : public OperationalCredentialsDelegate { public: + // + // Constructor to create an instance of this object that vends out operational credentials for a given fabric. + // + // An index should be provided to numerically identify this instance relative to others in a multi-fabric deployment. This is + // needed given the interactions of this object with persistent storage. Consequently, the index is used to scope the entries + // read/written to/from storage. + // + // It is recommended that this index track the fabric index within which this issuer is operating. + // + ExampleOperationalCredentialsIssuer(uint32_t index = 0) { mIndex = index; } virtual ~ExampleOperationalCredentialsIssuer() {} CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & attestationSignature, const ByteSpan & DAC, @@ -109,6 +119,7 @@ class DLL_EXPORT ExampleOperationalCredentialsIssuer : public OperationalCredent NodeId mNextRequestedNodeId = 1; FabricId mNextFabricId = 0; bool mNodeIdRequested = false; + uint64_t mIndex = 0; }; } // namespace Controller diff --git a/src/controller/OperationalCredentialsDelegate.h b/src/controller/OperationalCredentialsDelegate.h index 579bd9d985ecae..7eda947b1e5bab 100644 --- a/src/controller/OperationalCredentialsDelegate.h +++ b/src/controller/OperationalCredentialsDelegate.h @@ -43,7 +43,7 @@ class DLL_EXPORT OperationalCredentialsDelegate /** * @brief - * This function generates an operational certificate chain for the device. + * This function generates an operational certificate chain for a remote device that is being commissioned. * The API generates the certificate in X.509 DER format. * * The delegate is expected to use the certificate authority whose certificate diff --git a/src/controller/python/BUILD.gn b/src/controller/python/BUILD.gn index 38b6536d560739..3c95a64a9a0f1c 100644 --- a/src/controller/python/BUILD.gn +++ b/src/controller/python/BUILD.gn @@ -54,6 +54,7 @@ shared_library("ChipDeviceCtrl") { "ChipDeviceController-ScriptDevicePairingDelegate.h", "ChipDeviceController-StorageDelegate.cpp", "ChipDeviceController-StorageDelegate.h", + "OpCredsBinding.cpp", "chip/clusters/attribute.cpp", "chip/clusters/command.cpp", "chip/discovery/NodeResolution.cpp", @@ -124,6 +125,7 @@ pw_python_action("python") { "chip/ChipReplStartup.py", "chip/ChipStack.py", "chip/ChipUtility.py", + "chip/FabricAdmin.py", "chip/__init__.py", "chip/ble/__init__.py", "chip/ble/commissioning/__init__.py", @@ -156,6 +158,7 @@ pw_python_action("python") { "chip/native/__init__.py", "chip/setup_payload/__init__.py", "chip/setup_payload/setup_payload.py", + "chip/storage/__init__.py", "chip/tlv/__init__.py", ] diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index 5646ed964e5d63..b35180506bebd4 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -83,10 +83,6 @@ typedef void (*ChipThreadTaskRunnerFunct)(intptr_t context); } namespace { -chip::Controller::PythonPersistentStorageDelegate sStorageDelegate; -chip::Controller::ScriptDevicePairingDelegate sPairingDelegate; -chip::Controller::ScriptDeviceAddressUpdateDelegate sDeviceAddressUpdateDelegate; -chip::Controller::ExampleOperationalCredentialsIssuer sOperationalCredentialsIssuer; chip::SimpleFabricStorage sFabricStorage; chip::Platform::ScopedMemoryBuffer sSsidBuf; chip::Platform::ScopedMemoryBuffer sCredsBuf; @@ -94,6 +90,10 @@ chip::Platform::ScopedMemoryBuffer sThreadBuf; chip::Controller::CommissioningParameters sCommissioningParameters; } // namespace +chip::Controller::ScriptDevicePairingDelegate sPairingDelegate; +chip::Controller::ScriptDeviceAddressUpdateDelegate sDeviceAddressUpdateDelegate; +chip::Controller::Python::StorageAdapter * sStorageAdapter = nullptr; + // NOTE: Remote device ID is in sync with the echo server device id // At some point, we may want to add an option to connect to a device without // knowing its id, because the ID can be learned on the first response that is received. @@ -101,6 +101,8 @@ chip::NodeId kDefaultLocalDeviceId = chip::kTestControllerNodeId; chip::NodeId kRemoteDeviceId = chip::kTestDeviceNodeId; extern "C" { +ChipError::StorageType pychip_DeviceController_StackInit(); + ChipError::StorageType pychip_DeviceController_NewDeviceController(chip::Controller::DeviceCommissioner ** outDevCtrl, chip::NodeId localDeviceId); ChipError::StorageType pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl); @@ -181,67 +183,61 @@ uint64_t pychip_GetCommandSenderHandle(chip::DeviceProxy * device); ChipError::StorageType pychip_BLEMgrImpl_ConfigureBle(uint32_t bluetoothAdapterId); chip::ChipError::StorageType pychip_InteractionModel_ShutdownSubscription(uint64_t subscriptionId); + +// +// Storage +// +void pychip_Storage_InitializeStorageAdapter(chip::Controller::Python::PyObject * context, + chip::Controller::Python::SyncSetKeyValueCb setCb, + chip::Controller::Python::SetGetKeyValueCb getCb, + chip::Controller::Python::SyncDeleteKeyValueCb deleteCb); +void pychip_Storage_ShutdownAdapter(); } -ChipError::StorageType pychip_DeviceController_NewDeviceController(chip::Controller::DeviceCommissioner ** outDevCtrl, - chip::NodeId localDeviceId) +void pychip_Storage_InitializeStorageAdapter(chip::Controller::Python::PyObject * context, + chip::Controller::Python::SyncSetKeyValueCb setCb, + chip::Controller::Python::SetGetKeyValueCb getCb, + chip::Controller::Python::SyncDeleteKeyValueCb deleteCb) { - *outDevCtrl = new chip::Controller::DeviceCommissioner(); - VerifyOrReturnError(*outDevCtrl != NULL, CHIP_ERROR_NO_MEMORY.AsInteger()); - - if (localDeviceId == chip::kUndefinedNodeId) - { - localDeviceId = kDefaultLocalDeviceId; - } - - // Initialize device attestation verifier - // TODO: Replace testingRootStore with a AttestationTrustStore that has the necessary official PAA roots available - const chip::Credentials::AttestationTrustStore * testingRootStore = chip::Credentials::GetTestAttestationTrustStore(); - SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore)); - - CHIP_ERROR err = sOperationalCredentialsIssuer.Initialize(sStorageDelegate); - VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger()); - - err = sFabricStorage.Initialize(&sStorageDelegate); - VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger()); + sStorageAdapter = new chip::Controller::Python::StorageAdapter(context, setCb, getCb, deleteCb); +} - chip::Crypto::P256Keypair ephemeralKey; - err = ephemeralKey.Initialize(); - VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger()); +void pychip_Storage_ShutdownAdapter() +{ + delete sStorageAdapter; +} - chip::Platform::ScopedMemoryBuffer noc; - ReturnErrorCodeIf(!noc.Alloc(kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY.AsInteger()); - MutableByteSpan nocSpan(noc.Get(), kMaxCHIPDERCertLength); +chip::Controller::Python::StorageAdapter * pychip_Storage_GetStorageAdapter() +{ + return sStorageAdapter; +} - chip::Platform::ScopedMemoryBuffer icac; - ReturnErrorCodeIf(!icac.Alloc(kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY.AsInteger()); - MutableByteSpan icacSpan(icac.Get(), kMaxCHIPDERCertLength); +ChipError::StorageType pychip_DeviceController_StackInit() +{ + CHIP_ERROR err; - chip::Platform::ScopedMemoryBuffer rcac; - ReturnErrorCodeIf(!rcac.Alloc(kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY.AsInteger()); - MutableByteSpan rcacSpan(rcac.Get(), kMaxCHIPDERCertLength); + VerifyOrDie(sStorageAdapter != nullptr); - err = sOperationalCredentialsIssuer.GenerateNOCChainAfterValidation(localDeviceId, 0, ephemeralKey.Pubkey(), rcacSpan, icacSpan, - nocSpan); + err = sFabricStorage.Initialize(sStorageAdapter); VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger()); FactoryInitParams factoryParams; factoryParams.fabricStorage = &sFabricStorage; - factoryParams.imDelegate = &PythonInteractionModelDelegate::Instance(); - - SetupParams initParams; - initParams.storageDelegate = &sStorageDelegate; - initParams.deviceAddressUpdateDelegate = &sDeviceAddressUpdateDelegate; - initParams.pairingDelegate = &sPairingDelegate; - initParams.operationalCredentialsDelegate = &sOperationalCredentialsIssuer; - initParams.operationalKeypair = &ephemeralKey; - initParams.controllerRCAC = rcacSpan; - initParams.controllerICAC = icacSpan; - initParams.controllerNOC = nocSpan; + factoryParams.imDelegate = nullptr; ReturnErrorOnFailure(DeviceControllerFactory::GetInstance().Init(factoryParams).AsInteger()); - err = DeviceControllerFactory::GetInstance().SetupCommissioner(initParams, **outDevCtrl); - VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger()); + + // + // In situations where all the controller instances get shutdown, the entire stack is then also + // implicitly shutdown. In the REPL, users can create such a situation by manually shutting down + // controllers (for example, when they call ChipReplStartup::LoadFabricAdmins multiple times). In + // that situation, momentarily, the stack gets de-initialized. This results in further interactions with + // the stack being dangerous (and in fact, causes crashes). + // + // This retain call ensures the stack doesn't get de-initialized in the REPL. + // + DeviceControllerFactory::GetInstance().RetainSystemState(); + #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY chip::app::DnssdServer::Instance().StartServer(chip::Dnssd::CommissioningMode::kDisabled); #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY @@ -249,17 +245,6 @@ ChipError::StorageType pychip_DeviceController_NewDeviceController(chip::Control return CHIP_NO_ERROR.AsInteger(); } -ChipError::StorageType pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl) -{ - if (devCtrl != NULL) - { - devCtrl->Shutdown(); - delete devCtrl; - } - - return CHIP_NO_ERROR.AsInteger(); -} - ChipError::StorageType pychip_DeviceController_GetAddressAndPort(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId, char * outAddress, uint64_t maxAddressLen, uint16_t * outPort) @@ -336,9 +321,13 @@ ChipError::StorageType pychip_DeviceController_ConnectIP(chip::Controller::Devic chip::RendezvousParameters params = chip::RendezvousParameters().SetSetupPINCode(setupPINCode); VerifyOrReturnError(chip::Inet::IPAddress::FromString(peerAddrStr, peerAddr), CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); + // TODO: IP rendezvous should use TCP connection. addr.SetTransportType(chip::Transport::Type::kUdp).SetIPAddress(peerAddr); params.SetPeerAddress(addr).SetDiscriminator(0); + + devCtrl->ReleaseOperationalDevice(nodeid); + return devCtrl->PairDevice(nodeid, params, sCommissioningParameters).AsInteger(); } @@ -568,6 +557,11 @@ ChipError::StorageType pychip_Stack_Init() ChipError::StorageType pychip_Stack_Shutdown() { + // + // There is the symmetric call to match the Retain called at stack initialization + // time. + // + DeviceControllerFactory::GetInstance().ReleaseSystemState(); return CHIP_NO_ERROR.AsInteger(); } @@ -614,7 +608,9 @@ ChipError::StorageType pychip_GetConnectedDeviceByNodeId(chip::Controller::Devic { VerifyOrReturnError(devCtrl != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); auto * callbacks = new GetDeviceCallbacks(callback); + // callback(nullptr, 0); return devCtrl->GetConnectedDevice(nodeId, &callbacks->mOnSuccess, &callbacks->mOnFailure).AsInteger(); + // return CHIP_NO_ERROR.AsInteger(); } ChipError::StorageType pychip_GetDeviceBeingCommissioned(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId, diff --git a/src/controller/python/ChipDeviceController-StorageDelegate.cpp b/src/controller/python/ChipDeviceController-StorageDelegate.cpp index 608e3ed775c5d7..93706bc16c6a58 100644 --- a/src/controller/python/ChipDeviceController-StorageDelegate.cpp +++ b/src/controller/python/ChipDeviceController-StorageDelegate.cpp @@ -75,5 +75,49 @@ CHIP_ERROR PythonPersistentStorageDelegate::SyncDeleteKeyValue(const char * key) return CHIP_NO_ERROR; } +namespace Python { + +CHIP_ERROR StorageAdapter::SyncGetKeyValue(const char * key, void * value, uint16_t & size) +{ + ChipLogDetail(Controller, "StorageAdapter::GetKeyValue: Key = %s, Value = %p (%u)", key, value, size); + + uint16_t tmpSize = size; + + mGetKeyCb(mContext, key, (char *) value, &tmpSize); + + if (tmpSize == 0) + { + ChipLogDetail(Controller, "Key Not Found\n"); + return CHIP_ERROR_KEY_NOT_FOUND; + } + else if (size < tmpSize) + { + ChipLogDetail(Controller, "Buf not big enough\n"); + size = tmpSize; + return CHIP_ERROR_NO_MEMORY; + } + else + { + ChipLogDetail(Controller, "Key Found %d\n", tmpSize); + size = tmpSize; + return CHIP_NO_ERROR; + } +} + +CHIP_ERROR StorageAdapter::SyncSetKeyValue(const char * key, const void * value, uint16_t size) +{ + ChipLogDetail(Controller, "StorageAdapter::SetKeyValue: Key = %s, Value = %p (%u)", key, value, size); + mStorage[key] = std::string(static_cast(value), size); + mSetKeyCb(mContext, key, value, size); + return CHIP_NO_ERROR; +} + +CHIP_ERROR StorageAdapter::SyncDeleteKeyValue(const char * key) +{ + mDeleteKeyCb(mContext, key); + return CHIP_NO_ERROR; +} + +} // namespace Python } // namespace Controller } // namespace chip diff --git a/src/controller/python/ChipDeviceController-StorageDelegate.h b/src/controller/python/ChipDeviceController-StorageDelegate.h index 6cdb870b52ee85..bb00e240413182 100644 --- a/src/controller/python/ChipDeviceController-StorageDelegate.h +++ b/src/controller/python/ChipDeviceController-StorageDelegate.h @@ -25,10 +25,6 @@ class PythonPersistentStorageDelegate; -typedef void (*GetKeyValueFunct)(const uint8_t * key, uint8_t * value, uint16_t * size); -typedef void (*SetKeyValueFunct)(const uint8_t * key, const uint8_t * value); -typedef void (*DeleteKeyValueFunct)(const uint8_t * key); - namespace chip { namespace Controller { @@ -44,5 +40,38 @@ class PythonPersistentStorageDelegate : public PersistentStorageDelegate std::map mStorage; }; +namespace Python { + +using PyObject = void; + +using SyncSetKeyValueCb = void (*)(PyObject * appContext, const char * key, const void * value, uint16_t size); +using SetGetKeyValueCb = void (*)(PyObject * appContext, const char * key, char * value, uint16_t * size); +using SyncDeleteKeyValueCb = void (*)(PyObject * appContext, const char * key); + +class StorageAdapter : public PersistentStorageDelegate +{ +public: + StorageAdapter(PyObject * context, SyncSetKeyValueCb setCb, SetGetKeyValueCb getCb, SyncDeleteKeyValueCb deleteCb) + { + mSetKeyCb = setCb; + mGetKeyCb = getCb; + mDeleteKeyCb = deleteCb; + mContext = context; + } + + CHIP_ERROR SyncGetKeyValue(const char * key, void * buffer, uint16_t & size) override; + CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override; + CHIP_ERROR SyncDeleteKeyValue(const char * key) override; + +private: + SyncSetKeyValueCb mSetKeyCb; + SetGetKeyValueCb mGetKeyCb; + SyncDeleteKeyValueCb mDeleteKeyCb; + PyObject * mContext; + + std::map mStorage; +}; + +} // namespace Python } // namespace Controller } // namespace chip diff --git a/src/controller/python/OpCredsBinding.cpp b/src/controller/python/OpCredsBinding.cpp new file mode 100644 index 00000000000000..4f01d64bab9e77 --- /dev/null +++ b/src/controller/python/OpCredsBinding.cpp @@ -0,0 +1,186 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2019-2020 Google LLC. + * Copyright (c) 2013-2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "ChipDeviceController-ScriptDeviceAddressUpdateDelegate.h" +#include "ChipDeviceController-ScriptDevicePairingDelegate.h" +#include "ChipDeviceController-StorageDelegate.h" + +#include "controller/python/chip/interaction_model/Delegate.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace chip; + +static_assert(std::is_same::value, "python assumes CHIP_ERROR maps to c_uint32"); + +using Py_GenerateNOCChainFunc = void (*)(void * pyContext, const char * csrElements, const char * attestationSignature, + const char * dac, const char * pai, const char * paa, + Controller::OnNOCChainGeneration onNocChainGenerationFunc); +using Py_SetNodeIdForNextNOCRequest = void (*)(void * pyContext, NodeId nodeId); +using Py_SetFabricIdForNextNOCRequest = void (*)(void * pyContext, FabricId fabricId); + +namespace chip { +namespace Controller { +namespace Python { + +class OperationalCredentialsAdapter : public OperationalCredentialsDelegate +{ +public: + OperationalCredentialsAdapter(uint32_t fabricCredentialsIndex) : mExampleOpCredsIssuer(fabricCredentialsIndex) {} + + CHIP_ERROR Initialize(PersistentStorageDelegate & storageDelegate) { return mExampleOpCredsIssuer.Initialize(storageDelegate); } + + CHIP_ERROR GenerateNOCChain(NodeId nodeId, FabricId fabricId, const Crypto::P256PublicKey & pubKey, MutableByteSpan & rcac, + MutableByteSpan & icac, MutableByteSpan & noc) + { + return mExampleOpCredsIssuer.GenerateNOCChainAfterValidation(nodeId, fabricId, pubKey, rcac, icac, noc); + } + +private: + CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & attestationSignature, const ByteSpan & DAC, + const ByteSpan & PAI, const ByteSpan & PAA, + Callback::Callback * onCompletion) override + { + return mExampleOpCredsIssuer.GenerateNOCChain(csrElements, attestationSignature, DAC, PAI, PAA, onCompletion); + } + + void SetNodeIdForNextNOCRequest(NodeId nodeId) override { mExampleOpCredsIssuer.SetNodeIdForNextNOCRequest(nodeId); } + + void SetFabricIdForNextNOCRequest(FabricId fabricId) override { mExampleOpCredsIssuer.SetFabricIdForNextNOCRequest(fabricId); } + + ExampleOperationalCredentialsIssuer mExampleOpCredsIssuer; +}; + +} // namespace Python +} // namespace Controller +} // namespace chip + +extern chip::Controller::Python::StorageAdapter * pychip_Storage_GetStorageAdapter(); +extern chip::Controller::Python::StorageAdapter * sStorageAdapter; +extern chip::Controller::ScriptDeviceAddressUpdateDelegate sDeviceAddressUpdateDelegate; +extern chip::Controller::ScriptDevicePairingDelegate sPairingDelegate; + +extern "C" { +struct OpCredsContext +{ + Platform::UniquePtr mAdapter; + void * mPyContext; +}; + +void * pychip_OpCreds_InitializeDelegate(void * pyContext, uint32_t fabricCredentialsIndex) +{ + auto context = Platform::MakeUnique(); + context->mAdapter = Platform::MakeUnique(fabricCredentialsIndex); + + if (pychip_Storage_GetStorageAdapter() == nullptr) + { + return nullptr; + } + + if (context->mAdapter->Initialize(*pychip_Storage_GetStorageAdapter()) != CHIP_NO_ERROR) + { + return nullptr; + } + + return context.release(); +} + +ChipError::StorageType pychip_OpCreds_AllocateController(OpCredsContext * context, + chip::Controller::DeviceCommissioner ** outDevCtrl, uint8_t fabricIndex, + FabricId fabricId, chip::NodeId nodeId) +{ + ChipLogDetail(Controller, "Creating New Device Controller"); + + VerifyOrReturnError(context != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); + + auto devCtrl = std::make_unique(); + VerifyOrReturnError(devCtrl != nullptr, CHIP_ERROR_NO_MEMORY.AsInteger()); + + // Initialize device attestation verifier + // TODO: Replace testingRootStore with a AttestationTrustStore that has the necessary official PAA roots available + const chip::Credentials::AttestationTrustStore * testingRootStore = chip::Credentials::GetTestAttestationTrustStore(); + SetDeviceAttestationVerifier(GetDefaultDACVerifier(testingRootStore)); + + chip::Crypto::P256Keypair ephemeralKey; + CHIP_ERROR err = ephemeralKey.Initialize(); + VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger()); + + chip::Platform::ScopedMemoryBuffer noc; + ReturnErrorCodeIf(!noc.Alloc(Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY.AsInteger()); + MutableByteSpan nocSpan(noc.Get(), Controller::kMaxCHIPDERCertLength); + + chip::Platform::ScopedMemoryBuffer icac; + ReturnErrorCodeIf(!icac.Alloc(Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY.AsInteger()); + MutableByteSpan icacSpan(icac.Get(), Controller::kMaxCHIPDERCertLength); + + chip::Platform::ScopedMemoryBuffer rcac; + ReturnErrorCodeIf(!rcac.Alloc(Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY.AsInteger()); + MutableByteSpan rcacSpan(rcac.Get(), Controller::kMaxCHIPDERCertLength); + + err = context->mAdapter->GenerateNOCChain(nodeId, fabricId, ephemeralKey.Pubkey(), rcacSpan, icacSpan, nocSpan); + VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger()); + + Controller::SetupParams initParams; + initParams.storageDelegate = sStorageAdapter; + initParams.deviceAddressUpdateDelegate = &sDeviceAddressUpdateDelegate; + initParams.pairingDelegate = &sPairingDelegate; + initParams.operationalCredentialsDelegate = context->mAdapter.get(); + initParams.operationalKeypair = &ephemeralKey; + initParams.controllerRCAC = rcacSpan; + initParams.controllerICAC = icacSpan; + initParams.controllerNOC = nocSpan; + + err = Controller::DeviceControllerFactory::GetInstance().SetupCommissioner(initParams, *devCtrl); + VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger()); + + *outDevCtrl = devCtrl.release(); + + return CHIP_NO_ERROR.AsInteger(); +} + +void pychip_OpCreds_FreeDelegate(OpCredsContext * context) +{ + Platform::Delete(context); +} + +ChipError::StorageType pychip_DeviceController_DeleteDeviceController(chip::Controller::DeviceCommissioner * devCtrl) +{ + if (devCtrl != NULL) + { + devCtrl->Shutdown(); + delete devCtrl; + } + + return CHIP_NO_ERROR.AsInteger(); +} +} diff --git a/src/controller/python/build-chip-wheel.py b/src/controller/python/build-chip-wheel.py index 59d3fb8b9ce07f..4e138fbf096cc8 100644 --- a/src/controller/python/build-chip-wheel.py +++ b/src/controller/python/build-chip-wheel.py @@ -134,7 +134,8 @@ def finalize_options(self): 'rich', 'stringcase', 'pyyaml', - 'ipdb' + 'ipdb', + 'ipykernel' ] if platform.system() == "Darwin": @@ -162,6 +163,7 @@ def finalize_options(self): 'chip.clusters', 'chip.tlv', 'chip.setup_payload', + 'chip.storage', ] #print ("Server: {}".format(args.server)) if args.server: diff --git a/src/controller/python/chip-device-ctrl.py b/src/controller/python/chip-device-ctrl.py index 99baedbf07ab2f..8f4aa91cc16107 100755 --- a/src/controller/python/chip-device-ctrl.py +++ b/src/controller/python/chip-device-ctrl.py @@ -26,6 +26,8 @@ from __future__ import absolute_import from __future__ import print_function from chip import ChipDeviceCtrl +from chip import FabricAdmin +from chip import ChipStack from chip import ChipCommissionableNodeCtrl from chip import exceptions import argparse @@ -43,6 +45,14 @@ import traceback from cmd import Cmd from chip.setup_payload import SetupPayload +import deprecation +import warnings +import logging +from rich import print +from rich.pretty import pprint +from rich import pretty +import coloredlogs +import chip.logging # Extend sys.path with one or more directories, relative to the location of the # running script, in which the chip package might be found . This makes it @@ -137,10 +147,24 @@ def FormatZCLArguments(args, command): return commandArgs +def ShowColoredWarnings(message, category, filename, lineno, file=None, line=None): + logging.warning(' %s:%s: %s:%s' % + (filename, lineno, category.__name__, message)) + return + + class DeviceMgrCmd(Cmd): - def __init__(self, rendezvousAddr=None, controllerNodeId=0, bluetoothAdapter=None): + def __init__(self, rendezvousAddr=None, controllerNodeId=1, bluetoothAdapter=None): self.lastNetworkId = None + pretty.install(indent_guides=True, expand_all=True) + + coloredlogs.install(level='DEBUG') + chip.logging.RedirectToPythonLogging() + + logging.getLogger().setLevel(logging.DEBUG) + warnings.showwarning = ShowColoredWarnings + Cmd.__init__(self) Cmd.identchars = string.ascii_letters + string.digits + "-" @@ -155,10 +179,12 @@ def __init__(self, rendezvousAddr=None, controllerNodeId=0, bluetoothAdapter=Non self.bleMgr = None - self.devCtrl = ChipDeviceCtrl.ChipDeviceController( - controllerNodeId=controllerNodeId, bluetoothAdapter=bluetoothAdapter) + self.chipStack = ChipStack.ChipStack(bluetoothAdapter=bluetoothAdapter) + self.fabricAdmin = FabricAdmin.FabricAdmin() + self.devCtrl = self.fabricAdmin.NewController(controllerNodeId) - self.commissionableNodeCtrl = ChipCommissionableNodeCtrl.ChipCommissionableNodeController() + self.commissionableNodeCtrl = ChipCommissionableNodeCtrl.ChipCommissionableNodeController( + self.chipStack) # If we are on Linux and user selects non-default bluetooth adapter. if sys.platform.startswith("linux") and (bluetoothAdapter is not None): @@ -280,6 +306,9 @@ def do_closeble(self, line): Close the ble connection to the device. """ + warnings.warn( + "This method is being deprecated. Please use the DeviceController.CloseBLEConnection method directly in the REPL", DeprecationWarning) + args = shlex.split(line) if len(args) != 0: @@ -299,6 +328,9 @@ def do_setlogoutput(self, line): Set the level of Chip logging output. """ + warnings.warn( + "This method is being deprecated. Please use the DeviceController.SetLogFilter method directly in the REPL", DeprecationWarning) + args = shlex.split(line) if len(args) == 0: @@ -344,6 +376,10 @@ def do_setuppayload(self, line): setup-payload parse-manual setup-payload parse-qr """ + + warnings.warn( + "This method is being deprecated. Please use the SetupPayload function in the chip.setup_payload package directly", DeprecationWarning) + try: arglist = shlex.split(line) if arglist[0] not in ("generate", "parse-manual", "parse-qr"): @@ -471,7 +507,7 @@ def ConnectFromSetupPayload(self, setupPayload, nodeid): pincode = ctypes.c_uint32( int(setupPayload.attributes['SetUpPINCode'])) try: - self.devCtrl.ConnectIP(addrStrStorage, pincode, nodeid) + self.devCtrl.CommissionIP(addrStrStorage, pincode, nodeid) print("Connected") return 0 except Exception as ex: @@ -560,6 +596,9 @@ def do_connect(self, line): for connection) """ + warnings.warn( + "This method is being deprecated. Please use the DeviceController.[ConnectBLE|CommissionIP] methods directly in the REPL", DeprecationWarning) + try: args = shlex.split(line) if len(args) <= 1: @@ -573,7 +612,7 @@ def do_connect(self, line): print("Device is assigned with nodeid = {}".format(nodeid)) if args[0] == "-ip" and len(args) >= 3: - self.devCtrl.ConnectIP(args[1].encode( + self.devCtrl.CommissionIP(args[1].encode( "utf-8"), int(args[2]), nodeid) elif args[0] == "-ble" and len(args) >= 3: self.devCtrl.ConnectBLE(int(args[1]), int(args[2]), nodeid) @@ -1048,7 +1087,7 @@ def main(): "--controller-nodeid", action="store", dest="controllerNodeId", - default=0, + default=1, type='int', help="Controller node ID", metavar="", diff --git a/src/controller/python/chip-repl.py b/src/controller/python/chip-repl.py index 0f6798137e4d06..c37ef7ee29122b 100755 --- a/src/controller/python/chip-repl.py +++ b/src/controller/python/chip-repl.py @@ -33,36 +33,18 @@ def main(): parser = argparse.ArgumentParser() - parser.add_argument( - "-n", "--noautoinit", help="Disable the default auto-initialization of the controller", action="store_true") + parser.add_argument("-p", "--storagepath", help="Path to persistent storage configuration file (default: /tmp/repl-storage.json)", + action="store", default="/tmp/repl-storage.json") + args = parser.parse_args() c = Config() c.InteractiveShellApp.exec_lines = [ - "from rich import print", - "from rich.pretty import pprint", - "from rich import pretty", - "from rich import inspect", - "from rich.console import Console", - "import logging", - "from chip import ChipDeviceCtrl", - "import chip.clusters as Clusters", - "import coloredlogs", - "import chip.logging", - "import argparse", - "from chip.ChipReplStartup import *", - "ReplInit()", + "import pkgutil", + "module = pkgutil.get_loader('chip.ChipReplStartup')", + "%run {module.path} --storagepath " + f"{args.storagepath}" ] - if (not(args.noautoinit)): - c.InteractiveShellApp.exec_lines.extend([ - "import builtins", - "devCtrl = ChipDeviceCtrl.ChipDeviceController(controllerNodeId=12344321)", - "builtins.devCtrl = devCtrl", - "console = Console()", - "console.print('\\n\\n[blue]CHIP Device Controller has been initialized, and is available as [bold red]devCtrl')" - ]) - sys.argv = [sys.argv[0]] IPython.start_ipython(config=c) diff --git a/src/controller/python/chip/ChipCommissionableNodeCtrl.py b/src/controller/python/chip/ChipCommissionableNodeCtrl.py index 87b9f5ca9dd737..c1d47dd64b91c0 100644 --- a/src/controller/python/chip/ChipCommissionableNodeCtrl.py +++ b/src/controller/python/chip/ChipCommissionableNodeCtrl.py @@ -45,9 +45,9 @@ def wrapper(*args, **kwargs): @_singleton class ChipCommissionableNodeController(object): - def __init__(self, startNetworkThread=True): + def __init__(self, chipStack: ChipStack): self.commissionableNodeCtrl = None - self._ChipStack = ChipStack() + self._ChipStack = chipStack self._dmLib = None self._InitLib() diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 4abff36a6959ab..3390d01d3cf6c3 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -41,7 +41,10 @@ import enum import threading import typing - +import builtins +import ipdb +import ctypes +import copy __all__ = ["ChipDeviceController"] @@ -80,28 +83,30 @@ class DCState(enum.IntEnum): RENDEZVOUS_CONNECTED = 4 -@_singleton -class ChipDeviceController(object): - def __init__(self, startNetworkThread=True, controllerNodeId=0, bluetoothAdapter=None): +class ChipDeviceController(): + activeList = set() + + def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, fabricIndex: int, nodeId: int): self.state = DCState.NOT_INITIALIZED self.devCtrl = None - if bluetoothAdapter is None: - bluetoothAdapter = 0 - self._ChipStack = ChipStack(bluetoothAdapter=bluetoothAdapter) + self._ChipStack = builtins.chipStack self._dmLib = None self._InitLib() devCtrl = c_void_p(None) - res = self._dmLib.pychip_DeviceController_NewDeviceController( - pointer(devCtrl), controllerNodeId) + + res = self._ChipStack.Call( + lambda: self._dmLib.pychip_OpCreds_AllocateController(ctypes.c_void_p( + opCredsContext), pointer(devCtrl), fabricIndex, fabricId, nodeId) + ) + if res != 0: raise self._ChipStack.ErrorToException(res) self.devCtrl = devCtrl - self._ChipStack.devCtrl = devCtrl - self._Cluster = ChipClusters(self._ChipStack) + self._Cluster = ChipClusters(builtins.chipStack) self._Cluster.InitLib(self._dmLib) def HandleKeyExchangeComplete(err): @@ -110,7 +115,7 @@ def HandleKeyExchangeComplete(err): self._ChipStack.callbackRes = self._ChipStack.ErrorToException( err) else: - print("Secure Session to Device Established") + print("Established CASE with Device") self.state = DCState.IDLE self._ChipStack.completeEvent.set() @@ -137,10 +142,6 @@ def HandleCommissioningComplete(nodeid, err): self._ChipStack.commissioningCompleteEvent.set() self._ChipStack.commissioningEventRes = err - im.InitIMDelegate() - ClusterCommand.Init(self) - ClusterAttribute.Init() - self.cbHandleKeyExchangeCompleteFunct = _DevicePairingDelegate_OnPairingCompleteFunct( HandleKeyExchangeComplete) self._dmLib.pychip_ScriptDevicePairingDelegate_SetKeyExchangeCallback( @@ -157,20 +158,63 @@ def HandleCommissioningComplete(nodeid, err): self.cbOnAddressUpdateComplete) self.state = DCState.IDLE + self.isActive = True + + ChipDeviceController.activeList.add(self) + + def Shutdown(self): + ''' Shuts down this controller and reclaims any used resources, including the bound + C++ constructor instance in the SDK. + ''' + if (self.isActive): + if self.devCtrl != None: + self._ChipStack.Call( + lambda: self._dmLib.pychip_DeviceController_DeleteDeviceController( + self.devCtrl) + ) + self.devCtrl = None + + ChipDeviceController.activeList.remove(self) + self.isActive = False + + def ShutdownAll(): + ''' Shut down all active controllers and reclaim any used resources. + ''' + # + # We want a shallow copy here since it would other create new instances + # of the controllers in the list. + # + # We need a copy since we're going to walk through the list and shutdown + # each controller, which in turn, will remove themselves from the active list. + # + # We cannot do that while iterating through the original list. + # + activeList = copy.copy(ChipDeviceController.activeList) + + for controller in activeList: + controller.Shutdown() + + ChipDeviceController.activeList.clear() + + def CheckIsActive(self): + if (not self.isActive): + raise RuntimeError( + "DeviceCtrl instance was already shutdown previously!") def __del__(self): - if self.devCtrl != None: - self._dmLib.pychip_DeviceController_DeleteDeviceController( - self.devCtrl) - self.devCtrl = None + self.Shutdown() def IsConnected(self): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_IsConnected( self.devCtrl) ) def ConnectBle(self, bleConnection): + self.CheckIsActive() + self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ValidateBTP( self.devCtrl, @@ -181,6 +225,8 @@ def ConnectBle(self, bleConnection): ) def ConnectBLE(self, discriminator, setupPinCode, nodeid): + self.CheckIsActive() + self.state = DCState.RENDEZVOUS_ONGOING self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectBLE( @@ -195,18 +241,24 @@ def ConnectBLE(self, discriminator, setupPinCode, nodeid): return self._ChipStack.commissioningEventRes == 0 def CloseBLEConnection(self): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceCommissioner_CloseBleConnection( self.devCtrl) ) def CloseSession(self, nodeid): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_CloseSession( self.devCtrl, nodeid) ) def EstablishPASESessionIP(self, ipaddr, setupPinCode, nodeid): + self.CheckIsActive() + self.state = DCState.RENDEZVOUS_ONGOING return self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_EstablishPASESessionIP( @@ -214,6 +266,8 @@ def EstablishPASESessionIP(self, ipaddr, setupPinCode, nodeid): ) def Commission(self, nodeid): + self.CheckIsActive() + self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_Commission( self.devCtrl, nodeid) @@ -226,10 +280,15 @@ def Commission(self, nodeid): return False return self._ChipStack.commissioningEventRes == 0 - def ConnectIP(self, ipaddr, setupPinCode, nodeid): + def CommissionIP(self, ipaddr, setupPinCode, nodeid): + self.CheckIsActive() + # IP connection will run through full commissioning, so we need to wait # for the commissioning complete event, not just any callback. self.state = DCState.RENDEZVOUS_ONGOING + + self._ChipStack.commissioningCompleteEvent.clear() + self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectIP( self.devCtrl, ipaddr, setupPinCode, nodeid) @@ -242,25 +301,45 @@ def ConnectIP(self, ipaddr, setupPinCode, nodeid): return False return self._ChipStack.commissioningEventRes == 0 + def CommissionThread(self, discriminator, setupPinCode, nodeId, threadOperationalDataset: bytes): + ''' Commissions a Thread device over BLE + ''' + self.SetThreadOperationalDataset(threadOperationalDataset) + return self.ConnectBLE(discriminator, setupPinCode, nodeId) + + def CommissionWiFi(self, discriminator, setupPinCode, nodeId, ssid, credentials): + ''' Commissions a WiFi device over BLE + ''' + self.SetWiFiCredentials(ssid, credentials) + return self.ConnectBLE(discriminator, setupPinCode, nodeId) + def SetWiFiCredentials(self, ssid, credentials): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_SetWiFiCredentials( ssid, credentials) ) def SetThreadOperationalDataset(self, threadOperationalDataset): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_SetThreadOperationalDataset( threadOperationalDataset, len(threadOperationalDataset)) ) def ResolveNode(self, nodeid): + self.CheckIsActive() + return self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_UpdateDevice( self.devCtrl, nodeid) ) def GetAddressAndPort(self, nodeid): + self.CheckIsActive() + address = create_string_buffer(64) port = c_uint16(0) @@ -272,42 +351,56 @@ def GetAddressAndPort(self, nodeid): return (address.value.decode(), port.value) if error == 0 else None def DiscoverCommissionableNodesLongDiscriminator(self, long_discriminator): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesLongDiscriminator( self.devCtrl, long_discriminator) ) def DiscoverCommissionableNodesShortDiscriminator(self, short_discriminator): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesShortDiscriminator( self.devCtrl, short_discriminator) ) def DiscoverCommissionableNodesVendor(self, vendor): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesVendor( self.devCtrl, vendor) ) def DiscoverCommissionableNodesDeviceType(self, device_type): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesDeviceType( self.devCtrl, device_type) ) def DiscoverCommissionableNodesCommissioningEnabled(self): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_DiscoverCommissionableNodesCommissioningEnabled( self.devCtrl) ) def PrintDiscoveredDevices(self): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_PrintDiscoveredDevices( self.devCtrl) ) def ParseQRCode(self, qrCode, output): + self.CheckIsActive() + print(output) return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_ParseQRCode( @@ -315,18 +408,24 @@ def ParseQRCode(self, qrCode, output): ) def GetIPForDiscoveredDevice(self, idx, addrStr, length): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_GetIPForDiscoveredDevice( self.devCtrl, idx, addrStr, length) ) def DiscoverAllCommissioning(self): + self.CheckIsActive() + return self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_DiscoverAllCommissionableNodes( self.devCtrl) ) def OpenCommissioningWindow(self, nodeid, timeout, iteration, discriminator, option): + self.CheckIsActive() + res = self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_OpenCommissioningWindow( self.devCtrl, nodeid, timeout, iteration, discriminator, option) @@ -336,6 +435,8 @@ def OpenCommissioningWindow(self, nodeid, timeout, iteration, discriminator, opt raise self._ChipStack.ErrorToException(res) def GetCompressedFabricId(self): + self.CheckIsActive() + fabricid = c_uint64(0) res = self._ChipStack.Call( @@ -349,6 +450,8 @@ def GetCompressedFabricId(self): raise self._ChipStack.ErrorToException(res) def GetFabricId(self): + self.CheckIsActive() + fabricid = c_uint64(0) res = self._ChipStack.Call( @@ -362,12 +465,17 @@ def GetFabricId(self): raise self._ChipStack.ErrorToException(res) def GetClusterHandler(self): + self.CheckIsActive() + return self._Cluster def GetConnectedDeviceSync(self, nodeid): + self.CheckIsActive() + returnDevice = c_void_p(None) deviceAvailableCV = threading.Condition() + @_DeviceAvailableFunct def DeviceAvailableCallback(device, err): nonlocal returnDevice nonlocal deviceAvailableCV @@ -386,7 +494,7 @@ def DeviceAvailableCallback(device, err): return returnDevice res = self._ChipStack.Call(lambda: self._dmLib.pychip_GetConnectedDeviceByNodeId( - self.devCtrl, nodeid, _DeviceAvailableFunct(DeviceAvailableCallback))) + self.devCtrl, nodeid, DeviceAvailableCallback)) if res != 0: raise self._ChipStack.ErrorToException(res) @@ -408,6 +516,7 @@ async def SendCommand(self, nodeid: int, endpoint: int, payload: ClusterObjects. timedWriteTimeoutMs: Timeout for a timed invoke request. Omit or set to 'None' to indicate a non-timed request. ''' + self.CheckIsActive() eventLoop = asyncio.get_running_loop() future = eventLoop.create_future() @@ -436,6 +545,8 @@ async def WriteAttribute(self, nodeid: int, attributes: typing.List[typing.Tuple E.g (1, Clusters.TestCluster.Attributes.XYZAttribute('hello')) -- Write 'hello' to the XYZ attribute on the test cluster to endpoint 1 ''' + self.CheckIsActive() + eventLoop = asyncio.get_running_loop() future = eventLoop.create_future() @@ -491,6 +602,7 @@ async def ReadAttribute(self, nodeid: int, attributes: typing.List[typing.Union[ reportInterval: A tuple of two int-s for (MinIntervalFloor, MaxIntervalCeiling). Used by establishing subscriptions. When not provided, a read request will be sent. ''' + self.CheckIsActive() eventLoop = asyncio.get_running_loop() future = eventLoop.create_future() @@ -564,6 +676,7 @@ async def ReadEvent(self, nodeid: int, events: typing.List[typing.Union[ reportInterval: A tuple of two int-s for (MinIntervalFloor, MaxIntervalCeiling). Used by establishing subscriptions. When not provided, a read request will be sent. ''' + self.CheckIsActive() eventLoop = asyncio.get_running_loop() future = eventLoop.create_future() @@ -606,6 +719,8 @@ async def ReadEvent(self, nodeid: int, events: typing.List[typing.Union[ return await future def ZCLSend(self, cluster, command, nodeid, endpoint, groupid, args, blocking=False): + self.CheckIsActive() + req = None try: req = eval( @@ -620,6 +735,8 @@ def ZCLSend(self, cluster, command, nodeid, endpoint, groupid, args, blocking=Fa return (int(ex.state), None) def ZCLReadAttribute(self, cluster, attribute, nodeid, endpoint, groupid, blocking=True): + self.CheckIsActive() + req = None clusterType = eval(f"GeneratedObjects.{cluster}") @@ -646,6 +763,8 @@ def ZCLWriteAttribute(self, cluster: str, attribute: str, nodeid, endpoint, grou return asyncio.run(self.WriteAttribute(nodeid, [(endpoint, req)])) def ZCLSubscribeAttribute(self, cluster, attribute, nodeid, endpoint, minInterval, maxInterval, blocking=True): + self.CheckIsActive() + req = None try: req = eval(f"GeneratedObjects.{cluster}.Attributes.{attribute}") @@ -654,12 +773,17 @@ def ZCLSubscribeAttribute(self, cluster, attribute, nodeid, endpoint, minInterva return asyncio.run(self.ReadAttribute(nodeid, [(endpoint, req)], False, reportInterval=(minInterval, maxInterval))) def ZCLCommandList(self): + self.CheckIsActive() return self._Cluster.ListClusterCommands() def ZCLAttributeList(self): + self.CheckIsActive() + return self._Cluster.ListClusterAttributes() def SetLogFilter(self, category): + self.CheckIsActive() + if category < 0 or category > pow(2, 8): raise ValueError("category must be an unsigned 8-bit integer") @@ -668,11 +792,15 @@ def SetLogFilter(self, category): ) def GetLogFilter(self): + self.CheckIsActive() + self._ChipStack.Call( lambda: self._dmLib.pychip_DeviceController_GetLogFilter() ) def SetBlockingCB(self, blockingCB): + self.CheckIsActive() + self._ChipStack.blockingCB = blockingCB # ----- Private Members ----- @@ -680,10 +808,6 @@ def _InitLib(self): if self._dmLib is None: self._dmLib = CDLL(self._ChipStack.LocateChipDLL()) - self._dmLib.pychip_DeviceController_NewDeviceController.argtypes = [ - POINTER(c_void_p), c_uint64] - self._dmLib.pychip_DeviceController_NewDeviceController.restype = c_uint32 - self._dmLib.pychip_DeviceController_DeleteDeviceController.argtypes = [ c_void_p] self._dmLib.pychip_DeviceController_DeleteDeviceController.restype = c_uint32 diff --git a/src/controller/python/chip/ChipReplStartup.py b/src/controller/python/chip/ChipReplStartup.py index 6025f7d0c3c61a..7fcb9ad2945dca 100644 --- a/src/controller/python/chip/ChipReplStartup.py +++ b/src/controller/python/chip/ChipReplStartup.py @@ -6,10 +6,64 @@ import logging from chip import ChipDeviceCtrl import chip.clusters as Clusters +from chip.ChipStack import * import coloredlogs import chip.logging import argparse import builtins +import chip.FabricAdmin + +_fabricAdmins = None + + +def LoadFabricAdmins(): + global _fabricAdmins + + # + # Shutdown any fabric admins we had before as well as active controllers. This ensures we + # relinquish some resources if this is called multiple times (e.g in a Jupyter notebook) + # + chip.FabricAdmin.FabricAdmin.ShutdownAll() + ChipDeviceCtrl.ChipDeviceController.ShutdownAll() + + _fabricAdmins = [] + storageMgr = builtins.chipStack.GetStorageManager() + + console = Console() + + try: + adminList = storageMgr.GetReplKey('fabricAdmins') + except KeyError: + console.print( + "\n[purple]No previous fabric admins discovered in persistent storage - creating a new one...") + _fabricAdmins.append(chip.FabricAdmin.FabricAdmin()) + return _fabricAdmins + + console.print('\n') + + for k in adminList: + console.print( + f"[purple]Restoring FabricAdmin from storage to manage FabricId {adminList[k]['fabricId']}, FabricIndex {k}...") + _fabricAdmins.append(chip.FabricAdmin.FabricAdmin( + fabricId=adminList[k]['fabricId'], fabricIndex=int(k))) + + console.print( + '\n[blue]Fabric Admins have been loaded and are available at [red]fabricAdmins') + return _fabricAdmins + + +def CreateDefaultDeviceController(): + global _fabricAdmins + + if (len(_fabricAdmins) == 0): + raise RuntimeError("Was called before calling LoadFabricAdmins()") + + console = Console() + + console.print('\n') + console.print( + f"[purple]Creating default device controller on fabric {_fabricAdmins[0]._fabricId}...") + return _fabricAdmins[0].NewController() def ReplInit(): @@ -37,7 +91,9 @@ def ReplInit(): coloredlogs.install(level='DEBUG') chip.logging.RedirectToPythonLogging() - logging.getLogger().setLevel(logging.ERROR) + + # logging.getLogger().setLevel(logging.DEBUG) + logging.getLogger().setLevel(logging.WARN) def matterhelp(classOrObj=None): @@ -59,3 +115,20 @@ def mattersetdebug(enableDebugMode: bool = True): of returning well-formatted results). ''' builtins.enableDebugMode = enableDebugMode + + +console = Console() + +parser = argparse.ArgumentParser() +parser.add_argument( + "-p", "--storagepath", help="Path to persistent storage configuration file (default: /tmp/repl-storage.json)", action="store", default="/tmp/repl-storage.json") +args = parser.parse_args() +ReplInit() +chipStack = ChipStack(persistentStoragePath=args.storagepath) +fabricAdmins = LoadFabricAdmins() +devCtrl = CreateDefaultDeviceController() + +builtins.devCtrl = devCtrl + +console.print( + '\n\n[blue]Default CHIP Device Controller has been initialized to manage [bold red]fabricAdmins[0][blue], and is available as [bold red]devCtrl') diff --git a/src/controller/python/chip/ChipStack.py b/src/controller/python/chip/ChipStack.py index ca4affd3b30aae..47c5ef43ce14c8 100644 --- a/src/controller/python/chip/ChipStack.py +++ b/src/controller/python/chip/ChipStack.py @@ -35,9 +35,17 @@ from threading import Lock, Event, Condition from ctypes import * from .ChipUtility import ChipUtility +from .storage import * from .exceptions import * import builtins +from .interaction_model import InteractionModelError, delegate as im +from .clusters import Command as ClusterCommand +from .clusters import Attribute as ClusterAttribute +from .clusters import ClusterObjects as ClusterObjects +from .clusters import Objects as GeneratedObjects +from .clusters.CHIPClusters import * + __all__ = [ "DeviceStatusStruct", "ChipStackException", @@ -160,7 +168,7 @@ def Wait(self): @_singleton class ChipStack(object): - def __init__(self, installDefaultLogHandler=True, bluetoothAdapter=0): + def __init__(self, persistentStoragePath: str, installDefaultLogHandler=True, bluetoothAdapter=None): builtins.enableDebugMode = False self.networkLock = Lock() @@ -244,11 +252,29 @@ def HandleChipThreadRun(callback): if res != 0: raise self.ErrorToException(res) + if (bluetoothAdapter is None): + bluetoothAdapter = 0 + res = self._ChipStackLib.pychip_BLEMgrImpl_ConfigureBle( bluetoothAdapter) if res != 0: raise self.ErrorToException(res) + self._persistentStorage = PersistentStorage(persistentStoragePath) + + res = self._ChipStackLib.pychip_DeviceController_StackInit() + if res != 0: + raise self.ErrorToException(res) + + im.InitIMDelegate() + ClusterAttribute.Init() + ClusterCommand.Init() + + builtins.chipStack = self + + def GetStorageManager(self): + return self._persistentStorage + @property def defaultLogFunct(self): """Returns a python callable which, when called, logs a message to the python logger object @@ -292,7 +318,7 @@ def setLogFunct(self, logFunct): self._ChipStackLib.pychip_Stack_SetLogFunct(logFunct) def Shutdown(self): - self._ChipStack.Call(lambda: self._dmLib.pychip_Stack_Shutdown()) + self.Call(lambda: self._ChipStackLib.pychip_Stack_Shutdown()) self.networkLock = None self.completeEvent = None self._ChipStackLib = None diff --git a/src/controller/python/chip/FabricAdmin.py b/src/controller/python/chip/FabricAdmin.py new file mode 100644 index 00000000000000..362c7da90a671f --- /dev/null +++ b/src/controller/python/chip/FabricAdmin.py @@ -0,0 +1,209 @@ +# +# Copyright (c) 2021 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Needed to use types in type hints before they are fully defined. +from __future__ import annotations + +import ctypes +from dataclasses import dataclass, field +from typing import * +from ctypes import * +from rich.pretty import pprint +import ipdb +import json +import logging +import builtins +import base64 +import chip.exceptions +from chip import ChipDeviceCtrl +import copy + + +class FabricAdmin: + ''' Administers a given fabric instance. Each admin is associated with + a specific RCAC and ICAC as well as Fabric ID and Index. + + There can only be one admin instance for a given fabric in a single + Python process instance. + + The admin also persists to storage its detail automatically to permit + easy loading of its information later. + + >> C++ Binding Details + + Each instance of the fabric admin is associated with a single instance + of the OperationalCredentialsAdapter. This adapter instance implements + the OperationalCredentialsDelegate and is meant to provide a Python + adapter to the functions in that delegate so that the fabric admin + can in turn, provide users the ability to generate their own NOCs for devices + on the network (not implemented yet). For now, it relies on the in-built + ExampleOperationalCredentialsIssuer to do that. + + TODO: Add support for FabricAdmin to permit callers to hook up their own GenerateNOC + logic. + + >> Persistence + + Each instance persists its fabric ID and index to storage. This is in addition to the + persistence built into the ExampleOperationalCredentialsIssuer that persists details + about the RCAC/ICAC as well. This facilitates re-construction of a fabric admin on subsequent + boot for a given fabric and ensuring it automatically picks up the right ICAC/RCAC details as well. + ''' + + _handle = chip.native.GetLibraryHandle() + activeFabricIndexList = set() + activeFabricIdList = set() + + activeAdmins = set() + + def AllocateNextFabricIndex(self): + ''' Allocate the next un-used fabric index. + ''' + nextFabricIndex = 1 + while nextFabricIndex in FabricAdmin.activeFabricIndexList: + nextFabricIndex = nextFabricIndex + 1 + return nextFabricIndex + + def AllocateNextFabricId(self): + ''' Allocate the next un-used fabric ID. + ''' + nextFabricId = 1 + + while nextFabricId in FabricAdmin.activeFabricIdList: + nextFabricId = nextFabricId + 1 + return nextFabricId + + def __init__(self, rcac: bytes = None, icac: bytes = None, fabricIndex: int = None, fabricId: int = None): + ''' Creates a valid FabricAdmin object with valid RCAC/ICAC, and registers itself as an OperationalCredentialsDelegate + for other parts of the system (notably, DeviceController) to vend NOCs. + + rcac, icac: Specify the RCAC and ICAC to be used with this fabric (not-supported). If not specified, an RCAC and ICAC will + be automatically generated. + + fabricIndex: Local fabric index to be associated with this fabric. If omitted, one will be automatically assigned. + fabricId: Local fabric ID to be associated with this fabric. If omitted, one will be automatically assigned. + ''' + if (rcac is not None or icac is not None): + raise ValueError( + "Providing valid rcac/icac values is not supported right now!") + + if (fabricId is None): + self._fabricId = self.AllocateNextFabricId() + else: + if (fabricId in FabricAdmin.activeFabricIdList): + raise ValueError( + f"FabricId {fabricId} is already being managed by an existing FabricAdmin object!") + + self._fabricId = fabricId + + if (fabricIndex is None): + self._fabricIndex = self.AllocateNextFabricIndex() + else: + if (fabricIndex in FabricAdmin.activeFabricIndexList): + raise ValueError( + f"FabricIndex {fabricIndex} is already being managed by an existing FabricAdmin object!") + + self._fabricIndex = fabricIndex + + # Add it to the tracker to prevent future FabricAdmins from managing the same fabric. + FabricAdmin.activeFabricIdList.add(self._fabricId) + FabricAdmin.activeFabricIndexList.add(self._fabricIndex) + + print( + f"New FabricAdmin: FabricId: {self._fabricId}({self._fabricIndex})") + self._handle.pychip_OpCreds_InitializeDelegate.restype = c_void_p + + self.closure = builtins.chipStack.Call( + lambda: self._handle.pychip_OpCreds_InitializeDelegate( + ctypes.py_object(self), ctypes.c_uint32(self._fabricIndex)) + ) + + if (self.closure is None): + raise ValueError("Encountered error initializing OpCreds adapter") + + # + # Persist details to storage (read modify write). + # + try: + adminList = builtins.chipStack.GetStorageManager().GetReplKey('fabricAdmins') + except KeyError: + adminList = {str(self._fabricIndex): {'fabricId': self._fabricId}} + builtins.chipStack.GetStorageManager().SetReplKey('fabricAdmins', adminList) + + adminList[str(self._fabricIndex)] = {'fabricId': self._fabricId} + builtins.chipStack.GetStorageManager().SetReplKey('fabricAdmins', adminList) + + self._isActive = True + self.nextControllerId = 1 + + FabricAdmin.activeAdmins.add(self) + + def NewController(self, nodeId: int = None): + ''' Vend a new controller on this fabric seeded with the right fabric details. + ''' + if (not(self._isActive)): + raise RuntimeError( + f"FabricAdmin object was previously shutdown and is no longer valid!") + + if (nodeId is None): + nodeId = self.nextControllerId + self.nextControllerId = self.nextControllerId + 1 + + print( + f"Allocating new controller with FabricId: {self._fabricId}({self._fabricIndex}), NodeId: {nodeId}") + controller = ChipDeviceCtrl.ChipDeviceController( + self.closure, self._fabricId, self._fabricIndex, nodeId) + return controller + + def ShutdownAll(): + ''' Shuts down all active fabrics, but without deleting them from storage. + ''' + activeAdmins = copy.copy(FabricAdmin.activeAdmins) + + for admin in activeAdmins: + admin.Shutdown(False) + + FabricAdmin.activeAdmins.clear() + + def Shutdown(self, deleteFromStorage: bool = True): + ''' Shutdown this fabric and free up its resources. This is important since relying + solely on the destructor will not guarantee relishining of C++-side resources. + + deleteFromStorage: Whether to delete this fabric's details from persistent storage. + ''' + if (self._isActive): + builtins.chipStack.Call( + lambda: self._handle.pychip_OpCreds_FreeDelegate( + ctypes.c_void_p(self.closure)) + ) + + FabricAdmin.activeFabricIdList.remove(self._fabricId) + FabricAdmin.activeFabricIndexList.remove(self._fabricIndex) + + if (deleteFromStorage): + adminList = builtins.chipStack.GetStorageManager().GetReplKey('fabricAdmins') + del(adminList[str(self._fabricIndex)]) + if (len(adminList) == 0): + adminList = None + + builtins.chipStack.GetStorageManager().SetReplKey('fabricAdmins', adminList) + + FabricAdmin.activeAdmins.remove(self) + self._isActive = False + + def __del__(self): + self.Shutdown(False) diff --git a/src/controller/python/chip/clusters/Attribute.py b/src/controller/python/chip/clusters/Attribute.py index 2ab312d6ad5b9b..b3901dcdf9b308 100644 --- a/src/controller/python/chip/clusters/Attribute.py +++ b/src/controller/python/chip/clusters/Attribute.py @@ -467,6 +467,9 @@ def Shutdown(self): self._readTransaction._pReadClient, self._readTransaction._pReadCallback) self._isDone = True + def __del__(self): + self.Shutdown() + def __repr__(self): return f'' @@ -868,8 +871,13 @@ def ReadEvents(future: Future, eventLoop, device, devCtrl, events: List[EventPat path = chip.interaction_model.EventPathIBstruct.build(path) readargs.append(ctypes.c_char_p(path)) + readClientObj = ctypes.POINTER(c_void_p)() + readCallbackObj = ctypes.POINTER(c_void_p)() + ctypes.pythonapi.Py_IncRef(ctypes.py_object(transaction)) + params = _ReadParams.parse(b'\x00' * _ReadParams.sizeof()) + if subscriptionParameters is not None: params.MinInterval = subscriptionParameters.MinReportIntervalFloorSeconds params.MaxInterval = subscriptionParameters.MaxReportIntervalCeilingSeconds @@ -877,9 +885,15 @@ def ReadEvents(future: Future, eventLoop, device, devCtrl, events: List[EventPat params = _ReadParams.build(params) res = handle.pychip_ReadClient_ReadEvents( - ctypes.py_object(transaction), device, + ctypes.py_object(transaction), + ctypes.byref(readClientObj), + ctypes.byref(readCallbackObj), + device, ctypes.c_char_p(params), ctypes.c_size_t(len(events)), *readargs) + + transaction.SetClientObjPointers(readClientObj, readCallbackObj) + if res != 0: ctypes.pythonapi.Py_DecRef(ctypes.py_object(transaction)) return res diff --git a/src/controller/python/chip/clusters/Command.py b/src/controller/python/chip/clusters/Command.py index 8a6fe939509700..e22e736ca6762d 100644 --- a/src/controller/python/chip/clusters/Command.py +++ b/src/controller/python/chip/clusters/Command.py @@ -161,21 +161,7 @@ def SendCommand(future: Future, eventLoop, responseType: Type, device, commandPa transaction), device, c_uint16(0 if timedRequestTimeoutMs is None else timedRequestTimeoutMs), commandPath.EndpointId, commandPath.ClusterId, commandPath.CommandId, payloadTLV, len(payloadTLV)) -_deviceController = None - - -def SetDeviceController(deviceCtrl): - global _deviceController - _deviceController = deviceCtrl - - -def GetDeviceController(): - global _deviceController - return _deviceController - - -def Init(devCtrl): - SetDeviceController(devCtrl) +def Init(): handle = chip.native.GetLibraryHandle() # Uses one of the type decorators as an indicator for everything being diff --git a/src/controller/python/chip/clusters/attribute.cpp b/src/controller/python/chip/clusters/attribute.cpp index ecccd62e6feda9..93ca755dbc3da3 100644 --- a/src/controller/python/chip/clusters/attribute.cpp +++ b/src/controller/python/chip/clusters/attribute.cpp @@ -383,8 +383,10 @@ chip::ChipError::StorageType pychip_ReadClient_ReadAttributes(void * appContext, return err.AsInteger(); } -chip::ChipError::StorageType pychip_ReadClient_ReadEvents(void * appContext, DeviceProxy * device, uint8_t * readParamsBuf, - size_t n, ...) +chip::ChipError::StorageType pychip_ReadClient_ReadEvents(void * appContext, ReadClient ** pReadClient, + ReadClientCallback ** pCallback, DeviceProxy * device, + + uint8_t * readParamsBuf, size_t n, ...) { CHIP_ERROR err = CHIP_NO_ERROR; PyReadAttributeParams pyParams = {}; @@ -432,8 +434,12 @@ chip::ChipError::StorageType pychip_ReadClient_ReadEvents(void * appContext, Dev SuccessOrExit(err); } + *pReadClient = readClient.get(); + *pCallback = callback.get(); + + callback->AdoptReadClient(std::move(readClient)); + callback.release(); - readClient.release(); exit: va_end(args); diff --git a/src/controller/python/chip/storage/__init__.py b/src/controller/python/chip/storage/__init__.py new file mode 100644 index 00000000000000..a3643a6a11c086 --- /dev/null +++ b/src/controller/python/chip/storage/__init__.py @@ -0,0 +1,158 @@ +# +# Copyright (c) 2021 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Needed to use types in type hints before they are fully defined. +from __future__ import annotations + +import ctypes +from dataclasses import dataclass, field +from typing import * +from ctypes import * +from rich.pretty import pprint +import ipdb +import json +import logging +import base64 +import chip.exceptions +import copy +import chip.native +import builtins + +_SyncSetKeyValueCbFunct = CFUNCTYPE( + None, py_object, c_char_p, POINTER(c_char), c_uint16) +_SyncGetKeyValueCbFunct = CFUNCTYPE( + None, py_object, c_char_p, POINTER(c_char), POINTER(c_uint16)) +_SyncDeleteKeyValueCbFunct = CFUNCTYPE(None, py_object, POINTER(c_char_p)) + + +@_SyncSetKeyValueCbFunct +def _OnSyncSetKeyValueCb(storageObj, key: str, value, size): + storageObj.SetSdkKey(key.decode("utf-8"), ctypes.string_at(value, size)) + + +@_SyncGetKeyValueCbFunct +def _OnSyncGetKeyValueCb(storageObj, key: str, value, size): + try: + keyValue = storageObj.GetSdkKey(key.decode("utf-8")) + except Exception as ex: + keyValue = None + + if (keyValue): + if (size[0] < len(keyValue)): + size[0] = len(keyValue) + return + + count = 0 + + for idx, val in enumerate(keyValue): + value[idx] = val + count = count + 1 + + size[0] = count + else: + size[0] = 0 + + +@_SyncDeleteKeyValueCbFunct +def _OnSyncDeleteKeyValueCb(storageObj, key): + storageObj.SetSdkKey(key.decode("utf-8"), None) + + +class PersistentStorage: + + def __init__(self, path: str): + self._path = path + self._handle = chip.native.GetLibraryHandle() + + try: + self._file = open(path, 'r') + self._file.seek(0, 2) + size = self._file.tell() + self._file.seek(0) + + if (size != 0): + logging.critical(f"Loading configuration from {path}...") + self.jsonData = json.load(self._file) + else: + logging.warn( + f"No valid configuration present at {path} - clearing out configuration") + self.jsonData = {'repl-config': {}, 'sdk-config': {}} + + except Exception as ex: + logging.error(ex) + logging.warn( + f"Could not load configuration from {path} - resetting configuration...") + self.jsonData = {'repl-config': {}, 'sdk-config': {}} + + self._file = None + self._handle.pychip_Storage_InitializeStorageAdapter(ctypes.py_object( + self), _OnSyncSetKeyValueCb, _OnSyncGetKeyValueCb, _OnSyncDeleteKeyValueCb) + + def Sync(self): + if (self._file is None): + try: + self._file = open(self._path, 'w') + except Exception as ex: + logging.warn( + f"Could not open {path} for writing configuration. Error:") + logging.warn(ex) + + self._file.seek(0) + json.dump(self.jsonData, self._file, ensure_ascii=True, indent=4) + self._file.truncate() + self._file.flush() + + def SetReplKey(self, key: str, value): + logging.info(f"SetReplKey: {key} = {value}") + + if (key is None or key == ''): + raise ValueError("Invalid Key") + + if (value is None): + del(self.jsonData['repl-config'][key]) + else: + self.jsonData['repl-config'][key] = value + + self.Sync() + + def GetReplKey(self, key: str): + return copy.deepcopy(self.jsonData['repl-config'][key]) + + def SetSdkKey(self, key: str, value: bytes): + logging.info(f"SetSdkKey: {key} = {value}") + + if (key is None or key == ''): + raise ValueError("Invalid Key") + + if (value is None): + del(self.jsonData['sdk-config'][key]) + else: + self.jsonData['sdk-config'][key] = base64.b64encode( + value).decode("utf-8") + + self.Sync() + + def GetSdkKey(self, key: str): + return base64.b64decode(self.jsonData['sdk-config'][key]) + + def GetUnderlyingStorageAdapter(self): + return self._storageAdapterObj + + def __del__(self): + builtins.chipStack.Call( + lambda: self._handle.pychip_Storage_ShutdownAdapter() + ) diff --git a/src/controller/python/test/test_scripts/base.py b/src/controller/python/test/test_scripts/base.py index 94514687f04723..9152eb30973158 100644 --- a/src/controller/python/test/test_scripts/base.py +++ b/src/controller/python/test/test_scripts/base.py @@ -30,6 +30,8 @@ import ctypes import chip.clusters as Clusters import chip.clusters.Attribute as Attribute +from chip.ChipStack import * +import chip.FabricAdmin logger = logging.getLogger('PythonMatterControllerTEST') logger.setLevel(logging.INFO) @@ -102,10 +104,12 @@ def assertValueEqual(self, expected): class BaseTestHelper: def __init__(self, nodeid: int): - self.devCtrl = ChipDeviceCtrl.ChipDeviceController( - controllerNodeId=nodeid) + self.chipStack = ChipStack('/tmp/repl_storage.json') + self.fabricAdmin = chip.FabricAdmin.FabricAdmin( + fabricId=1, fabricIndex=1) + self.devCtrl = self.fabricAdmin.NewController(nodeid) + self.controllerNodeId = nodeid self.logger = logger - self.commissionableNodeCtrl = ChipCommissionableNodeCtrl.ChipCommissionableNodeController() def _WaitForOneDiscoveredDevice(self, timeoutSeconds: int = 2): print("Waiting for device responses...") @@ -133,13 +137,79 @@ def TestDiscovery(self, discriminator: int): def TestKeyExchange(self, ip: str, setuppin: int, nodeid: int): self.logger.info("Conducting key exchange with device {}".format(ip)) - if not self.devCtrl.ConnectIP(ip.encode("utf-8"), setuppin, nodeid): + if not self.devCtrl.CommissionIP(ip.encode("utf-8"), setuppin, nodeid): self.logger.info( "Failed to finish key exchange with device {}".format(ip)) return False self.logger.info("Device finished key exchange.") return True + async def TestMultiFabric(self, ip: str, setuppin: int, nodeid: int): + self.logger.info("Opening Commissioning Window") + + await self.devCtrl.SendCommand(nodeid, 0, Clusters.AdministratorCommissioning.Commands.OpenBasicCommissioningWindow(100)) + + self.logger.info("Creating 2nd Fabric Admin") + fabricAdmin2 = chip.FabricAdmin.FabricAdmin(fabricId=2, fabricIndex=2) + + self.logger.info("Creating Device Controller on 2nd Fabric") + devCtrl2 = fabricAdmin2.NewController(self.controllerNodeId) + + if not devCtrl2.CommissionIP(ip.encode("utf-8"), setuppin, nodeid): + self.logger.info( + "Failed to finish key exchange with device {}".format(ip)) + return False + + # + # Shutting down controllers results in races where the resolver still delivers + # resolution results to a now destroyed controller. Add a sleep for now to work around + # it while #14555 is being resolved. + time.sleep(1) + + # + # Shut-down all the controllers (which will free them up as well as de-initialize the + # stack as well. + # + self.logger.info( + "Shutting down controllers & fabrics and re-initing stack...") + + ChipDeviceCtrl.ChipDeviceController.ShutdownAll() + chip.FabricAdmin.FabricAdmin.ShutdownAll() + + self.fabricAdmin = chip.FabricAdmin.FabricAdmin( + fabricId=1, fabricIndex=1) + fabricAdmin2 = chip.FabricAdmin.FabricAdmin(fabricId=2, fabricIndex=2) + + self.devCtrl = self.fabricAdmin.NewController(self.controllerNodeId) + devCtrl2 = fabricAdmin2.NewController(self.controllerNodeId) + + data1 = await self.devCtrl.ReadAttribute(nodeid, [(Clusters.OperationalCredentials.Attributes.NOCs)], fabricFiltered=False) + data2 = await devCtrl2.ReadAttribute(nodeid, [(Clusters.OperationalCredentials.Attributes.NOCs)], fabricFiltered=False) + + # Read out noclist from each fabric, and each should contain two NOCs. + nocList1 = data1[0][Clusters.OperationalCredentials][Clusters.OperationalCredentials.Attributes.NOCs] + nocList2 = data2[0][Clusters.OperationalCredentials][Clusters.OperationalCredentials.Attributes.NOCs] + + if (len(nocList1) != 2 or len(nocList2) != 2): + self.logger.error("Got back invalid nocList") + return False + + data1 = await self.devCtrl.ReadAttribute(nodeid, [(Clusters.OperationalCredentials.Attributes.CurrentFabricIndex)], fabricFiltered=False) + data2 = await devCtrl2.ReadAttribute(nodeid, [(Clusters.OperationalCredentials.Attributes.CurrentFabricIndex)], fabricFiltered=False) + + # Read out current fabric from each fabric, and both should be different. + currentFabric1 = data1[0][Clusters.OperationalCredentials][Clusters.OperationalCredentials.Attributes.CurrentFabricIndex] + currentFabric2 = data2[0][Clusters.OperationalCredentials][Clusters.OperationalCredentials.Attributes.CurrentFabricIndex] + if (currentFabric1 == currentFabric2): + self.logger.error( + "Got back fabric indices that match for two different fabrics!") + return False + + devCtrl2.Shutdown() + fabricAdmin2.Shutdown() + + return True + def TestCloseSession(self, nodeid: int): self.logger.info(f"Closing sessions with device {nodeid}") try: diff --git a/src/controller/python/test/test_scripts/mobile-device-test.py b/src/controller/python/test/test_scripts/mobile-device-test.py index a2d290336d1633..f30f2a2f12a52d 100755 --- a/src/controller/python/test/test_scripts/mobile-device-test.py +++ b/src/controller/python/test/test_scripts/mobile-device-test.py @@ -80,8 +80,8 @@ def main(): FailIfNot(test.TestDiscovery(discriminator=TEST_DISCRIMINATOR), "Failed to discover any devices.") - FailIfNot(test.SetNetworkCommissioningParameters(dataset=TEST_THREAD_NETWORK_DATASET_TLV), - "Failed to finish network commissioning") + # FailIfNot(test.SetNetworkCommissioningParameters(dataset=TEST_THREAD_NETWORK_DATASET_TLV), + # "Failed to finish network commissioning") logger.info("Testing key exchange") FailIfNot(test.TestKeyExchange(ip=options.deviceAddress, @@ -89,6 +89,10 @@ def main(): nodeid=1), "Failed to finish key exchange") + asyncio.run(test.TestMultiFabric(ip=options.deviceAddress, + setuppin=20202021, + nodeid=1)) + logger.info("Testing closing sessions") FailIfNot(test.TestCloseSession(nodeid=1), "Failed to close sessions") @@ -147,9 +151,6 @@ def main(): endpoint=LIGHTING_ENDPOINT_ID, group=GROUP_ID), "Failed to test on off cluster") - logger.info("Testing non-controller APIs") - FailIfNot(test.TestNonControllerAPIs(), "Non controller API test failed") - timeoutTicker.stop() logger.info("Test finished")