Category Archives: HomeAssistant

Home Assistant Dynamic Entity Lists with Entity-Dependent Style

Home assistant is very powerful – possessing a great deal of flexibility both in terms of what can be monitored and how the monitored state is displayed. Much of the display flexibility comes through a combination of the Jinja templating engine and custom components.

Here is one example of this flexibility in action: display a dynamic list of sensors, coloring the status LED differently depending on the sensor state. Or more specifically: the ping status for a set of devices – in this case the ping status of all my raspberry pi cameras.

To display a dynamic list of sensors I first helped myself by giving my devices a consistent name prefix – e.g. “pi-cam-X” where X is the instance. I then installed the wonderful auto-entities plugin and specified an inclusion filter of “/pi-cam/”

Next to perform the styling I download the template-entity-row plugin – which allows applying a template to each entity row. The card yaml is actually fairly compact and readable:

type: custom:auto-entities
card:
  type: entities
filter:
  include:
    - name: /pi-cam/
      options:
        style: |
          :host {
            --card-mod-icon-color: {{ 'rgb(221,54,58)' if is_state('this.entity_id','off')  else 'rgb(67,212,58)' }};
          }
        type: custom:template-entity-row
        icon: mdi:circle
        state: >-
          {% if is_state('this.entity_id','off') %} Down {% else  %} Up {% endif %}

To be honest it took way longer to accept that this kind of flexibility was not available out of the box – it is too bad some of these add-ons are not just core to HA as they seem like core functionality.

The “out of the box” display is on the left. The ostensibly-improved status is on the right. Note that in truth i dont see a huge need for displaying textually what the red/green LED shows, however I much prefer “Up/Down” to “Connected/Disconnected”..

Controlling 433 Mhz Blinds from Home Assistant (the easy way)

A while back I bought a superhet 433 Mhz transceiver/receiver pair (like this). The goal was to attach this simple device to a pi and control it using the great rpi-rf package. Unfortunately, it appears that my particular transceivers (one BY-305 controlling five blinds, one AC-123-06D controlling two blinds) emit codes that aren’t easily detected by rpi-rf.

Rather than try and get a PhD in reverse engineering the protocol (well, i did try for it but barely qualify for A.B.D) I found the life saving rpi-rfsniffer package. I noticed that if I simply did the following:

 rfsniffer --rxpin 7 record 2ndFloorS_All4_Up

This allowed me to override the default receive pin (which i had plugged into GPIO4). I then held down the “up” button on my 433Mhz remote. I repeated this procedure for the up and down on both remotes, giving each recording session an appropriate name. One note: I found that rfsniffer waited sometimes far too long to terminate the recording. To limit it I modified line 62 of /usr/local/lib/python3.7/dist-packages/rfsniffer.py as follows:

if len(capture) < 16000 and  GPIO.wait_for_edge(rx_pin, GPIO.BOTH, timeout=1000):

This limits the capture to 16000 samples (about 6 seconds or so.)

To play back the recordings I did the following:

rfsniffer --txpin 11 play 2ndFloorS_All4_Up

Again i overrode the tx pin as pin 11 (GPIO17) playing back the samples I had just recorded.

To integrate this into home assistant I simply used the excellent command_line integration. This was quick and easy and probably cannot be improved upon as there is no status coming from the blinds.

switch:
  - platform: command_line
    switches:
      blinds_2ndfloor:
        command_on: ssh -o StrictHostKeyChecking=no user1@<pi1_ip> '/home/user1/blinds_south_up.sh'
        command_off: ssh -o StrictHostKeyChecking=no user1@<pi1_ip> '/home/user1/blinds_south_down.sh'

This exposes a single entity, called ‘blinds_2ndfloor’ that has “on” and “off” buttons. The on script looks like this:

rfsniffer --txpin 11 play 2ndFloorN_Up
rfsniffer --txpin 11 play 2ndFloorN_Up
rfsniffer --txpin 11 play 2ndFloorN_Up
rfsniffer --txpin 11 play 2ndFloorS_All4_Up
rfsniffer --txpin 11 play 2ndFloorS_All4_Up
rfsniffer --txpin 11 play 2ndFloorS_All4_Up

The repetition seemed necessary, empirically, as sometimes a single blind would not start if only one or two playbacks were made. Additionally, since there is only one pi, i found putting all the command serially was better than letting HA possibly try to run the north and south transceivers in parallel. The script for off looks similar but, of course, plays back the “Down” samples.

With those scripts in place one can easily add HA automations to bring the blinds up or down based on the time of day. Eventually you need not touch anything in your house and can progress to a future of blissful automation taking care of everything and allowing us to evolve into our proper form:

A list of ways our society is already like Pixar's dystopia in WALL·E

