Problem(s) I want to solve when dealing with fresh home build:
-
As little devices as possible, with preference of no devices in the wall units, only actual switches
-
Use of simple buttons that are consistent and not RF/brand/technology specific and have each input connected to the central unit
-
Use of smart Zigbee lights or classic ones, the system shall support both
-
HA to manage all the automations and backup if HA is down.
The key problem that made me develop my own hardware with ESP32: what do you do when HA is down and you want to control smart lights? Sure you can use direct binding, but how advance is this direct binding? Not much. Philips Hue Tap has 4 buttons but only one zigbee cluster - no possibility to distinguish and assign action to individual light.
The key concept to the solution I came up with is:
- Connect all buttons all across the home, one to each of the inputs (230V directly)
- Connect each smart light (or group of lights, up to you) to one output relay
- ESP32 runs esphome
- If ESP32 is connected to HA, then input signal is routed to the HA and HA manages the automations. HA can then control the zigbee lights, according to the user automations
- If ESP32 is not connected to HA (ESP32 down, wifi down, HA down), then input only toggles the relay state
- When HA boots-up, it can 1. turn on all relays to activate smart lights and 2. send necessary commands to the lights via Zigbee
Hardware
- ESP32 WROOM module, wifi mode
- 8 inputs, each connected with optocoupler for isolation
- 8 outputs, controlled directly with respective input number (when HA is down)
- PCF8574 IO expander for input reading
- 4 leds (2 meant for status, 2 for user)
3D view
Quickly put together. It hasn’t been produced yet nor tested yet.
The test has been made with protoboard:
- ESP32-WROOM
- PCF8574
- Spice simulation for input control
- esphome code
- Put HA down, press the input. Result: Output toggles
- Works as expected
ESPhome code
esphome:
name: pfc-io-expander-test
friendly_name: pfc_io_expander_test
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "mykey"
ota:
- platform: esphome
password: "mypassword"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Pfc-Io-Expander-Test"
password: "DlRrsFjTd0ft"
captive_portal:
# I2C configuration
i2c:
sda: GPIO21
scl: GPIO22
scan: true
id: bus_main
# PFC expanders
pcf8574:
- id: 'pcf8574_hub_input'
address: 0x26
pcf8575: false
# Button list
button:
- platform: restart
name: 'Restart'
- platform: factory_reset
name: 'Factory reset'
# Switches
switch:
- id: switch_1
platform: gpio
name: "Output #1"
pin: GPIO13
inverted: true
- id: switch_2
platform: gpio
name: "Output #2"
pin: GPIO12
inverted: true
- id: switch_3
platform: gpio
name: "Output #3"
pin: GPIO14
inverted: true
- id: switch_4
platform: gpio
name: "Output #4"
pin: GPIO27
inverted: true
- id: switch_5
platform: gpio
name: "Output #5"
pin: GPIO26
inverted: true
- id: switch_6
platform: gpio
name: "Output #6"
pin: GPIO25
inverted: true
- id: switch_7
platform: gpio
name: "Output #7"
pin: GPIO33
inverted: true
- id: switch_8
platform: gpio
name: "Output #8"
pin: GPIO32
inverted: true
# Inputs
binary_sensor:
- platform: gpio
name: "Input #1"
pin:
pcf8574: pcf8574_hub_input
number: 0
mode:
input: true
filters:
- invert:
- delayed_on_off: 50ms
on_press:
then:
if:
condition:
not:
api.connected:
then:
- switch.toggle: switch_1
- platform: gpio
name: "Input #2"
pin:
pcf8574: pcf8574_hub_input
number: 1
mode:
input: true
filters:
- invert:
- delayed_on_off: 50ms
on_press:
then:
if:
condition:
not:
api.connected:
then:
- switch.toggle: switch_2
- platform: gpio
name: "Input #3"
pin:
pcf8574: pcf8574_hub_input
number: 2
mode:
input: true
filters:
- invert:
- delayed_on_off: 50ms
on_press:
then:
if:
condition:
not:
api.connected:
then:
- switch.toggle: switch_3
- platform: gpio
name: "Input #4"
pin:
pcf8574: pcf8574_hub_input
number: 3
mode:
input: true
filters:
- invert:
- delayed_on_off: 50ms
on_press:
then:
if:
condition:
not:
api.connected:
then:
- switch.toggle: switch_4
- platform: gpio
name: "Input #5"
pin:
pcf8574: pcf8574_hub_input
number: 4
mode:
input: true
filters:
- invert:
- delayed_on_off: 50ms
on_press:
then:
if:
condition:
not:
api.connected:
then:
- switch.toggle: switch_5
- platform: gpio
name: "Input #6"
pin:
pcf8574: pcf8574_hub_input
number: 5
mode:
input: true
filters:
- invert:
- delayed_on_off: 50ms
on_press:
then:
if:
condition:
not:
api.connected:
then:
- switch.toggle: switch_6
- platform: gpio
name: "Input #7"
pin:
pcf8574: pcf8574_hub_input
number: 6
mode:
input: true
filters:
- invert:
- delayed_on_off: 50ms
on_press:
then:
if:
condition:
not:
api.connected:
then:
- switch.toggle: switch_7
- platform: gpio
name: "Input #8"
pin:
pcf8574: pcf8574_hub_input
number: 7
mode:
input: true
filters:
- invert:
- delayed_on_off: 50ms
on_press:
then:
if:
condition:
not:
api.connected:
then:
- switch.toggle: switch_8
Would like to hear if such hardware makes any sense to you. No prob to share the source and/or gerbers.