Repository navigation
WWST: add Zemismart KES606 four-gang relay/scene switch - #3239
zemismart-dev wants to merge 6 commits into
Conversation
|
Duplicate profile check: Passed - no duplicate profiles detected. |
|
Profile category check: ✅ Passed - all profiles have a category defined. |
|
Invitation URL: |
|
zigbee-switch_coverage.xml
Minimum allowed coverage is Generated by 🐒 cobertura-action against e1c0c3c |
Test Results 73 files ± 0 542 suites +1 0s ⏱️ ±0s For more details on these errors, see this check. Results for commit e1c0c3c. ± Comparison against base commit 87c61ad. |
cjswedes
left a comment
There was a problem hiding this comment.
A refresh-only parent with four independently switchable relay/scene children. Both the existing implementation and candidate tests pass the child automation-presentation checks, while the parent fails the generic requirement for an automation action or condition. We are requesting review of that design; no exception approval is assumed.
I am not sure what to do about this; it may need an exception. My only idea is that the parent could have a switch and button capability on its main component:
- button is pressed whenever a child device button is pressed (this is inline with functionality of other zigbee button devices)
- switch controls all child devices that are in the non-scene mode, and if 1 child is on then the parent is on, otherwise it is off.
| if device == nil then return false end | ||
| local parent = device | ||
| if device.network_type == device_lib.NETWORK_TYPE_CHILD then | ||
| local gang = tonumber((device.parent_assigned_child_key or ""):match("^gang([1-4])$")) | ||
| if gang == nil then return false end | ||
| parent = device:get_parent_device() | ||
| elseif device.network_type ~= device_lib.NETWORK_TYPE_ZIGBEE then | ||
| return false | ||
| end | ||
| if parent ~= nil and parent:get_manufacturer() == "_TZ3000_hurauima" | ||
| and parent:get_model() == "TS0726" then | ||
| return true, require("zemismart-kes606") | ||
| end |
There was a problem hiding this comment.
this can_handle is quite confusing:
- The
get_manufacturerandget_modelcommands when called on a zigbee child device are overwritten to lookup the mfr/model on the parent device. - The checking of if the parent_assigned_child_key parses correctly should not be done in this function. If that fails here, there are no other subdrivers/handlers where it will succeed, so we should just let it fail in this subdriver so that any errors (which shouldnt happen) are actually associated with the code that created the child devices
| if device == nil then return false end | |
| local parent = device | |
| if device.network_type == device_lib.NETWORK_TYPE_CHILD then | |
| local gang = tonumber((device.parent_assigned_child_key or ""):match("^gang([1-4])$")) | |
| if gang == nil then return false end | |
| parent = device:get_parent_device() | |
| elseif device.network_type ~= device_lib.NETWORK_TYPE_ZIGBEE then | |
| return false | |
| end | |
| if parent ~= nil and parent:get_manufacturer() == "_TZ3000_hurauima" | |
| and parent:get_model() == "TS0726" then | |
| return true, require("zemismart-kes606") | |
| end | |
| if device ~= nil and device:get_manufacturer() == "_TZ3000_hurauima" | |
| and device:get_model() == "TS0726" then | |
| return true, require("zemismart-kes606") | |
| end | |
| return false |
There was a problem hiding this comment.
Applied in 09a4655. The KES606 matcher now uses the exact manufacturer/model check you suggested, relying on the SDK's child-to-parent lookup. Child-key validation no longer affects subdriver selection; malformed keys remain within the KES606 handler and are rejected by its gang-specific command/preference guards. Added regression coverage for those cases.
| -- The composite relay/scene device has its own configure and refresh handlers. | ||
| if device:get_manufacturer() == "_TZ3000_hurauima" and device:get_model() == "TS0726" then | ||
| return false | ||
| end |
There was a problem hiding this comment.
Rather than excluding like this, we should have the zemismart-kes606 subdriver be a nested subdriver of this Tuya multi subdriver. That will prevent it from using the handlers here that are overridden by the new zemismart subdriver.
There was a problem hiding this comment.
Applied in 09a4655. KES606 is now nested under tuya-multi; the root entry and exact-fingerprint exclusion were removed. tuya-multi/sub_drivers.lua and the full init table register the same hierarchy for lazy loading.
KES606 children use the physical parent's endpoint map at the Tuya boundary. Other Tuya children keep their previous root routing, avoiding additional generic configure/refresh/magic-spell traffic. Tests cover nested parent/child dispatch and lifecycle behavior, generic Tuya parent/child behavior, sparse endpoint maps and single-endpoint configuration. Focused suites pass 140/140 on API 19 and API 21. This routing follow-up has not yet been installed on the physical test Hub; the October 13 physical reports remain tied to 192595d.
| local function onoff_report(_, device, value, zb_rx) | ||
| local gang = endpoint_from_rx(zb_rx) | ||
| local parent = parent_from_device(device) | ||
| if gang == nil or parent == nil or gang_mode(parent, gang) == "scene" then return end |
There was a problem hiding this comment.
Can you clarify why gang_mode (the persisted field) and child:supports_capability are both consulted in some paths (onoff_report) but only the field is consulted in others (relay_command)?
There was a problem hiding this comment.
The two checks serve different purposes. Within gang_mode, child capabilities are only a fallback when no tracked mode is available. The tracked mode is updated from device readback and governs whether an endpoint is eligible for relay control or scene handling. Pending transitions suppress routing until D020 confirms the actual mode.
Handler-level capability checks separately prevent emitting an event into an incompatible child profile while its cloud update is asynchronous. Relay commands therefore use the confirmed mode/pending guard; child switch-event emission additionally requires a switch-capable profile. A valid relay report still updates the parent cache during a profile transition, and profile completion triggers another read. I added a source comment to make the fallback distinction explicit.
| categories: | ||
| - name: RemoteController | ||
| preferences: | ||
| - title: Indicator Light |
There was a problem hiding this comment.
Regarding your review request:
The embedded preference definitions, or the approved shared preferences that should replace them without changing their meaning.
We would prefer you use the shared preferences where possible
There was a problem hiding this comment.
I audited the current standard, stse and certifiedpreferences catalogs (90 definitions). The three-state power-on and indicator settings and the 0–43200-second toggle countdown do not have equivalent shared definitions. For example, restorePowerState is Boolean; powerOffMemory adds unsupported reverse behavior; turnOffDelay lacks zero cancellation, the full range and delayed-on behavior.
stse.changeToWirelessSwitch matches the basic mode function, but replacing our existing switchMode enum also changes the saved key/type and introduces a false default for existing Scene children. I did not find a documented alias or supported per-device preference-value migration in the current profile/SDK interfaces. Ignoring the new default would leave the displayed setting inconsistent; treating it as an ordinary change risks switching a Scene gang back to relay mode.
I have therefore retained the inline definitions and saved settings in this revision. Could you advise whether there is a preferred compatible shared enum or supported migration mechanism for this case? The catalog/schema audit is complete, but I am not claiming a shared-preference conversion.
|
Thanks @cjswedes. The parent switch/button suggestion was implemented in 192595d, and the physical failed-case retests are complete:
These are targeted operational reports with documented exclusions, not a new Full Integration Test. A separate mixed-mode regression confirmed master commands skip Scene gangs and aggregate state follows eligible relay reports. All four gangs were restored to Switch; the final parent on/off regression and operator confirmation ended with all loads off. The submitted certification report's notes now reference the new evidence. I have also pushed 09a4655 for the matcher/nested-dispatch feedback and replied to all four inline comments. Focused API 19/API 21 suites each pass 140/140; lint and independent review passed. Full local zigbee-switch runs have the same pre-existing failing-case sets as the clean 192595d baseline; they are not reported as all-green. This new routing revision is locally validated only; the physical reports above remain associated with 192595d and package 2026-10-13T07:18:46.468510907. The shared-preference comment has a compatibility explanation and a request for guidance on safe mode-preference migration. No certification approval is assumed. |
Type of Change
Checklist
Description of Change
Add exact-fingerprint support for the Zemismart KES-606US-L4 (
_TZ3000_hurauima / TS0726) to Zigbee Switch, with four independent relay/scene children.Following maintainer feedback, the parent now exposes
switch,buttonandrefresh. Parent on/off targets only confirmed relay-mode gangs; scene-mode or pending-transition gangs are skipped. Its switch is on when any eligible relay reports on, and off only when every eligible relay is known off (or no relay-mode gang remains). Command acknowledgements and unknown reports do not invent aggregate state. A real scene-button command is forwarded to the appropriate child and the parent's aggregate pushed event; initialization and relay reports never synthesize presses.Requested modes are kept separate from protocol-confirmed modes. A persisted pending transition blocks control and prevents a premature aggregate off until D020 readback resolves the actual mode. Rejected changes and late asynchronous child profile updates are reconciled. Existing parent profiles migrate to the new switch/button profile with readback after completion.
Existing exact endpoint mapping, countdown, indicator and global/per-gang power-on settings are retained. The dedicated DefaultResponse handler keeps generic native handling from bypassing child/aggregate routing. Legacy ts0601 profile names remain for continuity; no other fingerprint or custom capability is added.
Current review changes and validation
Commit
09a46554713f6c093d1fdda2a333ce5a10856103simplifies the exact KES606 matcher as requested and nests the handler undertuya-multi, using both the lazy-load registration module and the full init table. The Tuya entry point consults the physical parent's endpoints for KES606 children, while generic Tuya children retain their previous root routing to avoid extra configuration traffic. Sparse SDK endpoint maps and single-endpoint behavior are covered.192595dbaseline using the same local SDK/runtime. Both revisions have the same failing case sets:1 API 19 failure and 62 API 21 failures involving existing SDK/capability argument validation and local Lua math.pow availability. No new broad failures were introduced. These full local runs are not claimed as all-green; the final two added sparse/single-endpoint tests were subsequently run in both focused suites.The October 15 routing revision has been built and tested locally, but has not replaced the Hub package or been physically retested. The hardware evidence below is explicitly for
192595dand its October 13 package. Hardware validation of the new routing revision remains a separate step before release.Hardware and certification evidence for the October 13 baseline
New package
2026-10-13T07:18:46.468510907is installed and selected by a clean pairing of the physical sample, with exactly one parent and four gang children. The initial generic-driver takeover retained three old generic endpoint children; the test family was explicitly removed and cleanly re-paired rather than treating that topology as accepted.The hardware-tested
192595dbaseline passed all six upstream Driver Tests jobs and CLA.The WWST application was submitted on September17 and remains under review. Historical full test 6MUUP3G0YH (46passed/1parent-presentation failure) belongs to the September17 package
2026-09-17T04:56:18.385495812; it is not evidence for the new parent capability behavior. The earlier scene report X90YMMGWXX belongs to the previous03:24 candidate. The later formal scene attempt XQA0I9YQF8 remains17passed/5failed/13excluded; continuous-log physical verification did not relabel it as passing. Earlier physical countdown/indicator/power-cycle evidence remains version-specific supplemental evidence.The original cloud-state stall cleared after an approved Hub reboot; its root cause was not established. The later September17 mode-return regression passed. Current October 13 hardware verification will be recorded separately.
This remains a draft for maintainer review of the routing follow-up and shared-preference compatibility explanation. No certification approval or parent-presentation exception is assumed.