Dockerised MQTT Audio Buzzer written in Python on Raspberry Pi

Dockerised MQTT Audio Buzzer written in Python on Raspberry Pi

I have set up wireless remotes and battery operated button wall panels. When the buttons are pressed it is not immediately obvious that the linked automations are successfully triggered1. Adding basic audio feedback into automations improves the usability by letting users know that their button press was registered successfully by the system.

At the end of this post you should be able to call the buzz_short script in your Home Assistant configuration as shown below to produce a simple audio tone. There are more features to be explained later.

- alias: Wall Switch Button 2 and 3
  hide_entity: yes
  trigger:
    platform: event
    event_type: wp-btn-2-3
  action:
    - service: script.buzz_short

You can access the Gitlab project here. Contributions and issue reports are welcome.

Technologies used and why

Why Docker and MQTT? You can just execute the Python script when required.

We don’t know where and how we want to use it. MQTT is the most universal way for different systems to communicate in a IoT environment such as home automation systems. By making this script respond to MQTT messages, it can be used by any system that supports MQTT.

By dockerising it, we can run it on our existing Raspberry Pi server alongside Home Assistant. Do you really want to power a dedicated hardware device just to produce a simple noise? I’ve written about the benefits of virtualising hardware and using Docker for home automation in a previous blog post. Docker means that you can easily add this to your own setup.

Example Use Cases:

  • Debugging, you can set it up to emit a sound every time a message is received on a certain MQTT topic.
  • Wake up alarm
  • Alarm system Alert
  • Reminders (water plants, take medication etc).
  • Wall panel audio feedback
  • Morning routine audio queues (as a countdown reminder for bus arrival time)

Features

  • specify an MQTT topic to listen to messages
  • change various parameters about the audio emitted such as buzz length, pause length, repetitions and count of tones per repetition.
  • predefined audio patterns e.g. long buzz, short buzz

Implementation

The audio buzzer program itself is written in Python.The Git repository contains everything you need. Alternatively, you can use the prepackaged image danobot/buzz for Raspberry Pi on Docker Hub.

If you don’t have Docker Compose installed, I wrote some easy instructions for Raspberry Pi. Add this entry to your docker-compose.yaml file and run docker-compose up gpio. To run the container in background, add the -d flag like docker-compose up -d gpio.

buzz:
  image: danobot/buzz
  container_name: buzz_ha
  environment:
    MQTT_TOPIC: "/buzz"
    MQTT_HOST: "10.1.1.130"
    # GPIO_PIN: 18
    # BUZZER_REPS: 1
    # BUZZER_PAUSE: 1
    # BUZZER_LENGTH: 20
    # BUZZER_COUNT: 1
  devices:
    - /dev/gpiomem

Just make sure you edit the environment variables (MQTT server connection details).

Note: Access to the /dev/gpiomem device is required for GPIO pin access on the Raspberry Pi.

All you need in terms of hardware a small buzzer type speaker that comes with Raspberry Pi starter kits. Connect the positive (longer) pin to the GPIO pin (default pin 18) and the negative (short) end to ground on your Raspberry Pi.

The pinout schema below might help.

Raspberry Pi Pinout Schema

MQTT Interface

The docker container produces a sound when a MQTT message is received on the base topic (<MQTT_TOPIC>).

The BUZZER_* environment variables overwrite the default values.

If the message on the specified base topic contains a JSON payload, then the default configuration is overwritten. All values are optional and can be overwritten in any combination.

MQTT Payload Example format:

{
  "reps": 3,
  "pause": 0.6,
  "length": 20,
  "count": 3
}

Tone Presets

I added 3 presets as described in the table below:

TopicPreset description
<MQTT_TOPIC>Will produce sound according to default options. If MQTT payload is supplied, default options will be overwritten.
<MQTT_TOPIC>/shortProduces single short beep
<MQTT_TOPIC>/longProduces single long beep
<MQTT_TOPIC>/alarmProduces alarm

Home Assistant integration

I created scripts in home Assistant which can be called easily throughout the configuration. The scripts have been saved in buzz.yaml which was included in the main configuration using script: !include_dir_merge_named scripts/.

These calls to mqtt.publish should be saved in Home Assistant scripts. That way they can be resused easily in multiple automations without duplicating the implementation details. This is best practise according to the DRY princible.

buzz_short:
  alias: Buzz Short
  sequence:
    - service: mqtt.publish
      data:
        topic: "/buzz/short"

buzz_long:
  alias: Buzz Long
  sequence:
    - service: mqtt.publish
      data:
        topic: "/buzz/short"

buzz_alarm:
  alias: Buzz Alarm
  sequence:
    - service: mqtt.publish
      data:
        topic: "/buzz/alarm"

You can even define custom tones by adding an MQTT payload to the mqtt.publish service call.

buzz_custom:
  alias: Buzz custom
  sequence:
    - service: mqtt.publish
      data:
        topic: "/buzz"
        payload: >
          {
            "reps": 2,
            "pause": 0.6,
            "length": 10,
            "count": 3
          }

Conclusion

You have added a new Docker container to your setup, integrated it via scripts in Home Assistant and updated some of your automations to provide audio feedback without much additional hardware. It may not be obvious how useful this audio buzzer is until you come up with some use cases for your own Home Assistant setup.

  1. This could be due to timers set up as part of the automation or that a light which usually provides a visual cue is already switched on when the button is pressed. ↩︎