Home Assistant

Naming schema

The default names generated by Home Assistant are unsustainable in the long term and hard to work with. This is how I tediously work around them.

Hoke Assistant prioratizes "friendly names" over entity_id, but they are only UI elements while entity_id can be thought of more as variables The most important aspect of home automation is automation, which involves some degree of programming and working with variables. Thats means having clearly defined and easy to find variable names (entity_id) is a lot more important.

General entity naming schema

These are the general naming schema rules I use for entities, which typically follow ${domain}.${area}_${kind}_${placement}.

Naming of light entities

Note

Indicator-type lights are assigned to a special "Indicators" area in Home Assistant.

Naming convention: light.${area}_${kind}_${placement}

The $placement part is optional and used when needed, for example if an area or room has multiple lamps. Somtimes light.${area}_${kind}_${number} will make more sense.

Example

  • light.bedroom_ceiling
  • light.hallway_lamps_table

Naming of binary_sensor entities

Naming convention for important entity_ids that get used in dashboards, scripts and automations:

  • binary_sensor.${kind}_${area}

Other less important binary_sensors that are created and not likely to be used in automations or dashboards, are left with their default values. Those are usually entities that I only look at by going to the device's page. If the entity does not matter at all, it gets disabled.

If there are more than one type of sensor in a location, they are named in one of the following ways, depending on which one makes sense each time:

  • binary_sensor.${kind}_${area}_${placement}
  • binary_sensor.${kind}_${area}_${number}

And then they get all grouped or templated together into a single binary_sensor.${kind}_${area}. Then it is often the group/template that it makes sense to show on dashboard and build automations with.

Some devices have for example binary_sensors for current/energy overload and those are named binary_sensor.overload_${kind}_${location}.

A (non-exhaustive) list of different $kinds of binary_sensors:

  • radar: mmWave presence detection
  • motion: PIR sensors, motion detectors and "moving target" on mmWave sensors
  • door: a magnetic/hall/reed/window sensor affixed to a door.
  • window: same, but affixed to a window
  • tamper: tamper detection, commonly found on various Z-Wave sensors

Example

  • binary_sensor.door_${area}
  • binary_sensor.window_${area}
  • binary_sensor.motion_${area}
  • binary_sensor.presence_${area}

This makes gives them predictable names. If you want to use a door sensor for the bathroom, it is easy to remember that it's simply binary_sensor.door_bathroom.

Naming by types of device

References for how to name entities commonly presented by various types of devices.

Air quality sensors

For sensor entities:

Nameentity_id naming schemaUnit
Carbon dioxide (CO₂)sensor.air_co2_${area}ppm
Volatile Organic Compounds (VOC)sensor.air_voc_${area}ppm
Air temperaturesensor.air_temperature_${area}C
Dew pointsensor.air_dew_point_${area}C

Z-Wave diagnostic sensors

Nameentity_id naming schema (prefix)
Successful Commands (RX)sensor.ok_rx_
Successful Commands (TX)sensor.ok_tx_
Successful Commands/min (RX)sensor.ok_rx_
Successful Commands/min (TX)sensor.ok_tx_
Commnads dropped (RX)sensor.dropped_rx_
Commands dropped (TX)sensor.dropped_tx_
RSSIsensor.rssi_
Round Trip Timesensor.rtt_
Timed out responsessensor.timeouts_

Typically I'll only enable the sensor.ok_tx_ and sensor.ok_rx_ entities. The sensor.ok_rx_per_min_ and sensor.ok_tx_per_min_ entities are Derivative Helper sensors.

Adding new devices

Adding a new device usually generates a fair amount of new entities, that come with the Home Assistant default names and are derived from their friendly names (for example binary_sensor.bathroom_door_window_sensor_state) that will need to be renamed.

This is a reference for how to rename them, for keeping things consistent.

Z-Wave

Default nameNaming standard
switch.outlet_${area}switch.outlet_${area} for kinds outlet
sensor.${kind}_${area}_electric_consumption_wsensor.electric_w_${kind}_${area}
sensor.${kind}_${area}_electric_consumption_kwhsensor.electric_kwh_${kind}_${area}
sensor.${kind}_${area}_electric_consumption_asensor.electric_a_${kind}_${area}
sensor.${kind}_${area}_electric_consumption_vsensor.electric_v_${kind}_${area}
update.${kind}_${area}_firmwareupdate.firmware_${kind}_${locatiom}
button.${kind}_${area}_pingbutton.ping_${kind}_${area}
sensor.${kind}_${area}_node_statussensor.node_status_${kind}_${area}
sensor.${kind}_${area}_successful_commands_rxsensor.ok_rx_${kind}_${area}
sensor.${kind}_${area}_successful_commands_txsensor.ok_tx_${kind}_${area}

Additionally I create derivative sensors:

  • sensor.ok_rx_per_min_${kind}_${area} of sensor.ok_rx_${kind}_${area}
  • sensor.ok_tx_per_min_${kind}_${area} of sensor.ok_tx_${kind}_${area}

They are good for spotting devices that are wrongly configured to send too many reports.

Zigbee

First we need to get the device to join the Zigbee network. These devices are not very standardized in how they join a network, and are very picky about distance from the controller. Sometimes there are instructions in Zigbee2mqtt's Device page but not always. Aside from the devices manual, it's a good place to start looking.

zigbee2mqtt

Tip

The web UI has a "Update Home Assistant entity ID" toggle, which defaults to false.

Once the device has joined, rename it from the default 0x.. name. The device's friendly_name and id are stored in the configuration.yaml file (using config as storage..). Since i manage this with ansible, i add something like this to the inventory variable hass_zigbee_devices, and ansible will template it into configuration.yaml (same YAML-structure):

'0x70ac08fffeb4cd10':
    friendly_name: light_livingroom_plants

Now the device is in Home Assistant, with a mostly-correct name, but the entity_ids are wrong and need to be redefined in Home Assistant.

default namenaming standard
select.${device_name}_power_on_behaviorselect.power_on_behavior_${device_name}
sensor.${device_name}_linkqualitysensor.linkquality_${device_name}

Zigbee devices don't expose a lot of entities.

Z-Wave or Zigbee

These are in general significantly more expensive than similar Zigbee devices, but I vastly prefer Z-Wave over Zigbee for a few reasons:

  • Z-Wave JS is vastly better made than Zigbee2MQTT and Deconz
    • Z-Wave JS UI/Server uses a websocket to communicate with Home Assistant, not MQTT.
  • Z-Wave devices are more reliable.
    • Z-Wave uses it's own radio frequency, while Zigbee uses 2.4GHz, which is pretty crowded and more prone to interference.
  • Z-Wave devices are easier to include (pair) and exclude (un-pair), having better instructions and documentation. The methods are also often somewhat standard.

Tip

I buy almost all of my Z-Wave devices used or second hand, often for significantly less than retail prices.

That being said, Zigbee devices are also useful. Not everything needs power monitoring (I use Zigbee switches downstream for Z-Wave switches with energy monitoring, so that the same energy usage isn't measured twice). IKEA makes great Zigbee devices, for a very fair price.

Database

I'm using MariaDB for my database instead of the default SQLite file, which is configured in the recorder integration1 as:

recorder:
  db_url: |
    mysql://${db_user}:@localhost/${db_name}?charset=utf8mb4&unix_socket=/run/mysqld/mysqld.sock
  auto_purge: true
  auto_repack: true

Connects as ${db_user} to the unix socket file in the standard location /run/mysqld/mysqld.sock, using 4-byte UTF-8 Unicode encoding.

Database total size

To get the total size of the database (in MB):

SELECT table_schema AS 'DB',
       ROUND(SUM(data_length + index_length) / 1024 / 1024, 1) AS 'Size in MB'
FROM information_schema.tables
WHERE table_schema='${db_name}';

The result is the size of data in the database schema ${db_name}, including the size used for indices.

This is also handy to define as a sensor in Home Assistant with the sql sensor platform2:

sql:
  - name: mariadb_database_size
    query: |
      SELECT table_schema AS 'DB',
             ROUND(SUM(data_length + index_length) / 1024 / 1024, 1) AS 'value'
      FROM information_schema.tables
      WHERE table_schema='${db_name}';
    # Column name from query result used as value for the sensor
    column: "value"
    device_class: data_size
    unit_of_measurement: MB

The name of column configuration value needs to match the name that the returned column is SELECT'ed AS in the SQL statement.

Analyzing which entity_ids take up space

To see which entities are taking up space:

SELECT COUNT(*) AS count,
       COUNT(*) * 100 / (SELECT COUNT(*) FROM states) AS 'count_pct',
	   states_meta.entity_id
FROM states
INNER JOIN states_meta
    ON states.metadata_id=states_meta.metadata_id
GROUP BY states_meta.entity_id
ORDER BY count DESC
LIMIT 10;

Will return the entity_ids that have the highest row count in your database. The JOIN in the statement isn't very efficient, so it will likely take some time for the query to return the result.

Adjust the LIMIT if you want a longer/shorter list.

Preventing battery drain from device monitoring

Using BLE for presence

Logitech devices

I have some mice from Logitech:

Some Logitech devices, such as the Logitech MX Master and Logitech 604 Lightspeed, increment the MAC address by one every time that the device is paired with a new system. You should determine whether this is the case, so that it can be accounted for at the end of the process.

Extracting Bluetooth identity keys on Linux

On Linux systems using bluez, the identity keys are stored in /var/lib/bluetooth3, so they are easy to retreive.

First, get the mac address of your Bluetooth adapter:

$ bluetoothctl list
Controller 8C:F8:C8:75:A2:11 hostname [default]

Most likely you'll only get one Controller line, as you most likely just have one Bluetooth adapter.

Also use bluetoothctl to list the devices your controller has paired with:

$ bluetoothctl devices Paired
Device E8:79:73:36:D3:C2 Adv360 Pro
Device C7:92:C6:8E:2A:E7 OpenComm2 UC by Shokz

Now take a look in /var/lib/bluetooth:

$ bt_adater="8C:F8:C8:75:A2:11"
$ sudo ls -1 /var/lib/bluetooth/${bt_adapter}/
C7:92:C6:8E:2A:E7
cache
E8:79:73:36:D3:C2
settings

There is a directory for each paired device (here C7:92:C6:8E:2A:E7 and E8:79:73:36:D3:C2):

$ sudo ls -1 /var/lib/bluetooth/${bt_adapter}/E8:79:73:36:D3:C2
attributes
info

Both files are .ini config files. The attributes file lists all UUIDs and Bluetooth attributes the device is capable of and the info file is where you'll find the pairing key.

$ sudo head /var/lib/bluetooth/${bt_adapter}/E8:79:73:36:D3:C2/info -n 3
[IdentityResolvingKey]
Key=${IRK_KEY}

There are apparently different types of pairing keys, not all of them are IRK or Identity Resolving Keys.

$ sudo tail /var/lib/bluetooth/${bt_adapter}/C7:92:C6:8E:2A:E7/info -n 4
[LinkKey]
Key=${KEY}
Type=4
PINLength=0

I am currently not sure what the difference is.

Names and info of other Bluetooth devices

The /var/lib/bluetooth/${bt_adapter}/cache dir has files for each device that your Bluetooth controller has "seen" (received broadcast advertisments from):

$ sudo cat /var/lib/bluetooth/${bt_adapter}/cache/E1:A1:38:55:04:6D
[General]
Name=F48F92A55A4C33A8EA

This could be useful to track bluetooth devices that broadcast a consistent name, but alter their MAC address.

Bluetooth key encodings and conversions

On MacOS, the IRK is given as a base64 encoded string of bytes. On Linux/bluez the key is a hex string (with each byte's hex representation).

>>> import base64
>>> base64.b64encode(bytes.fromhex("123456789abcdef123456789abcdef12")).decode()
'EjRWeJq83vEjRWeJq83vEg=='

Converts the hex-string 123456789abcdef123456789abcdef12 (which is [0x12, 0x34, ..., 0xef, 0x12]) into the base64 encoded string used by MacOS.

>>> bytes.hex(base64.b64decode("EjRWeJq83vEjRWeJq83vEg=="))
'123456789abcdef123456789abcdef12'

Converts it the other way, turning the base64 string into the hex-string.

7

home-assistant/core#101116: Private BLE wont find iphone (Has neat examples of using Jinja in YAML)

8

openhaystack: framework for tracking personal Bluetooth devices via Apple's massive Find My network.

9

bt-dualboot: Sync Bluetooth for dualboot Linux and Windows