Template Binary Sensor no longer functioning correctly with 0.116.4?

Running HA 0.116.4 in a Python 3.8 venv on Ubuntu 18.04.

I have a template binary sensor that looks for my car’s MAC in the Android app’s connected paired devices attribute:

binary_sensor:
  - platform: template
    sensors:
       driving:
          friendly_name: "Driving"
          value_template: "{{ '[CC:C0:79:64:68:C8]' in state_attr('sensor.turk_bluetooth_connection', 'connected_paired_devices') }}"

This sensor worked correctly without any issues logged on 0.116.3 and prior versions.
Post 0.116.4 I’m seeing a periodic error in my logs, with the sensor’s state going to “unavailable” at matching times before returning to “off”

2020-10-19 10:51:11 ERROR (MainThread) [homeassistant.components.template.template_entity] TemplateError('TypeError: argument of type 'NoneType' is not iterable') while processing template 'Template("{{ '[CC:C0:79:64:68:C8]' in state_attr('sensor.turk_bluetooth_connection', 'connected_paired_devices') }}")' for attribute '_state' in entity 'binary_sensor.driving'

In development tools > states the source shows correctly and changes when I change which bluetooth devices are connected to the phone:

The template no longer seems to change the binary sensor state when connected to the car. This did however function correctly on 0.116.3. I tested this last weekend before upgrading to 0.116.4 because I’d changed phones.

Any guidance on the error message argument of type ‘NoneType’ is not iterable would be much appreciated.

This is likely happening whenever the “connected_paired_devices” attribute of “sensor.turk_bluetooth_connection” is empty/None. The “in” operator you’re using requires a list. And “None” is not a list.

My guess would be that either the Android App is sometimes sending a None object instead of an empty list, that some kind of intermittent connectivity issue is causing HA to remove this attribute entirely, or that there is some bug in template binary_sensor, perhaps centering around any times that you “reload template entities”.

You can check for None before looking for that MAC in the list to stop the error. But, I’m not sure if that will get it to start updating correctly.

(untested, but I think the “is not None” syntax is valid in a template)

binary_sensor:
  - platform: template
    sensors:
       driving:
          friendly_name: "Driving"
          value_template: "{{ state_attr('sensor.turk_bluetooth_connection', 'connected_paired_devices') is not None and '[CC:C0:79:64:68:C8]' in state_attr('sensor.turk_bluetooth_connection', 'connected_paired_devices') }}"

Also, wanted to add: this is a really interesting piece of data to have, and a method I hadn’t thought of for detecting it. So I’ll be adding a feature like this to my own available data in the near future.

One final bit: to test to see what’s really happening, logging helps. I imagine there is a way to simply LOG in an Home Assistant Automation, but I don’t know what it is and couldn’t find it with a quick search.

I use pyscript for this sort of thing, and logging would be pretty easy with that:

last_seen_devices = None

@state_trigger('sensor.turk_bluetooth_connection')
def log_connected_devices():
  global last_seen_devices

  this_seen_devices = sensor.turk_bluetooth_connection.connected_paired_devices
  if this_seen_devices != last_seen_devices:
    last_seen_devices = this_seen_devices
    log.info(f'Devices: {this_seen_devices}')

That makes perfect sense.
It’s also helped me realise why the sensor itself isn’t functioning - I had a bluetooth connectivity issue with my watch that I fixed on Saturday night, so now that remains connected.
My template was checking for only the presence of the car MAC in the connected devices list by virtue of including the “[” and “]” in my value to check - this won’t work anymore as the watch is also connected.

I need to remove the list boundaries from my check value, giving:

{{(state_attr('sensor.turk_bluetooth_connection','connected_paired_devices')!=None) and ('CC:C0:79:64:68:C8' in state_attr('sensor.turk_bluetooth_connection','connected_paired_devices'))}}

Hopefully this will work on the drive home tonight.

When you see [‘a’, ‘b’, ‘c’] as an attribute value (not a state, because Home Assistant does things differently there) it is almost always a list in Python. (It COULD be a string that just happens to be equal to that value, but, this is also how Python and Home Assistant represent a list as a string… with the [ and ] on either end).

The “in” operator, when working against a string, checks to see if that substring is in the whole string. Like:

'def' in 'abcdefghijkl' == True

But for lists, it’s checking to see if the list contains that whole item, like:

'def' in [ 'abc', 'def', 'ghi', 'jkl' ] == True

Where it gets weird for some is when you think it’s a string but it’s really a list. Like this:

'def' in [ 'abc', 'defghi', 'jkl' ] == False
'def' in "[ 'abc', 'defghi', 'jkl' ]" == True #notice the extra surrounding quotes making it a string

Worked a treat, updating almost instantly.