<article-heading title="Doorbell" is-published="true" updated-date="2020-04-10" /> <p class="article-description"> I've been working from home a lot more recently, so I've been opting to get packages delivered straight to my home instead of the office. Since I need to sign for some packages myself, I need a reliable way to hear when someone is at the door. Now they can press a button outside, which triggers a notification and plays a doorbell chime inside the house. </p> <p> The obvious fix for this is to buy a simple <abbr title="radio frequency">RF</abbr> doorbell and install it, however... <ul> <li>Cheap RF doorbells seem to have pretty limited range, with the chime only working a short distance inside the house</li> <li>You need to be in range of the chime to be able to hear and respond to it</li> <li>There is no way to keep a record of when the doorbell is pressed</li> </ul> In addition, the built-in chimes are bland. My first Nokia phone had better single-channel MIDI tunes. </p> <h2>Interaction flow</h2> <section class="hero"> <figure> <img src="/content/articles/doorbell/doorbell.png" alt="A diagram showing how messages from a Mijia button are are delivered to Home Assistant and then through to Pushbullet and a connected speaker." /> <figcaption>A Zigbee button communicates to Zigbee2mqtt and Home Assistant to send a notification and trigger an audio alert. </figcaption> </figure> </section> <p> The interaction flow above is similar to how the <a data-article="mailbox-sensor">Mailbox sensor</a> and <a data-article="bedside-lamp-button">Bedside lamp button</a> operate, but this time the Raspberry Pi is connected directly to an external speaker </p> <h2>Devices</h2> <section class="gallery previews-medium"> <figure> <img src="/content/articles/doorbell/mijia-button.jpg" alt="A Xiaomi Mijia button" /> <figcaption>Mijia button <br /><a href="https://item.mi.com/product/5006.html">from Xiaomi</a></figcaption> </figure> <figure> <img src="/content/articles/doorbell/doorbell-cap.png" alt="A 3D rendered button cap with a ringing bell outline" /> <figcaption>3D printed doorbell cap </figcaption> </figure> <figure> <img src="/content/articles/doorbell/speaker.jpg" alt="A speaker" /> <figcaption>Speaker </figcaption> </figure> </section> <h2>Doorbell cap</h2> <section class="previews-medium inline"> <figure> <img src="/content/articles/doorbell/doorbell-with-cap.jpg" alt="The mounted doorbell with a 'ringing bell' icon cap" /> </figure> </section> <p> It needs to be clear that the button is actually a doorbell, so I decorated it with a 3D printed cap with a 'ringing bell' silhouette from the <a href="https://materialdesignicons.com/">Material Design Icons</a> set. This is just hot-glued to the button face, making the entire cap pressable. </p> <h2>Playing audio</h2> <p> Home Assistant offers a few integrations for playing audio. I tried the <a href="https://www.home-assistant.io/integrations/mpd/">Music Player Daemon</a> and <a href="https://www.home-assistant.io/integrations/vlc/">VLC</a> integrations, but settled on the low-fi <a href="https://www.home-assistant.io/integrations/shell_command/">Shell Command</a> with <code class="inline">aplay</code> due to its speed and minimalism. The only problem with using <code class="inline">aplay</code> is that it only accepts unencoded waveform audio. An easy workaround is to transcode audio files manually before using them: <code class="inline">ffmpeg -i input.mp3 output.wav</code>. </p> <p> In this example, I'm using <code class="inline">sound_file</code> as a parameter to make the <code class="inline">play_sound</code> command reusable. My Raspberry Pi has a USB audio card connected, but for the speaker I want to use the onboard audio card (which is aliased as 'sysdefault'). </p> <pre class="prettyprint" v-pre="v-pre">$ cat ${HOME_ASSISTANT}/configuration.yaml <code class="lang-yaml"> ... shell_command: play_sound: 'aplay -D sysdefault {{ sound_file }}' ...</code></pre> <p> Here, I'm using a new script to handle the "doorbell pressed" notification actions, to keep them decoupled from the automation trigger. </p> <pre class="prettyprint" v-pre="v-pre">$ cat /home/homeassistant/.homeassistant/scripts.yaml <code class="lang-yaml"> ... notify_doorbell_pressed: alias: Notify doorbell pressed sequence: - service: shell_command.play_sound data: sound_file: /home/pi/puzzle-solved.wav - service: notify.notify_pushbullet data: message: Doorbell was pressed ...</code></pre> <p> Finally, the automation simply waits for a <code class="inline">single</code> click trigger, which fires off the <code class="inline">notify_doorbell_pressed</code> script above. </p> <pre class="prettyprint" v-pre="v-pre">$ cat /home/homeassistant/.homeassistant/automations.yaml <code class="lang-yaml"> ... - id: doorbell_pressed alias: Doorbell pressed trigger: - entity_id: sensor.0x00158d0002c41211_click platform: state to: single action: - service: script.notify_doorbell_pressed ...</code></pre> <h2>Wrap-up</h2> <p> This serves as a sensible first cut of a doorbell. Next, I'm keen to include some behaviours from other smart doorbell solutions, such as an intercom. </p> <p> If you have any feedback or questions related to this article, please reply to <a href="https://twitter.com/TassSinclair/status/1246701205675376642">my post on Twitter</a>. </p> <p> This article is part of the <a data-article="home-automation">Home automation</a> set. </p>