diff --git a/.github/actions/bootstrap-cache/action.yaml b/.github/actions/bootstrap-cache/action.yaml index 9a883ecf22da79..f5ed24ba3f06e7 100644 --- a/.github/actions/bootstrap-cache/action.yaml +++ b/.github/actions/bootstrap-cache/action.yaml @@ -11,7 +11,7 @@ runs: attempt_limit: 3 attempt_delay: 2000 with: | - key: ${{ runner.os }}-env-${{ hashFiles('scripts/setup/*', 'third_party/pigweed/**') }} + key: ${{ runner.os }}-env-${{ hashFiles('scripts/setup/*', 'third_party/pigweed/**', '/etc/lsb-release') }} path: | .environment build_overrides/pigweed_environment.gni diff --git a/.github/workflows/bloat_check.yaml b/.github/workflows/bloat_check.yaml index a1b93c882bf64f..d9a2a506724188 100644 --- a/.github/workflows/bloat_check.yaml +++ b/.github/workflows/bloat_check.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 steps: - name: Checkout diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4297e791326786..5d8198013ed37b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -42,7 +42,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -456,7 +456,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/chef.yaml b/.github/workflows/chef.yaml index b3d3f7f3a90f7c..5d0a6130b686ae 100644 --- a/.github/workflows/chef.yaml +++ b/.github/workflows/chef.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 options: --user root steps: diff --git a/.github/workflows/examples-linux-standalone.yaml b/.github/workflows/examples-linux-standalone.yaml index 53728d33eac42a..0307eedc057bfd 100644 --- a/.github/workflows/examples-linux-standalone.yaml +++ b/.github/workflows/examples-linux-standalone.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-linux-tv-casting-app.yaml b/.github/workflows/examples-linux-tv-casting-app.yaml index 2797712bffa816..744c40b2654421 100644 --- a/.github/workflows/examples-linux-tv-casting-app.yaml +++ b/.github/workflows/examples-linux-tv-casting-app.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 steps: - name: Checkout diff --git a/.github/workflows/examples-mw320.yaml b/.github/workflows/examples-mw320.yaml index 780543a70d1f11..4b07c513db5d24 100644 --- a/.github/workflows/examples-mw320.yaml +++ b/.github/workflows/examples-mw320.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index 07ab55d1315bb5..61b7e8ab13f60e 100644 --- a/.github/workflows/examples-nxp.yaml +++ b/.github/workflows/examples-nxp.yaml @@ -96,3 +96,30 @@ jobs: if: ${{ !env.ACT }} with: platform-name: K32W + + zephyr: + name: ZEPHYR_RW61X + + runs-on: ubuntu-latest + if: github.actor != 'restyled-io[bot]' + + container: + image: ghcr.io/project-chip/chip-build-nxp-zephyr:64 + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Checkout submodules & Bootstrap + uses: ./.github/actions/checkout-submodules-and-bootstrap + with: + platform: nxp + + - name: Build RW61x Zephyr examples + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-rw61x-zephyr-all-clusters \ + --target nxp-rw61x-zephyr-thermostat \ + --target nxp-rw61x-zephyr-laundry-washer-factory \ + build \ + " diff --git a/.github/workflows/examples-qpg.yaml b/.github/workflows/examples-qpg.yaml index 2bb85ad4acbfac..e015d3db3f5d08 100644 --- a/.github/workflows/examples-qpg.yaml +++ b/.github/workflows/examples-qpg.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-stm32.yaml b/.github/workflows/examples-stm32.yaml index 809861cdee179e..47435add440808 100644 --- a/.github/workflows/examples-stm32.yaml +++ b/.github/workflows/examples-stm32.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/fuzzing-build.yaml b/.github/workflows/fuzzing-build.yaml index 30b697c5f1f6ce..17be73a9346d39 100644 --- a/.github/workflows/fuzzing-build.yaml +++ b/.github/workflows/fuzzing-build.yaml @@ -33,7 +33,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c76ddc512b1531..19cf8e8bd910b0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 steps: - name: Checkout diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index aed711e9906d68..bb8c8b03364715 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -445,7 +445,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" diff --git a/.github/workflows/unit_integration_test.yaml b/.github/workflows/unit_integration_test.yaml index c1d3bebddde5ae..59e2dafc30cd63 100644 --- a/.github/workflows/unit_integration_test.yaml +++ b/.github/workflows/unit_integration_test.yaml @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/zap_regeneration.yaml b/.github/workflows/zap_regeneration.yaml index 81ffbcbb3b057a..356c8922b9419e 100644 --- a/.github/workflows/zap_regeneration.yaml +++ b/.github/workflows/zap_regeneration.yaml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 defaults: run: shell: sh diff --git a/.github/workflows/zap_templates.yaml b/.github/workflows/zap_templates.yaml index 987cc82a2e3f06..2e9d5e82f1df90 100644 --- a/.github/workflows/zap_templates.yaml +++ b/.github/workflows/zap_templates.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: ghcr.io/project-chip/chip-build:54 + image: ghcr.io/project-chip/chip-build:65 defaults: run: shell: sh diff --git a/.vscode/settings.json b/.vscode/settings.json index d38758524ac8a5..397e6230087325 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -133,7 +133,8 @@ "random": "cpp", "thread": "cpp", "variant": "cpp", - "any": "cpp" + "any": "cpp", + "future": "cpp" }, // Configure paths or glob patterns to exclude from file watching. "files.watcherExclude": { diff --git a/docs/zap_clusters.md b/docs/zap_clusters.md index dc439fa2f37607..ac9c8f04e7f86f 100644 --- a/docs/zap_clusters.md +++ b/docs/zap_clusters.md @@ -87,6 +87,7 @@ Generally regenerate using one of: | 155 | 0x9B | EnergyPreference | | 156 | 0x9C | PowerTopology | | 157 | 0x9D | EnergyEvseMode | +| 158 | 0x9E | WaterHeaterMode | | 159 | 0x9F | DeviceEnergyManagementMode | | 257 | 0x101 | DoorLock | | 258 | 0x102 | WindowCovering | diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index b3ae5b1f385a74..3ed93a0190c273 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -9265,6 +9265,48 @@ endpoint 2 { ram attribute clusterRevision default = 4; } } +endpoint 3 { + device type ma_genericswitch = 15, version 3; + + + server cluster Identify { + ram attribute identifyTime default = 0x0000; + ram attribute identifyType default = 0x00; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute tagList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster Switch { + emits event InitialPress; + emits event LongPress; + emits event LongRelease; + emits event MultiPressComplete; + ram attribute numberOfPositions default = 2; + ram attribute currentPosition default = 0; + ram attribute multiPressMax default = 3; + ram attribute featureMap default = 58; + ram attribute clusterRevision default = 2; + } +} endpoint 65534 { device type ma_secondary_network_interface = 25, version 1; diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index c547030731c6cf..4dd86543613c40 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl-with-test-extensions.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data with some extensions" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl-with-test-extensions.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data with some extensions" } ], "endpointTypes": [ @@ -21900,6 +21900,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "StringEchoResponse", + "code": 13, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, { "name": "TestEnumsRequest", "code": 14, @@ -21973,32 +21981,24 @@ "isEnabled": 1 }, { - "name": "TestDifferentVendorMeiRequest", - "code": 4294049962, + "name": "StringEchoRequest", + "code": 24, "mfgCode": null, "source": "client", "isIncoming": 1, "isEnabled": 1 }, { - "name": "TestDifferentVendorMeiResponse", - "code": 4294049979, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "StringEchoRequest", - "code": 24, + "name": "TestDifferentVendorMeiRequest", + "code": 4294049962, "mfgCode": null, "source": "client", "isIncoming": 1, "isEnabled": 1 }, { - "name": "StringEchoResponse", - "code": 13, + "name": "TestDifferentVendorMeiResponse", + "code": 4294049979, "mfgCode": null, "source": "server", "isIncoming": 0, @@ -24783,6 +24783,465 @@ }, { "id": 4, + "name": "MA-genericswitch", + "deviceTypeRef": { + "code": 15, + "profileId": 259, + "label": "MA-genericswitch", + "name": "MA-genericswitch" + }, + "deviceTypes": [ + { + "code": 15, + "profileId": 259, + "label": "MA-genericswitch", + "name": "MA-genericswitch" + } + ], + "deviceVersions": [ + 3 + ], + "deviceIdentifiers": [ + 15 + ], + "deviceTypeName": "MA-genericswitch", + "deviceTypeCode": 15, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TagList", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Switch", + "code": 59, + "mfgCode": null, + "define": "SWITCH_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "NumberOfPositions", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentPosition", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MultiPressMax", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "58", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "InitialPress", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "LongPress", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "LongRelease", + "code": 4, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "MultiPressComplete", + "code": 6, + "mfgCode": null, + "side": "server", + "included": 12 + } + ] + } + ] + }, + { + "id": 5, "name": "Anonymous Endpoint Type", "deviceTypeRef": { "code": 25, @@ -25315,9 +25774,17 @@ "parentEndpointIdentifier": null }, { - "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeName": "MA-genericswitch", "endpointTypeIndex": 3, "profileId": 259, + "endpointId": 3, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 4, + "profileId": 259, "endpointId": 65534, "networkId": 0, "parentEndpointIdentifier": null diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap index 090dda6a70e2e5..a5e9bdd3164ee2 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.zap @@ -17,13 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "category": "matter", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", @@ -31,6 +24,13 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" } ], "endpointTypes": [ @@ -910,7 +910,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.zap b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.zap index d72b6d11800223..78aa987f1d8fa6 100644 --- a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.zap +++ b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.zap @@ -17,13 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "category": "matter", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", @@ -31,6 +24,13 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" } ], "endpointTypes": [ diff --git a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.zap b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.zap index 127d31dc60551f..535aa424e1d2a7 100644 --- a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.zap +++ b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.zap @@ -2997,7 +2997,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3013,7 +3013,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3029,7 +3029,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3045,7 +3045,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3061,7 +3061,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_pump_5f904818cc.zap b/examples/chef/devices/rootnode_pump_5f904818cc.zap index ca8e1ad91d30fc..f28d7cfbab317e 100644 --- a/examples/chef/devices/rootnode_pump_5f904818cc.zap +++ b/examples/chef/devices/rootnode_pump_5f904818cc.zap @@ -579,7 +579,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_pump_a811bb33a0.zap b/examples/chef/devices/rootnode_pump_a811bb33a0.zap index ad107294293b67..6314e3fb0c2e3a 100644 --- a/examples/chef/devices/rootnode_pump_a811bb33a0.zap +++ b/examples/chef/devices/rootnode_pump_a811bb33a0.zap @@ -579,7 +579,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.zap b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.zap index 6833a1a52bb222..a784ab5723b85f 100644 --- a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.zap +++ b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.zap @@ -17,13 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "category": "matter", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap index 7cba96b7f511d6..64c948a5c8c233 100644 --- a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap @@ -563,7 +563,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap index 3caa58a4d7f042..0b05af158f1bde 100644 --- a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap @@ -563,7 +563,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.zap b/examples/energy-management-app/energy-management-common/energy-management-app.zap index 597247dbc6998c..dc4b11c14c6742 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.zap +++ b/examples/energy-management-app/energy-management-common/energy-management-app.zap @@ -627,7 +627,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/light-switch-app/qpg/zap/switch.zap b/examples/light-switch-app/qpg/zap/switch.zap index 0f65ac5eb64615..362ef409bebaa6 100644 --- a/examples/light-switch-app/qpg/zap/switch.zap +++ b/examples/light-switch-app/qpg/zap/switch.zap @@ -17,13 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "category": "matter", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../../src/app/zap-templates/zcl/zcl.json", @@ -31,6 +24,13 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" } ], "endpointTypes": [ diff --git a/examples/lighting-app/lighting-common/lighting-app.zap b/examples/lighting-app/lighting-common/lighting-app.zap index 69ee10fe7794f0..6489a395b38c7e 100644 --- a/examples/lighting-app/lighting-common/lighting-app.zap +++ b/examples/lighting-app/lighting-common/lighting-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.zap b/examples/lighting-app/nxp/zap/lighting-on-off.zap index beccb5480ca340..839971a84dec9e 100644 --- a/examples/lighting-app/nxp/zap/lighting-on-off.zap +++ b/examples/lighting-app/nxp/zap/lighting-on-off.zap @@ -499,7 +499,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap index ba855b3908feae..65236d3c49498e 100644 --- a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap +++ b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ @@ -712,7 +712,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/lock-app/nxp/zap/lock-app.zap b/examples/lock-app/nxp/zap/lock-app.zap index ff1ead7297c757..70442ac916c7fe 100644 --- a/examples/lock-app/nxp/zap/lock-app.zap +++ b/examples/lock-app/nxp/zap/lock-app.zap @@ -499,7 +499,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.zap b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.zap index 03113285ad2567..1df2afdd38fc8a 100644 --- a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.zap +++ b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ diff --git a/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap b/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap index c98b9e661328e5..b019c91de5ef04 100644 --- a/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap +++ b/examples/ota-provider-app/ota-provider-common/ota-provider-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap index 75b4eb0a223b9e..ce4e60fe260d25 100644 --- a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ diff --git a/examples/pump-app/pump-common/pump-app.zap b/examples/pump-app/pump-common/pump-app.zap index c456f068835755..cb87c13835d08c 100644 --- a/examples/pump-app/pump-common/pump-app.zap +++ b/examples/pump-app/pump-common/pump-app.zap @@ -675,7 +675,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/pump-app/silabs/data_model/pump-thread-app.zap b/examples/pump-app/silabs/data_model/pump-thread-app.zap index c338b8de8155af..358703c49600cf 100644 --- a/examples/pump-app/silabs/data_model/pump-thread-app.zap +++ b/examples/pump-app/silabs/data_model/pump-thread-app.zap @@ -675,7 +675,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/pump-app/silabs/data_model/pump-wifi-app.zap b/examples/pump-app/silabs/data_model/pump-wifi-app.zap index c338b8de8155af..358703c49600cf 100644 --- a/examples/pump-app/silabs/data_model/pump-wifi-app.zap +++ b/examples/pump-app/silabs/data_model/pump-wifi-app.zap @@ -675,7 +675,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap b/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap index 168ddcd01592a5..040218e9083e23 100644 --- a/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap +++ b/examples/pump-controller-app/pump-controller-common/pump-controller-app.zap @@ -675,7 +675,7 @@ "storageOption": "External", "singleton": 1, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/thermostat/nxp/zap/thermostat_matter_thread.zap b/examples/thermostat/nxp/zap/thermostat_matter_thread.zap index 489e9e00ab44bf..8824bce22564b9 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_thread.zap +++ b/examples/thermostat/nxp/zap/thermostat_matter_thread.zap @@ -17,13 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "category": "matter", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../../src/app/zap-templates/zcl/zcl.json", @@ -31,6 +24,13 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" } ], "endpointTypes": [ diff --git a/examples/window-app/common/window-app.zap b/examples/window-app/common/window-app.zap index 5f689678cb9415..87d2ce831e4647 100644 --- a/examples/window-app/common/window-app.zap +++ b/examples/window-app/common/window-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ diff --git a/integrations/docker/images/chip-cert-bins/Dockerfile b/integrations/docker/images/chip-cert-bins/Dockerfile index 5fe42c49dba935..60b0e00863d403 100644 --- a/integrations/docker/images/chip-cert-bins/Dockerfile +++ b/integrations/docker/images/chip-cert-bins/Dockerfile @@ -1,6 +1,6 @@ # Stage 1: Setup dependencies (based on chip-build). -FROM ubuntu:24.04 as chip-build-cert -LABEL org.opencontainers.image.source https://github.com/project-chip/connectedhomeip +FROM ubuntu:24.04 AS chip-build-cert +LABEL org.opencontainers.image.source=https://github.com/project-chip/connectedhomeip ARG TARGETPLATFORM # COMMITHASH defines the target commit to build from. May be passed in using --build-arg. ARG COMMITHASH=c1ec2d777456924dcaa59b53351b00d73caf378f @@ -123,11 +123,11 @@ RUN set -x \ software-properties-common \ && add-apt-repository universe \ && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \ - && python3 get-pip.py \ + && python3 get-pip.py --break-system-packages \ && : # last line RUN set -x \ - && pip3 install attrs coloredlogs PyGithub pygit future portpicker mobly click cxxfilt ghapi pandas tabulate \ + && pip3 install attrs coloredlogs PyGithub pygit future portpicker mobly click cxxfilt ghapi pandas tabulate --break-system-packages \ && : # last line # build and install gn @@ -162,7 +162,7 @@ RUN ./scripts/checkout_submodules.py --allow-changing-global-git-config --shallo RUN bash scripts/bootstrap.sh # Stage 2: Build. -FROM chip-build-cert as chip-build-cert-bins +FROM chip-build-cert AS chip-build-cert-bins SHELL ["/bin/bash", "-c"] @@ -260,7 +260,7 @@ RUN case ${TARGETPLATFORM} in \ RUN source scripts/activate.sh && scripts/build_python.sh -m platform -d true -i out/python_env # Stage 3: Copy relevant cert bins to a minimal image to reduce size. -FROM ubuntu:22.04 +FROM ubuntu:24.04 ENV TZ=Etc/UTC RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN apt-get update -y diff --git a/scripts/rules.matterlint b/scripts/rules.matterlint index eff738deb58d8e..b4af613c584c29 100644 --- a/scripts/rules.matterlint +++ b/scripts/rules.matterlint @@ -102,6 +102,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/user-label-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/window-covering.xml"; diff --git a/scripts/setup/requirements.build.txt b/scripts/setup/requirements.build.txt index 82fe4cc08cea50..c9e8bad323bd85 100644 --- a/scripts/setup/requirements.build.txt +++ b/scripts/setup/requirements.build.txt @@ -1,8 +1,9 @@ # Minimal requirements for building stand-alone CHIP applications. # # The list of Python packages required to perform a minimal CHIP -# application build should be kept as small as possible. Ideally, -# core build scripts should depend only on the standard library. +# application build should be kept as small as possible. + +# Ideally, core build scripts should depend only on the standard library. # scripts/build click diff --git a/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp b/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp index 83a0b04281b1ad..a7b3eaed75fd7d 100644 --- a/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp +++ b/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp @@ -91,8 +91,8 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback( auto & iterations = commandData.iterations; auto & salt = commandData.salt; - Optional status = Optional::Missing(); - InteractionModel::Status globalStatus = InteractionModel::Status::Success; + Optional status = Optional::Missing(); + Status globalStatus = Status::Success; Spake2pVerifier verifier; ChipLogProgress(Zcl, "Received command to open commissioning window"); @@ -110,11 +110,9 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback( VerifyOrExit(iterations <= kSpake2p_Max_PBKDF_Iterations, status.Emplace(StatusCode::kPAKEParameterError)); VerifyOrExit(salt.size() >= kSpake2p_Min_PBKDF_Salt_Length, status.Emplace(StatusCode::kPAKEParameterError)); VerifyOrExit(salt.size() <= kSpake2p_Max_PBKDF_Salt_Length, status.Emplace(StatusCode::kPAKEParameterError)); - VerifyOrExit(commissioningTimeout <= commissionMgr.MaxCommissioningTimeout(), - globalStatus = InteractionModel::Status::InvalidCommand); - VerifyOrExit(commissioningTimeout >= commissionMgr.MinCommissioningTimeout(), - globalStatus = InteractionModel::Status::InvalidCommand); - VerifyOrExit(discriminator <= kMaxDiscriminatorValue, globalStatus = InteractionModel::Status::InvalidCommand); + VerifyOrExit(commissioningTimeout <= commissionMgr.MaxCommissioningTimeout(), globalStatus = Status::InvalidCommand); + VerifyOrExit(commissioningTimeout >= commissionMgr.MinCommissioningTimeout(), globalStatus = Status::InvalidCommand); + VerifyOrExit(discriminator <= kMaxDiscriminatorValue, globalStatus = Status::InvalidCommand); VerifyOrExit(verifier.Deserialize(pakeVerifier) == CHIP_NO_ERROR, status.Emplace(StatusCode::kPAKEParameterError)); VerifyOrExit(commissionMgr.OpenEnhancedCommissioningWindow(commissioningTimeout, discriminator, verifier, iterations, salt, @@ -130,7 +128,7 @@ bool emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback( } else { - if (globalStatus != InteractionModel::Status::Success) + if (globalStatus != Status::Success) { ChipLogError(Zcl, "Failed to open commissioning window. Global status " ChipLogFormatIMStatus, ChipLogValueIMStatus(globalStatus)); @@ -147,8 +145,8 @@ bool emberAfAdministratorCommissioningClusterOpenBasicCommissioningWindowCallbac MATTER_TRACE_SCOPE("OpenBasicCommissioningWindow", "AdministratorCommissioning"); auto commissioningTimeout = System::Clock::Seconds16(commandData.commissioningTimeout); - Optional status = Optional::Missing(); - InteractionModel::Status globalStatus = InteractionModel::Status::Success; + Optional status = Optional::Missing(); + Status globalStatus = Status::Success; ChipLogProgress(Zcl, "Received command to open basic commissioning window"); FabricIndex fabricIndex = commandObj->GetAccessingFabricIndex(); @@ -160,10 +158,8 @@ bool emberAfAdministratorCommissioningClusterOpenBasicCommissioningWindowCallbac VerifyOrExit(!commissionMgr.IsCommissioningWindowOpen(), status.Emplace(StatusCode::kBusy)); VerifyOrExit(failSafeContext.IsFailSafeFullyDisarmed(), status.Emplace(StatusCode::kBusy)); - VerifyOrExit(commissioningTimeout <= commissionMgr.MaxCommissioningTimeout(), - globalStatus = InteractionModel::Status::InvalidCommand); - VerifyOrExit(commissioningTimeout >= commissionMgr.MinCommissioningTimeout(), - globalStatus = InteractionModel::Status::InvalidCommand); + VerifyOrExit(commissioningTimeout <= commissionMgr.MaxCommissioningTimeout(), globalStatus = Status::InvalidCommand); + VerifyOrExit(commissioningTimeout >= commissionMgr.MinCommissioningTimeout(), globalStatus = Status::InvalidCommand); VerifyOrExit(commissionMgr.OpenBasicCommissioningWindowForAdministratorCommissioningCluster( commissioningTimeout, fabricIndex, fabricInfo->GetVendorId()) == CHIP_NO_ERROR, status.Emplace(StatusCode::kPAKEParameterError)); @@ -177,7 +173,7 @@ bool emberAfAdministratorCommissioningClusterOpenBasicCommissioningWindowCallbac } else { - if (globalStatus != InteractionModel::Status::Success) + if (globalStatus != Status::Success) { ChipLogError(Zcl, "Failed to open commissioning window. Global status " ChipLogFormatIMStatus, ChipLogValueIMStatus(globalStatus)); diff --git a/src/app/clusters/icd-management-server/icd-management-server.cpp b/src/app/clusters/icd-management-server/icd-management-server.cpp index e4ead150a1fd79..55f6b5129c0a41 100644 --- a/src/app/clusters/icd-management-server/icd-management-server.cpp +++ b/src/app/clusters/icd-management-server/icd-management-server.cpp @@ -259,10 +259,10 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co bool isClientAdmin = false; // Check if ClientType is valid - VerifyOrReturnError(clientType != ClientTypeEnum::kUnknownEnumValue, InteractionModel::Status::ConstraintError); + VerifyOrReturnError(clientType != ClientTypeEnum::kUnknownEnumValue, Status::ConstraintError); // Check if client is admin - VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), Status::Failure); bool isFirstEntryForFabric = false; ICDMonitoringTable table(*mStorage, fabricIndex, mICDConfigurationData->GetClientsSupportedPerFabric(), mSymmetricKeystore); @@ -275,14 +275,14 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co // Existing entry: Validate Key if, and only if, the ISD does NOT have administrator permissions if (!isClientAdmin) { - VerifyOrReturnError(verificationKey.HasValue(), InteractionModel::Status::Failure); - VerifyOrReturnError(entry.IsKeyEquivalent(verificationKey.Value()), InteractionModel::Status::Failure); + VerifyOrReturnError(verificationKey.HasValue(), Status::Failure); + VerifyOrReturnError(entry.IsKeyEquivalent(verificationKey.Value()), Status::Failure); } } else if (CHIP_ERROR_NOT_FOUND == err) { // New entry - VerifyOrReturnError(entry.index < table.Limit(), InteractionModel::Status::ResourceExhausted); + VerifyOrReturnError(entry.index < table.Limit(), Status::ResourceExhausted); // Check if it's going to be the first entry for fabric isFirstEntryForFabric = table.IsEmpty(); @@ -290,7 +290,7 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co else { // Error - return InteractionModel::Status::Failure; + return Status::Failure; } // Save @@ -304,8 +304,8 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co } err = entry.SetKey(key); - VerifyOrReturnError(CHIP_ERROR_INVALID_ARGUMENT != err, InteractionModel::Status::ConstraintError); - VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_ERROR_INVALID_ARGUMENT != err, Status::ConstraintError); + VerifyOrReturnError(CHIP_NO_ERROR == err, Status::Failure); err = table.Set(entry.index, entry); // Delete key upon failure to prevent key storage leakage. @@ -314,8 +314,8 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co entry.DeleteKey(); } - VerifyOrReturnError(CHIP_ERROR_INVALID_ARGUMENT != err, InteractionModel::Status::ConstraintError); - VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_ERROR_INVALID_ARGUMENT != err, Status::ConstraintError); + VerifyOrReturnError(CHIP_NO_ERROR == err, Status::Failure); if (isFirstEntryForFabric) { @@ -324,7 +324,7 @@ Status ICDManagementServer::RegisterClient(CommandHandler * commandObj, const Co } icdCounter = mICDConfigurationData->GetICDCounter().GetValue(); - return InteractionModel::Status::Success; + return Status::Success; } Status ICDManagementServer::UnregisterClient(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, @@ -336,32 +336,32 @@ Status ICDManagementServer::UnregisterClient(CommandHandler * commandObj, const bool isClientAdmin = false; // Check if client is admin - VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_NO_ERROR == CheckAdmin(commandObj, commandPath, isClientAdmin), Status::Failure); ICDMonitoringTable table(*mStorage, fabricIndex, mICDConfigurationData->GetClientsSupportedPerFabric(), mSymmetricKeystore); // Get current entry, if exists ICDMonitoringEntry entry(mSymmetricKeystore); CHIP_ERROR err = table.Find(nodeId, entry); - VerifyOrReturnError(CHIP_ERROR_NOT_FOUND != err, InteractionModel::Status::NotFound); - VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_ERROR_NOT_FOUND != err, Status::NotFound); + VerifyOrReturnError(CHIP_NO_ERROR == err, Status::Failure); // Existing entry: Validate Key if, and only if, the ISD has NOT administrator permissions if (!isClientAdmin) { - VerifyOrReturnError(verificationKey.HasValue(), InteractionModel::Status::Failure); - VerifyOrReturnError(entry.IsKeyEquivalent(verificationKey.Value()), InteractionModel::Status::Failure); + VerifyOrReturnError(verificationKey.HasValue(), Status::Failure); + VerifyOrReturnError(entry.IsKeyEquivalent(verificationKey.Value()), Status::Failure); } err = table.Remove(entry.index); - VerifyOrReturnError(CHIP_NO_ERROR == err, InteractionModel::Status::Failure); + VerifyOrReturnError(CHIP_NO_ERROR == err, Status::Failure); if (table.IsEmpty()) { TriggerICDMTableUpdatedEvent(); } - return InteractionModel::Status::Success; + return Status::Success; } void ICDManagementServer::TriggerICDMTableUpdatedEvent() @@ -396,9 +396,9 @@ bool emberAfIcdManagementClusterRegisterClientCallback(CommandHandler * commandO uint32_t icdCounter = 0; ICDManagementServer server; - InteractionModel::Status status = server.RegisterClient(commandObj, commandPath, commandData, icdCounter); + Status status = server.RegisterClient(commandObj, commandPath, commandData, icdCounter); - if (InteractionModel::Status::Success == status) + if (Status::Success == status) { // Response IcdManagement::Commands::RegisterClientResponse::Type response{ .ICDCounter = icdCounter }; @@ -419,7 +419,7 @@ bool emberAfIcdManagementClusterUnregisterClientCallback(CommandHandler * comman const Commands::UnregisterClient::DecodableType & commandData) { ICDManagementServer server; - InteractionModel::Status status = server.UnregisterClient(commandObj, commandPath, commandData); + Status status = server.UnregisterClient(commandObj, commandPath, commandData); commandObj->AddStatus(commandPath, status); return true; diff --git a/src/app/tests/TestCommandInteraction.cpp b/src/app/tests/TestCommandInteraction.cpp index 6212d696c85c45..34f59edd245ff6 100644 --- a/src/app/tests/TestCommandInteraction.cpp +++ b/src/app/tests/TestCommandInteraction.cpp @@ -165,27 +165,25 @@ struct BadFields } }; -InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aRequestCommandPath) +Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aRequestCommandPath) { // Mock cluster catalog, only support commands on one cluster on one endpoint. - using InteractionModel::Status; - if (aRequestCommandPath.mEndpointId != kTestEndpointId) { - return Status::UnsupportedEndpoint; + return Protocols::InteractionModel::Status::UnsupportedEndpoint; } if (aRequestCommandPath.mClusterId != kTestClusterId) { - return Status::UnsupportedCluster; + return Protocols::InteractionModel::Status::UnsupportedCluster; } if (aRequestCommandPath.mCommandId == kTestNonExistCommandId) { - return Status::UnsupportedCommand; + return Protocols::InteractionModel::Status::UnsupportedCommand; } - return Status::Success; + return Protocols::InteractionModel::Status::Success; } void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath, chip::TLV::TLVReader & aReader, @@ -346,7 +344,7 @@ class MockCommandHandlerCallback : public CommandHandlerImpl::Callback { DispatchSingleClusterCommand(aCommandPath, apPayload, &apCommandObj); } - InteractionModel::Status CommandExists(const ConcreteCommandPath & aCommandPath) + Protocols::InteractionModel::Status CommandExists(const ConcreteCommandPath & aCommandPath) { return ServerClusterCommandExists(aCommandPath); } @@ -1255,7 +1253,8 @@ TEST_F(TestCommandInteraction, TestCommandHandler_WithOnInvokeReceivedNotExistCo mockCommandHandlerDelegate.ResetCounter(); MockCommandResponder mockCommandResponder; - InteractionModel::Status status = commandHandler.OnInvokeCommandRequest(mockCommandResponder, std::move(commandDatabuf), false); + Protocols::InteractionModel::Status status = + commandHandler.OnInvokeCommandRequest(mockCommandResponder, std::move(commandDatabuf), false); EXPECT_EQ(status, Protocols::InteractionModel::Status::InvalidAction); EXPECT_TRUE(mockCommandResponder.mChunks.IsNull()); @@ -1650,8 +1649,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_RejectsMultipleCo mockCommandHandlerDelegate.ResetCounter(); commandDispatchedCount = 0; - InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false); - EXPECT_EQ(status, InteractionModel::Status::InvalidAction); + Protocols::InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false); + EXPECT_EQ(status, Protocols::InteractionModel::Status::InvalidAction); EXPECT_EQ(commandDispatchedCount, 0u); } @@ -1703,8 +1702,9 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_RejectMultipleCom CommandHandlerImpl commandHandler(&mockCommandHandlerDelegate); MockCommandResponder mockCommandResponder; - InteractionModel::Status status = commandHandler.OnInvokeCommandRequest(mockCommandResponder, std::move(commandDatabuf), false); - EXPECT_EQ(status, InteractionModel::Status::InvalidAction); + Protocols::InteractionModel::Status status = + commandHandler.OnInvokeCommandRequest(mockCommandResponder, std::move(commandDatabuf), false); + EXPECT_EQ(status, Protocols::InteractionModel::Status::InvalidAction); EXPECT_TRUE(mockCommandResponder.mChunks.IsNull()); EXPECT_EQ(commandDispatchedCount, 0u); @@ -1759,8 +1759,8 @@ TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_AcceptMultipleCom mockCommandHandlerDelegate.ResetCounter(); commandDispatchedCount = 0; - InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false); - EXPECT_EQ(status, InteractionModel::Status::Success); + Protocols::InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false); + EXPECT_EQ(status, Protocols::InteractionModel::Status::Success); EXPECT_EQ(commandDispatchedCount, 2u); } diff --git a/src/app/tests/suites/TestDescriptorCluster.yaml b/src/app/tests/suites/TestDescriptorCluster.yaml index b6b2cbc73e9f42..21a43fbe3c1cd0 100644 --- a/src/app/tests/suites/TestDescriptorCluster.yaml +++ b/src/app/tests/suites/TestDescriptorCluster.yaml @@ -82,7 +82,7 @@ tests: command: "readAttribute" attribute: "PartsList" response: - value: [1, 2] + value: [1, 2, 3] - label: "Read attribute ClusterRevision" command: "readAttribute" diff --git a/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp b/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp index 04e658f18cc188..a3f9f3ff6de892 100644 --- a/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp +++ b/src/app/tests/suites/commands/interaction_model/InteractionModel.cpp @@ -19,7 +19,20 @@ #include "InteractionModel.h" using namespace chip; -using namespace chip::app; + +using chip::app::AttributePathParams; +using chip::app::CommandSender; +using chip::app::ConcreteAttributePath; +using chip::app::ConcreteCommandPath; +using chip::app::ConcreteDataAttributePath; +using chip::app::DataVersionFilter; +using chip::app::EventHeader; +using chip::app::EventPathParams; +using chip::app::InteractionModelEngine; +using chip::app::ReadClient; +using chip::app::ReadPrepareParams; +using chip::app::StatusIB; +using chip::app::WriteClient; namespace chip { namespace test_utils { diff --git a/src/app/zap-templates/zcl/data-model/all.xml b/src/app/zap-templates/zcl/data-model/all.xml index 61d39b3b0173ea..6003a7cf4a3f1a 100644 --- a/src/app/zap-templates/zcl/data-model/all.xml +++ b/src/app/zap-templates/zcl/data-model/all.xml @@ -109,7 +109,8 @@ - + + diff --git a/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml index 111df8eca07eff..b8e81233473932 100644 --- a/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/mode-base-cluster.xml @@ -32,6 +32,7 @@ This is because zap does not currently support generating code for clusters that + @@ -47,6 +48,7 @@ This is because zap does not currently support generating code for clusters that + diff --git a/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml new file mode 100644 index 00000000000000..23a1b2eec5d4c0 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + General + Water Heater Mode + 0x009E + WATER_HEATER_MODE_CLUSTER + true + true + Attributes and commands for selecting a mode from a list of supported options. + + + + + + + + + + SupportedModes + CurrentMode + StartUpMode + OnMode + + + + + This command is used to change device modes. + On receipt of this command the device SHALL respond with a ChangeToModeResponse command. + + + + + + + This command is sent by the device on receipt of the ChangeToModeWithStatus command. + + + + + + diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index c6b39c837a1e00..3b11954f1582b0 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -131,6 +131,7 @@ "wake-on-lan-cluster.xml", "washer-controls-cluster.xml", "water-heater-management-cluster.xml", + "water-heater-mode-cluster.xml", "wifi-network-diagnostics-cluster.xml", "wifi-network-management-cluster.xml", "window-covering.xml", @@ -643,6 +644,7 @@ "Power Topology": ["FeatureMap"], "Valve Configuration and Control": ["RemainingDuration"], "Boolean State Configuration": ["CurrentSensitivityLevel"], + "Water Heater Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Wi-Fi Network Management": ["SSID"] }, "defaultReportingPolicy": "mandatory", diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index 18afa7eacc2f8a..b03da7bc7b1e67 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -129,6 +129,7 @@ "wake-on-lan-cluster.xml", "washer-controls-cluster.xml", "water-heater-management-cluster.xml", + "water-heater-mode-cluster.xml", "wifi-network-diagnostics-cluster.xml", "wifi-network-management-cluster.xml", "window-covering.xml", @@ -641,6 +642,7 @@ "Power Topology": ["FeatureMap"], "Valve Configuration and Control": ["RemainingDuration"], "Boolean State Configuration": ["CurrentSensitivityLevel"], + "Water Heater Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Wi-Fi Network Management": ["SSID"] }, "defaultReportingPolicy": "mandatory", diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 917e1a0584afe9..c6d29bc6bd3798 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -5172,6 +5172,56 @@ cluster EnergyEvseMode = 157 { command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } +/** Attributes and commands for selecting a mode from a list of supported options. */ +cluster WaterHeaterMode = 158 { + revision 1; + + enum ModeTag : enum16 { + kOff = 16384; + kManual = 16385; + kTimed = 16386; + } + + bitmap Feature : bitmap32 { + kOnOff = 0x1; + } + + struct ModeTagStruct { + optional vendor_id mfgCode = 0; + enum16 value = 1; + } + + struct ModeOptionStruct { + char_string<64> label = 0; + int8u mode = 1; + ModeTagStruct modeTags[] = 2; + } + + readonly attribute ModeOptionStruct supportedModes[] = 0; + readonly attribute int8u currentMode = 1; + attribute optional nullable int8u startUpMode = 2; + attribute optional nullable int8u onMode = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ChangeToModeRequest { + int8u newMode = 0; + } + + response struct ChangeToModeResponse = 1 { + enum8 status = 0; + optional char_string statusText = 1; + } + + /** This command is used to change device modes. + On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; +} + /** Attributes and commands for selecting a mode from a list of supported options. */ provisional cluster DeviceEnergyManagementMode = 159 { revision 1; diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index abba3d15cd18ca..3c95a3320ba91b 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -4754,6 +4754,7 @@ "define": "THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER", "side": "client", "enabled": 1, + "apiMaturity": "provisional", "commands": [ { "name": "GetActiveDatasetRequest", @@ -4771,17 +4772,9 @@ "isIncoming": 0, "isEnabled": 1 }, - { - "name": "SetActiveDatasetRequest", - "code": 4, - "mfgCode": null, - "source": "client", - "isIncoming": 0, - "isEnabled": 1 - }, { "name": "SetPendingDatasetRequest", - "code": 5, + "code": 4, "mfgCode": null, "source": "client", "isIncoming": 0, diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 0e027a3c0c0647..98e208fd3815ee 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -34085,6 +34085,378 @@ public void onSuccess(byte[] tlv) { } } + public static class WaterHeaterModeCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 158L; + + private static final long SUPPORTED_MODES_ATTRIBUTE_ID = 0L; + private static final long CURRENT_MODE_ATTRIBUTE_ID = 1L; + private static final long START_UP_MODE_ATTRIBUTE_ID = 2L; + private static final long ON_MODE_ATTRIBUTE_ID = 3L; + private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; + private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; + private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; + private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L; + private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; + private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; + + public WaterHeaterModeCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); + } + + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } + + public void changeToMode(ChangeToModeResponseCallback callback, Integer newMode) { + changeToMode(callback, newMode, 0); + } + + public void changeToMode(ChangeToModeResponseCallback callback, Integer newMode, int timedInvokeTimeoutMs) { + final long commandId = 0L; + + ArrayList elements = new ArrayList<>(); + final long newModeFieldID = 0L; + BaseTLVType newModetlvValue = new UIntType(newMode); + elements.add(new StructElement(newModeFieldID, newModetlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long statusFieldID = 0L; + Integer status = null; + final long statusTextFieldID = 1L; + Optional statusText = Optional.empty(); + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == statusFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + status = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == statusTextFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + statusText = Optional.of(castingValue.value(String.class)); + } + } + } + callback.onSuccess(status, statusText); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public interface ChangeToModeResponseCallback extends BaseClusterCallback { + void onSuccess(Integer status, Optional statusText); + } + + public interface SupportedModesAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface StartUpModeAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Integer value); + } + + public interface OnModeAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Integer value); + } + + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EventListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AttributeListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public void readSupportedModesAttribute( + SupportedModesAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_MODES_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_MODES_ATTRIBUTE_ID, true); + } + + public void subscribeSupportedModesAttribute( + SupportedModesAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_MODES_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, SUPPORTED_MODES_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readCurrentModeAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_MODE_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_MODE_ATTRIBUTE_ID, true); + } + + public void subscribeCurrentModeAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_MODE_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_MODE_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readStartUpModeAttribute( + StartUpModeAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_MODE_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, START_UP_MODE_ATTRIBUTE_ID, true); + } + + public void writeStartUpModeAttribute(DefaultClusterCallback callback, Integer value) { + writeStartUpModeAttribute(callback, value, 0); + } + + public void writeStartUpModeAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); + writeAttribute(new WriteAttributesCallbackImpl(callback), START_UP_MODE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeStartUpModeAttribute( + StartUpModeAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_MODE_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, START_UP_MODE_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readOnModeAttribute( + OnModeAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ON_MODE_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ON_MODE_ATTRIBUTE_ID, true); + } + + public void writeOnModeAttribute(DefaultClusterCallback callback, Integer value) { + writeOnModeAttribute(callback, value, 0); + } + + public void writeOnModeAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); + writeAttribute(new WriteAttributesCallbackImpl(callback), ON_MODE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeOnModeAttribute( + OnModeAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ON_MODE_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ON_MODE_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEventListAttribute( + EventListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeEventListAttribute( + EventListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAttributeListAttribute( + AttributeListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAttributeListAttribute( + AttributeListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readFeatureMapAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, true); + } + + public void subscribeFeatureMapAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readClusterRevisionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, true); + } + + public void subscribeClusterRevisionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval); + } + } + public static class DeviceEnergyManagementModeCluster extends BaseChipCluster { public static final long CLUSTER_ID = 159L; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java index 6cc21fd1f911c7..94bd7622678351 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java @@ -8608,6 +8608,143 @@ public String toString() { return output.toString(); } } +public static class WaterHeaterModeClusterModeTagStruct { + public Optional mfgCode; + public Integer value; + private static final long MFG_CODE_ID = 0L; + private static final long VALUE_ID = 1L; + + public WaterHeaterModeClusterModeTagStruct( + Optional mfgCode, + Integer value + ) { + this.mfgCode = mfgCode; + this.value = value; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(MFG_CODE_ID, mfgCode.map((nonOptionalmfgCode) -> new UIntType(nonOptionalmfgCode)).orElse(new EmptyType()))); + values.add(new StructElement(VALUE_ID, new UIntType(value))); + + return new StructType(values); + } + + public static WaterHeaterModeClusterModeTagStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Optional mfgCode = Optional.empty(); + Integer value = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == MFG_CODE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + mfgCode = Optional.of(castingValue.value(Integer.class)); + } + } else if (element.contextTagNum() == VALUE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + value = castingValue.value(Integer.class); + } + } + } + return new WaterHeaterModeClusterModeTagStruct( + mfgCode, + value + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("WaterHeaterModeClusterModeTagStruct {\n"); + output.append("\tmfgCode: "); + output.append(mfgCode); + output.append("\n"); + output.append("\tvalue: "); + output.append(value); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class WaterHeaterModeClusterModeOptionStruct { + public String label; + public Integer mode; + public ArrayList modeTags; + private static final long LABEL_ID = 0L; + private static final long MODE_ID = 1L; + private static final long MODE_TAGS_ID = 2L; + + public WaterHeaterModeClusterModeOptionStruct( + String label, + Integer mode, + ArrayList modeTags + ) { + this.label = label; + this.mode = mode; + this.modeTags = modeTags; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(LABEL_ID, new StringType(label))); + values.add(new StructElement(MODE_ID, new UIntType(mode))); + values.add(new StructElement(MODE_TAGS_ID, ArrayType.generateArrayType(modeTags, (elementmodeTags) -> elementmodeTags.encodeTlv()))); + + return new StructType(values); + } + + public static WaterHeaterModeClusterModeOptionStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + String label = null; + Integer mode = null; + ArrayList modeTags = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == LABEL_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + label = castingValue.value(String.class); + } + } else if (element.contextTagNum() == MODE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + mode = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == MODE_TAGS_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Array) { + ArrayType castingValue = element.value(ArrayType.class); + modeTags = castingValue.map((elementcastingValue) -> ChipStructs.WaterHeaterModeClusterModeTagStruct.decodeTlv(elementcastingValue)); + } + } + } + return new WaterHeaterModeClusterModeOptionStruct( + label, + mode, + modeTags + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("WaterHeaterModeClusterModeOptionStruct {\n"); + output.append("\tlabel: "); + output.append(label); + output.append("\n"); + output.append("\tmode: "); + output.append(mode); + output.append("\n"); + output.append("\tmodeTags: "); + output.append(modeTags); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class DeviceEnergyManagementModeClusterModeTagStruct { public Optional mfgCode; public Integer value; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index 698ee556bb324b..b733ca22822c88 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -253,6 +253,9 @@ public static BaseCluster getCluster(long clusterId) { if (clusterId == EnergyEvseMode.ID) { return new EnergyEvseMode(); } + if (clusterId == WaterHeaterMode.ID) { + return new WaterHeaterMode(); + } if (clusterId == DeviceEnergyManagementMode.ID) { return new DeviceEnergyManagementMode(); } @@ -10475,6 +10478,128 @@ public long getCommandID(String name) throws IllegalArgumentException { return Command.valueOf(name).getID(); } } + public static class WaterHeaterMode implements BaseCluster { + public static final long ID = 158L; + public long getID() { + return ID; + } + + public enum Attribute { + SupportedModes(0L), + CurrentMode(1L), + StartUpMode(2L), + OnMode(3L), + GeneratedCommandList(65528L), + AcceptedCommandList(65529L), + EventList(65530L), + AttributeList(65531L), + FeatureMap(65532L), + ClusterRevision(65533L),; + private final long id; + Attribute(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Attribute value(long id) throws NoSuchFieldError { + for (Attribute attribute : Attribute.values()) { + if (attribute.getID() == id) { + return attribute; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Event {; + private final long id; + Event(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Event value(long id) throws NoSuchFieldError { + for (Event event : Event.values()) { + if (event.getID() == id) { + return event; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Command { + ChangeToMode(0L),; + private final long id; + Command(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Command value(long id) throws NoSuchFieldError { + for (Command command : Command.values()) { + if (command.getID() == id) { + return command; + } + } + throw new NoSuchFieldError(); + } + }public enum ChangeToModeCommandField {NewMode(0),; + private final int id; + ChangeToModeCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static ChangeToModeCommandField value(int id) throws NoSuchFieldError { + for (ChangeToModeCommandField field : ChangeToModeCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }@Override + public String getAttributeName(long id) throws NoSuchFieldError { + return Attribute.value(id).toString(); + } + + @Override + public String getEventName(long id) throws NoSuchFieldError { + return Event.value(id).toString(); + } + + @Override + public String getCommandName(long id) throws NoSuchFieldError { + return Command.value(id).toString(); + } + + @Override + public long getAttributeID(String name) throws IllegalArgumentException { + return Attribute.valueOf(name).getID(); + } + + @Override + public long getEventID(String name) throws IllegalArgumentException { + return Event.valueOf(name).getID(); + } + + @Override + public long getCommandID(String name) throws IllegalArgumentException { + return Command.valueOf(name).getID(); + } + } public static class DeviceEnergyManagementMode implements BaseCluster { public static final long ID = 159L; public long getID() { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 06b24ad59e09af..23dc3048a5fb3d 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -11951,6 +11951,177 @@ public void onError(Exception ex) { } + public static class DelegatedWaterHeaterModeClusterChangeToModeResponseCallback implements ChipClusters.WaterHeaterModeCluster.ChangeToModeResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(Integer status, Optional statusText) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer"); + responseValues.put(statusResponseValue, status); + CommandResponseInfo statusTextResponseValue = new CommandResponseInfo("statusText", "Optional"); + responseValues.put(statusTextResponseValue, statusText); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + public static class DelegatedWaterHeaterModeClusterSupportedModesAttributeCallback implements ChipClusters.WaterHeaterModeCluster.SupportedModesAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWaterHeaterModeClusterStartUpModeAttributeCallback implements ChipClusters.WaterHeaterModeCluster.StartUpModeAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Integer value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWaterHeaterModeClusterOnModeAttributeCallback implements ChipClusters.WaterHeaterModeCluster.OnModeAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Integer value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWaterHeaterModeClusterGeneratedCommandListAttributeCallback implements ChipClusters.WaterHeaterModeCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWaterHeaterModeClusterAcceptedCommandListAttributeCallback implements ChipClusters.WaterHeaterModeCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWaterHeaterModeClusterEventListAttributeCallback implements ChipClusters.WaterHeaterModeCluster.EventListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWaterHeaterModeClusterAttributeListAttributeCallback implements ChipClusters.WaterHeaterModeCluster.AttributeListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedDeviceEnergyManagementModeClusterChangeToModeResponseCallback implements ChipClusters.DeviceEnergyManagementModeCluster.ChangeToModeResponseCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -21978,6 +22149,10 @@ public Map initializeClusterMap() { (ptr, endpointId) -> new ChipClusters.EnergyEvseModeCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("energyEvseMode", energyEvseModeClusterInfo); + ClusterInfo waterHeaterModeClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.WaterHeaterModeCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("waterHeaterMode", waterHeaterModeClusterInfo); + ClusterInfo deviceEnergyManagementModeClusterInfo = new ClusterInfo( (ptr, endpointId) -> new ChipClusters.DeviceEnergyManagementModeCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("deviceEnergyManagementMode", deviceEnergyManagementModeClusterInfo); @@ -22253,6 +22428,7 @@ public void combineCommand(Map destination, Map> getCommandMap() { commandMap.put("energyEvseMode", energyEvseModeClusterInteractionInfoMap); + Map waterHeaterModeClusterInteractionInfoMap = new LinkedHashMap<>(); + + Map waterHeaterModechangeToModeCommandParams = new LinkedHashMap(); + + CommandParameterInfo waterHeaterModechangeToModenewModeCommandParameterInfo = new CommandParameterInfo("newMode", Integer.class, Integer.class); + waterHeaterModechangeToModeCommandParams.put("newMode",waterHeaterModechangeToModenewModeCommandParameterInfo); + InteractionInfo waterHeaterModechangeToModeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster) + .changeToMode((ChipClusters.WaterHeaterModeCluster.ChangeToModeResponseCallback) callback + , (Integer) + commandArguments.get("newMode") + + ); + }, + () -> new DelegatedWaterHeaterModeClusterChangeToModeResponseCallback(), + waterHeaterModechangeToModeCommandParams + ); + waterHeaterModeClusterInteractionInfoMap.put("changeToMode", waterHeaterModechangeToModeInteractionInfo); + + commandMap.put("waterHeaterMode", waterHeaterModeClusterInteractionInfoMap); + Map deviceEnergyManagementModeClusterInteractionInfoMap = new LinkedHashMap<>(); Map deviceEnergyManagementModechangeToModeCommandParams = new LinkedHashMap(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index a15dca9774da6b..b6a359e031808b 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -10489,6 +10489,120 @@ private static Map readEnergyEvseModeInteractionInfo() return result; } + private static Map readWaterHeaterModeInteractionInfo() { + Map result = new LinkedHashMap<>();Map readWaterHeaterModeSupportedModesCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeSupportedModesAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readSupportedModesAttribute( + (ChipClusters.WaterHeaterModeCluster.SupportedModesAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterSupportedModesAttributeCallback(), + readWaterHeaterModeSupportedModesCommandParams + ); + result.put("readSupportedModesAttribute", readWaterHeaterModeSupportedModesAttributeInteractionInfo); + Map readWaterHeaterModeCurrentModeCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeCurrentModeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readCurrentModeAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWaterHeaterModeCurrentModeCommandParams + ); + result.put("readCurrentModeAttribute", readWaterHeaterModeCurrentModeAttributeInteractionInfo); + Map readWaterHeaterModeStartUpModeCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeStartUpModeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readStartUpModeAttribute( + (ChipClusters.WaterHeaterModeCluster.StartUpModeAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterStartUpModeAttributeCallback(), + readWaterHeaterModeStartUpModeCommandParams + ); + result.put("readStartUpModeAttribute", readWaterHeaterModeStartUpModeAttributeInteractionInfo); + Map readWaterHeaterModeOnModeCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeOnModeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readOnModeAttribute( + (ChipClusters.WaterHeaterModeCluster.OnModeAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterOnModeAttributeCallback(), + readWaterHeaterModeOnModeCommandParams + ); + result.put("readOnModeAttribute", readWaterHeaterModeOnModeAttributeInteractionInfo); + Map readWaterHeaterModeGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.WaterHeaterModeCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterGeneratedCommandListAttributeCallback(), + readWaterHeaterModeGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readWaterHeaterModeGeneratedCommandListAttributeInteractionInfo); + Map readWaterHeaterModeAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.WaterHeaterModeCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterAcceptedCommandListAttributeCallback(), + readWaterHeaterModeAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readWaterHeaterModeAcceptedCommandListAttributeInteractionInfo); + Map readWaterHeaterModeEventListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readEventListAttribute( + (ChipClusters.WaterHeaterModeCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterEventListAttributeCallback(), + readWaterHeaterModeEventListCommandParams + ); + result.put("readEventListAttribute", readWaterHeaterModeEventListAttributeInteractionInfo); + Map readWaterHeaterModeAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readAttributeListAttribute( + (ChipClusters.WaterHeaterModeCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterAttributeListAttributeCallback(), + readWaterHeaterModeAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readWaterHeaterModeAttributeListAttributeInteractionInfo); + Map readWaterHeaterModeFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readWaterHeaterModeFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readWaterHeaterModeFeatureMapAttributeInteractionInfo); + Map readWaterHeaterModeClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readWaterHeaterModeClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWaterHeaterModeClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readWaterHeaterModeClusterRevisionAttributeInteractionInfo); + + return result; + } private static Map readDeviceEnergyManagementModeInteractionInfo() { Map result = new LinkedHashMap<>();Map readDeviceEnergyManagementModeSupportedModesCommandParams = new LinkedHashMap(); InteractionInfo readDeviceEnergyManagementModeSupportedModesAttributeInteractionInfo = new InteractionInfo( @@ -21225,6 +21339,7 @@ public Map> getReadAttributeMap() { put("energyPreference", readEnergyPreferenceInteractionInfo()); put("powerTopology", readPowerTopologyInteractionInfo()); put("energyEvseMode", readEnergyEvseModeInteractionInfo()); + put("waterHeaterMode", readWaterHeaterModeInteractionInfo()); put("deviceEnergyManagementMode", readDeviceEnergyManagementModeInteractionInfo()); put("doorLock", readDoorLockInteractionInfo()); put("windowCovering", readWindowCoveringInteractionInfo()); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index 635f5bf1b48830..715cb477319345 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -1408,6 +1408,52 @@ public Map> getWriteAttributeMap() { ); writeEnergyEvseModeInteractionInfo.put("writeOnModeAttribute", writeEnergyEvseModeOnModeAttributeInteractionInfo); writeAttributeMap.put("energyEvseMode", writeEnergyEvseModeInteractionInfo); + Map writeWaterHeaterModeInteractionInfo = new LinkedHashMap<>(); + Map writeWaterHeaterModeStartUpModeCommandParams = new LinkedHashMap(); + CommandParameterInfo waterHeaterModestartUpModeCommandParameterInfo = + new CommandParameterInfo( + "value", + Integer.class, + Integer.class + ); + writeWaterHeaterModeStartUpModeCommandParams.put( + "value", + waterHeaterModestartUpModeCommandParameterInfo + ); + InteractionInfo writeWaterHeaterModeStartUpModeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).writeStartUpModeAttribute( + (DefaultClusterCallback) callback, + (Integer) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeWaterHeaterModeStartUpModeCommandParams + ); + writeWaterHeaterModeInteractionInfo.put("writeStartUpModeAttribute", writeWaterHeaterModeStartUpModeAttributeInteractionInfo); + Map writeWaterHeaterModeOnModeCommandParams = new LinkedHashMap(); + CommandParameterInfo waterHeaterModeonModeCommandParameterInfo = + new CommandParameterInfo( + "value", + Integer.class, + Integer.class + ); + writeWaterHeaterModeOnModeCommandParams.put( + "value", + waterHeaterModeonModeCommandParameterInfo + ); + InteractionInfo writeWaterHeaterModeOnModeAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WaterHeaterModeCluster) cluster).writeOnModeAttribute( + (DefaultClusterCallback) callback, + (Integer) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeWaterHeaterModeOnModeCommandParams + ); + writeWaterHeaterModeInteractionInfo.put("writeOnModeAttribute", writeWaterHeaterModeOnModeAttributeInteractionInfo); + writeAttributeMap.put("waterHeaterMode", writeWaterHeaterModeInteractionInfo); Map writeDeviceEnergyManagementModeInteractionInfo = new LinkedHashMap<>(); Map writeDeviceEnergyManagementModeStartUpModeCommandParams = new LinkedHashMap(); CommandParameterInfo deviceEnergyManagementModestartUpModeCommandParameterInfo = diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni index 631feb9442d4c0..c15fb2a01efd80 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -147,6 +147,8 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestFabricScoped.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestListStructOctet.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UserLabelClusterLabelStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt", ] eventstructs_sources = [ diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt new file mode 100644 index 00000000000000..731c0395d7213d --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt @@ -0,0 +1,76 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WaterHeaterModeClusterModeOptionStruct( + val label: String, + val mode: UInt, + val modeTags: List, +) { + override fun toString(): String = buildString { + append("WaterHeaterModeClusterModeOptionStruct {\n") + append("\tlabel : $label\n") + append("\tmode : $mode\n") + append("\tmodeTags : $modeTags\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LABEL), label) + put(ContextSpecificTag(TAG_MODE), mode) + startArray(ContextSpecificTag(TAG_MODE_TAGS)) + for (item in modeTags.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + endStructure() + } + } + + companion object { + private const val TAG_LABEL = 0 + private const val TAG_MODE = 1 + private const val TAG_MODE_TAGS = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): WaterHeaterModeClusterModeOptionStruct { + tlvReader.enterStructure(tlvTag) + val label = tlvReader.getString(ContextSpecificTag(TAG_LABEL)) + val mode = tlvReader.getUInt(ContextSpecificTag(TAG_MODE)) + val modeTags = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_MODE_TAGS)) + while (!tlvReader.isEndOfContainer()) { + add(WaterHeaterModeClusterModeTagStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + tlvReader.exitContainer() + + return WaterHeaterModeClusterModeOptionStruct(label, mode, modeTags) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt new file mode 100644 index 00000000000000..52281b378efc57 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import java.util.Optional +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WaterHeaterModeClusterModeTagStruct(val mfgCode: Optional, val value: UInt) { + override fun toString(): String = buildString { + append("WaterHeaterModeClusterModeTagStruct {\n") + append("\tmfgCode : $mfgCode\n") + append("\tvalue : $value\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + if (mfgCode.isPresent) { + val optmfgCode = mfgCode.get() + put(ContextSpecificTag(TAG_MFG_CODE), optmfgCode) + } + put(ContextSpecificTag(TAG_VALUE), value) + endStructure() + } + } + + companion object { + private const val TAG_MFG_CODE = 0 + private const val TAG_VALUE = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): WaterHeaterModeClusterModeTagStruct { + tlvReader.enterStructure(tlvTag) + val mfgCode = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_MFG_CODE))) { + Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_MFG_CODE))) + } else { + Optional.empty() + } + val value = tlvReader.getUInt(ContextSpecificTag(TAG_VALUE)) + + tlvReader.exitContainer() + + return WaterHeaterModeClusterModeTagStruct(mfgCode, value) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterModeCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterModeCluster.kt new file mode 100644 index 00000000000000..27352644935c8a --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterModeCluster.kt @@ -0,0 +1,1199 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ + +package matter.controller.cluster.clusters + +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transform +import matter.controller.InvokeRequest +import matter.controller.InvokeResponse +import matter.controller.MatterController +import matter.controller.ReadData +import matter.controller.ReadRequest +import matter.controller.SubscribeRequest +import matter.controller.SubscriptionState +import matter.controller.UByteSubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.WriteRequest +import matter.controller.WriteRequests +import matter.controller.WriteResponse +import matter.controller.cluster.structs.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WaterHeaterModeCluster( + private val controller: MatterController, + private val endpointId: UShort, +) { + class ChangeToModeResponse(val status: UByte, val statusText: String?) + + class SupportedModesAttribute(val value: List) + + sealed class SupportedModesAttributeSubscriptionState { + data class Success(val value: List) : + SupportedModesAttributeSubscriptionState() + + data class Error(val exception: Exception) : SupportedModesAttributeSubscriptionState() + + object SubscriptionEstablished : SupportedModesAttributeSubscriptionState() + } + + class StartUpModeAttribute(val value: UByte?) + + sealed class StartUpModeAttributeSubscriptionState { + data class Success(val value: UByte?) : StartUpModeAttributeSubscriptionState() + + data class Error(val exception: Exception) : StartUpModeAttributeSubscriptionState() + + object SubscriptionEstablished : StartUpModeAttributeSubscriptionState() + } + + class OnModeAttribute(val value: UByte?) + + sealed class OnModeAttributeSubscriptionState { + data class Success(val value: UByte?) : OnModeAttributeSubscriptionState() + + data class Error(val exception: Exception) : OnModeAttributeSubscriptionState() + + object SubscriptionEstablished : OnModeAttributeSubscriptionState() + } + + class GeneratedCommandListAttribute(val value: List) + + sealed class GeneratedCommandListAttributeSubscriptionState { + data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState() + } + + class AcceptedCommandListAttribute(val value: List) + + sealed class AcceptedCommandListAttributeSubscriptionState { + data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState() + } + + class EventListAttribute(val value: List) + + sealed class EventListAttributeSubscriptionState { + data class Success(val value: List) : EventListAttributeSubscriptionState() + + data class Error(val exception: Exception) : EventListAttributeSubscriptionState() + + object SubscriptionEstablished : EventListAttributeSubscriptionState() + } + + class AttributeListAttribute(val value: List) + + sealed class AttributeListAttributeSubscriptionState { + data class Success(val value: List) : AttributeListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState() + + object SubscriptionEstablished : AttributeListAttributeSubscriptionState() + } + + suspend fun changeToMode( + newMode: UByte, + timedInvokeTimeout: Duration? = null, + ): ChangeToModeResponse { + val commandId: UInt = 0u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_NEW_MODE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_NEW_MODE_REQ), newMode) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_STATUS: Int = 0 + var status_decoded: UByte? = null + + val TAG_STATUS_TEXT: Int = 1 + var statusText_decoded: String? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_STATUS)) { + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_STATUS_TEXT)) { + statusText_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } + } else { + tlvReader.skipElement() + } + } + + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") + } + + tlvReader.exitContainer() + + return ChangeToModeResponse(status_decoded, statusText_decoded) + } + + suspend fun readSupportedModesAttribute(): SupportedModesAttribute { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Supportedmodes attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(WaterHeaterModeClusterModeOptionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return SupportedModesAttribute(decodedValue) + } + + suspend fun subscribeSupportedModesAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 0u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + SupportedModesAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Supportedmodes attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(WaterHeaterModeClusterModeOptionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + emit(SupportedModesAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(SupportedModesAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readCurrentModeAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 1u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeCurrentModeAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 1u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UByteSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Currentmode attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) + + emit(UByteSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UByteSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readStartUpModeAttribute(): StartUpModeAttribute { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Startupmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return StartUpModeAttribute(decodedValue) + } + + suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 2u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeStartUpModeAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 2u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + StartUpModeAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Startupmode attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(StartUpModeAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(StartUpModeAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readOnModeAttribute(): OnModeAttribute { + val ATTRIBUTE_ID: UInt = 3u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Onmode attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return OnModeAttribute(decodedValue) + } + + suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 3u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeOnModeAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 3u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + OnModeAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Onmode attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUByte(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(OnModeAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(OnModeAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65528u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + GeneratedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Generatedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65529u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AcceptedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Acceptedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun subscribeEventListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65530u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + EventListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(EventListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(EventListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65531u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AttributeListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AttributeListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeFeatureMapAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65532u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeClusterRevisionAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65533u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Clusterrevision attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + companion object { + private val logger = Logger.getLogger(WaterHeaterModeCluster::class.java.name) + const val CLUSTER_ID: UInt = 158u + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/files.gni b/src/controller/java/generated/java/matter/controller/cluster/files.gni index 2bebadb13c36ce..bf7839d661528d 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -147,6 +147,8 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestFabricScoped.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestListStructOctet.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UserLabelClusterLabelStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt", ] matter_eventstructs_sources = [ @@ -355,6 +357,7 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ValveConfigurationAndControlCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WakeOnLanCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterManagementCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterModeCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkDiagnosticsCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkManagementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WindowCoveringCluster.kt", diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt new file mode 100644 index 00000000000000..52252bf6e4cc56 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt @@ -0,0 +1,76 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package matter.controller.cluster.structs + +import matter.controller.cluster.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WaterHeaterModeClusterModeOptionStruct( + val label: String, + val mode: UByte, + val modeTags: List, +) { + override fun toString(): String = buildString { + append("WaterHeaterModeClusterModeOptionStruct {\n") + append("\tlabel : $label\n") + append("\tmode : $mode\n") + append("\tmodeTags : $modeTags\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LABEL), label) + put(ContextSpecificTag(TAG_MODE), mode) + startArray(ContextSpecificTag(TAG_MODE_TAGS)) + for (item in modeTags.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + endStructure() + } + } + + companion object { + private const val TAG_LABEL = 0 + private const val TAG_MODE = 1 + private const val TAG_MODE_TAGS = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): WaterHeaterModeClusterModeOptionStruct { + tlvReader.enterStructure(tlvTag) + val label = tlvReader.getString(ContextSpecificTag(TAG_LABEL)) + val mode = tlvReader.getUByte(ContextSpecificTag(TAG_MODE)) + val modeTags = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_MODE_TAGS)) + while (!tlvReader.isEndOfContainer()) { + add(WaterHeaterModeClusterModeTagStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + tlvReader.exitContainer() + + return WaterHeaterModeClusterModeOptionStruct(label, mode, modeTags) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt new file mode 100644 index 00000000000000..fc91c1389574ab --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package matter.controller.cluster.structs + +import java.util.Optional +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WaterHeaterModeClusterModeTagStruct(val mfgCode: Optional, val value: UShort) { + override fun toString(): String = buildString { + append("WaterHeaterModeClusterModeTagStruct {\n") + append("\tmfgCode : $mfgCode\n") + append("\tvalue : $value\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + if (mfgCode.isPresent) { + val optmfgCode = mfgCode.get() + put(ContextSpecificTag(TAG_MFG_CODE), optmfgCode) + } + put(ContextSpecificTag(TAG_VALUE), value) + endStructure() + } + } + + companion object { + private const val TAG_MFG_CODE = 0 + private const val TAG_VALUE = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): WaterHeaterModeClusterModeTagStruct { + tlvReader.enterStructure(tlvTag) + val mfgCode = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_MFG_CODE))) { + Optional.of(tlvReader.getUShort(ContextSpecificTag(TAG_MFG_CODE))) + } else { + Optional.empty() + } + val value = tlvReader.getUShort(ContextSpecificTag(TAG_VALUE)) + + tlvReader.exitContainer() + + return WaterHeaterModeClusterModeTagStruct(mfgCode, value) + } + } +} diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 01a75bcc216288..9d1d0bd1bb65a3 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -25893,6 +25893,317 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } + case app::Clusters::WaterHeaterMode::Id: { + using namespace app::Clusters::WaterHeaterMode; + switch (aPath.mAttributeId) + { + case Attributes::SupportedModes::Id: { + using TypeInfo = Attributes::SupportedModes::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + jobject newElement_0_label; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.label, newElement_0_label)); + jobject newElement_0_mode; + std::string newElement_0_modeClassName = "java/lang/Integer"; + std::string newElement_0_modeCtorSignature = "(I)V"; + jint jninewElement_0_mode = static_cast(entry_0.mode); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_modeClassName.c_str(), + newElement_0_modeCtorSignature.c_str(), + jninewElement_0_mode, newElement_0_mode); + jobject newElement_0_modeTags; + chip::JniReferences::GetInstance().CreateArrayList(newElement_0_modeTags); + + auto iter_newElement_0_modeTags_2 = entry_0.modeTags.begin(); + while (iter_newElement_0_modeTags_2.Next()) + { + auto & entry_2 = iter_newElement_0_modeTags_2.GetValue(); + jobject newElement_2; + jobject newElement_2_mfgCode; + if (!entry_2.mfgCode.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_2_mfgCode); + } + else + { + jobject newElement_2_mfgCodeInsideOptional; + std::string newElement_2_mfgCodeInsideOptionalClassName = "java/lang/Integer"; + std::string newElement_2_mfgCodeInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_2_mfgCodeInsideOptional = static_cast(entry_2.mfgCode.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_2_mfgCodeInsideOptionalClassName.c_str(), + newElement_2_mfgCodeInsideOptionalCtorSignature.c_str(), jninewElement_2_mfgCodeInsideOptional, + newElement_2_mfgCodeInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(newElement_2_mfgCodeInsideOptional, newElement_2_mfgCode); + } + jobject newElement_2_value; + std::string newElement_2_valueClassName = "java/lang/Integer"; + std::string newElement_2_valueCtorSignature = "(I)V"; + jint jninewElement_2_value = static_cast(entry_2.value); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_2_valueClassName.c_str(), + newElement_2_valueCtorSignature.c_str(), + jninewElement_2_value, newElement_2_value); + + jclass modeTagStructStructClass_3; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$WaterHeaterModeClusterModeTagStruct", modeTagStructStructClass_3); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$WaterHeaterModeClusterModeTagStruct"); + return nullptr; + } + + jmethodID modeTagStructStructCtor_3; + err = chip::JniReferences::GetInstance().FindMethod(env, modeTagStructStructClass_3, "", + "(Ljava/util/Optional;Ljava/lang/Integer;)V", + &modeTagStructStructCtor_3); + if (err != CHIP_NO_ERROR || modeTagStructStructCtor_3 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$WaterHeaterModeClusterModeTagStruct constructor"); + return nullptr; + } + + newElement_2 = env->NewObject(modeTagStructStructClass_3, modeTagStructStructCtor_3, newElement_2_mfgCode, + newElement_2_value); + chip::JniReferences::GetInstance().AddToList(newElement_0_modeTags, newElement_2); + } + + jclass modeOptionStructStructClass_1; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$WaterHeaterModeClusterModeOptionStruct", modeOptionStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$WaterHeaterModeClusterModeOptionStruct"); + return nullptr; + } + + jmethodID modeOptionStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod(env, modeOptionStructStructClass_1, "", + "(Ljava/lang/String;Ljava/lang/Integer;Ljava/util/ArrayList;)V", + &modeOptionStructStructCtor_1); + if (err != CHIP_NO_ERROR || modeOptionStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$WaterHeaterModeClusterModeOptionStruct constructor"); + return nullptr; + } + + newElement_0 = env->NewObject(modeOptionStructStructClass_1, modeOptionStructStructCtor_1, newElement_0_label, + newElement_0_mode, newElement_0_modeTags); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::CurrentMode::Id: { + using TypeInfo = Attributes::CurrentMode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::StartUpMode::Id: { + using TypeInfo = Attributes::StartUpMode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::OnMode::Id: { + using TypeInfo = Attributes::OnMode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::EventList::Id: { + using TypeInfo = Attributes::EventList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } case app::Clusters::DeviceEnergyManagementMode::Id: { using namespace app::Clusters::DeviceEnergyManagementMode; switch (aPath.mAttributeId) diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index a61c38ca0edcc6..789e3ea5f1310e 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -6134,6 +6134,16 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } break; } + case app::Clusters::WaterHeaterMode::Id: { + using namespace app::Clusters::WaterHeaterMode; + switch (aPath.mEventId) + { + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } case app::Clusters::DeviceEnergyManagementMode::Id: { using namespace app::Clusters::DeviceEnergyManagementMode; switch (aPath.mEventId) diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index d9c9196015c96d..4e1c5d6678ed3e 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -249,7 +249,10 @@ def future(self) -> typing.Optional[concurrent.futures.Future]: async def __aexit__(self, exc_type, exc_value, traceback): if not self._future.done(): - raise RuntimeError("CallbackContext future not completed") + # In case the initial call (which sets up for the callback) fails, + # the future will never be used actually. So just cancel it here + # for completeness, in case somebody is expecting it to be completed. + self._future.cancel() self._future = None self._lock.release() @@ -603,11 +606,10 @@ async def ConnectBLE(self, discriminator: int, setupPinCode: int, nodeid: int, i async with self._commissioning_context as ctx: self._enablePairingCompleteCallback(True) - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectBLE( self.devCtrl, discriminator, isShortDiscriminator, setupPinCode, nodeid) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) @@ -615,11 +617,11 @@ async def UnpairDevice(self, nodeid: int) -> None: self.CheckIsActive() async with self._unpair_device_context as ctx: - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_UnpairDevice( self.devCtrl, nodeid, self.cbHandleDeviceUnpairCompleteFunct) ) - res.raise_on_error() + return await asyncio.futures.wrap_future(ctx.future) def CloseBLEConnection(self): @@ -656,8 +658,7 @@ async def _establishPASESession(self, callFunct): async with self._pase_establishment_context as ctx: self._enablePairingCompleteCallback(True) - res = await self._ChipStack.CallAsync(callFunct) - res.raise_on_error() + await self._ChipStack.CallAsync(callFunct) await asyncio.futures.wrap_future(ctx.future) async def EstablishPASESessionBLE(self, setupPinCode: int, discriminator: int, nodeid: int) -> None: @@ -756,13 +757,12 @@ async def DiscoverCommissionableNodes(self, filterType: discovery.FilterType = d # Discovery is also used during commissioning. Make sure this manual discovery # and commissioning attempts do not interfere with each other. async with self._commissioning_lock: - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_DiscoverCommissionableNodes( self.devCtrl, int(filterType), str(filter).encode("utf-8"))) - res.raise_on_error() async def _wait_discovery(): - while not await self._ChipStack.CallAsync( + while not await self._ChipStack.CallAsyncWithResult( lambda: self._dmLib.pychip_DeviceController_HasDiscoveredCommissionableNode(self.devCtrl)): await asyncio.sleep(0.1) return @@ -776,9 +776,8 @@ async def _wait_discovery(): # Expected timeout, do nothing pass finally: - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_StopCommissionableDiscovery(self.devCtrl)) - res.raise_on_error() return await self.GetDiscoveredDevices() @@ -796,7 +795,7 @@ def HandleDevice(deviceJson, deviceJsonLen): self._dmLib.pychip_DeviceController_IterateDiscoveredCommissionableNodes(devCtrl.devCtrl, HandleDevice) return devices - return await self._ChipStack.CallAsync(lambda: GetDevices(self)) + return await self._ChipStack.CallAsyncWithResult(lambda: GetDevices(self)) def GetIPForDiscoveredDevice(self, idx, addrStr, length): self.CheckIsActive() @@ -828,11 +827,10 @@ async def OpenCommissioningWindow(self, nodeid: int, timeout: int, iteration: in self.CheckIsActive() async with self._open_window_context as ctx: - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_OpenCommissioningWindow( self.devCtrl, self.pairingDelegate, nodeid, timeout, iteration, discriminator, option) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) @@ -896,14 +894,14 @@ async def FindOrEstablishPASESession(self, setupCode: str, nodeid: int, timeoutM ''' Returns CommissioneeDeviceProxy if we can find or establish a PASE connection to the specified device''' self.CheckIsActive() returnDevice = c_void_p(None) - res = await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( + res = await self._ChipStack.CallAsyncWithResult(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) if res.is_success: return DeviceProxyWrapper(returnDevice, DeviceProxyWrapper.DeviceProxyType.COMMISSIONEE, self._dmLib) await self.EstablishPASESession(setupCode, nodeid) - res = await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( + res = await self._ChipStack.CallAsyncWithResult(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) if res.is_success: return DeviceProxyWrapper(returnDevice, DeviceProxyWrapper.DeviceProxyType.COMMISSIONEE, self._dmLib) @@ -991,7 +989,7 @@ async def GetConnectedDevice(self, nodeid, allowPASE: bool = True, timeoutMs: in if allowPASE: returnDevice = c_void_p(None) - res = await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( + res = await self._ChipStack.CallAsyncWithResult(lambda: self._dmLib.pychip_GetDeviceBeingCommissioned( self.devCtrl, nodeid, byref(returnDevice)), timeoutMs) if res.is_success: LOGGER.info('Using PASE connection') @@ -1021,10 +1019,9 @@ def deviceAvailable(self, device, err): closure = DeviceAvailableClosure(eventLoop, future) ctypes.pythonapi.Py_IncRef(ctypes.py_object(closure)) - res = await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetConnectedDeviceByNodeId( + await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetConnectedDeviceByNodeId( self.devCtrl, nodeid, ctypes.py_object(closure), _DeviceAvailableCallback), timeoutMs) - res.raise_on_error() # The callback might have been received synchronously (during self._ChipStack.CallAsync()). # In that case the Future has already been set it will return immediately @@ -1439,6 +1436,13 @@ async def Read(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. + fabricFiltered: If True (default), the read/subscribe is fabric-filtered and will only see things associated with the fabric + of the reader/subscriber. Relevant for attributes with fabric-scoped data. + keepSubscriptions: Keep existing subscriptions. If set to False, existing subscriptions with this node will get cancelled + and a new one gets setup. + autoResubscribe: Automatically resubscribe to the subscription if subscription is lost. The automatic re-subscription only + applies if the subscription establishes on first try. If the first subscription establishment attempt fails the function + returns right away. Returns: - AsyncReadTransaction.ReadResponse. Please see ReadAttribute and ReadEvent for examples of how to access data. @@ -1508,6 +1512,13 @@ 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. + fabricFiltered: If True (default), the read/subscribe is fabric-filtered and will only see things associated with the fabric + of the reader/subscriber. Relevant for attributes with fabric-scoped data. + keepSubscriptions: Keep existing subscriptions. If set to False, existing subscriptions with this node will get cancelled + and a new one gets setup. + autoResubscribe: Automatically resubscribe to the subscription if subscription is lost. The automatic re-subscription only + applies if the subscription establishes on first try. If the first subscription establishment attempt fails the function + returns right away. Returns: - subscription request: ClusterAttribute.SubscriptionTransaction @@ -1584,6 +1595,11 @@ async def ReadEvent(self, nodeid: int, events: typing.List[typing.Union[ eventNumberFilter: Optional minimum event number filter. reportInterval: A tuple of two int-s for (MinIntervalFloor, MaxIntervalCeiling). Used by establishing subscriptions. When not provided, a read request will be sent. + keepSubscriptions: Keep existing subscriptions. If set to False, existing subscriptions with this node will get cancelled + and a new one gets setup. + autoResubscribe: Automatically resubscribe to the subscription if subscription is lost. The automatic re-subscription only + applies if the subscription establishes on first try. If the first subscription establishment attempt fails the function + returns right away. Returns: - subscription request: ClusterAttribute.SubscriptionTransaction @@ -1917,11 +1933,10 @@ async def Commission(self, nodeid) -> int: async with self._commissioning_context as ctx: self._enablePairingCompleteCallback(False) - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_Commission( self.devCtrl, nodeid) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) @@ -2065,11 +2080,10 @@ async def CommissionOnNetwork(self, nodeId: int, setupPinCode: int, async with self._commissioning_context as ctx: self._enablePairingCompleteCallback(True) - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_OnNetworkCommission( self.devCtrl, self.pairingDelegate, nodeId, setupPinCode, int(filterType), str(filter).encode("utf-8") if filter is not None else None, discoveryTimeoutMsec) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) @@ -2086,11 +2100,10 @@ async def CommissionWithCode(self, setupPayload: str, nodeid: int, discoveryType async with self._commissioning_context as ctx: self._enablePairingCompleteCallback(True) - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectWithCode( self.devCtrl, setupPayload.encode("utf-8"), nodeid, discoveryType.value) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) @@ -2106,11 +2119,10 @@ async def CommissionIP(self, ipaddr: str, setupPinCode: int, nodeid: int) -> int async with self._commissioning_context as ctx: self._enablePairingCompleteCallback(True) - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_ConnectIP( self.devCtrl, ipaddr.encode("utf-8"), setupPinCode, nodeid) ) - res.raise_on_error() return await asyncio.futures.wrap_future(ctx.future) @@ -2127,11 +2139,11 @@ async def IssueNOCChain(self, csr: Clusters.OperationalCredentials.Commands.CSRR self.CheckIsActive() async with self._issue_node_chain_context as ctx: - res = await self._ChipStack.CallAsync( + await self._ChipStack.CallAsync( lambda: self._dmLib.pychip_DeviceController_IssueNOCChain( self.devCtrl, py_object(self), csr.NOCSRElements, len(csr.NOCSRElements), nodeId) ) - res.raise_on_error() + return await asyncio.futures.wrap_future(ctx.future) diff --git a/src/controller/python/chip/ChipStack.py b/src/controller/python/chip/ChipStack.py index dc4efc223f491d..b717859c70351d 100644 --- a/src/controller/python/chip/ChipStack.py +++ b/src/controller/python/chip/ChipStack.py @@ -216,7 +216,7 @@ def Call(self, callFunct, timeoutMs: int = None): ''' return self.PostTaskOnChipThread(callFunct).Wait(timeoutMs) - async def CallAsync(self, callFunct, timeoutMs: int = None): + async def CallAsyncWithResult(self, callFunct, timeoutMs: int = None): '''Run a Python function on CHIP stack, and wait for the response. This function will post a task on CHIP mainloop and waits for the call response in a asyncio friendly manner. ''' @@ -232,6 +232,11 @@ async def CallAsync(self, callFunct, timeoutMs: int = None): return await asyncio.wait_for(callObj.future, timeoutMs / 1000 if timeoutMs else None) + async def CallAsync(self, callFunct, timeoutMs: int = None) -> None: + '''Run a Python function on CHIP stack, and wait for the response.''' + res: PyChipError = await self.CallAsyncWithResult(callFunct, timeoutMs) + res.raise_on_error() + def PostTaskOnChipThread(self, callFunct) -> AsyncCallableHandle: '''Run a Python function on CHIP stack, and wait for the response. This function will post a task on CHIP mainloop, and return an object with Wait() method for getting the result. diff --git a/src/controller/python/chip/clusters/Attribute.py b/src/controller/python/chip/clusters/Attribute.py index ba4c5d4b72dbe6..a8850f6b056186 100644 --- a/src/controller/python/chip/clusters/Attribute.py +++ b/src/controller/python/chip/clusters/Attribute.py @@ -469,7 +469,7 @@ def OverrideLivenessTimeoutMs(self, timeoutMs: int): async def TriggerResubscribeIfScheduled(self, reason: str): handle = chip.native.GetLibraryHandle() - await builtins.chipStack.CallAsync( + await builtins.chipStack.CallAsyncWithResult( lambda: handle.pychip_ReadClient_TriggerResubscribeIfScheduled( self._readTransaction._pReadClient, reason.encode("utf-8")) ) @@ -720,6 +720,8 @@ def handleEventData(self, header: EventHeader, path: EventPath, data: bytes, sta LOGGER.exception(ex) def handleError(self, chipError: PyChipError): + if self._subscription_handler: + self._subscription_handler.OnErrorCb(chipError.code, self._subscription_handler) self._resultError = chipError def _handleSubscriptionEstablished(self, subscriptionId): @@ -728,6 +730,7 @@ def _handleSubscriptionEstablished(self, subscriptionId): self, subscriptionId, self._devCtrl) self._future.set_result(self._subscription_handler) else: + self._subscription_handler._subscriptionId = subscriptionId if self._subscription_handler._onResubscriptionSucceededCb is not None: if (self._subscription_handler._onResubscriptionSucceededCb_isAsync): self._event_loop.create_task( @@ -779,10 +782,7 @@ def _handleDone(self): # if not self._future.done(): if self._resultError is not None: - if self._subscription_handler: - self._subscription_handler.OnErrorCb(self._resultError.code, self._subscription_handler) - else: - self._future.set_exception(self._resultError.to_exception()) + self._future.set_exception(self._resultError.to_exception()) else: self._future.set_result(AsyncReadTransaction.ReadResponse( attributes=self._cache.attributeCache, events=self._events, tlvAttributes=self._cache.attributeTLVCache)) diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 5d0d1ffd38fd3c..1901351596228a 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -7477,6 +7477,83 @@ class ChipClusters: }, }, } + _WATER_HEATER_MODE_CLUSTER_INFO = { + "clusterName": "WaterHeaterMode", + "clusterId": 0x0000009E, + "commands": { + 0x00000000: { + "commandId": 0x00000000, + "commandName": "ChangeToMode", + "args": { + "newMode": "int", + }, + }, + }, + "attributes": { + 0x00000000: { + "attributeName": "SupportedModes", + "attributeId": 0x00000000, + "type": "", + "reportable": True, + }, + 0x00000001: { + "attributeName": "CurrentMode", + "attributeId": 0x00000001, + "type": "int", + "reportable": True, + }, + 0x00000002: { + "attributeName": "StartUpMode", + "attributeId": 0x00000002, + "type": "int", + "reportable": True, + "writable": True, + }, + 0x00000003: { + "attributeName": "OnMode", + "attributeId": 0x00000003, + "type": "int", + "reportable": True, + "writable": True, + }, + 0x0000FFF8: { + "attributeName": "GeneratedCommandList", + "attributeId": 0x0000FFF8, + "type": "int", + "reportable": True, + }, + 0x0000FFF9: { + "attributeName": "AcceptedCommandList", + "attributeId": 0x0000FFF9, + "type": "int", + "reportable": True, + }, + 0x0000FFFA: { + "attributeName": "EventList", + "attributeId": 0x0000FFFA, + "type": "int", + "reportable": True, + }, + 0x0000FFFB: { + "attributeName": "AttributeList", + "attributeId": 0x0000FFFB, + "type": "int", + "reportable": True, + }, + 0x0000FFFC: { + "attributeName": "FeatureMap", + "attributeId": 0x0000FFFC, + "type": "int", + "reportable": True, + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + "reportable": True, + }, + }, + } _DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER_INFO = { "clusterName": "DeviceEnergyManagementMode", "clusterId": 0x0000009F, @@ -15136,6 +15213,7 @@ class ChipClusters: 0x0000009B: _ENERGY_PREFERENCE_CLUSTER_INFO, 0x0000009C: _POWER_TOPOLOGY_CLUSTER_INFO, 0x0000009D: _ENERGY_EVSE_MODE_CLUSTER_INFO, + 0x0000009E: _WATER_HEATER_MODE_CLUSTER_INFO, 0x0000009F: _DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER_INFO, 0x00000101: _DOOR_LOCK_CLUSTER_INFO, 0x00000102: _WINDOW_COVERING_CLUSTER_INFO, @@ -15263,6 +15341,7 @@ class ChipClusters: "EnergyPreference": _ENERGY_PREFERENCE_CLUSTER_INFO, "PowerTopology": _POWER_TOPOLOGY_CLUSTER_INFO, "EnergyEvseMode": _ENERGY_EVSE_MODE_CLUSTER_INFO, + "WaterHeaterMode": _WATER_HEATER_MODE_CLUSTER_INFO, "DeviceEnergyManagementMode": _DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER_INFO, "DoorLock": _DOOR_LOCK_CLUSTER_INFO, "WindowCovering": _WINDOW_COVERING_CLUSTER_INFO, diff --git a/src/controller/python/chip/clusters/Command.py b/src/controller/python/chip/clusters/Command.py index 93951338f988f5..785bb3d3daf47f 100644 --- a/src/controller/python/chip/clusters/Command.py +++ b/src/controller/python/chip/clusters/Command.py @@ -316,7 +316,7 @@ async def SendCommand(future: Future, eventLoop, responseType: Type, device, com payloadTLV = payload.ToTLV() ctypes.pythonapi.Py_IncRef(ctypes.py_object(transaction)) - return await builtins.chipStack.CallAsync( + return await builtins.chipStack.CallAsyncWithResult( lambda: handle.pychip_CommandSender_SendCommand( ctypes.py_object(transaction), device, c_uint16(0 if timedRequestTimeoutMs is None else timedRequestTimeoutMs), commandPath.EndpointId, @@ -388,7 +388,7 @@ async def SendBatchCommands(future: Future, eventLoop, device, commands: List[In transaction = AsyncBatchCommandsTransaction(future, eventLoop, responseTypes) ctypes.pythonapi.Py_IncRef(ctypes.py_object(transaction)) - return await builtins.chipStack.CallAsync( + return await builtins.chipStack.CallAsyncWithResult( lambda: handle.pychip_CommandSender_SendBatchCommands( py_object(transaction), device, c_uint16(0 if timedRequestTimeoutMs is None else timedRequestTimeoutMs), diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 511bdb3399f619..398d9324438df8 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -26802,6 +26802,278 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'uint' = 0 +@dataclass +class WaterHeaterMode(Cluster): + id: typing.ClassVar[int] = 0x0000009E + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="supportedModes", Tag=0x00000000, Type=typing.List[WaterHeaterMode.Structs.ModeOptionStruct]), + ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), + ClusterObjectFieldDescriptor(Label="startUpMode", Tag=0x00000002, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="onMode", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + supportedModes: 'typing.List[WaterHeaterMode.Structs.ModeOptionStruct]' = None + currentMode: 'uint' = None + startUpMode: 'typing.Union[None, Nullable, uint]' = None + onMode: 'typing.Union[None, Nullable, uint]' = None + generatedCommandList: 'typing.List[uint]' = None + acceptedCommandList: 'typing.List[uint]' = None + eventList: 'typing.List[uint]' = None + attributeList: 'typing.List[uint]' = None + featureMap: 'uint' = None + clusterRevision: 'uint' = None + + class Enums: + class ModeTag(MatterIntEnum): + kOff = 0x4000 + kManual = 0x4001 + kTimed = 0x4002 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving and unknown + # enum value. This specific should never be transmitted. + kUnknownEnumValue = 0, + + class Bitmaps: + class Feature(IntFlag): + kOnOff = 0x1 + + class Structs: + @dataclass + class ModeTagStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="mfgCode", Tag=0, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="value", Tag=1, Type=uint), + ]) + + mfgCode: 'typing.Optional[uint]' = None + value: 'uint' = 0 + + @dataclass + class ModeOptionStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="label", Tag=0, Type=str), + ClusterObjectFieldDescriptor(Label="mode", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="modeTags", Tag=2, Type=typing.List[WaterHeaterMode.Structs.ModeTagStruct]), + ]) + + label: 'str' = "" + mode: 'uint' = 0 + modeTags: 'typing.List[WaterHeaterMode.Structs.ModeTagStruct]' = field(default_factory=lambda: []) + + class Commands: + @dataclass + class ChangeToMode(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x0000009E + command_id: typing.ClassVar[int] = 0x00000000 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'ChangeToModeResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), + ]) + + newMode: 'uint' = 0 + + @dataclass + class ChangeToModeResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x0000009E + command_id: typing.ClassVar[int] = 0x00000001 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), + ]) + + status: 'uint' = 0 + statusText: 'typing.Optional[str]' = None + + class Attributes: + @dataclass + class SupportedModes(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009E + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[WaterHeaterMode.Structs.ModeOptionStruct]) + + value: 'typing.List[WaterHeaterMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + + @dataclass + class CurrentMode(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009E + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000001 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class StartUpMode(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009E + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000002 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) + + value: 'typing.Union[None, Nullable, uint]' = None + + @dataclass + class OnMode(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009E + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000003 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) + + value: 'typing.Union[None, Nullable, uint]' = None + + @dataclass + class GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009E + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF8 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AcceptedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009E + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF9 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class EventList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009E + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFA + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AttributeList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009E + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFB + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class FeatureMap(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009E + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFC + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class ClusterRevision(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000009E + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFD + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass class DeviceEnergyManagementMode(Cluster): id: typing.ClassVar[int] = 0x0000009F diff --git a/src/controller/python/chip/clusters/__init__.py b/src/controller/python/chip/clusters/__init__.py index 473e3f70a4f8d9..1aa2a61a8911d6 100644 --- a/src/controller/python/chip/clusters/__init__.py +++ b/src/controller/python/chip/clusters/__init__.py @@ -46,7 +46,8 @@ TemperatureControl, TemperatureMeasurement, Thermostat, ThermostatUserInterfaceConfiguration, ThreadBorderRouterManagement, ThreadNetworkDiagnostics, TimeFormatLocalization, TimeSynchronization, TotalVolatileOrganicCompoundsConcentrationMeasurement, UnitLocalization, UnitTesting, UserLabel, - ValveConfigurationAndControl, WakeOnLan, WiFiNetworkDiagnostics, WindowCovering) + ValveConfigurationAndControl, WakeOnLan, WaterHeaterManagement, WaterHeaterMode, WiFiNetworkDiagnostics, + WindowCovering) __all__ = [Attribute, CHIPClusters, Command, AccessControl, AccountLogin, Actions, ActivatedCarbonFilterMonitoring, AdministratorCommissioning, AirQuality, ApplicationBasic, ApplicationLauncher, AudioOutput, BallastConfiguration, BarrierControl, BasicInformation, @@ -69,4 +70,4 @@ Switch, TargetNavigator, TemperatureControl, TemperatureMeasurement, Thermostat, ThermostatUserInterfaceConfiguration, ThreadBorderRouterManagement, ThreadNetworkDiagnostics, TimeFormatLocalization, TimeSynchronization, TotalVolatileOrganicCompoundsConcentrationMeasurement, UnitLocalization, - UnitTesting, UserLabel, ValveConfigurationAndControl, WakeOnLan, WiFiNetworkDiagnostics, WindowCovering] + UnitTesting, UserLabel, ValveConfigurationAndControl, WakeOnLan, WaterHeaterManagement, WaterHeaterMode, WiFiNetworkDiagnostics, WindowCovering] diff --git a/src/controller/python/chip/clusters/attribute.cpp b/src/controller/python/chip/clusters/attribute.cpp index 7c5b2c906ab69c..421284a0ae795b 100644 --- a/src/controller/python/chip/clusters/attribute.cpp +++ b/src/controller/python/chip/clusters/attribute.cpp @@ -145,18 +145,20 @@ class ReadClientCallback : public ReadClient::Callback void OnSubscriptionEstablished(SubscriptionId aSubscriptionId) override { + // Only enable auto resubscribe if the subscription is established successfully. + mAutoResubscribeNeeded = mAutoResubscribe; gOnSubscriptionEstablishedCallback(mAppContext, aSubscriptionId); } CHIP_ERROR OnResubscriptionNeeded(ReadClient * apReadClient, CHIP_ERROR aTerminationCause) override { - if (mAutoResubscribe) + if (mAutoResubscribeNeeded) { ReturnErrorOnFailure(ReadClient::Callback::OnResubscriptionNeeded(apReadClient, aTerminationCause)); } gOnResubscriptionAttemptedCallback(mAppContext, ToPyChipError(aTerminationCause), apReadClient->ComputeTimeTillNextSubscription()); - if (mAutoResubscribe) + if (mAutoResubscribeNeeded) { return CHIP_NO_ERROR; } @@ -242,7 +244,8 @@ class ReadClientCallback : public ReadClient::Callback PyObject * mAppContext; std::unique_ptr mReadClient; - bool mAutoResubscribe = true; + bool mAutoResubscribe = true; + bool mAutoResubscribeNeeded = false; }; extern "C" { diff --git a/src/controller/python/chip/clusters/command.cpp b/src/controller/python/chip/clusters/command.cpp index d65766b7989d4d..037c848f96fae0 100644 --- a/src/controller/python/chip/clusters/command.cpp +++ b/src/controller/python/chip/clusters/command.cpp @@ -203,10 +203,13 @@ PyChipError SendBatchCommandsInternal(void * appContext, DeviceProxy * device, u CHIP_ERROR err = CHIP_NO_ERROR; bool testOnlySuppressTimedRequestMessage = false; - uint16_t * testOnlyCommandRefsOverride = nullptr; +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + uint16_t * testOnlyCommandRefsOverride = nullptr; +#endif VerifyOrReturnError(device->GetSecureSession().HasValue(), ToPyChipError(CHIP_ERROR_MISSING_SECURE_SESSION)); +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST // Test only override validation checks and setup if (testOnlyOverrides != nullptr) { @@ -228,6 +231,7 @@ PyChipError SendBatchCommandsInternal(void * appContext, DeviceProxy * device, u config.SetRemoteMaxPathsPerInvoke(testOnlyOverrides->overrideRemoteMaxPathsPerInvoke); } else +#endif { auto remoteSessionParameters = device->GetSecureSession().Value()->GetRemoteSessionParameters(); config.SetRemoteMaxPathsPerInvoke(remoteSessionParameters.GetMaxPathsPerInvoke()); @@ -273,6 +277,7 @@ PyChipError SendBatchCommandsInternal(void * appContext, DeviceProxy * device, u Optional timedRequestTimeout = timedRequestTimeoutMs != 0 ? Optional(timedRequestTimeoutMs) : Optional::Missing(); CommandSender::FinishCommandParameters finishCommandParams(timedRequestTimeout); +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST if (testOnlyCommandRefsOverride != nullptr) { finishCommandParams.commandRef.SetValue(testOnlyCommandRefsOverride[i]); @@ -291,6 +296,7 @@ PyChipError SendBatchCommandsInternal(void * appContext, DeviceProxy * device, u callback->AddCommandRefToIndexLookup(finishCommandParams.commandRef.Value(), i); } else +#endif { SuccessOrExit(err = callback->AddCommandRefToIndexLookup(finishCommandParams.commandRef.Value(), i)); } @@ -300,12 +306,14 @@ PyChipError SendBatchCommandsInternal(void * appContext, DeviceProxy * device, u Optional interactionTimeout = interactionTimeoutMs != 0 ? MakeOptional(System::Clock::Milliseconds32(interactionTimeoutMs)) : Optional::Missing(); +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST if (testOnlySuppressTimedRequestMessage) { SuccessOrExit(err = sender->TestOnlyCommandSenderTimedRequestFlagWithNoTimedInvoke(device->GetSecureSession().Value(), interactionTimeout)); } else +#endif { SuccessOrExit(err = sender->SendCommandRequest(device->GetSecureSession().Value(), interactionTimeout)); } diff --git a/src/controller/tests/data_model/DataModelFixtures.cpp b/src/controller/tests/data_model/DataModelFixtures.cpp index 11dbd1059f7415..2e5d7e65f7ee42 100644 --- a/src/controller/tests/data_model/DataModelFixtures.cpp +++ b/src/controller/tests/data_model/DataModelFixtures.cpp @@ -312,15 +312,15 @@ CHIP_ERROR WriteSingleClusterData(const Access::SubjectDescriptor & aSubjectDesc // Boolean attribute of unit testing cluster triggers "multiple errors" case. if (aPath.mClusterId == Clusters::UnitTesting::Id && aPath.mAttributeId == Attributes::Boolean::TypeInfo::GetAttributeId()) { - InteractionModel::ClusterStatusCode status{ Protocols::InteractionModel::Status::InvalidValue }; + Protocols::InteractionModel::ClusterStatusCode status{ Protocols::InteractionModel::Status::InvalidValue }; if (gWriteResponseDirective == WriteResponseDirective::kSendMultipleSuccess) { - status = InteractionModel::Status::Success; + status = Protocols::InteractionModel::Status::Success; } else if (gWriteResponseDirective == WriteResponseDirective::kSendMultipleErrors) { - status = InteractionModel::Status::Failure; + status = Protocols::InteractionModel::Status::Failure; } else { @@ -337,14 +337,14 @@ CHIP_ERROR WriteSingleClusterData(const Access::SubjectDescriptor & aSubjectDesc if (aPath.mClusterId == Clusters::UnitTesting::Id && aPath.mAttributeId == Attributes::Int8u::TypeInfo::GetAttributeId()) { - InteractionModel::ClusterStatusCode status{ Protocols::InteractionModel::Status::InvalidValue }; + Protocols::InteractionModel::ClusterStatusCode status{ Protocols::InteractionModel::Status::InvalidValue }; if (gWriteResponseDirective == WriteResponseDirective::kSendClusterSpecificSuccess) { - status = InteractionModel::ClusterStatusCode::ClusterSpecificSuccess(kExampleClusterSpecificSuccess); + status = Protocols::InteractionModel::ClusterStatusCode::ClusterSpecificSuccess(kExampleClusterSpecificSuccess); } else if (gWriteResponseDirective == WriteResponseDirective::kSendClusterSpecificFailure) { - status = InteractionModel::ClusterStatusCode::ClusterSpecificFailure(kExampleClusterSpecificFailure); + status = Protocols::InteractionModel::ClusterStatusCode::ClusterSpecificFailure(kExampleClusterSpecificFailure); } else { @@ -446,10 +446,10 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip } } -InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) +Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath) { // Mock cluster catalog, only support commands on one cluster on one endpoint. - using InteractionModel::Status; + using Protocols::InteractionModel::Status; if (aCommandPath.mEndpointId != kTestEndpointId) { diff --git a/src/controller/tests/data_model/TestCommands.cpp b/src/controller/tests/data_model/TestCommands.cpp index 0f6166cfed59b9..4e8b3dd39adb74 100644 --- a/src/controller/tests/data_model/TestCommands.cpp +++ b/src/controller/tests/data_model/TestCommands.cpp @@ -165,7 +165,7 @@ TEST_F(TestCommands, TestMultipleSuccessNoDataResponses) // not safe to do so. auto onSuccessCb = [&successCalls, &statusCheck](const ConcreteCommandPath & commandPath, const StatusIB & aStatus, const auto & dataResponse) { - statusCheck = (aStatus.mStatus == InteractionModel::Status::Success); + statusCheck = (aStatus.mStatus == Protocols::InteractionModel::Status::Success); ++successCalls; }; @@ -290,7 +290,7 @@ TEST_F(TestCommands, TestMultipleFailures) // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's // not safe to do so. auto onFailureCb = [&failureCalls, &statusCheck](CHIP_ERROR aError) { - statusCheck = aError.IsIMStatus() && StatusIB(aError).mStatus == InteractionModel::Status::Failure; + statusCheck = aError.IsIMStatus() && StatusIB(aError).mStatus == Protocols::InteractionModel::Status::Failure; ++failureCalls; }; diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 331d61129b9daf..7f03a9690b8e61 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -14,8 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#import -#import +#import #import "MTRAttributeTLVValueDecoder_Internal.h" #import "MTRBaseDevice_Internal.h" @@ -31,31 +30,32 @@ #import "MTRLogging_Internal.h" #import "MTRMetricKeys.h" #import "MTRSetupPayload_Internal.h" +#import "MTRUtilities.h" #import "NSDataSpanConversion.h" #import "NSStringSpanConversion.h" #import "zap-generated/MTRCommandPayloads_Internal.h" -#include "app/ConcreteAttributePath.h" -#include "app/ConcreteCommandPath.h" -#include "app/ConcreteEventPath.h" -#include "app/StatusResponse.h" -#include "lib/core/CHIPError.h" -#include "lib/core/DataModelTypes.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#import "app/ConcreteAttributePath.h" +#import "app/ConcreteCommandPath.h" +#import "app/ConcreteEventPath.h" +#import "app/StatusResponse.h" +#import "lib/core/CHIPError.h" +#import "lib/core/DataModelTypes.h" + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#import using namespace chip; using namespace chip::app; @@ -2290,8 +2290,9 @@ + (MTRAttributeRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)end - (BOOL)isEqualToAttributeRequestPath:(MTRAttributeRequestPath *)path { - return [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && - [_attribute isEqualToNumber:path.attribute]; + return MTREqualObjects(_endpoint, path.endpoint) + && MTREqualObjects(_cluster, path.cluster) + && MTREqualObjects(_attribute, path.attribute); } - (BOOL)isEqual:(id)object @@ -2362,8 +2363,9 @@ + (MTREventRequestPath *)requestPathWithEndpointID:(NSNumber * _Nullable)endpoin - (BOOL)isEqualToEventRequestPath:(MTREventRequestPath *)path { - return - [_endpoint isEqualToNumber:path.endpoint] && [_cluster isEqualToNumber:path.cluster] && [_event isEqualToNumber:path.event]; + return MTREqualObjects(_endpoint, path.endpoint) + && MTREqualObjects(_cluster, path.cluster) + && MTREqualObjects(_event, path.event); } - (BOOL)isEqual:(id)object @@ -2432,7 +2434,8 @@ ConcreteClusterPath path(static_cast([endpointID unsignedShort - (BOOL)isEqualToClusterPath:(MTRClusterPath *)clusterPath { - return [_endpoint isEqualToNumber:clusterPath.endpoint] && [_cluster isEqualToNumber:clusterPath.cluster]; + return MTREqualObjects(_endpoint, clusterPath.endpoint) + && MTREqualObjects(_cluster, clusterPath.cluster); } - (BOOL)isEqual:(id)object @@ -2520,7 +2523,7 @@ ConcreteDataAttributePath path(static_cast([endpointID unsigne - (BOOL)isEqualToAttributePath:(MTRAttributePath *)attributePath { - return [self isEqualToClusterPath:attributePath] && [_attribute isEqualToNumber:attributePath.attribute]; + return [self isEqualToClusterPath:attributePath] && MTREqualObjects(_attribute, attributePath.attribute); } - (BOOL)isEqual:(id)object @@ -2613,7 +2616,7 @@ ConcreteEventPath path(static_cast([endpointID unsignedShortVa - (BOOL)isEqualToEventPath:(MTREventPath *)eventPath { - return [self isEqualToClusterPath:eventPath] && [_event isEqualToNumber:eventPath.event]; + return [self isEqualToClusterPath:eventPath] && MTREqualObjects(_event, eventPath.event); } - (BOOL)isEqual:(id)object @@ -2703,7 +2706,7 @@ ConcreteCommandPath path(static_cast([endpointID unsignedShort - (BOOL)isEqualToCommandPath:(MTRCommandPath *)commandPath { - return [self isEqualToClusterPath:commandPath] && [_command isEqualToNumber:commandPath.command]; + return [self isEqualToClusterPath:commandPath] && MTREqualObjects(_command, commandPath.command); } - (BOOL)isEqual:(id)object diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 767fcd9c8307eb..93f96398b51c2f 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -15,7 +15,7 @@ * limitations under the License. */ -#import +#import #import #import "MTRAsyncWorkQueue.h" @@ -39,19 +39,20 @@ #import "MTRMetricsCollector.h" #import "MTRTimeUtils.h" #import "MTRUnfairLock.h" +#import "MTRUtilities.h" #import "zap-generated/MTRCommandPayloads_Internal.h" -#include "lib/core/CHIPError.h" -#include "lib/core/DataModelTypes.h" -#include -#include +#import "lib/core/CHIPError.h" +#import "lib/core/DataModelTypes.h" +#import +#import -#include -#include -#include -#include -#include -#include +#import +#import +#import +#import +#import +#import typedef void (^MTRDeviceAttributeReportHandler)(NSArray * _Nonnull); @@ -336,7 +337,8 @@ - (id)copyWithZone:(NSZone *)zone - (BOOL)isEqualToClusterData:(MTRDeviceClusterData *)otherClusterData { - return [_dataVersion isEqual:otherClusterData.dataVersion] && [_attributes isEqual:otherClusterData.attributes]; + return MTREqualObjects(_dataVersion, otherClusterData.dataVersion) + && MTREqualObjects(_attributes, otherClusterData.attributes); } - (BOOL)isEqual:(id)object diff --git a/src/darwin/Framework/CHIP/MTRUtilities.mm b/src/darwin/Framework/CHIP/MTRUtilities.mm index de85b498626495..e9698ab24d0b41 100644 --- a/src/darwin/Framework/CHIP/MTRUtilities.mm +++ b/src/darwin/Framework/CHIP/MTRUtilities.mm @@ -19,5 +19,16 @@ BOOL MTREqualObjects(id _Nullable a, id _Nullable b) { - return (a == nil) ? (b == nil) : [a isEqual:b]; + // Check if A is nil, and return based on B being nil (or not) + if (a == nil) { + return b == nil; + } + + // If B is nil at this point, we're not equal + if (b == nil) { + return NO; + } + + // Otherwise work on equality, given that we're both non nil + return [a isEqual:b]; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index b735da19e2edf6..87b96a713cf814 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -3443,6 +3443,45 @@ static BOOL AttributeIsSpecifiedInEnergyEVSEModeCluster(AttributeId aAttributeId } } } +static BOOL AttributeIsSpecifiedInWaterHeaterModeCluster(AttributeId aAttributeId) +{ + using namespace Clusters::WaterHeaterMode; + switch (aAttributeId) { + case Attributes::SupportedModes::Id: { + return YES; + } + case Attributes::CurrentMode::Id: { + return YES; + } + case Attributes::StartUpMode::Id: { + return YES; + } + case Attributes::OnMode::Id: { + return YES; + } + case Attributes::GeneratedCommandList::Id: { + return YES; + } + case Attributes::AcceptedCommandList::Id: { + return YES; + } + case Attributes::EventList::Id: { + return YES; + } + case Attributes::AttributeList::Id: { + return YES; + } + case Attributes::FeatureMap::Id: { + return YES; + } + case Attributes::ClusterRevision::Id: { + return YES; + } + default: { + return NO; + } + } +} static BOOL AttributeIsSpecifiedInDeviceEnergyManagementModeCluster(AttributeId aAttributeId) { using namespace Clusters::DeviceEnergyManagementMode; @@ -6963,6 +7002,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId) case Clusters::EnergyEvseMode::Id: { return AttributeIsSpecifiedInEnergyEVSEModeCluster(aAttributeId); } + case Clusters::WaterHeaterMode::Id: { + return AttributeIsSpecifiedInWaterHeaterModeCluster(aAttributeId); + } case Clusters::DeviceEnergyManagementMode::Id: { return AttributeIsSpecifiedInDeviceEnergyManagementModeCluster(aAttributeId); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index d55efa91505867..96f5a211636050 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -9819,6 +9819,114 @@ static id _Nullable DecodeAttributeValueForEnergyEVSEModeCluster(AttributeId aAt *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; return nil; } +static id _Nullable DecodeAttributeValueForWaterHeaterModeCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::WaterHeaterMode; + switch (aAttributeId) { + case Attributes::SupportedModes::Id: { + using TypeInfo = Attributes::SupportedModes::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSArray * _Nonnull value; + { // Scope for our temporary variables + auto * array_0 = [NSMutableArray new]; + auto iter_0 = cppValue.begin(); + while (iter_0.Next()) { + auto & entry_0 = iter_0.GetValue(); + MTRWaterHeaterModeClusterModeOptionStruct * newElement_0; + newElement_0 = [MTRWaterHeaterModeClusterModeOptionStruct new]; + newElement_0.label = AsString(entry_0.label); + if (newElement_0.label == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + newElement_0.mode = [NSNumber numberWithUnsignedChar:entry_0.mode]; + { // Scope for our temporary variables + auto * array_2 = [NSMutableArray new]; + auto iter_2 = entry_0.modeTags.begin(); + while (iter_2.Next()) { + auto & entry_2 = iter_2.GetValue(); + MTRWaterHeaterModeClusterModeTagStruct * newElement_2; + newElement_2 = [MTRWaterHeaterModeClusterModeTagStruct new]; + if (entry_2.mfgCode.HasValue()) { + newElement_2.mfgCode = [NSNumber numberWithUnsignedShort:chip::to_underlying(entry_2.mfgCode.Value())]; + } else { + newElement_2.mfgCode = nil; + } + newElement_2.value = [NSNumber numberWithUnsignedShort:entry_2.value]; + [array_2 addObject:newElement_2]; + } + CHIP_ERROR err = iter_2.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + newElement_0.modeTags = array_2; + } + [array_0 addObject:newElement_0]; + } + CHIP_ERROR err = iter_0.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value = array_0; + } + return value; + } + case Attributes::CurrentMode::Id: { + using TypeInfo = Attributes::CurrentMode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:cppValue]; + return value; + } + case Attributes::StartUpMode::Id: { + using TypeInfo = Attributes::StartUpMode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [NSNumber numberWithUnsignedChar:cppValue.Value()]; + } + return value; + } + case Attributes::OnMode::Id: { + using TypeInfo = Attributes::OnMode::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [NSNumber numberWithUnsignedChar:cppValue.Value()]; + } + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} static id _Nullable DecodeAttributeValueForDeviceEnergyManagementModeCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::DeviceEnergyManagementMode; @@ -20054,6 +20162,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T case Clusters::EnergyEvseMode::Id: { return DecodeAttributeValueForEnergyEVSEModeCluster(aPath.mAttributeId, aReader, aError); } + case Clusters::WaterHeaterMode::Id: { + return DecodeAttributeValueForWaterHeaterModeCluster(aPath.mAttributeId, aReader, aError); + } case Clusters::DeviceEnergyManagementMode::Id: { return DecodeAttributeValueForDeviceEnergyManagementModeCluster(aPath.mAttributeId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 671383907ad433..7163211742094e 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -8531,6 +8531,103 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Water Heater Mode + * + * Attributes and commands for selecting a mode from a list of supported options. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterWaterHeaterMode : MTRGenericBaseCluster + +/** + * Command ChangeToMode + * + * This command is used to change device modes. + On receipt of this command the device SHALL respond with a ChangeToModeResponse command. + */ +- (void)changeToModeWithParams:(MTRWaterHeaterModeClusterChangeToModeParams *)params completion:(void (^)(MTRWaterHeaterModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeSupportedModesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeSupportedModesWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeSupportedModesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeCurrentModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeCurrentModeWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeStartUpModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeStartUpModeWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeStartUpModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRBaseClusterWaterHeaterMode (Availability) + +/** + * For all instance methods (reads, writes, commands) that take a completion, + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Device Energy Management Mode * @@ -18729,6 +18826,16 @@ typedef NS_OPTIONS(uint32_t, MTREnergyEVSEModeFeature) { MTREnergyEVSEModeFeatureOnOff MTR_PROVISIONALLY_AVAILABLE = 0x1, } MTR_PROVISIONALLY_AVAILABLE; +typedef NS_ENUM(uint16_t, MTRWaterHeaterModeModeTag) { + MTRWaterHeaterModeModeTagOff MTR_PROVISIONALLY_AVAILABLE = 0x4000, + MTRWaterHeaterModeModeTagManual MTR_PROVISIONALLY_AVAILABLE = 0x4001, + MTRWaterHeaterModeModeTagTimed MTR_PROVISIONALLY_AVAILABLE = 0x4002, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_OPTIONS(uint32_t, MTRWaterHeaterModeFeature) { + MTRWaterHeaterModeFeatureOnOff MTR_PROVISIONALLY_AVAILABLE = 0x1, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint16_t, MTRDeviceEnergyManagementModeModeTag) { MTRDeviceEnergyManagementModeModeTagNoOptimization MTR_PROVISIONALLY_AVAILABLE = 0x4000, MTRDeviceEnergyManagementModeModeTagDeviceOptimization MTR_PROVISIONALLY_AVAILABLE = 0x4001, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index fa9a4ef3fcf602..6a15e501af9a7d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -55863,6 +55863,461 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @end +@implementation MTRBaseClusterWaterHeaterMode + +- (void)changeToModeWithParams:(MTRWaterHeaterModeClusterChangeToModeParams *)params completion:(void (^)(MTRWaterHeaterModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRWaterHeaterModeClusterChangeToModeParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WaterHeaterMode::Commands::ChangeToMode::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRWaterHeaterModeClusterChangeToModeResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)readAttributeSupportedModesWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::SupportedModes::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeSupportedModesWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::SupportedModes::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeSupportedModesWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::SupportedModes::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeCurrentModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::CurrentMode::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeCurrentModeWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::CurrentMode::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::CurrentMode::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeStartUpModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeStartUpModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; +} +- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; + TypeInfo::Type cppValue; + if (value == nil) { + cppValue.SetNull(); + } else { + auto & nonNullValue_0 = cppValue.SetNonNull(); + nonNullValue_0 = value.unsignedCharValue; + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeStartUpModeWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeStartUpModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::OnMode::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeOnModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; +} +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = WaterHeaterMode::Attributes::OnMode::TypeInfo; + TypeInfo::Type cppValue; + if (value == nil) { + cppValue.SetNull(); + } else { + auto & nonNullValue_0 = cppValue.SetNonNull(); + nonNullValue_0 = value.unsignedCharValue; + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::OnMode::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::OnMode::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::GeneratedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::GeneratedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::GeneratedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::AcceptedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::AcceptedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::AcceptedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::EventList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::EventList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::EventList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::AttributeList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::AttributeList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::AttributeList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::FeatureMap::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::FeatureMap::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::FeatureMap::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::ClusterRevision::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WaterHeaterMode::Attributes::ClusterRevision::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WaterHeaterMode::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + @implementation MTRBaseClusterDeviceEnergyManagementMode - (void)changeToModeWithParams:(MTRDeviceEnergyManagementModeClusterChangeToModeParams *)params completion:(void (^)(MTRDeviceEnergyManagementModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 02230b74b6483f..445404818a9573 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -159,6 +159,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { MTRClusterIDTypeEnergyPreferenceID MTR_PROVISIONALLY_AVAILABLE = 0x0000009B, MTRClusterIDTypePowerTopologyID MTR_PROVISIONALLY_AVAILABLE = 0x0000009C, MTRClusterIDTypeEnergyEVSEModeID MTR_PROVISIONALLY_AVAILABLE = 0x0000009D, + MTRClusterIDTypeWaterHeaterModeID MTR_PROVISIONALLY_AVAILABLE = 0x0000009E, MTRClusterIDTypeDeviceEnergyManagementModeID MTR_PROVISIONALLY_AVAILABLE = 0x0000009F, MTRClusterIDTypeDoorLockID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000101, MTRClusterIDTypeWindowCoveringID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000102, @@ -2748,6 +2749,18 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterEnergyEVSEModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterEnergyEVSEModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster WaterHeaterMode attributes + MTRAttributeIDTypeClusterWaterHeaterModeAttributeSupportedModesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeCurrentModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterWaterHeaterModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster DeviceEnergyManagementMode attributes MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeSupportedModesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeCurrentModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, @@ -6390,6 +6403,10 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterEnergyEVSEModeCommandChangeToModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRCommandIDTypeClusterEnergyEVSEModeCommandChangeToModeResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + // Cluster WaterHeaterMode commands + MTRCommandIDTypeClusterWaterHeaterModeCommandChangeToModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRCommandIDTypeClusterWaterHeaterModeCommandChangeToModeResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + // Cluster DeviceEnergyManagementMode commands MTRCommandIDTypeClusterDeviceEnergyManagementModeCommandChangeToModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRCommandIDTypeClusterDeviceEnergyManagementModeCommandChangeToModeResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 4492c5895c3219..777f3c0c3ba164 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -243,6 +243,9 @@ case MTRClusterIDTypeEnergyEVSEModeID: result = @"EnergyEVSEMode"; break; + case MTRClusterIDTypeWaterHeaterModeID: + result = @"WaterHeaterMode"; + break; case MTRClusterIDTypeDeviceEnergyManagementModeID: result = @"DeviceEnergyManagementMode"; break; @@ -4820,6 +4823,56 @@ break; } + case MTRClusterIDTypeWaterHeaterModeID: + + switch (attributeID) { + + // Cluster WaterHeaterMode attributes + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeSupportedModesID: + result = @"SupportedModes"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeCurrentModeID: + result = @"CurrentMode"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID: + result = @"StartUpMode"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID: + result = @"OnMode"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeGeneratedCommandListID: + result = @"GeneratedCommandList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeAcceptedCommandListID: + result = @"AcceptedCommandList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeEventListID: + result = @"EventList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeAttributeListID: + result = @"AttributeList"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeFeatureMapID: + result = @"FeatureMap"; + break; + + case MTRAttributeIDTypeClusterWaterHeaterModeAttributeClusterRevisionID: + result = @"ClusterRevision"; + break; + + default: + result = [NSString stringWithFormat:@"", attributeID]; + break; + } + case MTRClusterIDTypeDeviceEnergyManagementModeID: switch (attributeID) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 1113a02929193b..530ffcc58e2808 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -4021,6 +4021,56 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Water Heater Mode + * Attributes and commands for selecting a mode from a list of supported options. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterWaterHeaterMode : MTRGenericCluster + +- (void)changeToModeWithParams:(MTRWaterHeaterModeClusterChangeToModeParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRWaterHeaterModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeSupportedModesWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeCurrentModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeStartUpModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRClusterWaterHeaterMode (Availability) + +/** + * For all instance methods that take a completion (i.e. command invocations), + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Device Energy Management Mode * Attributes and commands for selecting a mode from a list of supported options. diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index c9b3095c75b150..a753bca9616931 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -10678,6 +10678,109 @@ - (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueD @end +@implementation MTRClusterWaterHeaterMode + +- (void)changeToModeWithParams:(MTRWaterHeaterModeClusterChangeToModeParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRWaterHeaterModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRWaterHeaterModeClusterChangeToModeParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WaterHeaterMode::Commands::ChangeToMode::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRWaterHeaterModeClusterChangeToModeResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (NSDictionary * _Nullable)readAttributeSupportedModesWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeSupportedModesID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeCurrentModeWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeCurrentModeID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeStartUpModeWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID) params:params]; +} + +- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeStartUpModeWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID) params:params]; +} + +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeOnModeWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeClusterRevisionID) params:params]; +} + +@end + @implementation MTRClusterDeviceEnergyManagementMode - (void)changeToModeWithParams:(MTRDeviceEnergyManagementModeClusterChangeToModeParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRDeviceEnergyManagementModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index acb7982d9f9283..7c30f13fbe7044 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -6178,6 +6178,57 @@ MTR_PROVISIONALLY_AVAILABLE error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWaterHeaterModeClusterChangeToModeParams : NSObject + +@property (nonatomic, copy, getter=getNewMode) NSNumber * _Nonnull newMode MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWaterHeaterModeClusterChangeToModeResponseParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull status MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSString * _Nullable statusText MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRWaterHeaterModeClusterChangeToModeResponseParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_PROVISIONALLY_AVAILABLE @interface MTRDeviceEnergyManagementModeClusterChangeToModeParams : NSObject diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index 8ab9ac346812c5..441fc5cb8361cf 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -17590,6 +17590,178 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::EnergyEv @end +@implementation MTRWaterHeaterModeClusterChangeToModeParams +- (instancetype)init +{ + if (self = [super init]) { + + _newMode = @(0); + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWaterHeaterModeClusterChangeToModeParams alloc] init]; + + other.newMode = self.newMode; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: newMode:%@; >", NSStringFromClass([self class]), _newMode]; + return descriptionString; +} + +@end + +@implementation MTRWaterHeaterModeClusterChangeToModeParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.newMode = self.newMode.unsignedCharValue; + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRWaterHeaterModeClusterChangeToModeResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _status = @(0); + + _statusText = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWaterHeaterModeClusterChangeToModeResponseParams alloc] init]; + + other.status = self.status; + other.statusText = self.statusText; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: status:%@; statusText:%@; >", NSStringFromClass([self class]), _status, _statusText]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRWaterHeaterModeClusterChangeToModeResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType &)decodableStruct +{ + { + self.status = [NSNumber numberWithUnsignedChar:decodableStruct.status]; + } + { + if (decodableStruct.statusText.HasValue()) { + self.statusText = AsString(decodableStruct.statusText.Value()); + if (self.statusText == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.statusText = nil; + } + } + return CHIP_NO_ERROR; +} + +@end + @implementation MTRDeviceEnergyManagementModeClusterChangeToModeParams - (instancetype)init { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h index 7072a0db6c26ef..c229f6cda86db8 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -1162,6 +1162,18 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRWaterHeaterModeClusterChangeToModeParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRWaterHeaterModeClusterChangeToModeResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType &)decodableStruct; + +@end + @interface MTRDeviceEnergyManagementModeClusterChangeToModeParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm index 5e09e32a955523..4abe6bf88050bd 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm @@ -701,6 +701,15 @@ static BOOL CommandNeedsTimedInvokeInEnergyEVSEModeCluster(AttributeId aAttribut } } } +static BOOL CommandNeedsTimedInvokeInWaterHeaterModeCluster(AttributeId aAttributeId) +{ + using namespace Clusters::WaterHeaterMode; + switch (aAttributeId) { + default: { + return NO; + } + } +} static BOOL CommandNeedsTimedInvokeInDeviceEnergyManagementModeCluster(AttributeId aAttributeId) { using namespace Clusters::DeviceEnergyManagementMode; @@ -1407,6 +1416,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn case Clusters::EnergyEvseMode::Id: { return CommandNeedsTimedInvokeInEnergyEVSEModeCluster(commandID); } + case Clusters::WaterHeaterMode::Id: { + return CommandNeedsTimedInvokeInWaterHeaterModeCluster(commandID); + } case Clusters::DeviceEnergyManagementMode::Id: { return CommandNeedsTimedInvokeInDeviceEnergyManagementModeCluster(commandID); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index 049f67951b7408..445807b9902bd8 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -3306,6 +3306,18 @@ static id _Nullable DecodeEventPayloadForEnergyEVSEModeCluster(EventId aEventId, *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; return nil; } +static id _Nullable DecodeEventPayloadForWaterHeaterModeCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::WaterHeaterMode; + switch (aEventId) { + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} static id _Nullable DecodeEventPayloadForDeviceEnergyManagementModeCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::DeviceEnergyManagementMode; @@ -4900,6 +4912,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead case Clusters::EnergyEvseMode::Id: { return DecodeEventPayloadForEnergyEVSEModeCluster(aPath.mEventId, aReader, aError); } + case Clusters::WaterHeaterMode::Id: { + return DecodeEventPayloadForWaterHeaterModeCluster(aPath.mEventId, aReader, aError); + } case Clusters::DeviceEnergyManagementMode::Id: { return DecodeEventPayloadForDeviceEnergyManagementModeCluster(aPath.mEventId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index e72e520b198f79..dd93b4322ad447 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -1454,6 +1454,19 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy) NSArray * _Nonnull modeTags MTR_PROVISIONALLY_AVAILABLE; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWaterHeaterModeClusterModeTagStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nullable mfgCode MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull value MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWaterHeaterModeClusterModeOptionStruct : NSObject +@property (nonatomic, copy) NSString * _Nonnull label MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull mode MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSArray * _Nonnull modeTags MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_PROVISIONALLY_AVAILABLE @interface MTRDeviceEnergyManagementModeClusterModeTagStruct : NSObject @property (nonatomic, copy) NSNumber * _Nullable mfgCode MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index 09314a688222f6..6fe345c0621baf 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -6008,6 +6008,69 @@ - (NSString *)description @end +@implementation MTRWaterHeaterModeClusterModeTagStruct +- (instancetype)init +{ + if (self = [super init]) { + + _mfgCode = nil; + + _value = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRWaterHeaterModeClusterModeTagStruct alloc] init]; + + other.mfgCode = self.mfgCode; + other.value = self.value; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: mfgCode:%@; value:%@; >", NSStringFromClass([self class]), _mfgCode, _value]; + return descriptionString; +} + +@end + +@implementation MTRWaterHeaterModeClusterModeOptionStruct +- (instancetype)init +{ + if (self = [super init]) { + + _label = @""; + + _mode = @(0); + + _modeTags = [NSArray array]; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRWaterHeaterModeClusterModeOptionStruct alloc] init]; + + other.label = self.label; + other.mode = self.mode; + other.modeTags = self.modeTags; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: label:%@; mode:%@; modeTags:%@; >", NSStringFromClass([self class]), _label, _mode, _modeTags]; + return descriptionString; +} + +@end + @implementation MTRDeviceEnergyManagementModeClusterModeTagStruct - (instancetype)init { diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 132ab263cf30f6..da059fc505de8c 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -1898,6 +1898,20 @@ - (void)test020_ReadMultipleAttributes MTRBaseDevice * device = GetConnectedDevice(); dispatch_queue_t queue = dispatch_get_main_queue(); + // Get the list of endpoints from the device. Endpoint 0 we have to add explicitly, since it's + // not in its own PartsList. + XCTestExpectation * descriptorReadExpectation = [self expectationWithDescription:@"read PartsList from endpoint 0"]; + __auto_type * descriptorCluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device endpointID:@(0) queue:queue]; + __block NSMutableArray * endpointList = [NSMutableArray arrayWithObject:@0]; + [descriptorCluster readAttributePartsListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + XCTAssertNil(error); + XCTAssertNotNil(value); + [endpointList addObjectsFromArray:value]; + [descriptorReadExpectation fulfill]; + }]; + + [self waitForExpectations:@[ descriptorReadExpectation ] timeout:kTimeoutInSeconds]; + NSArray * attributePaths = @[ [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@0], [MTRAttributeRequestPath requestPathWithEndpointID:nil clusterID:@29 attributeID:@1], @@ -2028,8 +2042,7 @@ - (void)test020_ReadMultipleAttributes MTRAttributePath * path = result[@"attributePath"]; if ([path.attribute unsignedIntegerValue] < 4) { XCTAssertEqualObjects(path.cluster, @29); - __auto_type endpoint = [path.endpoint unsignedShortValue]; - XCTAssertTrue(endpoint == 0 || endpoint == 1 || endpoint == 2); + XCTAssertTrue([endpointList containsObject:path.endpoint]); } else { XCTAssertEqualObjects(path.cluster, @40); XCTAssertEqualObjects(path.endpoint, @0); @@ -2041,10 +2054,10 @@ - (void)test020_ReadMultipleAttributes XCTFail("Unexpected result dictionary %@", result); } } - // Our test application has 3 endpoints. We have a descriptor on each one, - // so that's 4 results per endpoint, and we only have Basic Information on - // endpoint 0, so that's 4 more results. - XCTAssertEqual(attributeResultCount, 3 * 4 + 4); + // We have a descriptor on each endpoint, so that's 4 results per endpoint, + // and we only have Basic Information on endpoint 0, so that's 4 more + // results. + XCTAssertEqual(attributeResultCount, endpointList.count * 4 + 4); XCTAssertEqual(eventResultCount, [eventPaths count]); [expectation fulfill]; @@ -2061,11 +2074,11 @@ - (void)test021_ReadMultipleWildcardPathsIncludeUnsupportedAttribute // Read the PartList of descriptor on endpoint 0 to find out how many endpoints there are. XCTestExpectation * descriptorReadExpectation = [self expectationWithDescription:@"read PartsList from endpoint 0"]; __auto_type * descriptorCluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device endpointID:@(0) queue:queue]; - __block size_t endpointCount = 0; + __block NSMutableArray * endpointList = [NSMutableArray arrayWithObject:@0]; [descriptorCluster readAttributePartsListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { XCTAssertNil(error); XCTAssertNotNil(value); - endpointCount = value.count + 1; // Include endpoint 0 + [endpointList addObjectsFromArray:value]; [descriptorReadExpectation fulfill]; }]; @@ -2103,14 +2116,13 @@ - (void)test021_ReadMultipleWildcardPathsIncludeUnsupportedAttribute // and we only have Basic Information on endpoint 0, so that's 4 more // results. Note that there are no results for failAttributeID, because we // used a wildcard path and hence it got ignored. - XCTAssertEqual(resultArray.count, endpointCount * 4 + 4); + XCTAssertEqual(resultArray.count, endpointList.count * 4 + 4); for (NSDictionary * result in resultArray) { MTRAttributePath * path = result[@"attributePath"]; if ([path.attribute unsignedIntegerValue] < 4) { XCTAssertEqualObjects(path.cluster, @29); - __auto_type endpoint = [path.endpoint unsignedShortValue]; - XCTAssertTrue(endpoint == 0 || endpoint == 1 || endpoint == 2); + XCTAssertTrue([endpointList containsObject:path.endpoint]); } else { XCTAssertEqualObjects(path.cluster, @40); XCTAssertEqualObjects(path.endpoint, @0); @@ -3171,7 +3183,7 @@ + (void)checkAttributeReportTriggersConfigurationChanged:(MTRAttributeIDType)att XCTestExpectation * gotAttributeReportExpectation = [testcase expectationWithDescription:@"Attribute report has been received"]; XCTestExpectation * gotAttributeReportEndExpectation = [testcase expectationWithDescription:@"Attribute report has ended"]; - XCTestExpectation * deviceConfigurationChangedExpectation = [testcase expectationWithDescription:@"Device configuration changed was receieved"]; + XCTestExpectation * deviceConfigurationChangedExpectation = [testcase expectationWithDescription:@"Device configuration changed was received"]; deviceConfigurationChangedExpectation.inverted = !expectConfigurationChanged; __block unsigned attributeReportsReceived = 0; @@ -3252,13 +3264,22 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged // attribute list and cluster revision for the Identify cluster, accepted commands list for oven cavity operational state ID cluster and // feature map for groups ID cluster. __block NSNumber * dataVersionForPartsList; + __block NSMutableArray *> * valueForPartsList; + __block NSNumber * endpointForPartsList; __block NSNumber * dataVersionForDeviceTypesList; + __block NSNumber * endpointForDeviceTypeList; __block NSNumber * dataVersionForServerList; + __block NSNumber * endpointForServerList; __block NSNumber * dataVersionForAcceptedCommandList; + __block NSNumber * endpointForAcceptedCommandList; __block NSNumber * dataVersionForAttributeList; + __block NSNumber * endpointForAttributeList; __block NSNumber * dataVersionForClusterRevision; + __block NSNumber * endpointForClusterRevision; __block NSNumber * dataVersionForFeatureMap; + __block NSNumber * endpointForFeatureMap; __block NSNumber * dataVersionForPowerConfigurationSources; + __block NSNumber * endpointForPowerConfigurationSources; delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { attributeReportsReceived += attributeReport.count; @@ -3268,20 +3289,24 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged MTRAttributePath * attributePath = attributeDict[MTRAttributePathKey]; XCTAssertNotNil(attributePath); - if (attributePath.cluster.unsignedLongValue == MTRClusterIDTypeDescriptorID) { + if (attributePath.cluster.unsignedLongValue == MTRClusterIDTypeDescriptorID && attributePath.endpoint.unsignedLongValue == 0) { NSDictionary * data = attributeDict[MTRDataKey]; XCTAssertNotNil(data); switch (attributePath.attribute.unsignedLongValue) { case MTRAttributeIDTypeClusterDescriptorAttributePartsListID: { dataVersionForPartsList = data[MTRDataVersionKey]; + valueForPartsList = [data[MTRValueKey] mutableCopy]; + endpointForPartsList = attributePath.endpoint; break; } case MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID: { dataVersionForDeviceTypesList = data[MTRDataVersionKey]; + endpointForDeviceTypeList = attributePath.endpoint; break; } case MTRAttributeIDTypeClusterDescriptorAttributeServerListID: { dataVersionForServerList = data[MTRDataVersionKey]; + endpointForServerList = attributePath.endpoint; break; } } @@ -3291,10 +3316,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged switch (attributePath.attribute.unsignedLongValue) { case MTRAttributeIDTypeGlobalAttributeAttributeListID: { dataVersionForAttributeList = data[MTRDataVersionKey]; + endpointForAttributeList = attributePath.endpoint; break; } case MTRAttributeIDTypeGlobalAttributeClusterRevisionID: { dataVersionForClusterRevision = data[MTRDataVersionKey]; + endpointForClusterRevision = attributePath.endpoint; break; } } @@ -3302,14 +3329,17 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged NSDictionary * data = attributeDict[MTRDataKey]; XCTAssertNotNil(data); dataVersionForAcceptedCommandList = data[MTRDataVersionKey]; + endpointForAcceptedCommandList = attributePath.endpoint; } else if (attributePath.cluster.unsignedLongValue == MTRClusterIDTypeGroupsID && attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeGlobalAttributeFeatureMapID) { NSDictionary * data = attributeDict[MTRDataKey]; XCTAssertNotNil(data); dataVersionForFeatureMap = data[MTRDataVersionKey]; + endpointForFeatureMap = attributePath.endpoint; } else if (attributePath.cluster.unsignedLongValue == MTRClusterIDTypePowerSourceConfigurationID && attributePath.attribute.unsignedLongValue == MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID) { NSDictionary * data = attributeDict[MTRDataKey]; XCTAssertNotNil(data); dataVersionForPowerConfigurationSources = data[MTRDataVersionKey]; + endpointForPowerConfigurationSources = attributePath.endpoint; } } }; @@ -3342,37 +3372,30 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged // Test attribute path - endpointId = 0, clusterId = descriptor, attributeId = parts list. dataVersionForPartsList = [NSNumber numberWithUnsignedLongLong:(dataVersionForPartsList.unsignedLongLongValue + 1)]; - NSArray *> * unsignedIntegerArrayValue = @[ - @{ + // Figure out an endpoint ID (not 0) we can add to PartsList. + for (unsigned i = 1; true; ++i) { + __auto_type unsignedIntegerValue = @{ MTRDataKey : @ { MTRTypeKey : MTRUnsignedIntegerValueType, - MTRValueKey : @1, - } - }, - @{ - MTRDataKey : @ { - MTRTypeKey : MTRUnsignedIntegerValueType, - MTRValueKey : @2, + MTRValueKey : @(i), } - }, - @{ - MTRDataKey : @ { - MTRTypeKey : MTRUnsignedIntegerValueType, - MTRValueKey : @3, - } - }, - ]; + }; + if (![valueForPartsList containsObject:unsignedIntegerValue]) { + [valueForPartsList addObject:unsignedIntegerValue]; + break; + } + } NSArray *> * attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributePartsListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForPartsList clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributePartsListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForPartsList, MTRTypeKey : MTRArrayValueType, - MTRValueKey : unsignedIntegerArrayValue, + MTRValueKey : valueForPartsList, } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributePartsListID clusterId:MTRClusterIDTypeDescriptorID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForPartsList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributePartsListID clusterId:MTRClusterIDTypeDescriptorID endpointId:endpointForPartsList device:device delegate:delegate dataVersion:dataVersionForPartsList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 0, clusterId = descriptor, attributeId = device types list. dataVersionForDeviceTypesList = [NSNumber numberWithUnsignedLongLong:(dataVersionForDeviceTypesList.unsignedLongLongValue + 1)]; @@ -3401,7 +3424,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged ]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForDeviceTypeList clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForDeviceTypesList, MTRTypeKey : MTRArrayValueType, @@ -3409,12 +3432,34 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID clusterId:MTRClusterIDTypeDescriptorID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForDeviceTypesList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + // unsignedIntegerArrayValue is used for a variety of tests below. + NSArray *> * unsignedIntegerArrayValue = @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @1, + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @2, + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @3, + } + }, + ]; + + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributeDeviceTypeListID clusterId:MTRClusterIDTypeDescriptorID endpointId:endpointForDeviceTypeList device:device delegate:delegate dataVersion:dataVersionForDeviceTypesList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 0, clusterId = descriptor, attributeId = server list. dataVersionForServerList = [NSNumber numberWithUnsignedLongLong:(dataVersionForServerList.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeServerListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForServerList clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeServerListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForServerList, MTRTypeKey : MTRArrayValueType, @@ -3422,12 +3467,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributeServerListID clusterId:MTRClusterIDTypeDescriptorID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForServerList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterDescriptorAttributeServerListID clusterId:MTRClusterIDTypeDescriptorID endpointId:endpointForServerList device:device delegate:delegate dataVersion:dataVersionForServerList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 1, clusterId = ovencavityoperationalstateID, attributeId = accepted command list. dataVersionForAcceptedCommandList = [NSNumber numberWithUnsignedLongLong:(dataVersionForAcceptedCommandList.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(1) clusterID:@(MTRClusterIDTypeOvenCavityOperationalStateID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForAcceptedCommandList clusterID:@(MTRClusterIDTypeOvenCavityOperationalStateID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForAcceptedCommandList, MTRTypeKey : MTRArrayValueType, @@ -3435,12 +3480,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID clusterId:MTRClusterIDTypeOvenCavityOperationalStateID endpointId:@(1) device:device delegate:delegate dataVersion:dataVersionForAcceptedCommandList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID clusterId:MTRClusterIDTypeOvenCavityOperationalStateID endpointId:endpointForAcceptedCommandList device:device delegate:delegate dataVersion:dataVersionForAcceptedCommandList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 0, clusterId = identify, attributeId = attribute list. dataVersionForAttributeList = [NSNumber numberWithUnsignedLongLong:(dataVersionForAttributeList.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAttributeListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForAttributeList clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAttributeListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForAttributeList, MTRTypeKey : MTRArrayValueType, @@ -3448,12 +3493,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeAttributeListID clusterId:MTRClusterIDTypeIdentifyID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForAttributeList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeAttributeListID clusterId:MTRClusterIDTypeIdentifyID endpointId:endpointForAttributeList device:device delegate:delegate dataVersion:dataVersionForAttributeList attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 0, clusterId = identify, attributeId = cluster revision. dataVersionForClusterRevision = [NSNumber numberWithUnsignedLongLong:(dataVersionForClusterRevision.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeClusterRevisionID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForClusterRevision clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeClusterRevisionID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForClusterRevision, MTRTypeKey : MTRUnsignedIntegerValueType, @@ -3461,12 +3506,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeClusterRevisionID clusterId:MTRClusterIDTypeIdentifyID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForClusterRevision attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeClusterRevisionID clusterId:MTRClusterIDTypeIdentifyID endpointId:endpointForClusterRevision device:device delegate:delegate dataVersion:dataVersionForClusterRevision attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path - endpointId = 0, clusterId = groupsID, attributeId = feature map. dataVersionForFeatureMap = [NSNumber numberWithUnsignedLongLong:(dataVersionForFeatureMap.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeGroupsID) attributeID:@(MTRAttributeIDTypeGlobalAttributeFeatureMapID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForFeatureMap clusterID:@(MTRClusterIDTypeGroupsID) attributeID:@(MTRAttributeIDTypeGlobalAttributeFeatureMapID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForFeatureMap, MTRTypeKey : MTRUnsignedIntegerValueType, @@ -3474,12 +3519,12 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeFeatureMapID clusterId:MTRClusterIDTypeGroupsID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForFeatureMap attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeGlobalAttributeFeatureMapID clusterId:MTRClusterIDTypeGroupsID endpointId:endpointForFeatureMap device:device delegate:delegate dataVersion:dataVersionForFeatureMap attributeReport:attributeReport testcase:self expectConfigurationChanged:YES]; // Test attribute path that doesn't cause a device configuration changed - endpointId = 1, clusterId = power source configuration, attributeId = sources. dataVersionForPowerConfigurationSources = [NSNumber numberWithUnsignedLongLong:(dataVersionForPowerConfigurationSources.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypePowerSourceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForPowerConfigurationSources clusterID:@(MTRClusterIDTypePowerSourceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForPowerConfigurationSources, MTRTypeKey : MTRArrayValueType, @@ -3487,7 +3532,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } } ]; - [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID clusterId:MTRClusterIDTypePowerSourceConfigurationID endpointId:@(0) device:device delegate:delegate dataVersion:dataVersionForPowerConfigurationSources attributeReport:attributeReport testcase:self expectConfigurationChanged:NO]; + [MTRDeviceTests checkAttributeReportTriggersConfigurationChanged:MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID clusterId:MTRClusterIDTypePowerSourceConfigurationID endpointId:endpointForPowerConfigurationSources device:device delegate:delegate dataVersion:dataVersionForPowerConfigurationSources attributeReport:attributeReport testcase:self expectConfigurationChanged:NO]; NSArray *> * newUnsignedIntegerArrayValue = @[ @{ @@ -3510,7 +3555,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged dataVersionForPowerConfigurationSources = [NSNumber numberWithUnsignedLongLong:(dataVersionForPowerConfigurationSources.unsignedLongLongValue + 1)]; attributeReport = @[ @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAttributeListID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForAttributeList clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeGlobalAttributeAttributeListID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForAttributeList, MTRTypeKey : MTRArrayValueType, @@ -3518,7 +3563,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } }, @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeGroupsID) attributeID:@(MTRAttributeIDTypeGlobalAttributeFeatureMapID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForFeatureMap clusterID:@(MTRClusterIDTypeGroupsID) attributeID:@(MTRAttributeIDTypeGlobalAttributeFeatureMapID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForFeatureMap, MTRTypeKey : MTRUnsignedIntegerValueType, @@ -3526,7 +3571,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged } }, @{ - MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(MTRClusterIDTypePowerSourceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID)], + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:endpointForPowerConfigurationSources clusterID:@(MTRClusterIDTypePowerSourceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID)], MTRDataKey : @ { MTRDataVersionKey : dataVersionForPowerConfigurationSources, MTRTypeKey : MTRArrayValueType, diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index ced79aadb78b82..4c7375c45dd06b 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -2508,11 +2508,12 @@ - (void)testDataStorageUpdatesWhenRemovingEndpoints __block NSNumber * rootEndpoint = @0; // This test will do the following - - // 1. Get the data version and attribute value of the parts list for endpoint 0 to inject a fake report. The attribute report will delete endpoint 2. + // 1. Get the data version and attribute value of the parts list for endpoint 0 to inject a fake report. + // The injected attribute report will delete endpoint 2. // That should cause the endpoint and its corresponding clusters to be removed from data storage. - // 2. The data store is populated with cluster index and cluster data for endpoints 0, 1 and 2 initially. + // 2. The data store is populated with cluster index and cluster data for the set of endpoints in our test app initially. // 3. After the fake attribute report is injected with deleted endpoint 2, make sure the data store is still populated with cluster index and cluster data - // for endpoints 0 and 1 but not 2. + // for all the other endpoints. __block MTRDeviceDataValueDictionary testDataForPartsList; __block id testClusterDataValueForPartsList; delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { @@ -2534,18 +2535,21 @@ - (void)testDataStorageUpdatesWhenRemovingEndpoints }; __block NSMutableDictionary *> * initialClusterIndex = [[NSMutableDictionary alloc] init]; - __block NSMutableArray * testEndpoints; + // Some of the places we get endpoint lists get them from enumerating dictionary keys, which + // means order is not guaranteed. Make sure we compare sets of endpoints, not arrays, to + // account for that. + __block NSSet * testEndpoints; delegate.onReportEnd = ^{ XCTAssertNotNil(dataVersionForPartsList); XCTAssertNotNil(testClusterDataValueForPartsList); - testEndpoints = [self getEndpointArrayFromPartsList:testDataForPartsList forDevice:device]; + testEndpoints = [NSSet setWithArray:[self getEndpointArrayFromPartsList:testDataForPartsList forDevice:device]]; - // Make sure that the cluster data in the data storage is populated with cluster index and cluster data for endpoints 0, 1 and 2. + // Make sure that the cluster data in the data storage is populated with cluster index and cluster data for our endpoints. // We do not need to check _persistedClusterData here. _persistedClusterData will be paged in from storage when needed so // just checking data storage should suffice here. dispatch_sync(self->_storageQueue, ^{ - XCTAssertTrue([[controller.controllerDataStore _fetchEndpointIndexForNodeID:deviceID] isEqualToArray:testEndpoints]); + XCTAssertEqualObjects([NSSet setWithArray:[controller.controllerDataStore _fetchEndpointIndexForNodeID:deviceID]], testEndpoints); // Populate the initialClusterIndex to use as a reference for all cluster paths later. for (NSNumber * endpoint in testEndpoints) { @@ -2568,8 +2572,9 @@ - (void)testDataStorageUpdatesWhenRemovingEndpoints // Inject a fake attribute report deleting endpoint 2 from the parts list at the root endpoint. dataVersionForPartsList = [NSNumber numberWithUnsignedLongLong:(dataVersionForPartsList.unsignedLongLongValue + 1)]; - // Delete endpoint 2 from the attribute value in parts list. + // Delete our to-be-deleted endpoint from the attribute value in parts list. Make sure it's in the list to start with. NSNumber * toBeDeletedEndpoint = @2; + XCTAssertTrue([testEndpoints containsObject:toBeDeletedEndpoint]); id endpointData = @{ MTRDataKey : @ { @@ -2578,6 +2583,7 @@ - (void)testDataStorageUpdatesWhenRemovingEndpoints } }; + XCTAssertTrue([testClusterDataValueForPartsList containsObject:endpointData]); [testClusterDataValueForPartsList removeObject:endpointData]; NSArray *> * attributeReport = @[ @{ @@ -2612,13 +2618,13 @@ - (void)testDataStorageUpdatesWhenRemovingEndpoints delegate.onReportEnd = ^{ XCTAssertNotNil(testClusterDataValueForPartsList); - testEndpoints = [self getEndpointArrayFromPartsList:testDataForPartsList forDevice:device]; + testEndpoints = [NSSet setWithArray:[self getEndpointArrayFromPartsList:testDataForPartsList forDevice:device]]; - // Make sure that the cluster data in the data storage for endpoints 0 and 1 are present but not for endpoint 2. + // Make sure that the cluster data is removed from the data storage for the endpoint we deleted, but still there for the others. // We do not need to check _persistedClusterData here. _persistedClusterData will be paged in from storage when needed so // just checking data storage should suffice here. dispatch_sync(self->_storageQueue, ^{ - XCTAssertTrue([[controller.controllerDataStore _fetchEndpointIndexForNodeID:deviceID] isEqualToArray:testEndpoints]); + XCTAssertEqualObjects([NSSet setWithArray:[controller.controllerDataStore _fetchEndpointIndexForNodeID:deviceID]], testEndpoints); for (NSNumber * endpoint in testEndpoints) { XCTAssertNotNil(initialClusterIndex); for (NSNumber * cluster in [initialClusterIndex objectForKey:endpoint]) { diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index df5949868d0012..b23605ce2eaa4e 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -1626,6 +1626,7 @@ B2E0D7B2245B0B5C003C5B48 /* MTRManualSetupPayloadParser.h in Headers */, 3CF134A7289D8ADA0017A19E /* MTRCSRInfo.h in Headers */, 88E07D612B9A89A4005FD53E /* MTRMetricKeys.h in Headers */, + 3D4733B32BE2D1DA003DC19B /* MTRUtilities.h in Headers */, B2E0D7B1245B0B5C003C5B48 /* Matter.h in Headers */, 7596A84428762729004DAE0E /* MTRDevice.h in Headers */, B2E0D7B8245B0B5C003C5B48 /* MTRSetupPayload.h in Headers */, @@ -1671,7 +1672,6 @@ 514C7A022B64223400DD6D7B /* MTRServerEndpoint_Internal.h in Headers */, 511913FC28C100EF009235E9 /* MTRBaseSubscriptionCallback.h in Headers */, 51565CB12A7AD77600469F18 /* MTRDeviceControllerDataStore.h in Headers */, - 3D4733B32BE2D1DA003DC19B /* MTRUtilities.h in Headers */, 3D843713294977000070D20A /* NSDataSpanConversion.h in Headers */, 991DC08B247704DC00C13860 /* MTRLogging_Internal.h in Headers */, 51FE723F2ACDEF3E00437032 /* MTRCommandPayloadExtensions_Internal.h in Headers */, diff --git a/src/messaging/ExchangeMgr.cpp b/src/messaging/ExchangeMgr.cpp index bf92fa22f54985..0e41593b08afea 100644 --- a/src/messaging/ExchangeMgr.cpp +++ b/src/messaging/ExchangeMgr.cpp @@ -215,16 +215,23 @@ void ExchangeManager::OnMessageReceived(const PacketHeader & packetHeader, const } } + // Work around pigweed not allowing more than 14 format args in a log + // message when using tokenized logs. + char typeStr[4 + 1 + 2 + 1]; + snprintf(typeStr, sizeof(typeStr), "%04X:%02X", payloadHeader.GetProtocolID().GetProtocolId(), payloadHeader.GetMessageType()); + // // Legend that can be used to decode this log line can be found in README.md // - ChipLogProgress(ExchangeManager, - ">>> [E:" ChipLogFormatExchangeId " S:%u M:" ChipLogFormatMessageCounter - "%s] (%s) Msg RX from %u:" ChipLogFormatX64 " [%04X] --- Type %04x:%02x (%s:%s)", - ChipLogValueExchangeIdFromReceivedHeader(payloadHeader), session->SessionIdForLogging(), - packetHeader.GetMessageCounter(), ackBuf, Transport::GetSessionTypeString(session), session->GetFabricIndex(), - ChipLogValueX64(session->GetPeer().GetNodeId()), static_cast(compressedFabricId), - payloadHeader.GetProtocolID().GetProtocolId(), payloadHeader.GetMessageType(), protocolName, msgTypeName); + ChipLogProgress( + ExchangeManager, + ">>> [E:" ChipLogFormatExchangeId " S:%u M:" ChipLogFormatMessageCounter "%s] (%s) Msg RX from %u:" ChipLogFormatX64 + " [%04X] --- Type %s (%s:%s) (B:%u)", + ChipLogValueExchangeIdFromReceivedHeader(payloadHeader), session->SessionIdForLogging(), packetHeader.GetMessageCounter(), + ackBuf, Transport::GetSessionTypeString(session), session->GetFabricIndex(), + ChipLogValueX64(session->GetPeer().GetNodeId()), static_cast(compressedFabricId), typeStr, protocolName, + msgTypeName, + static_cast(msgBuf->TotalLength() + packetHeader.EncodeSizeBytes() + payloadHeader.EncodeSizeBytes())); #endif MessageFlags msgFlags; diff --git a/src/messaging/README.md b/src/messaging/README.md index bfb379e22aa49c..b439a45de6b840 100644 --- a/src/messaging/README.md +++ b/src/messaging/README.md @@ -16,7 +16,7 @@ will be expanded are denoted with `$` . Unless specified, numerical values are represented in decimal notation. ``` -<<< [E:$exchange_id S:$session_id M:$msg_id (Ack: $ack_msg_id)] ($msg_category) Msg TX to $fabric_index:$destination [$compressed_fabric_id] [$peer_address] --- Type $protocol_id:$msg_type ($protocol_name:$msg_type_name) +<<< [E:$exchange_id S:$session_id M:$msg_id (Ack: $ack_msg_id)] ($msg_category) Msg TX to $fabric_index:$destination [$compressed_fabric_id] [$peer_address] --- Type $protocol_id:$msg_type ($protocol_name:$msg_type_name) (B:$size) ``` | Field | Description | @@ -34,6 +34,7 @@ Unless specified, numerical values are represented in decimal notation. | msg_type | 8-bit message type ID (in hex) | | protocol_name | If available, a logical name for the protocol | | msg_type_name | If available, a logical name for the message type | +| size | Size, in bytes, of the message being transmitted. Includes the Matter payload header and packet header but not transport headers | #### Examples: @@ -65,7 +66,7 @@ will be expanded are denoted with `$` . Unless specified, numerical values are represented in decimal notation. ``` ->>> [E:$exchange_id M: $msg_id (Ack: $ack_msg_id)] ($msg_category) Msg RX from $fabric_index:$source [$compressed_fabric_id] --- Type $protocol_id:$msg_type ($protocol_name:$msg_type_name) +>>> [E:$exchange_id M: $msg_id (Ack: $ack_msg_id)] ($msg_category) Msg RX from $fabric_index:$source [$compressed_fabric_id] --- Type $protocol_id:$msg_type ($protocol_name:$msg_type_name) (B:$size) ``` This has a similar legend to that for transmission except `$source` denotes the diff --git a/src/transport/SessionManager.cpp b/src/transport/SessionManager.cpp index ffb3633b289e21..e22f0722d7cb55 100644 --- a/src/transport/SessionManager.cpp +++ b/src/transport/SessionManager.cpp @@ -339,6 +339,8 @@ CHIP_ERROR SessionManager::PrepareMessage(const SessionHandle & sessionHandle, P return CHIP_ERROR_INTERNAL; } + ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); + #if CHIP_PROGRESS_LOGGING CompressedFabricId compressedFabricId = kUndefinedCompressedFabricId; @@ -372,19 +374,26 @@ CHIP_ERROR SessionManager::PrepareMessage(const SessionHandle & sessionHandle, P char typeStr[4 + 1 + 2 + 1]; snprintf(typeStr, sizeof(typeStr), "%04X:%02X", payloadHeader.GetProtocolID().GetProtocolId(), payloadHeader.GetMessageType()); + // More work around pigweed not allowing more than 14 format args in a log + // message when using tokenized logs. + // ChipLogFormatExchangeId logs the numeric exchange ID (at most 5 chars, + // since it's a uint16_t) and one char for initiator/responder. Plus we + // need a null-terminator. + char exchangeStr[5 + 1 + 1]; + snprintf(exchangeStr, sizeof(exchangeStr), ChipLogFormatExchangeId, ChipLogValueExchangeIdFromSentHeader(payloadHeader)); + // // Legend that can be used to decode this log line can be found in messaging/README.md // ChipLogProgress(ExchangeManager, - "<<< [E:" ChipLogFormatExchangeId " S:%u M:" ChipLogFormatMessageCounter - "%s] (%s) Msg TX to %u:" ChipLogFormatX64 " [%04X] [%s] --- Type %s (%s:%s)", - ChipLogValueExchangeIdFromSentHeader(payloadHeader), sessionHandle->SessionIdForLogging(), - packetHeader.GetMessageCounter(), ackBuf, Transport::GetSessionTypeString(sessionHandle), fabricIndex, - ChipLogValueX64(destination), static_cast(compressedFabricId), addressStr, typeStr, protocolName, - msgTypeName); + "<<< [E:%s S:%u M:" ChipLogFormatMessageCounter "%s] (%s) Msg TX to %u:" ChipLogFormatX64 + " [%04X] [%s] --- Type %s (%s:%s) (B:%u)", + exchangeStr, sessionHandle->SessionIdForLogging(), packetHeader.GetMessageCounter(), ackBuf, + Transport::GetSessionTypeString(sessionHandle), fabricIndex, ChipLogValueX64(destination), + static_cast(compressedFabricId), addressStr, typeStr, protocolName, msgTypeName, + static_cast(message->TotalLength())); #endif - ReturnErrorOnFailure(packetHeader.EncodeBeforeData(message)); preparedMessage = EncryptedPacketBufferHandle::MarkEncrypted(std::move(message)); return CHIP_NO_ERROR; diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 5ea642c2490387..a7fef6deeee4df 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -16396,6 +16396,234 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace EnergyEvseMode +namespace WaterHeaterMode { +namespace Attributes { + +namespace StartUpMode { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace StartUpMode + +namespace OnMode { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace OnMode + +namespace ClusterRevision { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WaterHeaterMode + namespace DeviceEnergyManagementMode { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index 2e9f20115c2738..63493b3f90551d 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -2700,6 +2700,40 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace EnergyEvseMode +namespace WaterHeaterMode { +namespace Attributes { + +namespace StartUpMode { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace StartUpMode + +namespace OnMode { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int8u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace OnMode + +namespace ClusterRevision { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WaterHeaterMode + namespace DeviceEnergyManagementMode { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index 7be9f882fd37ef..6e78fd6c09a8bf 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -408,6 +408,11 @@ void emberAfPowerTopologyClusterInitCallback(chip::EndpointId endpoint); */ void emberAfEnergyEvseModeClusterInitCallback(chip::EndpointId endpoint); +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWaterHeaterModeClusterInitCallback(chip::EndpointId endpoint); + /** * @param endpoint Endpoint that is being initialized */ @@ -3549,6 +3554,45 @@ MatterEnergyEvseModeClusterServerPreAttributeChangedCallback(const chip::app::Co */ void emberAfEnergyEvseModeClusterServerTickCallback(chip::EndpointId endpoint); +// +// Water Heater Mode Cluster +// + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWaterHeaterModeClusterServerInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being shutdown + */ +void MatterWaterHeaterModeClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWaterHeaterModeClusterClientInitCallback(chip::EndpointId endpoint); + +/** + * @param attributePath Concrete attribute path that changed + */ +void MatterWaterHeaterModeClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath); + +/** + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status +MatterWaterHeaterModeClusterServerPreAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath, + EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** + * @param endpoint Endpoint that is being served + */ +void emberAfWaterHeaterModeClusterServerTickCallback(chip::EndpointId endpoint); + // // Device Energy Management Mode Cluster // @@ -6021,6 +6065,12 @@ bool emberAfMessagesClusterPresentMessagesRequestCallback( bool emberAfMessagesClusterCancelMessagesRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Messages::Commands::CancelMessagesRequest::DecodableType & commandData); +/** + * @brief Water Heater Mode Cluster ChangeToMode Command callback (from client) + */ +bool emberAfWaterHeaterModeClusterChangeToModeCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::DecodableType & commandData); /** * @brief Door Lock Cluster LockDoor Command callback (from client) */ diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h index 903dfb78e4d372..877b78724d559a 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h @@ -1895,6 +1895,20 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(EnergyPreference::Energ } } +static auto __attribute__((unused)) EnsureKnownEnumValue(WaterHeaterMode::ModeTag val) +{ + using EnumType = WaterHeaterMode::ModeTag; + switch (val) + { + case EnumType::kOff: + case EnumType::kManual: + case EnumType::kTimed: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} + static auto __attribute__((unused)) EnsureKnownEnumValue(DoorLock::AlarmCodeEnum val) { using EnumType = DoorLock::AlarmCodeEnum; diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index 65e540c8bbcb2f..778f3d79bde381 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -2808,6 +2808,28 @@ enum class Feature : uint32_t }; } // namespace EnergyEvseMode +namespace WaterHeaterMode { + +// Enum for ModeTag +enum class ModeTag : uint16_t +{ + kOff = 0x4000, + kManual = 0x4001, + kTimed = 0x4002, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 0, +}; + +// Bitmap for Feature +enum class Feature : uint32_t +{ + kOnOff = 0x1, +}; +} // namespace WaterHeaterMode + namespace DeviceEnergyManagementMode { // Enum for ModeTag diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index d821d185f11272..fcae2110b2ce53 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -17501,6 +17501,119 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre namespace Events {} // namespace Events } // namespace EnergyEvseMode +namespace WaterHeaterMode { +namespace Structs {} // namespace Structs + +namespace Commands { +namespace ChangeToMode { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kNewMode), newMode); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kNewMode)) + { + err = DataModel::Decode(reader, newMode); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ChangeToMode. +namespace ChangeToModeResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kStatus), status); + encoder.Encode(to_underlying(Fields::kStatusText), statusText); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kStatus)) + { + err = DataModel::Decode(reader, status); + } + else if (__context_tag == to_underlying(Fields::kStatusText)) + { + err = DataModel::Decode(reader, statusText); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ChangeToModeResponse. +} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::SupportedModes::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, supportedModes); + case Attributes::CurrentMode::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, currentMode); + case Attributes::StartUpMode::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, startUpMode); + case Attributes::OnMode::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, onMode); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; + } +} +} // namespace Attributes + +namespace Events {} // namespace Events + +} // namespace WaterHeaterMode namespace DeviceEnergyManagementMode { namespace Structs {} // namespace Structs @@ -31835,6 +31948,13 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::WaterHeaterMode::Id: { + switch (aCommand) + { + default: + return false; + } + } case Clusters::DeviceEnergyManagementMode::Id: { switch (aCommand) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index a32e52a5c072f8..9377e6e1739a75 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -24365,6 +24365,208 @@ struct TypeInfo }; } // namespace Attributes } // namespace EnergyEvseMode +namespace WaterHeaterMode { +namespace Structs { +namespace ModeTagStruct = Clusters::detail::Structs::ModeTagStruct; +namespace ModeOptionStruct = Clusters::detail::Structs::ModeOptionStruct; +} // namespace Structs + +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace ChangeToMode { +struct Type; +struct DecodableType; +} // namespace ChangeToMode + +namespace ChangeToModeResponse { +struct Type; +struct DecodableType; +} // namespace ChangeToModeResponse + +} // namespace Commands + +namespace Commands { +namespace ChangeToMode { +enum class Fields : uint8_t +{ + kNewMode = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ChangeToMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } + + uint8_t newMode = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ChangeToMode::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } + + uint8_t newMode = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ChangeToMode +namespace ChangeToModeResponse { +enum class Fields : uint8_t +{ + kStatus = 0, + kStatusText = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ChangeToModeResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } + + uint8_t status = static_cast(0); + Optional statusText; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ChangeToModeResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } + + uint8_t status = static_cast(0); + Optional statusText; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ChangeToModeResponse +} // namespace Commands + +namespace Attributes { + +namespace SupportedModes { +struct TypeInfo +{ + using Type = chip::app::DataModel::List; + using DecodableType = + chip::app::DataModel::DecodableList; + using DecodableArgType = + const chip::app::DataModel::DecodableList &; + + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::SupportedModes::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace SupportedModes +namespace CurrentMode { +struct TypeInfo +{ + using Type = uint8_t; + using DecodableType = uint8_t; + using DecodableArgType = uint8_t; + + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::CurrentMode::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace CurrentMode +namespace StartUpMode { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = const chip::app::DataModel::Nullable &; + + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::StartUpMode::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace StartUpMode +namespace OnMode { +struct TypeInfo +{ + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = const chip::app::DataModel::Nullable &; + + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::OnMode::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace OnMode +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::SupportedModes::TypeInfo::DecodableType supportedModes; + Attributes::CurrentMode::TypeInfo::DecodableType currentMode = static_cast(0); + Attributes::StartUpMode::TypeInfo::DecodableType startUpMode; + Attributes::OnMode::TypeInfo::DecodableType onMode; + Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; + Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; + Attributes::EventList::TypeInfo::DecodableType eventList; + Attributes::AttributeList::TypeInfo::DecodableType attributeList; + Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); + Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); + }; +}; +} // namespace Attributes +} // namespace WaterHeaterMode namespace DeviceEnergyManagementMode { namespace Structs { namespace ModeTagStruct = Clusters::detail::Structs::ModeTagStruct; diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index b025f1ccf57811..c80ee5f834801e 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -4273,6 +4273,52 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; } // namespace Attributes } // namespace EnergyEvseMode +namespace WaterHeaterMode { +namespace Attributes { + +namespace SupportedModes { +static constexpr AttributeId Id = 0x00000000; +} // namespace SupportedModes + +namespace CurrentMode { +static constexpr AttributeId Id = 0x00000001; +} // namespace CurrentMode + +namespace StartUpMode { +static constexpr AttributeId Id = 0x00000002; +} // namespace StartUpMode + +namespace OnMode { +static constexpr AttributeId Id = 0x00000003; +} // namespace OnMode + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WaterHeaterMode + namespace DeviceEnergyManagementMode { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h index ba42f10b50ffae..b94e6c1772f2aa 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h @@ -250,6 +250,9 @@ static constexpr ClusterId Id = 0x0000009C; namespace EnergyEvseMode { static constexpr ClusterId Id = 0x0000009D; } // namespace EnergyEvseMode +namespace WaterHeaterMode { +static constexpr ClusterId Id = 0x0000009E; +} // namespace WaterHeaterMode namespace DeviceEnergyManagementMode { static constexpr ClusterId Id = 0x0000009F; } // namespace DeviceEnergyManagementMode diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h index 608b7d7c7565a7..382737bcee0c8e 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h @@ -1073,6 +1073,20 @@ static constexpr CommandId Id = 0x00000001; } // namespace Commands } // namespace EnergyEvseMode +namespace WaterHeaterMode { +namespace Commands { + +namespace ChangeToMode { +static constexpr CommandId Id = 0x00000000; +} // namespace ChangeToMode + +namespace ChangeToModeResponse { +static constexpr CommandId Id = 0x00000001; +} // namespace ChangeToModeResponse + +} // namespace Commands +} // namespace WaterHeaterMode + namespace DeviceEnergyManagementMode { namespace Commands { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 63b07843fd2703..c5971984fed334 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -110,6 +110,7 @@ | EnergyPreference | 0x009B | | PowerTopology | 0x009C | | EnergyEvseMode | 0x009D | +| WaterHeaterMode | 0x009E | | DeviceEnergyManagementMode | 0x009F | | DoorLock | 0x0101 | | WindowCovering | 0x0102 | @@ -7786,6 +7787,64 @@ class EnergyEvseModeChangeToMode : public ClusterCommand chip::app::Clusters::EnergyEvseMode::Commands::ChangeToMode::Type mRequest; }; +/*----------------------------------------------------------------------------*\ +| Cluster WaterHeaterMode | 0x009E | +|------------------------------------------------------------------------------| +| Commands: | | +| * ChangeToMode | 0x00 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * SupportedModes | 0x0000 | +| * CurrentMode | 0x0001 | +| * StartUpMode | 0x0002 | +| * OnMode | 0x0003 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +/* + * Command ChangeToMode + */ +class WaterHeaterModeChangeToMode : public ClusterCommand +{ +public: + WaterHeaterModeChangeToMode(CredentialIssuerCommands * credsIssuerConfig) : ClusterCommand("change-to-mode", credsIssuerConfig) + { + AddArgument("NewMode", 0, UINT8_MAX, &mRequest.newMode); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster DeviceEnergyManagementMode | 0x009F | |------------------------------------------------------------------------------| @@ -21858,6 +21917,75 @@ void registerClusterEnergyEvseMode(Commands & commands, CredentialIssuerCommands commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterWaterHeaterMode(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::WaterHeaterMode; + + const char * clusterName = "WaterHeaterMode"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "supported-modes", Attributes::SupportedModes::Id, credsIssuerConfig), // + make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // + make_unique(Id, "start-up-mode", Attributes::StartUpMode::Id, credsIssuerConfig), // + make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // + make_unique>>( + Id, "supported-modes", Attributes::SupportedModes::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "current-mode", 0, UINT8_MAX, Attributes::CurrentMode::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "start-up-mode", 0, UINT8_MAX, Attributes::StartUpMode::Id, WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>>(Id, "on-mode", 0, UINT8_MAX, Attributes::OnMode::Id, + WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>>( + Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>>( + Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "supported-modes", Attributes::SupportedModes::Id, credsIssuerConfig), // + make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // + make_unique(Id, "start-up-mode", Attributes::StartUpMode::Id, credsIssuerConfig), // + make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + // + // Events + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +} void registerClusterDeviceEnergyManagementMode(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { using namespace chip::app::Clusters::DeviceEnergyManagementMode; @@ -28002,6 +28130,7 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue registerClusterEnergyPreference(commands, credsIssuerConfig); registerClusterPowerTopology(commands, credsIssuerConfig); registerClusterEnergyEvseMode(commands, credsIssuerConfig); + registerClusterWaterHeaterMode(commands, credsIssuerConfig); registerClusterDeviceEnergyManagementMode(commands, credsIssuerConfig); registerClusterDoorLock(commands, credsIssuerConfig); registerClusterWindowCovering(commands, credsIssuerConfig); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index 1bf30e655ab661..9de841aaaa4af3 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -8023,6 +8023,15 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("status", indent + 1, value.status)); + ReturnErrorOnFailure(DataModelLogger::LogValue("statusText", indent + 1, value.statusText)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const DeviceEnergyManagementMode::Commands::ChangeToModeResponse::DecodableType & value) { @@ -13702,6 +13711,63 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP } break; } + case WaterHeaterMode::Id: { + switch (path.mAttributeId) + { + case WaterHeaterMode::Attributes::SupportedModes::Id: { + chip::app::DataModel::DecodableList + value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SupportedModes", 1, value); + } + case WaterHeaterMode::Attributes::CurrentMode::Id: { + uint8_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("CurrentMode", 1, value); + } + case WaterHeaterMode::Attributes::StartUpMode::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("StartUpMode", 1, value); + } + case WaterHeaterMode::Attributes::OnMode::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("OnMode", 1, value); + } + case WaterHeaterMode::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GeneratedCommandList", 1, value); + } + case WaterHeaterMode::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AcceptedCommandList", 1, value); + } + case WaterHeaterMode::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case WaterHeaterMode::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AttributeList", 1, value); + } + case WaterHeaterMode::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case WaterHeaterMode::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } case DeviceEnergyManagementMode::Id: { switch (path.mAttributeId) { @@ -19187,6 +19253,17 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa } break; } + case WaterHeaterMode::Id: { + switch (path.mCommandId) + { + case WaterHeaterMode::Commands::ChangeToModeResponse::Id: { + WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ChangeToModeResponse", 1, value); + } + } + break; + } case DeviceEnergyManagementMode::Id: { switch (path.mCommandId) { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h index 7aecdf187d7a49..8ca6e2ef3904d6 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -748,6 +748,8 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::EnergyEvse::Commands::GetTargetsResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::EnergyEvseMode::Commands::ChangeToModeResponse::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::DeviceEnergyManagementMode::Commands::ChangeToModeResponse::DecodableType & value); diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 9d6610f69f3faf..c9386dc42a6a7b 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -112,6 +112,7 @@ | EnergyPreference | 0x009B | | PowerTopology | 0x009C | | EnergyEvseMode | 0x009D | +| WaterHeaterMode | 0x009E | | DeviceEnergyManagementMode | 0x009F | | DoorLock | 0x0101 | | WindowCovering | 0x0102 | @@ -90296,6 +90297,1027 @@ class SubscribeAttributeEnergyEvseModeClusterRevision : public SubscribeAttribut } }; +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster WaterHeaterMode | 0x009E | +|------------------------------------------------------------------------------| +| Commands: | | +| * ChangeToMode | 0x00 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * SupportedModes | 0x0000 | +| * CurrentMode | 0x0001 | +| * StartUpMode | 0x0002 | +| * OnMode | 0x0003 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL +/* + * Command ChangeToMode + */ +class WaterHeaterModeChangeToMode : public ClusterCommand { +public: + WaterHeaterModeChangeToMode() + : ClusterCommand("change-to-mode") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("NewMode", 0, UINT8_MAX, &mRequest.newMode); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWaterHeaterModeClusterChangeToModeParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.newMode = [NSNumber numberWithUnsignedChar:mRequest.newMode]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster changeToModeWithParams:params completion: + ^(MTRWaterHeaterModeClusterChangeToModeResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::WaterHeaterMode::Commands::ChangeToModeResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute SupportedModes + */ +class ReadWaterHeaterModeSupportedModes : public ReadAttribute { +public: + ReadWaterHeaterModeSupportedModes() + : ReadAttribute("supported-modes") + { + } + + ~ReadWaterHeaterModeSupportedModes() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::SupportedModes::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeSupportedModesWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.SupportedModes response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode SupportedModes read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeSupportedModes : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeSupportedModes() + : SubscribeAttribute("supported-modes") + { + } + + ~SubscribeAttributeWaterHeaterModeSupportedModes() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::SupportedModes::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeSupportedModesWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.SupportedModes response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute CurrentMode + */ +class ReadWaterHeaterModeCurrentMode : public ReadAttribute { +public: + ReadWaterHeaterModeCurrentMode() + : ReadAttribute("current-mode") + { + } + + ~ReadWaterHeaterModeCurrentMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::CurrentMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeCurrentModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.CurrentMode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode CurrentMode read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeCurrentMode : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeCurrentMode() + : SubscribeAttribute("current-mode") + { + } + + ~SubscribeAttributeWaterHeaterModeCurrentMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::CurrentMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeCurrentModeWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.CurrentMode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute StartUpMode + */ +class ReadWaterHeaterModeStartUpMode : public ReadAttribute { +public: + ReadWaterHeaterModeStartUpMode() + : ReadAttribute("start-up-mode") + { + } + + ~ReadWaterHeaterModeStartUpMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::StartUpMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeStartUpModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.StartUpMode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode StartUpMode read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteWaterHeaterModeStartUpMode : public WriteAttribute { +public: + WriteWaterHeaterModeStartUpMode() + : WriteAttribute("start-up-mode") + { + AddArgument("attr-name", "start-up-mode"); + AddArgument("attr-value", 0, UINT8_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteWaterHeaterModeStartUpMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::StartUpMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nullable value = nil; + if (!mValue.IsNull()) { + value = [NSNumber numberWithUnsignedChar:mValue.Value()]; + } + + [cluster writeAttributeStartUpModeWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("WaterHeaterMode StartUpMode write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + chip::app::DataModel::Nullable mValue; +}; + +class SubscribeAttributeWaterHeaterModeStartUpMode : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeStartUpMode() + : SubscribeAttribute("start-up-mode") + { + } + + ~SubscribeAttributeWaterHeaterModeStartUpMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::StartUpMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeStartUpModeWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.StartUpMode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute OnMode + */ +class ReadWaterHeaterModeOnMode : public ReadAttribute { +public: + ReadWaterHeaterModeOnMode() + : ReadAttribute("on-mode") + { + } + + ~ReadWaterHeaterModeOnMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::OnMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeOnModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.OnMode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode OnMode read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteWaterHeaterModeOnMode : public WriteAttribute { +public: + WriteWaterHeaterModeOnMode() + : WriteAttribute("on-mode") + { + AddArgument("attr-name", "on-mode"); + AddArgument("attr-value", 0, UINT8_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteWaterHeaterModeOnMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::OnMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nullable value = nil; + if (!mValue.IsNull()) { + value = [NSNumber numberWithUnsignedChar:mValue.Value()]; + } + + [cluster writeAttributeOnModeWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("WaterHeaterMode OnMode write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + chip::app::DataModel::Nullable mValue; +}; + +class SubscribeAttributeWaterHeaterModeOnMode : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeOnMode() + : SubscribeAttribute("on-mode") + { + } + + ~SubscribeAttributeWaterHeaterModeOnMode() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::OnMode::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeOnModeWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.OnMode response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GeneratedCommandList + */ +class ReadWaterHeaterModeGeneratedCommandList : public ReadAttribute { +public: + ReadWaterHeaterModeGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadWaterHeaterModeGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeWaterHeaterModeGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeGeneratedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AcceptedCommandList + */ +class ReadWaterHeaterModeAcceptedCommandList : public ReadAttribute { +public: + ReadWaterHeaterModeAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadWaterHeaterModeAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeWaterHeaterModeAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAcceptedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EventList + */ +class ReadWaterHeaterModeEventList : public ReadAttribute { +public: + ReadWaterHeaterModeEventList() + : ReadAttribute("event-list") + { + } + + ~ReadWaterHeaterModeEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeEventList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeWaterHeaterModeEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEventListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AttributeList + */ +class ReadWaterHeaterModeAttributeList : public ReadAttribute { +public: + ReadWaterHeaterModeAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadWaterHeaterModeAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeWaterHeaterModeAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAttributeListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute FeatureMap + */ +class ReadWaterHeaterModeFeatureMap : public ReadAttribute { +public: + ReadWaterHeaterModeFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadWaterHeaterModeFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeWaterHeaterModeFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeFeatureMapWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ClusterRevision + */ +class ReadWaterHeaterModeClusterRevision : public ReadAttribute { +public: + ReadWaterHeaterModeClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadWaterHeaterModeClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WaterHeaterMode ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWaterHeaterModeClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeWaterHeaterModeClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeWaterHeaterModeClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeClusterRevisionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WaterHeaterMode.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + #endif // MTR_ENABLE_PROVISIONAL #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL @@ -192487,6 +193509,68 @@ void registerClusterEnergyEvseMode(Commands & commands) commands.RegisterCluster(clusterName, clusterCommands); #endif // MTR_ENABLE_PROVISIONAL } +void registerClusterWaterHeaterMode(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::WaterHeaterMode; + + const char * clusterName = "WaterHeaterMode"; + + commands_list clusterCommands = { + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + }; + + commands.RegisterCluster(clusterName, clusterCommands); +#endif // MTR_ENABLE_PROVISIONAL +} void registerClusterDeviceEnergyManagementMode(Commands & commands) { #if MTR_ENABLE_PROVISIONAL @@ -195995,6 +197079,7 @@ void registerClusters(Commands & commands) registerClusterEnergyPreference(commands); registerClusterPowerTopology(commands); registerClusterEnergyEvseMode(commands); + registerClusterWaterHeaterMode(commands); registerClusterDeviceEnergyManagementMode(commands); registerClusterDoorLock(commands); registerClusterWindowCovering(commands);