Close

The buttons that you press

A project log for Calling for hot water

Remote controlled buttons for activating hot water recirculation.

wjcarpenterWJCarpenter 09/10/2023 at 20:280 Comments

I had good experience with using the M5Stack Atom Matrix devices in my Water Watcher project. With a 5x5 grid of RGB LEDs, there are lots of possibilities for displaying feedback, and the entire face of the device is a large button that can be pushed to signal something. For this project, I still need a pushable button, but I only need a couple bits of feedback: has the button been pushed, and is the recirculation pump still active. I decided to use M5Stack Atom Lite devices for this project. They are much more compact than anything I would likely create myself. They have an ESP32 and are powered via USB-C. They have a large button on the face and a single RGB LED. They have several other features that I don't need for this project.

I expect to deploy at least two of these in upstairs bathrooms, and it's possible I will sprinkle one or two more at other locations. I wanted all of the feedback to go to all of the devices, and I also wanted to know reliably that the button press had the desired effect. For those reasons, the button press is detected by Home Assistant, and Home Assistant controls the RGB LED.

The button press is simple to configure in ESPHome and is readily detected as a trigger by Home Assistant. The RGB LED control takes a little bit more work. I defined three services on the Atom: set_led_hot, set_led_cold, and set_led_off. That abstracts the device behavior from Home Assistant's intentions when it calls the services. Each service just calls a script to do something with the RGB LED. The Atom boots up as "cold" and is typically in that state. The RGB LED emits a soft and steady blue. The "hot" display is orange-yellow and blinking. The "off" display is obvious, though I don't currently have a use for it. All of the colors, brightness values, and blinking behavior were set by trial and error to get something I liked.

I split the ESPHome configuration into two pieces. One piece has the device-specific information (node name and API encryption key), and the ESPHome "include" feature is used to combine that with a common file that is the same for all of the devices.

One of the device-specific pieces:

substitutions:
  node_name: hotbuttonkb
  api_key: !secret hotbuttonkb_apikey

<<: !include { file: hotbutton.yaml.inc}

 The common file:

esphome:
  name: $node_name
  on_boot:
    then:
      # delay to allow other boot time stuff to settle down
      - delay: 5s
      - script.execute: set_led_cold
esp32:
  board: pico32

wifi:
  networks:
    - ssid: !secret wifi_ssid
      password: !secret wifi_password

sensor:
  - platform: wifi_signal
    name: ${node_name} WiFi Signal

logger:
  level: DEBUG
ota:
  password: !secret ota_password
api:
  encryption:
    key: ${api_key}
  reboot_timeout: 60min
  services:
    - service: set_led_hot
      then:
        - logger.log:
            tag: 'hotbutton'
            level: INFO
            format: "service: set_led_hot"
        - script.execute: set_led_hot
    - service: set_led_cold
      then:
        - logger.log:
            tag: 'hotbutton'
            level: INFO
            format: "service: set_led_cold"
        - script.execute: set_led_cold
    - service: set_led_off
      then:
        - logger.log:
            tag: 'hotbutton'
            level: INFO
            format: "service: set_led_off"
        - script.execute: set_led_off

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO39
      inverted: true
    name: ${node_name} Button
    id: big_button
    internal: false

light:
  - platform: fastled_clockless
    id: bright_light
    name: ${node_name} LED
    chipset: SK6812
    pin: GPIO27
    num_leds: 1
    rgb_order: GRB # required
    default_transition_length: 0s
    effects:
      - pulse:
          name: fast_pulse
          transition_length: 0.25s
          update_interval: 0.25s
          min_brightness: 20%
          max_brightness: 99%

script:
  - id: set_led_hot
    then:
      - light.turn_on:
          id: bright_light
          red: 100%
          green: 60%
          blue: 0%
          effect: fast_pulse

  - id: set_led_cold
    then:
      - light.turn_on:
          id: bright_light
          color_brightness: 20%
          red: 0%
          green: 0%
          blue: 100%
          effect: none

  - id: set_led_off
    then:
      - light.turn_on:
          id: bright_light
          color_brightness: 0%
          red: 0%
          green: 0%
          blue: 0%
          effect: none

Discussions