From ba875f972a9ffe836b59f8010b26707c82fb7c88 Mon Sep 17 00:00:00 2001 From: Kai Liao <140431279+kliao-csa@users.noreply.github.com> Date: Tue, 15 Aug 2023 13:33:38 -0600 Subject: [PATCH 1/6] Workflow fail summarization (#28650) cron workflow that lists the most recent failures on the master branch, including a frequency calculation of most commonly failed recent workflow by percentage --- .github/workflows/recent_fail_summary.yaml | 39 ++++++++++++++++++++++ scripts/tools/summarize_fail.py | 7 ++++ 2 files changed, 46 insertions(+) create mode 100644 .github/workflows/recent_fail_summary.yaml create mode 100644 scripts/tools/summarize_fail.py diff --git a/.github/workflows/recent_fail_summary.yaml b/.github/workflows/recent_fail_summary.yaml new file mode 100644 index 00000000000000..f41ecdc659be84 --- /dev/null +++ b/.github/workflows/recent_fail_summary.yaml @@ -0,0 +1,39 @@ +# Copyright (c) 2020 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. + +name: Recent Fail Summary +on: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }} + +jobs: + list_workflows: + name: Summarize Recent Workflow Failures + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup + run: | + gh run list -b master -s failure --json displayTitle,workflowName > runlist.json + pip install pandas + env: + GH_TOKEN: ${{ github.token }} + - name: Run Summarization Script + run: python scripts/tools/summarize_fail.py + diff --git a/scripts/tools/summarize_fail.py b/scripts/tools/summarize_fail.py new file mode 100644 index 00000000000000..90d60ba5860379 --- /dev/null +++ b/scripts/tools/summarize_fail.py @@ -0,0 +1,7 @@ +import pandas as pd + +df = pd.read_json("runlist.json") +print("Recent Failures:") +print(df) +print("Percentage Frequency:") +print(df["workflowName"].value_counts(normalize=True) * 100) From b378defac9682e40ae1494457c136df244250ff6 Mon Sep 17 00:00:00 2001 From: mpbreton-silabs <107145920+mpbreton-silabs@users.noreply.github.com> Date: Tue, 15 Aug 2023 17:16:19 -0400 Subject: [PATCH 2/6] Validate if the Current Group = RemovedGroup before invalidating scene (#28565) * Validate if the Current Group = RemovedGroup or check if CurrentScene is in RemovedGroup before invalidating the scene. * Fix nonsensical code * ditto * ditto bis * restyle * Remove check that was not specification compliant * Cleanup * Update src/app/clusters/scenes-server/scenes-server.cpp Co-authored-by: Boris Zbarsky --------- Co-authored-by: Boris Zbarsky --- src/app/clusters/scenes-server/scenes-server.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/app/clusters/scenes-server/scenes-server.cpp b/src/app/clusters/scenes-server/scenes-server.cpp index e0398563982352..1c89884f687246 100644 --- a/src/app/clusters/scenes-server/scenes-server.cpp +++ b/src/app/clusters/scenes-server/scenes-server.cpp @@ -510,7 +510,15 @@ void ScenesServer::GroupWillBeRemoved(FabricIndex aFabricIx, EndpointId aEndpoin SceneTable * sceneTable = scenes::GetSceneTableImpl(aEndpointId); VerifyOrReturn(nullptr != sceneTable); - MakeSceneInvalid(aEndpointId); + chip::GroupId currentGroup; + Attributes::CurrentGroup::Get(aEndpointId, ¤tGroup); + + // If currentGroup is what is being removed, we can't possibly still have a valid scene, + // because the scene we have (if any) will also be removed. + if (aGroupId == currentGroup) + { + MakeSceneInvalid(aEndpointId); + } VerifyOrReturn(nullptr != mGroupProvider); if (0 != aGroupId && !mGroupProvider->HasEndpoint(aFabricIx, aGroupId, aEndpointId)) From cf6ad442f70eb3174426a928a443e86fab68954e Mon Sep 17 00:00:00 2001 From: jrhees-cae <61466710+jrhees-cae@users.noreply.github.com> Date: Tue, 15 Aug 2023 17:20:17 -0600 Subject: [PATCH 3/6] [TC-DRLK-2.10] Add cleanup of Lock User created in step 5a (#28642) * [TC-DRLK-2.10] Add cleanup of Lock User created in step 5a. Fix typo in instructions. Fixes https://github.com/CHIP-Specifications/chip-test-plans/issues/3291 * Restyled by prettier-yaml --------- Co-authored-by: Restyled.io --- .../certification/Test_TC_DRLK_2_10.yaml | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_10.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_10.yaml index 63c411486353eb..c00e52dd5674e7 100644 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_10.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_10.yaml @@ -444,7 +444,7 @@ tests: - label: "Step 5a: TH sends Set User Command to DUT with the following values: - OperationType as 0-Add UserIndex as 2( Different from an existing + OperationType as 0-Add UserIndex as 4( Different from an existing UserIndex) UserName as xxx UserUniqueID as 6452 UserStatus as 1-OccupiedEnabled UserType as 0-UnrestrictedUser CredentialRule as 0-Single" @@ -697,7 +697,34 @@ tests: [1658223096.125372][4517:4522] CHIP:TOO: } disabled: true - - label: "Step 5g: TH sends Clear Credential Command to DUT" + - label: + "Step 5g: TH sends Clear User Command to DUT for user created in Step + 5a" + PICS: DRLK.S.C1d.Rsp + verification: | + ./chip-tool doorlock clear-user 4 1 1 --timedInteractionTimeoutMs 1000 + + Via the TH (chip-tool), verify the SUCCESS response for clearing the users details. + + [1658142762.492854][2993:2998] CHIP:DMG: + [1658142762.492888][2993:2998] CHIP:DMG: StatusIB = + [1658142762.492920][2993:2998] CHIP:DMG: { + [1658142762.492957][2993:2998] CHIP:DMG: status = 0x00 (SUCCESS), + [1658142762.492994][2993:2998] CHIP:DMG: }, + [1658142762.493026][2993:2998] CHIP:DMG: + [1658142762.493060][2993:2998] CHIP:DMG: }, + [1658142762.493097][2993:2998] CHIP:DMG: + [1658142762.493125][2993:2998] CHIP:DMG: }, + [1658142762.493158][2993:2998] CHIP:DMG: + [1658142762.493182][2993:2998] CHIP:DMG: ], + [1658142762.493211][2993:2998] CHIP:DMG: + [1658142762.493235][2993:2998] CHIP:DMG: InteractionModelRevision = 1 + [1658142762.493258][2993:2998] CHIP:DMG: }, + disabled: true + + - label: + "Step 6a: TH sends Clear Credential Command to DUT for Credential + created in Step 3a" PICS: DRLK.S.C26.Rsp verification: | ./chip-tool doorlock clear-credential '{ "credentialType" : 1 , "credentialIndex" : 1 }' 1 1 --timedInteractionTimeoutMs 1000 @@ -721,7 +748,9 @@ tests: [1658142697.890616][2985:2990] CHIP:DMG: ICR moving to [AwaitingDe] disabled: true - - label: "Step 5h: TH sends Clear User Command to DUT" + - label: + "Step 6b: TH sends Clear User Command to DUT for User created in Step + 3a" PICS: DRLK.S.C1d.Rsp verification: | ./chip-tool doorlock clear-user 1 1 1 --timedInteractionTimeoutMs 1000 From 446dd191531ec153e8a8a4fa89f3c22ebcde2484 Mon Sep 17 00:00:00 2001 From: Grzegorz Ferenc <41291385+greg-fer@users.noreply.github.com> Date: Wed, 16 Aug 2023 08:30:43 +0200 Subject: [PATCH 4/6] doc: chip_tool_guide: doorlock user & credentials (#27601) * doc: chip_tool_guide: doorlock user & credentials Added a new section about setting up doorlock users and credentials and interacting with them. Signed-off-by: Grzegorz Ferenc * edits from Arek and Boris Signed-off-by: Grzegorz Ferenc * Restyled by prettier-markdown * fix spelling Signed-off-by: Grzegorz Ferenc * update wordlist and reword additions Signed-off-by: Grzegorz Ferenc * Restyled by prettier-markdown * comments from Boris Signed-off-by: Grzegorz Ferenc * comments from Boris Signed-off-by: Grzegorz Ferenc * misspell term update Signed-off-by: Grzegorz Ferenc * Restyled by prettier-markdown --------- Signed-off-by: Grzegorz Ferenc Co-authored-by: Restyled.io --- docs/guides/chip_tool_guide.md | 277 ++++++++++++++++++++++++++++++++- 1 file changed, 275 insertions(+), 2 deletions(-) diff --git a/docs/guides/chip_tool_guide.md b/docs/guides/chip_tool_guide.md index 49fe4ad48a83da..5ea235ab1263ac 100644 --- a/docs/guides/chip_tool_guide.md +++ b/docs/guides/chip_tool_guide.md @@ -1249,7 +1249,7 @@ The steps are the same as for the `subscribe` or `subscribe-event` commands.
-## Using wildcards +### Using wildcards The CHIP Tool supports command wildcards for parameter values for clusters, attributes or events, or endpoints, or any combination of these. With the @@ -1320,7 +1320,7 @@ In this command: $ ./chip-tool doorlock read-by-id 0xFFFFFFFF 1 0xFFFF ``` -### Using wildcards with `any` command +#### Using wildcards with `any` command Using the `any` command lets you use wildcards also for the cluster names. The `any` command can be combined with the following commands: @@ -1393,3 +1393,276 @@ $ ./chip-tool any read-by-id + +## Saving users and credentials on door lock devices + +Matter door lock devices can store pools of users and credentials that allow you +to configure different access scenarios. Each user and credential in the pool +has an index value. Additionally, each user has a list of Occupied Credentials. + +By default, each door lock device comes with no user or credential defined, but +it reserves several slots in both pools that can be populated with new users and +credentials, up to the value specified in the the `NumberOfTotalUsersSupported` +attribute and the `NumberOfCredentialsSupportedPerUser` attribute, respectively. + +All communication between users and credentials happens only using their +respective index values. No other information is shared between both pools. + +The CHIP Tool lets you add users and credentials on door lock devices and +securely match their indexes to one another. This is an optional feature +available only when working with devices that implement the `doorlock` cluster. + +> **Note:** Users and credentials can only be modified by whoever has the right +> permissions, as specified in the Access Control List. + +To save credentials and users, you need to complete the following steps, +described in detail in the following sections: + +1. Set up a user on the device. +1. Assign a credential for the newly created user. + +### Step 1: Set up a user + +To set up a user on a door lock device with the CHIP Tool, use the following +command pattern: + +``` +$ ./chip-tool doorlock set-user --timedInteractionTimeoutMs +``` + +In this command: + +- __ is one of the available types of operation for the user: + + - `Add` - This operation sets a new user in the slot at __. + - `Clear` - This operation removes an existing user from the slot at + __. + - `Modify` - This operation modifies an existing user at the slot at + __. + +- __ is the index value of the user, between `1` and the value of + the `NumberOfTotalUsersSupported` attribute. Setting the user index to `0` + will cause an error. +- __ is the name of the user, which can have maximum 10 bytes of + size. Can be set to `null`. +- __ is a 4-byte number that describes the unique user ID. + Can be set to `null`. +- __ can be set to `null` or to one of the following values: + + - `1` (`OccupiedEnabled`) - This status indicates that the given user slot + is used and active. + - `3` (`OccupiedDisabled`) - This status indicates that the given user + slot is used, but disabled. Unlike `0` and `1`, supporting this status + is optional. + +- __ is the type of the user, which can have one of the values + specified in the Matter Application Clusters specification for the + `doorlock` cluster (see section "5.2.9.16. `UserTypeEnum`"). Can be set to + `null`. +- __ is the number of credentials that must be used to + unlock the door lock. This parameter can be set to `null` or to one of the + following values: + + - `0` (Single) - One credential type is required to unlock. + - `1` (Dual) - Two credential types are required to unlock. + - `2` (Triple) - Three credential types are required to unlock. + +- __ is the node ID of the door lock device. +- __ is the ID of the endpoint on the door lock device. +- `--timedInteractionTimeoutMs` is the duration in milliseconds (__) + of the time window for receiving a request on the server side. This should + allow enough time for receiving the request. + +**Examples of command:** + +The following command runs the `set-user` command that adds (`0`) a user at the +index `1`; the user has the name `AAA` and the unique ID `6452`. The user's +status is set to `OccupiedEnabled` (`1`), the user type is set to +`UnrestrictedUser` (`0`), the credential rule is set to single (`0`), the +targeted node ID of the destination door lock device is `1` and the targeted +`doorlock` cluster's endpoint ID on that device is `1`. The +`--timedInteractionTimeoutMs` has a custom value. + +``` +$ ./chip-tool doorlock set-user 0 1 AAA 6452 1 0 0 1 1 --timedInteractionTimeoutMs 1000 +``` + +The following command mirrors the action of the command above, but it targets an +empty user name (`null`) and has `null` for the unique ID. The user status +defaults to `OccupiedEnabled`, the user type defaults to `UnrestrictedUser`, and +the credential rule defaults to single. + +``` +$ ./chip-tool doorlock set-user 0 1 null null null null null 1 1 --timedInteractionTimeoutMs 1000 +``` + +For more use cases for this command, see the "5.2.7.34. Set User Command" +section in the Matter Application Clusters specification. + +### Step 2: Assign a credential + +Once you have a user created on the door lock device, use the following command +pattern to assign a credential to it: + +``` +$ ./chip-tool doorlock set-credential <{Credential}> --timedInteractionTimeoutMs +``` + +In this command: + +- __ is one of the available types of operation for the + credential: + + - `Add` - This operation adds a new credential to a user at the slot at + __. + - `Clear` - This operation removes an existing credential from the user at + the slot at __. + - `Modify` - This operation modifies an existing credential for the user + at the slot at __. + +- _<{Credential}\>_ is a JSON object, with the following two fields: + + - `"credentialType"` is the key field for the type of the credential. It + can have one of the following values: + + - `0` - Programming PIN + - `1` - PIN + - `2` - RFID + - `3` - Fingerprint + - `4` - Finger vein + + - `"credentialIndex"` is the key field for the index of the credential. If + `"credentialType"` is not "Programming PIN", `"credentialIndex"` must be + between `1` and the value of the `NumberOfCredentialsSupportedPerUser` + attribute (see the section 5.2.3.20 of the Matter Application Clusters + specification for details). `0` is required for the Programming PIN. In + other cases, setting the credential index to `0` will cause an error. + +- __ is an octet string parameter with the secret credential + data. For example, the PIN code value (`12345` in the example below). +- __ is the index of the user that will be associated with the + credential. Can be set to `null` to create a new user. +- __ is the status of the user that will be associated with the + credential. See the description of this parameter in + [Set up a user](#step-1-set-up-a-user). Can be set to `null`. +- __ is the type of the user, which can have one of the values + specified in the Matter Application Clusters specification for the + `doorlock` cluster (see section "5.2.9.16. `UserTypeEnum`"). Can be set to + `null`. +- __ is the node ID of the door lock device. +- __ is the ID of the endpoint on the door lock device. +- `--timedInteractionTimeoutMs` is the duration in milliseconds (__) + of the time window for receiving a request on the server side. This should + allow enough time for receiving the request. + +**Example of command:** + +The following command runs the `set-credential` command that adds (`0`) a PIN +credential (type `1`) at the index `1`. The credential data is set to `12345` +(PIN code value). This credential is associated with the user at the index `1`. +The `null` parameters for the user status and the user type indicate that the +credentials are added to an existing user. The targeted node ID of the +destination door lock device is `1` and the targeted `doorlock` cluster's +endpoint ID on that device is `1`. The `--timedInteractionTimeoutMs` has a +custom value. + +``` +$ ./chip-tool doorlock set-credential 0 '{ "credentialType": 1, "credentialIndex": 1 }' "12345" 1 null null 1 1 --timedInteractionTimeoutMs 1000 +``` + +For more use cases for this command, see the "5.2.7.40. Set Credential Command" +section in the Matter Application Clusters specification. + +### Operations on users and credentials + +After you set up users and credentials on your door lock device, you can use +several CHIP Tool commands to interact with them. + +All commands reuse the parameters explained earlier in this section. The +following command patterns are available: + +- Reading the status of the user: + + ``` + $ ./chip-tool doorlock get-user + ``` + + This command returns the status of the user at the specified __ + at the specified __ and __. + +- Reading the status of the credential: + + ``` + $ ./chip-tool doorlock get-credential-status <{Credential}> + ``` + + This command returns the status of the credential of the specified + _<{Credential}\>_ at the specified __ and __. + +- Cleaning the user: + + ``` + $ ./chip-tool doorlock clear-user --timedInteractionTimeoutMs + ``` + + This command cleans the slot containing the specified __ at the + specified __ and __. + +- Cleaning the credential: + + ``` + $ ./chip-tool doorlock clear-credential <{Credential}> --timedInteractionTimeoutMs + ``` + + This command cleans the slot containing the specified _<{Credential}\>_ at + the specified __ and __. + +### Operations with user PIN code + +If you set the __ to PIN when +[assigning credentials](#step-2-assign-a-credential), you can use the following +command patterns to verify if it works and invoke it to open or close the door +lock: + +- Verifying the PIN code: + + ``` + $ ./chip-tool doorlock read require-pinfor-remote-operation + ``` + + This command returns either `false` or `true`: + + - `false` indicates that providing the PIN code is not required to close + or open the door lock. + - `true` indicates that the PIN code is required to close or open the door + lock. + +- Changing the requirement for the PIN code usage: + + ``` + $ ./chip-tool doorlock write require-pinfor-remote-operation true + ``` + + This command modifies the setting of `require-pinfor-remote-operation` to + `true`. After you run it, you will have to use the PIN code to lock or + unlock the door. + +- Closing the door lock with the PIN code: + + ``` + $ ./chip-tool doorlock lock-door --timedInteractionTimeoutMs --PinCode 12345 + ``` + + In this command, you need to provide `--PinCode` corresponding to the PIN + code you set with __ (for example `12345`). + +- Opening the door lock with the PIN code: + + ``` + $ ./chip-tool doorlock unlock-door --timedInteractionTimeoutMs --PinCode 12345 + ``` + + In this command, you need to provide `--PinCode` corresponding to the PIN + code you set with __ (for example `12345`). From bd771bedd0abb7e4b58289e19a5ec66f19b2e911 Mon Sep 17 00:00:00 2001 From: HunsupJung <59987061+HunsupJung@users.noreply.github.com> Date: Wed, 16 Aug 2023 16:24:59 +0900 Subject: [PATCH 5/6] virtual-device-app: Add ColorControlManager for Extended Color Light (#28653) Signed-off-by: Hunsup Jung Signed-off-by: Charles Kim --- examples/virtual-device-app/android/BUILD.gn | 3 + .../android/java/ClusterChangeAttribute.cpp | 54 ++++ .../android/java/ColorControlManager.cpp | 269 ++++++++++++++++++ .../android/java/ColorControlManager.h | 55 ++++ .../android/java/DeviceApp-JNI.cpp | 9 + .../device/app/ColorControlManager.java | 18 ++ .../virtual-device-app.matter | 154 ++++++++++ .../virtual-device-app.zap | 118 +++++++- 8 files changed, 673 insertions(+), 7 deletions(-) create mode 100644 examples/virtual-device-app/android/java/ColorControlManager.cpp create mode 100644 examples/virtual-device-app/android/java/ColorControlManager.h create mode 100644 examples/virtual-device-app/android/java/src/com/matter/virtual/device/app/ColorControlManager.java diff --git a/examples/virtual-device-app/android/BUILD.gn b/examples/virtual-device-app/android/BUILD.gn index ffa9a9fe6e3520..61b29e9d8453a1 100644 --- a/examples/virtual-device-app/android/BUILD.gn +++ b/examples/virtual-device-app/android/BUILD.gn @@ -27,6 +27,8 @@ shared_library("jni") { "java/AppImpl.cpp", "java/AppImpl.h", "java/ClusterChangeAttribute.cpp", + "java/ColorControlManager.cpp", + "java/ColorControlManager.h", "java/DeviceApp-JNI.cpp", "java/JNIDACProvider.cpp", "java/JNIDACProvider.h", @@ -65,6 +67,7 @@ android_library("java") { sources = [ "java/src/com/matter/virtual/device/app/Clusters.java", + "java/src/com/matter/virtual/device/app/ColorControlManager.java", "java/src/com/matter/virtual/device/app/DACProvider.java", "java/src/com/matter/virtual/device/app/DeviceApp.java", "java/src/com/matter/virtual/device/app/DeviceAppCallback.java", diff --git a/examples/virtual-device-app/android/java/ClusterChangeAttribute.cpp b/examples/virtual-device-app/android/java/ClusterChangeAttribute.cpp index be16005ff089a1..721f4682d1c566 100644 --- a/examples/virtual-device-app/android/java/ClusterChangeAttribute.cpp +++ b/examples/virtual-device-app/android/java/ClusterChangeAttribute.cpp @@ -16,6 +16,7 @@ * limitations under the License. */ +#include "ColorControlManager.h" #include "OnOffManager.h" #include #include @@ -38,6 +39,56 @@ static void OnOffClusterAttributeChangeCallback(const app::ConcreteAttributePath } } +static void ColorControlClusterAttributeChangeCallback(const app::ConcreteAttributePath & attributePath, uint16_t size, + uint8_t * value) +{ + if (attributePath.mAttributeId == ColorControl::Attributes::CurrentHue::Id) + { + uint8_t currentHue = static_cast(*value); + + ChipLogProgress(Zcl, "Received CurrentHue command endpoint %d value = %d", static_cast(attributePath.mEndpointId), + currentHue); + + ColorControlManager().PostCurrentHueChanged(attributePath.mEndpointId, currentHue); + } + else if (attributePath.mAttributeId == ColorControl::Attributes::CurrentSaturation::Id) + { + uint8_t currentSaturation = static_cast(*value); + + ChipLogProgress(Zcl, "Received CurrentSaturation command endpoint %d value = %d", + static_cast(attributePath.mEndpointId), currentSaturation); + + ColorControlManager().PostCurrentSaturationChanged(attributePath.mEndpointId, currentSaturation); + } + else if (attributePath.mAttributeId == ColorControl::Attributes::ColorTemperatureMireds::Id) + { + int16_t colorTemperatureMireds = static_cast(*value); + + ChipLogProgress(Zcl, "Received ColorTemperatureMireds command endpoint %d value = %d", + static_cast(attributePath.mEndpointId), colorTemperatureMireds); + + ColorControlManager().PostColorTemperatureChanged(attributePath.mEndpointId, colorTemperatureMireds); + } + else if (attributePath.mAttributeId == ColorControl::Attributes::ColorMode::Id) + { + uint8_t colorMode = static_cast(*value); + + ChipLogProgress(Zcl, "Received ColorMode command endpoint %d value = %d", static_cast(attributePath.mEndpointId), + colorMode); + + ColorControlManager().PostColorModeChanged(attributePath.mEndpointId, colorMode); + } + else if (attributePath.mAttributeId == ColorControl::Attributes::EnhancedColorMode::Id) + { + uint8_t enhancedColorMode = static_cast(*value); + + ChipLogProgress(Zcl, "Received EnhancedColorMode command endpoint %d value = %d", + static_cast(attributePath.mEndpointId), enhancedColorMode); + + ColorControlManager().PostEnhancedColorModeChanged(attributePath.mEndpointId, enhancedColorMode); + } +} + void MatterPostAttributeChangeCallback(const app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, uint8_t * value) { @@ -49,6 +100,9 @@ void MatterPostAttributeChangeCallback(const app::ConcreteAttributePath & attrib case OnOff::Id: OnOffClusterAttributeChangeCallback(attributePath, size, value); break; + case ColorControl::Id: + ColorControlClusterAttributeChangeCallback(attributePath, size, value); + break; default: break; diff --git a/examples/virtual-device-app/android/java/ColorControlManager.cpp b/examples/virtual-device-app/android/java/ColorControlManager.cpp new file mode 100644 index 00000000000000..0386f96272f66e --- /dev/null +++ b/examples/virtual-device-app/android/java/ColorControlManager.cpp @@ -0,0 +1,269 @@ +/** + * + * 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. + */ +#include "ColorControlManager.h" +#include "DeviceApp-JNI.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; + +static constexpr size_t kColorControlManagerTableSize = EMBER_AF_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT; + +namespace { + +ColorControlManager * gColorControlManagerTable[kColorControlManagerTableSize] = { nullptr }; +static_assert(kColorControlManagerTableSize <= kEmberInvalidEndpointIndex, "gColorControlManagerTable table size error"); + +} // namespace + +void emberAfColorControlClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "Device App::ColorControl::PostClusterInit"); + DeviceAppJNIMgr().PostClusterInit(chip::app::Clusters::ColorControl::Id, endpoint); +} + +void ColorControlManager::NewManager(jint endpoint, jobject manager) +{ + ChipLogProgress(Zcl, "Device App: ColorControlManager::NewManager"); + uint16_t ep = emberAfGetClusterServerEndpointIndex(static_cast(endpoint), app::Clusters::ColorControl::Id, + EMBER_AF_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); + VerifyOrReturn(ep < kColorControlManagerTableSize, + ChipLogError(Zcl, "Device App::ColorControl::NewManager: endpoint %d not found", endpoint)); + + VerifyOrReturn(gColorControlManagerTable[ep] == nullptr, + ChipLogError(Zcl, "ST Device App::ColorControl::NewManager: endpoint %d already has a manager", endpoint)); + ColorControlManager * mgr = new ColorControlManager(); + CHIP_ERROR err = mgr->InitializeWithObjects(manager); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "ST Device App::ColorControl::NewManager: failed to initialize manager for endpoint %d", endpoint); + delete mgr; + } + else + { + gColorControlManagerTable[ep] = mgr; + } +} + +static ColorControlManager * GetColorControlManager(EndpointId endpoint) +{ + uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, app::Clusters::ColorControl::Id, + EMBER_AF_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); + return (ep >= kColorControlManagerTableSize ? nullptr : gColorControlManagerTable[ep]); +} + +void ColorControlManager::PostCurrentHueChanged(chip::EndpointId endpoint, int value) +{ + ChipLogProgress(Zcl, "Device App: ColorControlManager::PostCurrentHueChanged"); + ColorControlManager * mgr = GetColorControlManager(endpoint); + VerifyOrReturn(mgr != nullptr, ChipLogError(Zcl, "ColorControlManager null")); + + mgr->HandleCurrentHueChanged(value); +} + +void ColorControlManager::PostCurrentSaturationChanged(chip::EndpointId endpoint, int value) +{ + ChipLogProgress(Zcl, "Device App: ColorControlManager::PostCurrentSaturationChanged"); + ColorControlManager * mgr = GetColorControlManager(endpoint); + VerifyOrReturn(mgr != nullptr, ChipLogError(Zcl, "ColorControlManager null")); + + mgr->HandleCurrentSaturationChanged(value); +} + +void ColorControlManager::PostColorTemperatureChanged(chip::EndpointId endpoint, int value) +{ + ChipLogProgress(Zcl, "Device App: ColorControlManager::PostColorTemperatureChanged"); + ColorControlManager * mgr = GetColorControlManager(endpoint); + VerifyOrReturn(mgr != nullptr, ChipLogError(Zcl, "ColorControlManager null")); + + mgr->HandleColorTemperatureChanged(value); +} + +void ColorControlManager::PostColorModeChanged(chip::EndpointId endpoint, int value) +{ + ChipLogProgress(Zcl, "Device App: ColorControlManager::PostColorModeChanged"); + ColorControlManager * mgr = GetColorControlManager(endpoint); + VerifyOrReturn(mgr != nullptr, ChipLogError(Zcl, "ColorControlManager null")); + + mgr->HandleColorModeChanged(value); +} + +void ColorControlManager::PostEnhancedColorModeChanged(chip::EndpointId endpoint, int value) +{ + ChipLogProgress(Zcl, "Device App: ColorControlManager::PostEnhancedColorModeChanged"); + ColorControlManager * mgr = GetColorControlManager(endpoint); + VerifyOrReturn(mgr != nullptr, ChipLogError(Zcl, "ColorControlManager null")); + + mgr->HandleEnhancedColorModeChanged(value); +} + +CHIP_ERROR ColorControlManager::InitializeWithObjects(jobject managerObject) +{ + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturnLogError(env != nullptr, CHIP_ERROR_INCORRECT_STATE); + + mColorControlManagerObject = env->NewGlobalRef(managerObject); + VerifyOrReturnLogError(mColorControlManagerObject != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + jclass ColorControlManagerClass = env->GetObjectClass(managerObject); + VerifyOrReturnLogError(ColorControlManagerClass != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + mHandleCurrentHueChangedMethod = env->GetMethodID(ColorControlManagerClass, "HandleCurrentHueChanged", "(I)V"); + if (mHandleCurrentHueChangedMethod == nullptr) + { + ChipLogError(Zcl, "Failed to access ColorControlManager 'HandleCurrentHueChanged' method"); + env->ExceptionClear(); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + mHandleCurrentSaturationChangedMethod = env->GetMethodID(ColorControlManagerClass, "HandleCurrentSaturationChanged", "(I)V"); + if (mHandleCurrentSaturationChangedMethod == nullptr) + { + ChipLogError(Zcl, "Failed to access ColorControlManager 'HandleCurrentSaturationChanged' method"); + env->ExceptionClear(); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + mHandleColorTemperatureChangedMethod = env->GetMethodID(ColorControlManagerClass, "HandleColorTemperatureChanged", "(I)V"); + if (mHandleColorTemperatureChangedMethod == nullptr) + { + ChipLogError(Zcl, "Failed to access ColorControlManager 'HandleColorTemperatureChanged' method"); + env->ExceptionClear(); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + mHandleColorModeChangedMethod = env->GetMethodID(ColorControlManagerClass, "HandleColorModeChanged", "(I)V"); + if (mHandleColorModeChangedMethod == nullptr) + { + ChipLogError(Zcl, "Failed to access ColorControlManager 'HandleColorModeChanged' method"); + env->ExceptionClear(); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + mHandleEnhancedColorModeChangedMethod = env->GetMethodID(ColorControlManagerClass, "HandleEnhancedColorModeChanged", "(I)V"); + if (mHandleEnhancedColorModeChangedMethod == nullptr) + { + ChipLogError(Zcl, "Failed to access ColorControlManager 'HandleEnhancedColorModeChanged' method"); + env->ExceptionClear(); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + return CHIP_NO_ERROR; +} + +void ColorControlManager::HandleCurrentHueChanged(int value) +{ + ChipLogProgress(Zcl, "ColorControlManager::HandleCurrentHueChanged"); + + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturn(env != NULL, ChipLogProgress(Zcl, "env null")); + VerifyOrReturn(mColorControlManagerObject != nullptr, ChipLogProgress(Zcl, "mColorControlManagerObject null")); + VerifyOrReturn(mHandleCurrentHueChangedMethod != nullptr, ChipLogProgress(Zcl, "mHandleCurrentHueChangedMethod null")); + + env->ExceptionClear(); + env->CallVoidMethod(mColorControlManagerObject, mHandleCurrentHueChangedMethod, value); + if (env->ExceptionCheck()) + { + ChipLogError(AppServer, "Java exception in ColorControlManager::HandleCurrentHueChanged"); + env->ExceptionDescribe(); + env->ExceptionClear(); + } +} + +void ColorControlManager::HandleCurrentSaturationChanged(int value) +{ + ChipLogProgress(Zcl, "ColorControlManager::HandleCurrentSaturationChanged"); + + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturn(env != NULL, ChipLogProgress(Zcl, "env null")); + VerifyOrReturn(mColorControlManagerObject != nullptr, ChipLogProgress(Zcl, "mColorControlManagerObject null")); + VerifyOrReturn(mHandleCurrentSaturationChangedMethod != nullptr, + ChipLogProgress(Zcl, "mHandleCurrentSaturationChangedMethod null")); + + env->ExceptionClear(); + env->CallVoidMethod(mColorControlManagerObject, mHandleCurrentSaturationChangedMethod, value); + if (env->ExceptionCheck()) + { + ChipLogError(AppServer, "Java exception in ColorControlManager::HandleCurrentSaturationChanged"); + env->ExceptionDescribe(); + env->ExceptionClear(); + } +} + +void ColorControlManager::HandleColorTemperatureChanged(int value) +{ + ChipLogProgress(Zcl, "ColorControlManager::HandleColorTemperatureChanged"); + + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturn(env != NULL, ChipLogProgress(Zcl, "env null")); + VerifyOrReturn(mColorControlManagerObject != nullptr, ChipLogProgress(Zcl, "mColorControlManagerObject null")); + VerifyOrReturn(mHandleColorTemperatureChangedMethod != nullptr, + ChipLogProgress(Zcl, "mHandleColorTemperatureChangedMethod null")); + + env->ExceptionClear(); + env->CallVoidMethod(mColorControlManagerObject, mHandleColorTemperatureChangedMethod, value); + if (env->ExceptionCheck()) + { + ChipLogError(AppServer, "Java exception in ColorControlManager::mHandleColorTemperatureChanged"); + env->ExceptionDescribe(); + env->ExceptionClear(); + } +} + +void ColorControlManager::HandleColorModeChanged(int value) +{ + ChipLogProgress(Zcl, "ColorControlManager::HandleColorModeChanged"); + + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturn(env != NULL, ChipLogProgress(Zcl, "env null")); + VerifyOrReturn(mColorControlManagerObject != nullptr, ChipLogProgress(Zcl, "mColorControlManagerObject null")); + VerifyOrReturn(mHandleColorModeChangedMethod != nullptr, ChipLogProgress(Zcl, "mHandleColorModeChangedMethod null")); + + env->ExceptionClear(); + env->CallVoidMethod(mColorControlManagerObject, mHandleColorModeChangedMethod, value); + if (env->ExceptionCheck()) + { + ChipLogError(AppServer, "Java exception in ColorControlManager::HandleColorModeChanged"); + env->ExceptionDescribe(); + env->ExceptionClear(); + } +} + +void ColorControlManager::HandleEnhancedColorModeChanged(int value) +{ + ChipLogProgress(Zcl, "ColorControlManager::HandleEnhancedColorModeChanged"); + + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrReturn(env != NULL, ChipLogProgress(Zcl, "env null")); + VerifyOrReturn(mColorControlManagerObject != nullptr, ChipLogProgress(Zcl, "mColorControlManagerObject null")); + VerifyOrReturn(mHandleEnhancedColorModeChangedMethod != nullptr, + ChipLogProgress(Zcl, "mHandleEnhancedColorModeChangedMethod null")); + + env->ExceptionClear(); + env->CallVoidMethod(mColorControlManagerObject, mHandleEnhancedColorModeChangedMethod, value); + if (env->ExceptionCheck()) + { + ChipLogError(AppServer, "Java exception in ColorControlManager::HandleEnhancedColorModeChanged"); + env->ExceptionDescribe(); + env->ExceptionClear(); + } +} diff --git a/examples/virtual-device-app/android/java/ColorControlManager.h b/examples/virtual-device-app/android/java/ColorControlManager.h new file mode 100644 index 00000000000000..be1022348c900c --- /dev/null +++ b/examples/virtual-device-app/android/java/ColorControlManager.h @@ -0,0 +1,55 @@ +/* + * + * 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. + */ +#pragma once + +#include +#include + +class ColorControlManager +{ +public: + static void NewManager(jint endpoint, jobject manager); + + static void PostCurrentHueChanged(chip::EndpointId endpoint, int currentHue); + + static void PostCurrentSaturationChanged(chip::EndpointId endpoint, int currentSaturation); + + static void PostColorTemperatureChanged(chip::EndpointId endpoint, int colorTemperature); + + static void PostColorModeChanged(chip::EndpointId endpoint, int colorMode); + + static void PostEnhancedColorModeChanged(chip::EndpointId endpoint, int enhancedColorMode); + + void HandleCurrentHueChanged(int value); + + void HandleCurrentSaturationChanged(int value); + + void HandleColorTemperatureChanged(int value); + + void HandleColorModeChanged(int value); + + void HandleEnhancedColorModeChanged(int value); + +private: + CHIP_ERROR InitializeWithObjects(jobject managerObject); + jobject mColorControlManagerObject = nullptr; + jmethodID mHandleCurrentHueChangedMethod = nullptr; + jmethodID mHandleCurrentSaturationChangedMethod = nullptr; + jmethodID mHandleColorTemperatureChangedMethod = nullptr; + jmethodID mHandleColorModeChangedMethod = nullptr; + jmethodID mHandleEnhancedColorModeChangedMethod = nullptr; +}; diff --git a/examples/virtual-device-app/android/java/DeviceApp-JNI.cpp b/examples/virtual-device-app/android/java/DeviceApp-JNI.cpp index 6e44f1fbd40777..02998bb4c7295d 100644 --- a/examples/virtual-device-app/android/java/DeviceApp-JNI.cpp +++ b/examples/virtual-device-app/android/java/DeviceApp-JNI.cpp @@ -20,6 +20,7 @@ #include "AppImpl.h" #include "JNIDACProvider.h" +#include "ColorControlManager.h" #include "OnOffManager.h" #include "credentials/DeviceAttestationCredsProvider.h" #include @@ -157,3 +158,11 @@ JNI_METHOD(jboolean, setOnOff)(JNIEnv *, jobject, jint endpoint, jboolean value) return DeviceLayer::SystemLayer().ScheduleLambda([endpoint, value] { OnOffManager::SetOnOff(endpoint, value); }) == CHIP_NO_ERROR; } + +/* + * Color Control Manager + */ +JNI_METHOD(void, setColorControlManager)(JNIEnv *, jobject, jint endpoint, jobject manager) +{ + ColorControlManager::NewManager(endpoint, manager); +} diff --git a/examples/virtual-device-app/android/java/src/com/matter/virtual/device/app/ColorControlManager.java b/examples/virtual-device-app/android/java/src/com/matter/virtual/device/app/ColorControlManager.java new file mode 100644 index 00000000000000..725d0b94cc9a22 --- /dev/null +++ b/examples/virtual-device-app/android/java/src/com/matter/virtual/device/app/ColorControlManager.java @@ -0,0 +1,18 @@ +package com.matter.virtual.device.app; + +public interface ColorControlManager { + /* + * Set up the initial value when device is powered on + */ + void initAttributeValue(int endpoint); + + void HandleEnhancedColorModeChanged(int value); + + void HandleColorModeChanged(int value); + + void HandleCurrentHueChanged(int value); + + void HandleCurrentSaturationChanged(int value); + + void HandleColorTemperatureChanged(int value); +} diff --git a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter index 13c09f66a40190..95fcd28b05d0ef 100644 --- a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter +++ b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter @@ -1600,6 +1600,140 @@ server cluster UserLabel = 65 { readonly attribute int16u clusterRevision = 65533; } +/** Attributes and commands for controlling the color properties of a color-capable light. */ +server cluster ColorControl = 768 { + enum ColorLoopAction : ENUM8 { + kDeactivate = 0; + kActivateFromColorLoopStartEnhancedHue = 1; + kActivateFromEnhancedCurrentHue = 2; + } + + enum ColorLoopDirection : ENUM8 { + kDecrementHue = 0; + kIncrementHue = 1; + } + + enum ColorMode : ENUM8 { + kCurrentHueAndCurrentSaturation = 0; + kCurrentXAndCurrentY = 1; + kColorTemperature = 2; + } + + enum HueDirection : ENUM8 { + kShortestDistance = 0; + kLongestDistance = 1; + kUp = 2; + kDown = 3; + } + + enum HueMoveMode : ENUM8 { + kStop = 0; + kUp = 1; + kDown = 3; + } + + enum HueStepMode : ENUM8 { + kUp = 1; + kDown = 3; + } + + enum SaturationMoveMode : ENUM8 { + kStop = 0; + kUp = 1; + kDown = 3; + } + + enum SaturationStepMode : ENUM8 { + kUp = 1; + kDown = 3; + } + + bitmap ColorCapabilities : BITMAP16 { + kHueSaturationSupported = 0x1; + kEnhancedHueSupported = 0x2; + kColorLoopSupported = 0x4; + kXYAttributesSupported = 0x8; + kColorTemperatureSupported = 0x10; + } + + bitmap ColorLoopUpdateFlags : BITMAP8 { + kUpdateAction = 0x1; + kUpdateDirection = 0x2; + kUpdateTime = 0x4; + kUpdateStartHue = 0x8; + } + + bitmap Feature : BITMAP32 { + kHueAndSaturation = 0x1; + kEnhancedHue = 0x2; + kColorLoop = 0x4; + kXY = 0x8; + kColorTemperature = 0x10; + } + + readonly attribute int8u currentHue = 0; + readonly attribute int8u currentSaturation = 1; + readonly attribute int16u remainingTime = 2; + readonly attribute int16u currentX = 3; + readonly attribute int16u currentY = 4; + readonly attribute int16u colorTemperatureMireds = 7; + readonly attribute enum8 colorMode = 8; + attribute bitmap8 options = 15; + readonly attribute nullable int8u numberOfPrimaries = 16; + readonly attribute enum8 enhancedColorMode = 16385; + readonly attribute bitmap16 colorCapabilities = 16394; + 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 MoveToHueRequest { + INT8U hue = 0; + HueDirection direction = 1; + INT16U transitionTime = 2; + BITMAP8 optionsMask = 3; + BITMAP8 optionsOverride = 4; + } + + request struct MoveToSaturationRequest { + INT8U saturation = 0; + INT16U transitionTime = 1; + BITMAP8 optionsMask = 2; + BITMAP8 optionsOverride = 3; + } + + request struct MoveToHueAndSaturationRequest { + INT8U hue = 0; + INT8U saturation = 1; + INT16U transitionTime = 2; + BITMAP8 optionsMask = 3; + BITMAP8 optionsOverride = 4; + } + + request struct MoveToColorRequest { + INT16U colorX = 0; + INT16U colorY = 1; + INT16U transitionTime = 2; + BITMAP8 optionsMask = 3; + BITMAP8 optionsOverride = 4; + } + + request struct MoveToColorTemperatureRequest { + INT16U colorTemperatureMireds = 0; + INT16U transitionTime = 1; + BITMAP8 optionsMask = 2; + BITMAP8 optionsOverride = 3; + } + + command MoveToHue(MoveToHueRequest): DefaultSuccess = 0; + command MoveToSaturation(MoveToSaturationRequest): DefaultSuccess = 3; + command MoveToHueAndSaturation(MoveToHueAndSaturationRequest): DefaultSuccess = 6; + command MoveToColor(MoveToColorRequest): DefaultSuccess = 7; + command MoveToColorTemperature(MoveToColorTemperatureRequest): DefaultSuccess = 10; +} + endpoint 0 { device type ma_rootdevice = 22, version 1; @@ -1937,6 +2071,26 @@ endpoint 1 { ram attribute featureMap default = 0; callback attribute clusterRevision default = 1; } + + server cluster ColorControl { + ram attribute currentHue default = 0x00; + ram attribute currentSaturation default = 0x00; + ram attribute remainingTime default = 0x0000; + ram attribute currentX default = 0x616B; + ram attribute currentY default = 0x607D; + ram attribute colorTemperatureMireds default = 0x00FA; + ram attribute colorMode default = 0x01; + ram attribute options default = 0x00; + ram attribute numberOfPrimaries; + ram attribute enhancedColorMode default = 0x01; + ram attribute colorCapabilities default = 0x0000; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 1; + ram attribute clusterRevision default = 5; + } } diff --git a/examples/virtual-device-app/virtual-device-common/virtual-device-app.zap b/examples/virtual-device-app/virtual-device-common/virtual-device-app.zap index 8b7302ca6b3172..8a72eaeede29ca 100644 --- a/examples/virtual-device-app/virtual-device-common/virtual-device-app.zap +++ b/examples/virtual-device-app/virtual-device-common/virtual-device-app.zap @@ -33,7 +33,33 @@ ], "endpointTypes": [ { + "id": 1, "name": "MA-rootdevice", + "deviceTypeRef": { + "id": 2, + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + }, + "deviceTypes": [ + { + "id": 2, + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + } + ], + "deviceTypeRefs": [ + 2 + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 22 + ], "deviceTypeName": "MA-rootdevice", "deviceTypeCode": 22, "deviceTypeProfileId": 259, @@ -7003,7 +7029,33 @@ ] }, { + "id": 2, "name": "MA-videoplayer", + "deviceTypeRef": { + "id": 8, + "code": 256, + "profileId": 259, + "label": "MA-onofflight", + "name": "MA-onofflight" + }, + "deviceTypes": [ + { + "id": 8, + "code": 256, + "profileId": 259, + "label": "MA-onofflight", + "name": "MA-onofflight" + } + ], + "deviceTypeRefs": [ + 8 + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 256 + ], "deviceTypeName": "MA-onofflight", "deviceTypeCode": 256, "deviceTypeProfileId": 259, @@ -12016,6 +12068,22 @@ "incoming": 1, "outgoing": 0 }, + { + "name": "MoveHue", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 0 + }, + { + "name": "StepHue", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 0 + }, { "name": "MoveToSaturation", "code": 3, @@ -12024,6 +12092,22 @@ "incoming": 1, "outgoing": 0 }, + { + "name": "MoveSaturation", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 0 + }, + { + "name": "StepSaturation", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 0 + }, { "name": "MoveToHueAndSaturation", "code": 6, @@ -12047,6 +12131,14 @@ "source": "client", "incoming": 1, "outgoing": 0 + }, + { + "name": "MoveColorTemperature", + "code": 75, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 0 } ], "attributes": [ @@ -12090,7 +12182,7 @@ "mfgCode": null, "define": "COLOR_CONTROL_CLUSTER", "side": "server", - "enabled": 0, + "enabled": 1, "attributes": [ { "name": "CurrentHue", @@ -12956,6 +13048,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "AttributeList", "code": 65531, @@ -15623,18 +15731,14 @@ "endpointTypeIndex": 0, "profileId": 259, "endpointId": 0, - "networkId": 0, - "endpointVersion": 1, - "deviceIdentifier": 22 + "networkId": 0 }, { "endpointTypeName": "MA-videoplayer", "endpointTypeIndex": 1, "profileId": 259, "endpointId": 1, - "networkId": 0, - "endpointVersion": 1, - "deviceIdentifier": 256 + "networkId": 0 } ], "log": [] From 07fa5bf3459d6310f03e0d274137f91f0b3615c9 Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Wed, 16 Aug 2023 00:51:27 -0700 Subject: [PATCH 6/6] add missing json member for AttributeWriteRequest (#28712) --- .../model/AttributeWriteRequest.java | 99 +++++++++++++++++-- .../devicecontroller/model/InvokeElement.java | 8 +- 2 files changed, 100 insertions(+), 7 deletions(-) diff --git a/src/controller/java/src/chip/devicecontroller/model/AttributeWriteRequest.java b/src/controller/java/src/chip/devicecontroller/model/AttributeWriteRequest.java index 0b74693480f5ba..792b7577efc15d 100644 --- a/src/controller/java/src/chip/devicecontroller/model/AttributeWriteRequest.java +++ b/src/controller/java/src/chip/devicecontroller/model/AttributeWriteRequest.java @@ -20,23 +20,47 @@ import java.util.Locale; import java.util.Objects; import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.Nullable; +import org.json.JSONException; +import org.json.JSONObject; /** An attribute write request that should be used for interaction model write interaction. */ public final class AttributeWriteRequest { + private static final Logger logger = Logger.getLogger(AttributeWriteRequest.class.getName()); private final ChipPathId endpointId, clusterId, attributeId; private final Optional dataVersion; - private final byte[] tlv; + @Nullable private final byte[] tlv; + @Nullable private final JSONObject json; private AttributeWriteRequest( ChipPathId endpointId, ChipPathId clusterId, ChipPathId attributeId, - byte[] tlv, + @Nullable byte[] tlv, + @Nullable String jsonString, Optional dataVersion) { this.endpointId = endpointId; this.clusterId = clusterId; this.attributeId = attributeId; - this.tlv = tlv.clone(); + + if (tlv != null) { + this.tlv = tlv.clone(); + } else { + this.tlv = null; + } + + JSONObject jsonObject = null; + if (jsonString != null) { + try { + jsonObject = new JSONObject(jsonString); + } catch (JSONException ex) { + logger.log(Level.SEVERE, "Error parsing JSON string", ex); + } + } + + this.json = jsonObject; this.dataVersion = dataVersion; } @@ -60,8 +84,23 @@ public boolean hasDataVersion() { return dataVersion.isPresent(); } + @Nullable public byte[] getTlvByteArray() { - return tlv.clone(); + if (tlv != null) { + return tlv.clone(); + } + return null; + } + + @Nullable + public JSONObject getJson() { + return json; + } + + @Nullable + public String getJsonString() { + if (json == null) return null; + return json.toString(); } // check whether the current AttributeWriteRequest has same path as others. @@ -93,7 +132,8 @@ public String toString() { public static AttributeWriteRequest newInstance( ChipPathId endpointId, ChipPathId clusterId, ChipPathId attributeId, byte[] tlv) { - return new AttributeWriteRequest(endpointId, clusterId, attributeId, tlv, Optional.empty()); + return new AttributeWriteRequest( + endpointId, clusterId, attributeId, tlv, null, Optional.empty()); } public static AttributeWriteRequest newInstance( @@ -102,7 +142,7 @@ public static AttributeWriteRequest newInstance( ChipPathId attributeId, byte[] tlv, Optional dataVersion) { - return new AttributeWriteRequest(endpointId, clusterId, attributeId, tlv, dataVersion); + return new AttributeWriteRequest(endpointId, clusterId, attributeId, tlv, null, dataVersion); } /** Create a new {@link AttributeWriteRequest} with only concrete ids. */ @@ -113,9 +153,11 @@ public static AttributeWriteRequest newInstance( ChipPathId.forId(clusterId), ChipPathId.forId(attributeId), tlv, + null, Optional.empty()); } + /** Create a new {@link AttributeWriteRequest} with only concrete ids. */ public static AttributeWriteRequest newInstance( int endpointId, long clusterId, long attributeId, byte[] tlv, Optional dataVersion) { return new AttributeWriteRequest( @@ -123,6 +165,51 @@ public static AttributeWriteRequest newInstance( ChipPathId.forId(clusterId), ChipPathId.forId(attributeId), tlv, + null, + dataVersion); + } + + public static AttributeWriteRequest newInstance( + ChipPathId endpointId, ChipPathId clusterId, ChipPathId attributeId, String jsonString) { + return new AttributeWriteRequest( + endpointId, clusterId, attributeId, null, jsonString, Optional.empty()); + } + + /** Create a new {@link AttributeWriteRequest} with only concrete ids. */ + public static AttributeWriteRequest newInstance( + int endpointId, long clusterId, long attributeId, String jsonString) { + return new AttributeWriteRequest( + ChipPathId.forId(endpointId), + ChipPathId.forId(clusterId), + ChipPathId.forId(attributeId), + null, + jsonString, + Optional.empty()); + } + + public static AttributeWriteRequest newInstance( + ChipPathId endpointId, + ChipPathId clusterId, + ChipPathId attributeId, + String jsonString, + Optional dataVersion) { + return new AttributeWriteRequest( + endpointId, clusterId, attributeId, null, jsonString, dataVersion); + } + + /** Create a new {@link AttributeWriteRequest} with only concrete ids. */ + public static AttributeWriteRequest newInstance( + int endpointId, + long clusterId, + long attributeId, + String jsonString, + Optional dataVersion) { + return new AttributeWriteRequest( + ChipPathId.forId(endpointId), + ChipPathId.forId(clusterId), + ChipPathId.forId(attributeId), + null, + jsonString, dataVersion); } } diff --git a/src/controller/java/src/chip/devicecontroller/model/InvokeElement.java b/src/controller/java/src/chip/devicecontroller/model/InvokeElement.java index 2ae4b55ff423e6..1a97bf64bc012a 100644 --- a/src/controller/java/src/chip/devicecontroller/model/InvokeElement.java +++ b/src/controller/java/src/chip/devicecontroller/model/InvokeElement.java @@ -81,10 +81,16 @@ public byte[] getTlvByteArray() { } @Nullable - public JSONObject getJson() { + public JSONObject getJsonObject() { return json; } + @Nullable + public String getJsonString() { + if (json == null) return null; + return json.toString(); + } + // check whether the current InvokeElement has same path as others. @Override public boolean equals(Object object) {