Skip to content

Make sensor polarity per-sensor, ready for the active-high detector (#9) - #23

Merged
bazauto merged 1 commit into
mainfrom
feat/per-sensor-polarity
Sep 23, 2026
Merged

bazauto merged 1 commit into
mainfrom
feat/per-sensor-polarity

Conversation

@bazauto

@bazauto bazauto commented Sep 23, 2026

Copy link
Copy Markdown
Owner

Makes sensor polarity a per-sensor field instead of one global ACTIVE_LOW, so the node can carry the bazauto/block-detection board alongside the existing devices.

Why

Polarity belongs to the device on the far end of the wire, not to the node. Until now every fitted device happened to be active low: the LM-iD.1 on board 1 and the Waveshare IR modules on board 2. The new block-detection board is the first one that isn't. It drives its output push-pull, 3.3 V when occupied, so a broken signal wire into the expander's pull-up reads occupied. That is the point of it (#9). One global flag couldn't describe a node carrying both kinds.

What changed

  • Every SENSORS entry in config.py now has an active_low field, set from a per-device constant: LM_ID_ACTIVE_LOW = True, WAVESHARE_IR_ACTIVE_LOW = True, BAZAUTO_BD_ACTIVE_LOW = False.
  • select_installed refuses an entry with no polarity, or with anything other than a real True or False. There is no default. A guessed polarity publishes clear for every occupied block, and "False" is truthy.
  • main.py builds each sensor as (sensor_id, pin, active_low) and reads each one with its own polarity. The pull-up stays on for every sensor. For an active-high device, the pull-up is what makes a broken wire read occupied.

The layout's behaviour doesn't change. Every entry, including the installed Goods Shed pair, is still active low. Moving a cs--- entry to the new board is a one-line change, made after that channel's wire-pull check on the bench. That check belongs to the current-sensing validation, and it can't be done on the host.

Tests

python -m pytest: 185 passed. New tests cover:

  • a missing polarity is refused;
  • a polarity that isn't a bool (1, 0, "False", None) is refused;
  • a mixed table reads each sensor the right way round;
  • the installed pair is active low;
  • the new board's constant is active high;
  • every IR entry uses the IR polarity.

main.py imports machine and isn't host-tested. Its change only passes the value through, and deploying and reading Goods Shed on the bench covers it.

MQTT contract check: topics, payloads, QoS, retention and the 30 s re-assert are unchanged. tick() re-asserts the cached reading, which is now computed with each sensor's own polarity.

Docs

CLAUDE.md, docs/pin-allocation.md (the polarity section is rewritten with a per-device table), and docs/block-detector-wiring.md (records that the new board replaces the "power Input A plus inverter" plan for board 1).

Refs #9. This doesn't close it: the IR half is still open, and the new board hasn't been fitted or wire-pull tested yet.

🤖 Generated with Claude Code

@bazauto
bazauto enabled auto-merge (squash) September 23, 2026 16:50
@bazauto
bazauto merged commit bb61c3e into main Sep 23, 2026
1 check passed
@bazauto
bazauto deleted the feat/per-sensor-polarity branch September 23, 2026 16:50
Polarity belongs to the device on the far end of the wire, not to the node,
and the bazauto/block-detection board is the first device that disagrees with
the rest: push-pull, 3.3 V when occupied. One global ACTIVE_LOW could not
express a node carrying both.

Every SENSORS entry now carries active_low, set from a per-device constant
(LM_ID_ACTIVE_LOW, WAVESHARE_IR_ACTIVE_LOW, BAZAUTO_BD_ACTIVE_LOW). There is
no default: select_installed refuses an entry without one, or with anything
other than a real bool, since "False" is truthy and a guessed polarity
publishes clear for every occupied block.

No behaviour change on the layout: every entry, including the installed
Goods Shed pair, is still active low. Swapping a cs--- entry to the new board
is a one-line change, made after its wire-pull bench check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant