Skip to content

feat(sensor): Available typed-input for sensor and binary_sensor - #2041

Open
Swamp-Ig wants to merge 8 commits into
zachowj:mainfrom
Swamp-Ig:feat/entity-available
Open

feat(sensor): Available typed-input for sensor and binary_sensor#2041
Swamp-Ig wants to merge 8 commits into
zachowj:mainfrom
Swamp-Ig:feat/entity-available

Conversation

@Swamp-Ig

Copy link
Copy Markdown
Contributor

Adds configurable entity Available for sensor and binary_sensor nodes, so flows can mark HA entities truly unavailable instead of hacking state: "unknown" / null (which breaks numeric sensors). Zach accepted the design in Discussion #2029. Long-standing ask: companion #206, contrib #1044.

Paired companion PR: zachowj/hass-node-red#409.

Summary

  • Sensor / binary_sensor Available typed-input (default bool/true); coerce with HA template bool; reject junk.
  • Wire root available; availability-only updates; omit = hold once presence-available; yellow Unavailable node status.
  • Companion 4.2.4+ required for custom Available / msg overrides; default bool/true still works on older companions (field omitted on the wire).
  • Docs: Available + partial-update semantics on sensor / binary_sensor help.
  • v1 scope: sensor + binary_sensor only (number/text/select/time can follow later).

Wire contract (with companion #409)

Once contrib has announced a package version (presence-available):

  • available: true|false → set availability
  • available omitted → leave availability unchanged (do not invent available from state)
  • Discovery / register with no state → entity starts unavailable

Default Available = bool/true means every message carries available: true (today’s always-available behaviour). Custom Available paths own reconnect/restart; Resend state, attributes and available restores the last snapshot.

Stacking note

Depends on #2039 (version handshake), which currently also carries #2040’s lockfile/CI commit. Base is main so GitHub shows those commits until they merge; this PR’s own commits are the four availability ones on top. Fine to merge #2040/#2039 first, or skip intermediates and merge this alone — it carries them.

Test plan

  • Vitest availability suites (integration + coerce + gating)
  • Manual smoke matrix below
  • CI green
  • Pair against hass-node-red#409

Smoke matrix

Repeat behavioural rows for sensor and binary_sensor unless noted. Auto = vitest / companion pytest; Manual = hand smoke.

Lifecycle / discovery

ID Expect Auto Manual
A1 / D1 / D1b Unavailable on create, no state ✅ companion discovery-without-state (presence) ✅ 2026-07-29
A2 / D2 First state → available ✅ companion WS entity updates ✅ 2026-07-29
A3 Orphan after HA-down delete — not availability-specific ✅ 2026-07-24 (nice)
A4 Delete node removes entity — covered by prior #402/#2034 ✅ 2026-07-29

Editor / upgrade

ID Auto Manual
U1 / U1b / U3 — editor UI ✅ 2026-07-29
U4 — docs in PR ✅ 2026-07-30
U4b sk/zh — out of scope ⁉️ I only speak English (Australian English at that) — localized helper text left for a follow-up
U2 / X1 migration ✅ 2026-07-29

Defaults / msg / coerce / override

Setup for M*: Available = msgpayload.connected (or similar).

ID Auto Manual
S1 / S1b ✅ vitest S1 (+ binary) ✅ 2026-07-29
M1–M5 partial — companion WS attrs/hold; full path manual ✅ 2026-07-29
M6 / M7 ✅ vitest M6/M7 ✅ 2026-07-29
C1 / C2 / C5 parseAvailableValue unit ✅ 2026-07-29
C3 omit-hold ✅ companion presence state-only holds ✅ 2026-07-29
C4 ✅ via M7 ✅ 2026-07-29
O1 / O2 / O3 ✅ vitest O3 also ✅ manual; O1/O2 auto-only

Resend

ID Auto Manual
R1–R3 — lastPayload merge not fully unit-mocked E2E ✅ 2026-07-29
R4 / R5 ✅ same as empty discovery / C3 contract (companion) — not re-smoked; redundant with D1/C3

Version mismatch

ID Auto Manual
V1 / V2 (new companion + old contrib) ✅ companion legacy discovery/state invent-True ✅ 2026-07-24
V3 ✅ vitest V3 ✅ 2026-07-24
V4 editor invalid — editor toast/△ ✅ 2026-07-29
V5 / V7 ✅ vitest ✅ 2026-07-29
V6 — same gate as V5 pre-send ✅ 2026-07-29 (manual); no dedicated vitest name

Out of scope

ID Notes
X3 Switch / number / other entity nodes — no Available row in v1

Swamp-Ig added 6 commits July 30, 2026 20:31
Remove the duplicate @vuepress/helper snapshot that broke
--frozen-lockfile, bump prettier to the 3.9.x CI was already
resolving under ^3.8.1, freeze installs in workflows, and pin
format-docs to the same prettier version.

Closes zachowj#2036
Probe first for old companions that reject unknown keys, then announce
contrib_version when companion is 4.2.4+.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an explicit Available typed-input to the Sensor and Binary Sensor entity nodes so flows can mark Home Assistant entities available/unavailable without abusing special state values, while maintaining compatibility with older Node-RED Companion versions via version/capability gating.

Changes:

  • Adds available / availableType configuration + editor UI for sensor and binary_sensor nodes, plus runtime handling for availability-only / partial updates and “Unavailable” node status.
  • Introduces helper utilities for availability parsing + companion version capability checks, and extends entity integration payloads + resend snapshot to include available.
  • Updates docs and CI/tooling (prettier pin, frozen lockfile installs) and adds Vitest unit/integration coverage for the new behavior.

Reviewed changes

Copilot reviewed 40 out of 41 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/unit/nodes/binary-sensor/inputSchema.test.ts Validates schema rules for availability-only updates and required Available config fields.
test/unit/helpers/utils.test.ts Adds unit coverage for parseAvailableValue coercion/rejection behavior.
test/unit/helpers/exposed-settings.test.ts Updates expected exposed schema version for sensor nodes.
test/unit/helpers/entityAvailable.test.ts Adds unit tests for default-Available detection and companion capability gating.
test/unit/editor/convert-entity.test.ts Ensures entity conversion sets version and Available defaults.
test/unit/common/status/Status.test.ts Adds coverage for new setUnavailable status styling.
test/integration/sensor-availability.test.ts Integration coverage for sensor availability, gating, and partial-update/no-op behavior.
test/integration/binary-sensor-availability.test.ts Integration coverage for binary_sensor availability and partial-update/no-op behavior.
test/helpers/controllerTestHarness.ts Adds controller harness utilities for integration tests (mock RED, HA client, integration).
src/nodes/sensor/migrations.ts Adds v1 migration defaults for Available fields on sensor nodes.
src/nodes/sensor/locale.json Adds “Available” label and updates resend label text.
src/nodes/sensor/editor.ts Adds Available typed-input field, types, and companion validation/warning hook.
src/nodes/sensor/editor.html Adds editor form row for Available typed-input.
src/nodes/entity-config/locale.json Updates resend label to include availability.
src/nodes/binary-sensor/migrations.ts Adds v1 migration defaults for Available fields on binary-sensor nodes.
src/nodes/binary-sensor/locale.json Adds “Available” label and updates resend label text.
src/nodes/binary-sensor/index.ts Adds Available inputs + schema changes to permit state-less updates.
src/nodes/binary-sensor/editor.ts Adds Available typed-input field, types, and companion validation/warning hook.
src/nodes/binary-sensor/editor.html Adds editor form row for Available typed-input.
src/homeAssistant/Websocket.ts Adds contrib-version announce step in nodered/version handshake (gated by companion version).
src/helpers/utils.ts Adds parseAvailableValue coercion helper modeled on HA bool vocabulary subset.
src/helpers/entityAvailable.ts Adds helpers for default Available detection and companion capability checks.
src/editor/exposenode.ts Adds editor-side validation + warning UI for companion version requirements.
src/editor/convert-entity.ts Ensures converted entity nodes get version bump + Available defaults.
src/const.ts Introduces minimum companion version constants for handshake and entity availability.
src/common/status/Status.ts Adds setUnavailable status method (yellow ring).
src/common/status/locale.json Adds status locale keys for companion gating, invalid input, and unavailable.
src/common/services/StorageService.ts Extends last-payload snapshot typing to optionally include available.
src/common/integration/UnidirectionalEntityIntegration.ts Adds available to discovery/entity payloads, supports omitting fields, gates by companion version, and extends resend snapshot merge semantics.
src/common/errors/locale.json Adds localized errors for invalid Available values and minimum companion requirement.
src/common/controllers/SensorBaseController.ts Implements Available resolution/coercion, partial updates, gating rules, and Unavailable status behavior.
pnpm-lock.yaml Updates lockfile for prettier pin and removes duplicate snapshot entry.
package.json Pins prettier dependency version.
docs/node/sensor.md Documents Available and partial-update semantics for sensor nodes.
docs/node/entity.md Updates resend wording to include available.
docs/node/entity-config.md Updates resend wording to include available.
docs/node/binary-sensor.md Documents Available and partial-update semantics for binary_sensor nodes.
.github/workflows/publish.yml Uses pnpm install --frozen-lockfile for publish workflow.
.github/workflows/format-docs.yml Pins prettier version used by docs formatting workflow.
.github/workflows/documentation.yml Uses pnpm install --frozen-lockfile for docs build workflow.
.github/workflows/ci.yml Uses pnpm install --frozen-lockfile across CI jobs.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

Comment thread src/editor/exposenode.ts Outdated
@Swamp-Ig

Copy link
Copy Markdown
Contributor Author

@zachowj could you kindly turn off forced copilot reviews? I have a pretty limited credits.
Settings -> Rules -> Rulesets -> Default -> uncheck “Automatically request Copilot code review”

@zachowj

zachowj commented Jul 31, 2026

Copy link
Copy Markdown
Owner

@zachowj could you kindly turn off forced copilot reviews? I have a pretty limited credits. Settings -> Rules -> Rulesets -> Default -> uncheck “Automatically request Copilot code review”

Not sure when that got flipped on but it's off for both repos now.

@Swamp-Ig

Swamp-Ig commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

@zachowj thanks! Otherwise I'm pretty happy with everything 😁 Let me know if there's any issues.

I thought a lot about state, availability, and attributes being independent updates. I figured this way was the most flexible and users could still manage them as a group if they really wanted to.

The set of attributes aren't independent however, they'll be updated together as a map. I figured allowing independent updates could be the next step if we wanted, I can think of some use cases where this could make sense.

The only real thing that might be a breaking change is Unknown states no longer stand in for unavailable. This is more semantically in sync with HA general practice anyway though.

@zachowj

zachowj commented Aug 6, 2026

Copy link
Copy Markdown
Owner

At first glance, everything looks good to go. My plan is to spend some time testing everything this weekend, and if all goes well, I'll merge it.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@Swamp-Ig

Swamp-Ig commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

@zachowj Awesome! I did some fairly extensive test cases as well as testing stuff by hand, but definitely see if you can break it. If you can think of other tests outside of the test matrix I'd be interested to see. Hopefully there's nothing I've missed! If you merge this one, then #2040 and #2039 can be closed as they're incorporated in this anyhow. (same for the companion, there's one stacked PR there though).

Resolve conflicts: take postcss ^8.5.23 from main; keep
COMPANION_MIN_VERSION_ENTITY_AVAILABLE for availability gating.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants