This is the third article in a series about my DIY approach to wall-mounted home automation dashboards.
Choosing the dashboard platform
The “heart” of my home automation system is Home Assistant, an open source home automation platform written in Python. Its built-in web frontend is suitable for a dashboard, but only if the only thing you want to control is Home Assistant. I knew from the start that there were going to be several custom components in my dashboard, so my primary requirement was ease of development and personal familiarity.
- I’ve used Dashing before, and was comfortable with the technological stack (Sinatra, CoffeeScript), knew that I would be able to rapidly build what I wanted.
- There are lots of ready-built components for Dashing already.
- It’s decoupled from Home Assistant itself (communicates via REST API that Home Assistant exposes).
- Some parts of Hadashboard are quite hacky: bi-directional update daemon is written in Python for some reason, there is quite a bit of code duplication, etc.
- It’s not under active development: Hadashboard 2.x is all-Python app that is not based on Dashing anymore.
Ring the bells!
I’ll use my “kids calling” system as an example to show how easily extensible this system is. So the objective: make it possible for my wife to press a button in the kitchen’s dashboard to call everyone for dinner. The system should:
- Have a visual indication that it was activated.
- Provide a way to acknowledge/silence the bells from kids’ rooms.
- Have an indication downstairs that the call was acknowledged.
I created 5 “boolean inputs” in Home Assistant configuration, one for each room that I wanted to have a bell:
input_boolean: bell_arie: name: "Arie's Bell" initial: off icon: mdi:bell bell_benjie: name: "Benjie's Bell" initial: off icon: mdi:bell ...
In Hadashboard, I extended the
hainputboolean.coffee component (that controls Home Assistant boolean inputs) to
accept an optional “sound” attribute: if set to a sound file, this file will be played when the switch is “on”
(Dashing uses Batman.js for HTML/JS bindings):
--- a/widgets/hainputboolean/hainputboolean.coffee +++ b/widgets/hainputboolean/hainputboolean.coffee @@ -2,10 +2,24 @@ class Dashing.Hainputboolean extends Dashing.ClickableWidget constructor: -> super @queryState() + @audioplayer = new Audio('') + @audioplayer.loop = true @accessor 'state', get: -> @_state ? 'off' - set: (key, value) -> @_state = value + set: (key, value) -> + @_state = value + if @get('sound') + if value == 'on' + if (@audioplayer.paused) + @audioplayer.src = @get('sound') + @audioplayer.play() + else + @audioplayer.pause() + + @accessor 'sound', + get: -> @['sound'] ? '' + set: Batman.Property.defaultAccessor.set
Here’s how it looks in the Dashboards’ HTML code:
The “calling” side:
<li data-row="2" data-col="8" data-sizex="1" data-sizey="1"> <div data-id="bell_arie" data-view="Hainputboolean" data-title="Call Arie" data-icon="mdi:bell"></div> </li>
The “callee” side:
<li data-row="1" data-col="8" data-sizex="1" data-sizey="1"> <div data-id="bell_arie" data-view="Hainputboolean" data-sound="/assets/sounds/ship-bell-1.m4a" data-title="Bell Off" data-icon="mdi:bell-off"></div> </li>
Note how it connects to the same boolean toggle backend, but the sound is defined only for the callee side, and the icons and the captions are different.
And… that’s all that was needed to make this calling system to work! Here’s a short video of how it functions: