pyisyox.classifier module¶
HA platform classifier for IoX nodedefs.
This module produces a classification of an IoX NodeDef
into Home Assistant platform contributions. It is the fallback tier of
the two-tier strategy described in the modernization plan:
Type-based classification (consumer-side, e.g. hacs-isy994) — primary path. Native Insteon/Z-Wave nodes carry a real
typestring ("1.65.69.0"for KeypadLinc dimmer, etc.) that hacs-isy994 already maps to platforms with hardware-aware nuance. Preserve that path.Nodedef-based classification (this module) — fallback. Fires when the consumer’s type-based lookup returns no match, which in practice means PG3 plugin nodes and any future device class without a hardcoded mapping. The current HA core integration dumps these all into
sensor; this classifier escapes that trap.
The classification is three-axis and produces a set of HA platform contributions, not a single platform pick:
controllable— at most one of light/switch/climate/lock/cover/ alarm_control_panel, derived fromcmds.accepts.triggers— every command incmds.sends(the node emits these events; e.g., an InsteonOnOffControlpaddle that sendsDON/DOFon press becomes a HAdevice_triggersource).buttons— accept commands pressable with no arguments: parameterless, or every parameteroptional(the controller fills in defaults — InsteonBEEPis the canonical case: one optionallevelparam). ExcludesQUERY(implicit on every node) and any command claimed by the controllable platform. Surface as HAbuttonentities — press = send the verb with zero args.parameterized_commands— accept commands with at least one required parameter (same QUERY / controllable exclusions). These can’t be plain buttons: each parameter carries aneditorref whose shape drives what input entity it needs. Consumers that don’t yet handle them can ignore this bucket.readings— one entity per property, after filtering out properties already represented by the controllable platform (e.g.,ST/OL/RRon a light are the light’s state, not separate sensors).aux_controls— the unified successor to thereadings/parameterized_commands/buttonssplit: oneAuxControlper logical control, with a status and itsinit-linked write command folded together (read/write coalesced). New consumers should prefer this; the three legacy buckets stay populated unchanged for now.
One HA device per node aggregates entities from these buckets.
- class ControllablePlatform(*values)[source]¶
Bases:
StrEnumThe single controllable HA platform a nodedef may map to.
- LIGHT¶
- SWITCH¶
- CLIMATE¶
- LOCK¶
- COVER¶
- ALARM_CONTROL_PANEL¶
- class ReadingPlatform(*values)[source]¶
Bases:
StrEnumHA platform for a property reading entity.
- SENSOR¶
- BINARY_SENSOR¶
- class Reading(property, platform, is_enum=False)[source]¶
Bases:
objectA property surfaced as a sensor or binary_sensor entity.
- Variables:
property (pyisyox.schema.nodedef.NodeProperty) – The
NodePropertydefinition.platform (pyisyox.classifier.ReadingPlatform) – Which HA platform hosts this entity.
is_enum (bool) – True when the property’s editor carries an enum
namesmap — caller should set HAdevice_class="enum"and supplyoptions=[...]from the editor.
- Parameters:
property (NodeProperty)
platform (ReadingPlatform)
is_enum (bool)
- property: NodeProperty¶
- platform: ReadingPlatform¶
- class AuxPlatform(*values)[source]¶
Bases:
StrEnumCandidate HA platform for one coalesced aux control.
A candidate — the consumer keeps final say (type-tier-1, bespoke/service routing, HA-device grouping sit on top).
- SENSOR¶
- BINARY_SENSOR¶
- NUMBER¶
- SELECT¶
- SWITCH¶
- BUTTON¶
- class AuxControl(id, readable, writable, candidate_platform=None, property=None, command=None, editor_id=None, is_enum=False)[source]¶
Bases:
objectOne logical aux control: a read status and/or a write command, coalesced.
The IoX nodedef expresses the read/write pairing via a command parameter’s
init(the id of the<st>status it is “initialized and synchronized with” — e.g. a heat-setpoint command’s paraminit="CLISPH"; an Insteon i3 flags sub-node’sGV0paraminit="ST"⇄ theST“Mode” status). This is the authoritative pairing key — not naive id matching: the cmd id and the status id can differ (i3GV0⇄ST).Controllable-owned ids and
QUERYare already excluded (the controllable platform represents those).STis not special here: it is removed only when a controllable platform owns it; otherwise it is an ordinary coalescable status.- Variables:
id (str) – The control id (the status id when read/write paired, else the command id, else the property id).
readable (bool) – A backing status property exists (readback source).
writable (bool) – An accept command drives it.
candidate_platform (pyisyox.classifier.AuxPlatform | None) – Editor-shape-derived HA platform candidate.
Noneonly when no editor resolves and there is no readable backing status (a readable control falls back to its property’s read classification — SENSOR/BINARY_SENSOR); write-only with no editor staysNonefor the consumer.property (pyisyox.schema.nodedef.NodeProperty | None) – The backing
NodeProperty, if readable.command (pyisyox.schema.cmd.Command | None) – The driving
Command, if writable.editor_id (str | None) – The editor governing the control — the write command’s parameter editor when writable (the write affordance is authoritative), else the property editor.
is_enum (bool) – The governing editor carries an enum
namesmap.
- Parameters:
id (str)
readable (bool)
writable (bool)
candidate_platform (AuxPlatform | None)
property (NodeProperty | None)
command (Command | None)
editor_id (str | None)
is_enum (bool)
- candidate_platform: AuxPlatform | None¶
- property: NodeProperty | None¶
- class ClassificationResult(controllable=None, controllable_command_ids=<factory>, triggers=<factory>, buttons=<factory>, parameterized_commands=<factory>, readings=<factory>, aux_controls=<factory>)[source]¶
Bases:
objectThe set of HA platform contributions for one nodedef.
- Variables:
controllable (pyisyox.classifier.ControllablePlatform | None) – The controllable platform, or
Nonefor a read-only / event-only node.controllable_command_ids (frozenset[str]) – Command ids that belong to the controllable platform (so they aren’t double-counted as buttons). Empty when
controllableisNone.triggers (list[pyisyox.schema.cmd.Command]) – Commands the node emits — surface as
device_trigger.buttons (list[pyisyox.schema.cmd.Command]) – Accept commands pressable with zero args (parameterless, or all parameters
optional) — one fire-and-forgetbuttonentity each. ExcludesQUERYand controllable-claimed cmds.parameterized_commands (list[pyisyox.schema.cmd.Command]) – Accept commands with at least one required parameter. Not plain buttons; left for consumers that map parameter editors to input entities. Same QUERY / controllable exclusions as
buttons.readings (list[pyisyox.classifier.Reading]) – Per-property reading entities.
aux_controls (list[pyisyox.classifier.AuxControl]) – Coalesced read/write controls (see the module docstring) — the unified successor to
readings/parameterized_commands/buttons.
- Parameters:
- controllable: ControllablePlatform | None¶
- aux_controls: list[AuxControl]¶
- classify(nodedef, find_editor=None)[source]¶
Classify a nodedef into HA platform contributions.
- Parameters:
nodedef (NodeDef) – The nodedef to classify. Same shape regardless of native vs PG3 plugin origin.
find_editor (Callable[[str], Editor | None] | None) – Optional editor resolver, scoped to
nodedef’s family/instance. When provided, property readings are split into sensor vs binary_sensor by editor UOM and taggedis_enumfor enum editors. WhenNone(e.g. in unit tests), all readings default tosensorwithis_enum=False— callers can still render them, just without device-class hints.
- Returns:
A
ClassificationResultwith controllable / triggers / buttons / parameterized_commands / readings / aux_controls populated.find_editoralso drivesaux_controlscandidate platforms; without it a readable writable control falls back to its property’s read classification, and a write-only control falls back tocandidate_platform=Nonefor the consumer to resolve.- Return type: