Files
lippert-onecontrol/canbus/awning-closed-sensor-spec.md
wesandClaude Opus 4.8 0c6721953a docs(awning): spec for standalone WiFi reed "closed" sensor (Option 1)
ESP32-C3 + weatherproof reed on OmnissiahsReach WiFi (no Zigbee mesh) for true
stowed/not-stowed state: BOM, wiring, ESPHome config, HA/bridge integration,
optional truthful template cover, and the Option-2 (wire-to-CAN-node) note.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 22:24:51 -04:00

193 lines
8.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Awning "Closed" Sensor — Spec (Option 1: standalone WiFi reed node)
**Goal:** give the campsite awning a *true* stowed/not-stowed state instead of the
`assumed_state` the CAN cover currently reports. A magnetic reed switch at the
fully-retracted position, read by a small ESP running ESPHome over the existing
`OmnissiahsReach` WiFi — **no Zigbee mesh, no coordinator, no new ecosystem.**
This is "Option 1" (standalone node). Option 2 (wire the reed back to a spare GPIO
on the CAN node `192.168.69.18` so the cover entity itself becomes truthful) is the
more-integrated alternative but needs a 2-wire run from the awning to the control
panel; it's noted at the end. Pairs with the current-sensing auto-retract already
in `esphome/onecontrol-canbus.yaml` (README "awning" section): current does the
*dynamic* stop during retract, the reed gives *persistent* truth afterward.
## What it delivers (and what it doesn't)
- **Reliable CLOSED (stowed) detection.** Awnings extend to an arbitrary spot, so
there's no meaningful "fully open" endpoint — but the fully-retracted position is
hard and repeatable. That's the state that matters (don't drive off / don't let
it flap): a single reed there answers *stowed vs. not*.
- It does **not** measure extension %. If you ever want an "opening/closing"
animation you already get that from the CAN motion byte; the reed just pins down
the resting truth.
## Bill of materials (~$1520)
| Part | Notes |
|------|-------|
| **ESP32-C3 SuperMini** (or Wemos D1 mini / ESP8266) | Tiny, WiFi, 3.3 V logic. C3 recommended (native ESP-IDF, cheap, plenty of GPIO). |
| **Weatherproof reed switch** | RV-compartment / garage-door style, **potted + leaded**, normally-open. Get a wide-gap one (pull-in ≥ 1520 mm) so alignment is forgiving. |
| **Bar/block magnet** | Match/exceed the reed's rated gap. Rare-earth block for margin. |
| **12 V → 5 V buck** (MP1584 / mini360 or an automotive USB buck) | Tap the awning motor's 12 V; always-on beats battery/deep-sleep for instant state and no maintenance. |
| **Small IP65 enclosure + gland** | Mount the ESP + buck out of the weather. |
| Fused 12 V tap (inline 1 A) | Protect the tap off the motor harness. |
## Wiring
```
awning 12V harness --[inline 1A fuse]--> buck IN+ buck OUT+ (5V) --> ESP 5V
chassis GND -----> buck IN- ----buck OUT- ------> ESP GND
reed leg A --> ESP GPIO4
reed leg B --> ESP GND
```
- Reed to GND with the **internal pull-up** enabled: pin idles HIGH (not stowed),
goes LOW when the magnet is present (stowed). The ESPHome config below inverts
that so the sensor reads ON = stowed.
- No external resistor needed. An optional 0.1 µF across the reed helps debounce,
but the software `delayed_on/off` below is enough.
- Avoid the C3 strapping pins (GPIO2, 8, 9); GPIO4 is safe. GPIO8 has the onboard
LED if you want a status blink.
## Mounting
- **Magnet on the moving part** (the lead rail / roller endcap that seats when
stowed); **reed on the fixed part** (mounting rail or a bracket on the coach).
- Aim for the magnet to land within the reed's pull-in gap when the awning is
pulled in tight — the same "closed" position the current-stall stop lands on.
Expect a test-fit: mark where the rail seats, mount, confirm the sensor flips.
- Outdoor: use the potted reed, point the gland down, silicone the entry, and
strain-relief the lead so awning motion doesn't fatigue it.
## ESPHome config
New device `awning-sensor` (mirror the conventions in `onecontrol-canbus.yaml` /
`gazebo-fan-proxy.yaml`: `secrets.yaml` for WiFi + API key, OTA after first USB
flash, fallback AP + captive portal). DHCP on `OmnissiahsReach`.
```yaml
substitutions:
name: awning-sensor
friendly_name: Awning Sensor
esphome:
name: ${name}
friendly_name: ${friendly_name}
esp32:
board: esp32-c3-devkitm-1
framework:
type: esp-idf
logger:
api:
encryption:
key: !secret api_key
ota:
- platform: esphome
wifi:
ssid: !secret wifi_ssid # OmnissiahsReach
password: !secret wifi_password
ap:
ssid: "Awning-Sensor Fallback"
password: !secret fallback_ap_password
captive_portal:
binary_sensor:
- platform: gpio
name: "Awning Stowed"
id: awning_stowed
pin:
number: GPIO4
mode:
input: true
pullup: true
inverted: true # reed->GND: magnet present = LOW = ON (stowed)
filters:
- delay_on: 200ms # debounce the rail seating
- delay_off: 200ms
# ON = awning pulled in tight (stowed / closed)
# OFF = not stowed (extended, or mid-travel)
```
`secrets.yaml` needs `wifi_ssid`, `wifi_password`, `fallback_ap_password`,
`api_key` (generate with `esphome`). First flash over USB (`esphome run ... `),
thereafter OTA — same as the other campsite nodes.
## HA integration
The reed is a separate device from the CAN node, so it lands as its own entity:
1. **Campsite Pi** auto-discovers it via the ESPHome integration →
`binary_sensor.awning_sensor_awning_stowed` (rename to
`binary_sensor.awning_stowed`). ON = stowed.
2. **Bridge to home HA** — add to `/config/packages/mqtt_bridge.yaml` (repo:
`canbus/ha/mqtt_bridge_onecontrol.yaml`) next to the other campsite entities:
a discovery block (`homeassistant/binary_sensor/campsite/awning_stowed/config`,
device `campsite_onecontrol`, `device_class: "opening"` reads on=open/off=closed,
or leave classless for a plain stowed/clear), plus a state-forward trigger on
`binary_sensor.awning_stowed``campsite/binary_sensor/awning_stowed/state`.
Appears on home as `binary_sensor.campsite_onecontrol_awning_stowed`.
3. Add the tile to home HA **Overview → Camper → OneControl** section.
### Optional: make the cover *truthful* (template cover)
Right now `cover.onecontrol_can_awning` is `assumed_state`. With the reed you can
wrap it in a template cover on the Pi whose closed state is the *real* reed, while
commands still hit the CAN cover:
```yaml
cover:
- platform: template
covers:
awning_true:
friendly_name: "Awning"
device_class: awning
value_template: "{{ 'closed' if is_state('binary_sensor.awning_stowed','on') else 'open' }}"
close_cover:
- action: cover.close_cover # -> CAN cover auto-retract
target: { entity_id: cover.onecontrol_can_awning }
stop_cover:
- action: cover.stop_cover
target: { entity_id: cover.onecontrol_can_awning }
```
Bridge `cover.awning_true` to home instead of the raw CAN cover, and you get a
cover that shows genuine open/closed. (Keep `payload_open` disabled as today.)
### Automations this unlocks
- **Left-it-out alarm:** awning `not stowed` + (leaving geofence / wind gust > X /
rain) → Discord ping, or auto-fire `cover.close_cover`.
- **Confirm the retract actually seated:** after an auto-retract, if the current
stall fired but the reed is still OFF a few seconds later → alert (mis-seat).
> **Option-1 limitation:** because the reed is on a *separate* device from the CAN
> node, the auto-retract's stall gate can't consume it on-device — any
> reed↔retract logic is a cross-device HA automation, not firmware. If you want
> the ESP to stop the motor *on the reed itself* (belt-and-suspenders with the
> current stall), that's Option 2 (wire the reed to a spare GPIO on the CAN node
> `192.168.69.18`; the cover entity then reads it directly and becomes truthful
> with no template cover).
## Touchpoints checklist (campsite ESPHome node)
- [ ] `secrets.yaml` (WiFi = OmnissiahsReach, API key, fallback AP pw)
- [ ] USB flash once, confirm on `OmnissiahsReach` (DHCP `192.168.69.x`); OTA after
- [ ] Adopt in campsite Pi HA (ESPHome integration), rename entity
- [ ] Mount reed + magnet, verify it flips exactly at the stowed position
- [ ] `mqtt_bridge.yaml`: discovery + state-forward → home HA; add dashboard tile
- [ ] (optional) template cover `awning_true`; bridge it instead of the raw cover
- [ ] (optional) automations: left-out alarm, retract-seat confirmation
## Validation
1. USB-flash, join WiFi, adopt in HA. Toggle by hand with a magnet → `awning_stowed`
flips ON/OFF with the 200 ms debounce.
2. Mount, retract via the dashboard (auto-retract): at full stow the reed should go
ON right around when the current-stall stop fires.
3. Extend at the OEM wall switch → reed OFF. Confirm home HA mirrors it.