Disclaimers:

  • For docker-based HA: To enable ssh based remote invoke, one must ensure the /root/.ssh as a volume, then inside HA generate your ssh keypairs. Then add the HA pub key to your pi authorized_keys file.
  • I totally realize this method of capturning the RF signals is suboptimal: in theory if you live in a busy RF environment you would be capturing, then playing back stray signals. The solution is obviously do your RF captures in your neighborhood anechoic chamber.

HA MQTT Auto Discovery

As described on their official MQTT Auto Discovery page, Home Assistant allows one to create sensors on the fly. This is particularly important if you are, say, trying to add some non-trivial number of devices that speak MQTT.

I saw a lot of posts about people struggling to get this working. I too had a few issues and felt it worth stating my take on it. Spoiler alert: HA MQTT auto discovery works perfectly, so long as you get over some of the setup nuances. I thought I’d document these for posterity:

  • If you added MQTT support through the GUI, auto discovery is set to false by default. There doesn’t appear to be any way to fix this through the GUI. If you then add MQTT to your configuration yaml, the GUI config overrides it! The only way to overcome this is to delete MQTT from the GUI and then add it in the configuration yaml, restart HA, etc..
  • To publish a value there is a two step process
    1. Publish to the configuration topic to define the sensor. The concept of how this works is well documented on the main link given above – however it is important to note that you do NOT have to provide the configuration for all values in a entity with multiple values. This is actually a nice feature – and works so long as you always publish the config before sending the value. It was not clear to me (and i didnt investigate) if there was any good way to minimize the need to broadcast configurations; e.g. how do you know HA saw your config before you send state? To be safe i just publish the config and state one after another everytime. This doesnt seem optimal but it works.
    2. Publish the state via the state topic passed in during the config publish. The only thing to note here is that, unfortunately, it does not appear that values get rooted under the objectid you provide. Insted they are placed under a sensor with the name you provide – seemingly HA completely ignores the objectid…

Otherwise this feature works very well. Some tips I found for debugging this:

  • Enabling logging on mqtt works well. To do this add to configuration.yaml:
logger:
  default: warning
  logs:
    homeassistant.components.mqtt: debug

You can then tail (if under docker) config/home-assistant.log

  • Using the “Publish a packet” or “Listen to a topic” pages under MQTT->configure (in the HA configuration->integrations page) is good for eliminating any client broker issues you might see
  • Additionally, if you are using eclipse-mosquitto as your mqtt server, you can directly view (HA aside) publishes. In docker it would be:
docker exec -it <mosquittodockerid> /bin/sh
mosquitto_sub -u user -P pass -h localhost -t topic

Where “topic” above is whatever you are publishing, e.g. “homeassistant/sensor/grinch/state”

Lastly, in looking for a good c++ mqtt client, I tried paho and mosquitto. I found mosquitto worked best – both for the server (which i run in a docker) and c++ client. My decision was based on this simple requirement: the library should build (paho failed), work with c++11 (other, albeit cool-looking, c++ libraries required c++14), and be easy. Mosquitto fit the bill perfectly. I am sure – perhaps – there could be other libraries that might work as well – i just never found them.

InfluxDB Queries on HomeAssistant Data

I recently added in influx db + grafana + mariadb to one of my HA instances. I was surprised at how easy it was to get HA happy. Essentially nothing more than running the docker instances for each of these components and adding minimal yaml to HA.

When i went to query the data there were a few surprises that I thought I’d note. First, as noted in https://community.home-assistant.io/t/missing-sensors-in-influxdb/144948, HA puts sensors that have a unit name inside a measurement of that name. Thus if i show measurements that match my model_y, for example, all i get are binary (e.g. unittless) sensors:

> show measurements with measurement =~ /sensoricareabout/
name: measurements
name
----
binary_sensor.sensoridontcareabout1
climate.sensoridontcareabout2
device_tracker.sensoridontcareabout3
...

However if i query series, similarly, i see the measurement i care about:

> show series where "entity_id" =~ /sensoricareabout/
key
---
°F,domain=sensor,entity_id=sensoricareabout_foo_1
°F,domain=sensor,entity_id=sensoricareabout_foo_2

Thus, oddly, to query the data i want i form a query something like this:

 select value from "°F" where entity_id = 'sensoricareabout_foo_1'

A couple things. So, it is odd to me to have to query from what I essentially view as a table °F… but that is probably more HA’s fault than influxdb. Second, i think the quoting is a little weird. Note above that the measurement is double quoted, whereas the tag is single quoted. This is important. You can sometimes (maybe?) leave the double quotes off the former but the latter must strictly be single quotes…

The moral of the story is that if you want to find the data you are looking for you need to look under ‘%’ or the actual unit of measurement. For example in grafana i would:

  • click on explore
  • select ‘%’
  • Add a where clause to filter by entity_id
  • Possibly find my series there…
    • But if not remove the where, and switch from % to the unit of measurement, and repeat by adding the where clause

This all works well but is a little unintuitive and might make one think HA has forgotten to put the data into influx.