Add features but don’t take away basic operation

Using connected smart bulbs means the old and simple switch on the wall is useless. With smart bulbs you need an constant power for it to function correctly. Turning on and off a light using a wall switch is so common that it is hard to unlearn. You could use a sticky note over the switch, off course to prevent people from using the switch. Another way is to hard-wire the bulb(s) so that no matter the state of the switch, the bulb(s) are connected. This leaves you with a useless switch on the wall, but at least your automated lights will keep on working. You can remove the switch entirely if you like, but that can be more work than it’s worth. And it can be useful to be able to use a physical switch in case of an automation not working for what ever reason.

sticky note on a switch
A sticky note on a switch

Smart bulbs vs smart switches

For the reasons above some would say use smart switches instead of smart bulbs, this is sound advice, but smart bulbs do offer extra functionality. The most smart bulbs have at least a dimming function, which is also available in some smart switches (with dimmable bulbs). A lot of smart bulbs also offer white spectrum and color changing. On the other hand a single smart switch could be used to control multiple dumb bulbs.

Choosing between smart bulbs or switches comes down to preference and availability, both have their use cases. In most cases a combination can work best and that can give you the best user experience.

How to choose a switch

Most manufacturers of smart systems also have smart switches available. These typically come in three systems. Standalone, behind the current dumb switch or replacing the switch. Typically, these use the same protocol as the bulbs, which is a whole other topic. The standalone switches are mostly battery powered and come in several forms, some look like a remote, others can be mounted on the wall. Built in or replacement switches come in battery powered and mains powered versions depending on the manufacturer.

Philips Hue standalone dimmer
Philips Hue’s version of a remote like dimmer. Philips Hue build in switch
Philips Hue switch module.

I chose to go another route in my hallway. I have a Philips Hue smart bulb which normally runs on about 15 percent brightness, this bulb is controlled by Home Assistant. At first the switch controlling the light fixture was left in an on state, but as it goes, family who want to turn off a light would use the switch. Which led to not turning on the lamp automatically next time. To solve this I used a Shelly 1 a simple wifi powered relais. Instead of the default firmware, I chose to replace it with ESPHome I was using ESPHome for other projects and I really like it. The way I have it set up at the moment is in a detached switch state, i.e. the switch and relais are not coupled together. When flipping the physical switch, there is some logic running in the firmware which checks if:

  1. There is a Wifi connection
  2. The Shelly is connected with the API
  3. The internal relais is on

If all checks are true it then sends a service call to Home Assistant to turn on the bulb. As soon as one of the checks returns false, it will toggle the internal relais.

The code

ESPhome uses YAML to configure the device, below you’ll find the code running on the Shelly controlling my hall light. The !secret variables are provided via a secrets file. I do have a function for double pressing to provide extra function. At the moment I am not using it, yet it could be used to turn the light on at 100 percent and back to the default 15 percent. The service call and entity_id in the on_state block are from Home Assistant.

# Basic config
substitutions:
  device_name: hal
  device_description: "Shelly switch hal (detached)"


esphome:
  name: ${device_name}
  comment: "${device_description}"
  platform: ESP8266
  board: esp01_1m
  
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  domain: !secret domain
  manual_ip:
    # Set this to the IP of the ESP
    static_ip: !secret hal_ip
    # Set this to the IP address of the router. Often ends with .1
    gateway: !secret gateway
    # The subnet of the network. 255.255.255.0 works for most home networks.
    subnet: !secret subnet
    
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ${device_name} Hotspot
    password: !secret hotspot_password

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:
  password: !secret ota_api_password

ota:
  password: !secret ota_api_password


# Enable Web server (optional).
web_server:
  port: 80

# Text sensors with general information.
text_sensor:
  # Expose ESPHome version as sensor.
  - platform: version
    name: ${device_name} ESPHome Version
    hide_timestamp: True
  # Expose WiFi information as sensors.
  - platform: wifi_info
    ip_address:
      name: ${device_name} IP
    ssid:
      name: ${device_name} SSID
    bssid:
      name: ${device_name} BSSID

# Sensors with general information.
sensor:
  # Uptime sensor.
  - platform: uptime
    name: ${device_name} Uptime

  # WiFi Signal sensor.
  - platform: wifi_signal
    name: ${device_name} WiFi Signal
    update_interval: 60s
    
  - platform: homeassistant
    id: hal_brightness
    entity_id: light.hal
    attribute: brightness
    
# Device Specific Config
output:
  - platform: gpio
    pin: GPIO4
    id: relay

switch:
  - platform: gpio
    name: ${device_name} Relais
    pin: GPIO4
    id: shelly_relay
    # after reboot, keep the relay off. this prevents light turning on after a power outage
    restore_mode: ALWAYS_OFF

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO5
      #mode: INPUT_PULLUP
      #inverted: True
    name: ${device_name} Schakelaar
    on_double_click:
      min_length: 50ms
      max_length: 350ms
      then:
        - if:
            condition:
              and:
                - wifi.connected:
                - api.connected:
                - switch.is_on: shelly_relay
            # send double click event in case wifi and api are conncected
            then:
              - homeassistant.event:
                  event: esphome.hall_button
                  data:
                    title: hal double pressed
              - logger.log: "hal double pressed" 
            # toggle relay in case either wifi or api are not connected
            else:
              - switch.toggle: shelly_relay

    on_state:
      then:
        - if:
            condition:
              and:
                - wifi.connected:
                - api.connected:
                - switch.is_on: shelly_relay
            # send double click event in case wifi and api are conncected
            then:
              - homeassistant.service:
                  service: light.toggle
                  data:
                    entity_id: light.hal
            # toggle relay in case either wifi or api are not connected
            else:
              - switch.toggle: shelly_relay
#    internal: true
    id: button