Teaching Python

We're two middle school teachers learning and teaching Python

Hacking the Classroom Hand Sanitizer Dispenser Part 2

Part 2: Automating the Outputs

In Part 1 of this series, we hacked the hand sanitizer dispenser and got it talking to Home Assistant as a binary sensor. For this part, we'll work on a couple of useful automations in HA that will collect data and make it fun for students to sanitize.

By the end of this part, you should have a sensor that shows today's dispenses, an automation that makes Alexa speak and some lights flash, and even an interface to a local MQTT broker to send and receive data with other devices.

Making Alexa Speak

To make Alexa speak, I needed to send her notification commands using the excellent Alexa Media Player plugin for Home Assistant. The best way to install this was using the HACS project.

Adding Yeelight

I had a couple of Yeelight RGBW bulbs left over from a project last year that I wanted to integrate. This is an officially supported integration for Home Assistant. I put one of them into a lamp by the Amazon Echo and used the WhatsApp effect to flash the bulb green when the dispenser is triggered

Yeelight Device Screenshot

Dispenses Today

Next, I wanted to track the number of dispenses per day. I used the history_stats component for HA to add up the number of dispenses that day. The config entry tracks the number of times the dispenser went from OFF to ON since midnight that night.

  - platform: history_stats
    name: Sanitizer Dispenses Today
    entity_id: binary_sensor.sanitizer_dispense
    state: 'on'
    type: count
    start: '{{ now().replace(hour=0, minute=0, second=0) }}'
    end: '{{ now() }}'

The Actual Automation

Helpers

I created a simple dropdown helper to keep track of the quips for Alexa to speak. The input_select is used to keep a dropdown list of possible quips. The most recently selected quip is chosen as the current option on the dropdown.

Quips Dropdown

This makes it really easy to add and remove quips from the system as you get tired of them. You can also use Alexa's SSML tags to add inflection, emotion tags, and even interjections.

Automation Steps

The automation itself is triggered when the sanitizer_dispense sensor is set to moving. From there, several steps occur.

  1. The random quip is selected from the input_select.quips dropdown.
  2. The quip is sent to the Alexa Media Player's notify service.
  3. The Yeelight is sent the WhatsApp effect
  4. The Twitter integration sends the most recent quip to the Findeiss 1 Twitter account (@FindessO).

Full YAML file

Here's the full YAML file. Once you create a new Home Assistant automation, choose the option from the three-dot menu on the upper right and choose "Edit as YAML." Paste the following into the box and change the names of the devices to match the ones you set up in previous steps.

alias: Sanitizer Dispensed
description: ''
trigger:
  - type: moving
    platform: device
    entity_id: binary_sensor.sanitizer_dispense
    domain: binary_sensor
condition: []
action:
  - service: input_select.select_option
    data_template:
      option: |
        {{ state_attr("input_select.quips", "options") | random }}
    entity_id: input_select.quips
  - data_template:
      data:
        method: speak
        type: announce
      message: |
        "{{ states('input_select.quips') }}"
      target:
        - media_player.pc_s_echo
    service: notify.alexa_media
  - data:
      effect: WhatsApp
    entity_id: light.findeiss_1_table_lamp
    service: light.turn_on
  - service: notify.f1_twitter
    data_template:
      message: >-
        Someone used the hand sanitizer and I said "{{
        states('input_select.quips') | striptags }}"
mode: queued
max: 20

Tracking Historical Data with InfluxDB and Grafana

It's pretty easy to set up InfluxDB to track time-series data using the Supervised verison of Home Assistant. For more information, the Home Assistant documentation is very thorough. While you're at it, adding Grafana is a great way to come up with detailed visualizations.

Once you've added InfluxDB using the Superviser panel, make sure that you have your entities included in your configuration.yaml file. If you're running on a storage-limited device like a Raspberry Pi, then it's helpful to limit the number of recorded streams to just the ones you care about.

influxdb:
  host: a0d7b954-influxdb
  port: 8086
  database: homeassistant
  username: homeassistant
  password: !secret influx_db_password
  max_retries: 3
  default_measurement: state
  include:
    entities:
      - sensor.f1_sanitizer_dispenses_today
      - light.findeiss_1_table_lamp
      - binary_sensor.sanitizer_dispense
      - binary_sensor.east_doors
      - binary_sensor.west_doors
      - counter.printer
      - sensor.findeiss_1_temperature
      - sensor.findeiss_1_humidity

The Finished Project

This project has been running for the majority of the school year and I'm pleased to say that it works very reliably. I've even added a second Raspberry Pi to my setup that displays the Home Assistant dashboard on one of our classroom TVs.

Over the past year, our dispenser has been used 2,838 times. Hopefully that's killed a few COVID-19 bugs. 😀