@@ -48,9 +48,11 @@ class SystemEventControl(StrEnum):
4848 underscore-prefixed codes with an empty ``node_address``.
4949
5050 Codes ``_0``-``_23`` are the full ISY-994 set from the *ISY994
51- Developer Cookbook* §8.5; ``_28`` is an IoX-6 addition (Matter)
52- not in that document. Newer IoX firmware emits a few more
53- undocumented codes — those aren't enumerated; :meth:`label` passes
51+ Developer Cookbook* §8.5; ``_24``-``_28`` are IoX-6 additions
52+ (system editors, the modern Z-Wave / ZigBee / Matter drivers,
53+ system upgrade) not in that document — tracked from UDI's
54+ internal ``UDEvents.h`` taxonomy. Newer IoX firmware may emit
55+ further codes; those aren't enumerated, and :meth:`label` passes
5456 them through verbatim so logs still identify them.
5557 """
5658
@@ -110,24 +112,53 @@ class SystemEventControl(StrEnum):
110112 UPB_DEVICE_STATUS = "_16"
111113 #: Gas-meter events — ISY994 only.
112114 GAS_METER = "_17"
113- #: Zigbee events — ISY994 only.
115+ #: Legacy ZigBee events — ISY994-era driver. See :attr:`ZIGBEE_UYB`
116+ #: (``_27``) for the IoX-6+ ZigBee driver used on eisy.
114117 ZIGBEE = "_18"
115118 #: ELK alarm-panel events — requires the ELK module (see the ELK
116119 #: Integration Developer's Manual).
117120 ELK = "_19"
118121 #: Device-linker events — ``<action>`` 1 (status) / 2 (cleared).
119122 #: See :class:`DeviceLinkerAction`.
120123 DEVICE_LINKER = "_20"
121- #: Z-Wave integration events — requires the Z-Wave module (see the
122- #: Z-Wave Integration Developer's Manual).
124+ #: Legacy Z-Wave integration events — ISY994-era driver. See
125+ #: :attr:`ZMATTER_ZWAVE` (``_25``) for the IoX-6+ ZMatter Z-Wave
126+ #: driver used on eisy.
123127 ZWAVE = "_21"
124128 #: Billing events — ISY994 ZS-series only.
125129 BILLING = "_22"
126130 #: Portal events — portal socket-connection / account-registration
127131 #: status when a portal module is installed.
128132 PORTAL = "_23"
129- #: Matter network status — IoX 6+ with the Matter module. Not in
130- #: the ISY994 cookbook.
133+ #: System editor changed — fired when a "system editor" (e.g.
134+ #: ``_sys_notify_short``) is updated. ``<node>`` carries the editor
135+ #: name. ``<action>`` is :class:`SystemEditorAction`. IoX-6 addition.
136+ SYSTEM_EDITOR = "_24"
137+ #: ZMatter Z-Wave events — IoX-6+ Z-Wave driver on eisy hardware.
138+ #: ``<action>`` is dotted (``"{category}.{type}"``); category
139+ #: numbers are system-status (1), discovery (2), general-status (3),
140+ #: general-error (4), S2 (5), OTA (6), backup/restore (7), device-
141+ #: interview (8), button-detect (9), logger (10). Sub-action details
142+ #: aren't modelled — the dotted string passes through verbatim.
143+ #: Distinct from :attr:`ZWAVE` (``_21``, ISY994-era driver).
144+ ZMATTER_ZWAVE = "_25"
145+ #: System-upgrade lifecycle — ``<action>`` is :class:`SystemUpgradeAction`
146+ #: (active / inactive / available / reboot-required). IoX-6 addition.
147+ SYSTEM_UPGRADE = "_26"
148+ #: ZigBee events — IoX-6+ ZigBee driver on eisy hardware. Same
149+ #: dotted ``"{category}.{type}"`` action shape as :attr:`ZMATTER_ZWAVE`
150+ #: (minus the logger sub-category). Distinct from :attr:`ZIGBEE`
151+ #: (``_18``, ISY994-era driver).
152+ ZIGBEE_UYB = "_27"
153+ #: Matter network status — IoX-6+ Matter driver. ``<action>`` is
154+ #: dotted; active sub-categories are 1 (system status), 2 (discovery),
155+ #: 3 (RX/TX), 8 (device interview). Not in the ISY994 cookbook.
156+ #:
157+ #: **Note:** ``_28`` is also reserved in UDI's source for Profile
158+ #: change events (actions 1-8 — profile/editor/nodedef/linkdef
159+ #: updated/deleted) — but no firmware path fires those today
160+ #: (placeholders since Dec 2024 per UDI). Don't subscribe expecting
161+ #: them.
131162 MATTER_STATUS = "_28"
132163
133164 @classmethod
@@ -281,6 +312,39 @@ def label(cls, value: str) -> str:
281312 return _enum_label (cls , value )
282313
283314
315+ class SystemUpgradeAction (StrEnum ):
316+ """Action codes on :attr:`SystemEventControl.SYSTEM_UPGRADE` (``_26``)
317+ frames — IoX-6 firmware-upgrade lifecycle."""
318+
319+ #: Upgrade in progress.
320+ ACTIVE = "1"
321+ #: Upgrade not active (post-completion or idle).
322+ INACTIVE = "2"
323+ #: A new upgrade is available to install.
324+ AVAILABLE = "3"
325+ #: Upgrade applied; reboot required to take effect.
326+ REBOOT_REQUIRED = "4"
327+
328+ @classmethod
329+ def label (cls , value : str ) -> str :
330+ """Friendly lower-case name, or the raw value."""
331+ return _enum_label (cls , value )
332+
333+
334+ class SystemEditorAction (StrEnum ):
335+ """Action codes on :attr:`SystemEventControl.SYSTEM_EDITOR` (``_24``)
336+ frames. The ``<node>`` slot carries the editor name (e.g.
337+ ``_sys_notify_short``)."""
338+
339+ #: A system editor's contents changed.
340+ EDITOR_CHANGED = "1"
341+
342+ @classmethod
343+ def label (cls , value : str ) -> str :
344+ """Friendly lower-case name, or the raw value."""
345+ return _enum_label (cls , value )
346+
347+
284348class DeviceWriteAction (StrEnum ):
285349 """Device-write sub-codes that ride through on ``_7``
286350 (:attr:`SystemEventControl.PROGRESS`) frames — PyISY 3.x surfaced
@@ -359,6 +423,20 @@ class NodeLifecycleAction(StrEnum):
359423 #: should discard cached info for the node and rebuild it.
360424 #: ``<eventInfo>`` carries the full ``<node>`` structure.
361425 NODE_REVISED = "RV"
426+ #: Supported-type info changed — the node's nodedef assignment was
427+ #: reassigned (e.g. a node server's ``changeNode``, or a device
428+ #: driver detecting new capabilities). The primary signal that a
429+ #: cached nodedef → entity mapping is stale. *Not* fired for
430+ #: ``/rest/profiles`` definition updates or moves, or at startup
431+ #: migration — those rewrite the profile DB without notifying.
432+ NODE_TYPE_INFO_CHANGED = "NI"
433+ #: All nodes for a single device have been added (bulk). Fired
434+ #: after an include / re-pair so consumers can coalesce a single
435+ #: refresh per device instead of per child node.
436+ ALL_NODES_ADDED = "AA"
437+ #: Scene link updated — a link's properties (on-level / ramp rate)
438+ #: changed for an existing scene member.
439+ LINK_UPDATED = "LU"
362440 #: Discovering nodes (linking in progress). No node.
363441 DISCOVERING_NODES = "SN"
364442 #: Node discovery complete. No node.
@@ -419,6 +497,9 @@ def label(cls, value: str) -> str:
419497 NodeLifecycleAction .PENDING_DEVICE_OP : (),
420498 NodeLifecycleAction .PROGRAMMING_DEVICE : (),
421499 NodeLifecycleAction .NODE_REVISED : (), # plus the full <node> structure
500+ NodeLifecycleAction .NODE_TYPE_INFO_CHANGED : (),
501+ NodeLifecycleAction .ALL_NODES_ADDED : (),
502+ NodeLifecycleAction .LINK_UPDATED : (),
422503 NodeLifecycleAction .DISCOVERING_NODES : (),
423504 NodeLifecycleAction .NODE_DISCOVERY_COMPLETE : (),
424505 NodeLifecycleAction .NODE_ERROR : (),
@@ -454,6 +535,8 @@ def label(cls, value: str) -> str:
454535 SystemEventControl .PROGRESS : ProgressAction ,
455536 SystemEventControl .SECURITY_SYSTEM : SecuritySystemAction ,
456537 SystemEventControl .DEVICE_LINKER : DeviceLinkerAction ,
538+ SystemEventControl .SYSTEM_EDITOR : SystemEditorAction ,
539+ SystemEventControl .SYSTEM_UPGRADE : SystemUpgradeAction ,
457540}
458541
459542
@@ -472,7 +555,9 @@ def describe_system_event(control: str, action: str) -> str:
472555 * ``"_0"`` / ``"90"`` → ``"heartbeat = 90"`` (action = seconds to
473556 the next heartbeat; not enumerated)
474557 * ``"_28"`` / ``"1.3"`` → ``"matter_status = 1.3"`` (no enum)
475- * ``"_26"`` / ``"2"`` → ``"_26 = 2"`` (control we don't recognise —
558+ * ``"_26"`` / ``"2"`` → ``"system_upgrade = inactive"``
559+ * ``"_24"`` / ``"1"`` → ``"system_editor = editor_changed"``
560+ * ``"_99"`` / ``"x"`` → ``"_99 = x"`` (control we don't recognise —
476561 both halves pass through verbatim)
477562
478563 Intended for the debug logging consumers do over raw event frames
@@ -623,20 +708,27 @@ def requires_reload(self) -> bool:
623708 Reload-worthy: ``ND`` / ``NR`` / ``NN`` (node added/removed/renamed
624709 — the registry's set or display names are stale), ``EN``
625710 (enabled/disabled — the entity's property shape may change),
626- ``RV`` (revised — discard and rebuild this node), ``RG`` (removed
627- from scene — membership changed), ``SC`` (node-discovery complete
628- — new nodes may have appeared), and the folder/scene tree verbs
711+ ``RV`` (revised — discard and rebuild this node), ``NI``
712+ (supported-type info changed — the node's nodedef assignment was
713+ reassigned, so the cached nodedef→entity mapping is stale; per
714+ UDI's notification taxonomy this is *the* primary signal for
715+ profile-related node changes), ``AA`` (all-nodes-added bulk
716+ signal after a device include), ``RG`` (removed from scene —
717+ membership changed), ``SC`` (node-discovery complete — new
718+ nodes may have appeared), and the folder/scene tree verbs
629719 ``FD`` / ``FR`` / ``FN`` / ``GD`` / ``GR`` / ``GN`` (the
630720 ``groups`` / ``folders`` registries are stale).
631721
632722 Softer signals — informational, don't trigger reload UX:
633723 ``MV`` (added to scene), ``CL`` (link changed — not supported),
634- ``PC`` (parent changed), ``PI`` (power info), ``DI`` (device id —
635- not implemented), ``DP`` (UPB property), ``WH`` (pending op),
636- ``WD`` (programming device — a property-update event follows),
637- ``SN`` (discovering nodes — wait for ``SC``), ``CE`` / ``NE``
638- (comm error/cleared — no shape change), ``WR`` (a networking
639- resource was renamed — doesn't touch nodes).
724+ ``LU`` (scene link's on-level/ramp updated — property change,
725+ not shape change), ``PC`` (parent changed), ``PI`` (power
726+ info), ``DI`` (device id — not implemented), ``DP`` (UPB
727+ property), ``WH`` (pending op), ``WD`` (programming device — a
728+ property-update event follows), ``SN`` (discovering nodes —
729+ wait for ``SC``), ``CE`` / ``NE`` (comm error/cleared — no
730+ shape change), ``WR`` (a networking resource was renamed —
731+ doesn't touch nodes).
640732 """
641733 return self .action in {
642734 NodeLifecycleAction .NODE_ADDED ,
@@ -645,6 +737,8 @@ def requires_reload(self) -> bool:
645737 NodeLifecycleAction .NODE_REMOVED_FROM_GROUP ,
646738 NodeLifecycleAction .NODE_ENABLED ,
647739 NodeLifecycleAction .NODE_REVISED ,
740+ NodeLifecycleAction .NODE_TYPE_INFO_CHANGED ,
741+ NodeLifecycleAction .ALL_NODES_ADDED ,
648742 NodeLifecycleAction .NODE_DISCOVERY_COMPLETE ,
649743 NodeLifecycleAction .FOLDER_ADDED ,
650744 NodeLifecycleAction .FOLDER_REMOVED ,
0 commit comments