Automation mysteriously failed to trigger on Smoke Detector sensor "on" state

Earlier today a smoke detector set off the security alarm at our non-occupied vacation house. The only reason I knew about it was from getting a phone call from a nearby resident hearing the alarm.

The HASS automation logic is dead simple - just fire when any of the 6 fire/smoke detector binary_sensors changes to an “on” state and run a notification script.

binary_sensor.upstairs_smoke_16 properly switched from off to an on state but the automation that would have notified me failed to trigger and I can see no reason why it didn’t.

- id: Notify if fire or smoke sensor tripped
  alias: Fire/Smoke sensor tripped notification
  initial_state: True
  trigger:
  - platform: state
    entity_id: >
      binary_sensor.basement_fire_21, 
      binary_sensor.basement_smoke_18, 
      binary_sensor.main_floor_fire_20, 
      binary_sensor.main_floor_smoke_17, 
      binary_sensor.upstairs_hvac_fire_19,
      binary_sensor.upstairs_smoke_16
    to: 'on'
  action:
    service: script.alert_message
    data_template:
      title: "Lake Home"
      message: "Lake Home Alert! {% set parts = trigger.entity_id.split('.') -%} {{ states[parts[0]][parts[1]].name }} Alarm triggered!"

image

image

As an aside, I remotely opened the door to the kindly neighbor who checked upstairs and found no smoke. The detector will apparently need to be cleaned or replaced. But I have this awful feeling I can’t trust my critical home security automations until I understand WTH could have gone wrong.

Check the automation trace and the script trace to determine why this alert was not sent. Also check your logs.

I’m not sure if this is valid syntax for listing multiple entities, normally I do it like this:

entity_id:
  - binary_sensor.basement_fire_21
  - binary_sensor.basement_smoke_18
  - binary_sensor.main_floor_fire_20
  - binary_sensor.main_floor_smoke_17
  - binary_sensor.upstairs_hvac_fire_19
  - binary_sensor.upstairs_smoke_16
to: 'on'

Also your template in the message doesn’t make any sense to me, you split the entity_id and then check the states where you combine both parts of the entity_id again, why split it?
A way simpler template would be

{{ trigger.to_state.name }}

Which will give you the friendly name and if the friendly name doesn’t exist, it falls back to the entity_id.

Did you ever test this automation?

1 Like

Woah. Yeah. That aint right.

I’m not aware of a means to bench test an automation that includes “trigger” entities. The automation testing tool certainly can’t handle it.

However, I am using the exact same logic to trigger on door and window sensors and that works perfectly. That gave me the confidence the automation was correct without having to resort to physically creating intense heat and smoke.

Multiple entities can be coded that way, but since it is apparently unusual, I will change it, but that’s not the issue. The complex template to pull out the “upstairs_smoke” text from the entity name also works as intended, but I will now specify the friendly names for each to simplify the logic. Again, these changes are intended only to simplify things (and I appreciate the tips).

The problem does not seem to me to be the automation because of the fact it was never triggered (and nothing in the error log either). I think something went wrong with the event bus and somehow critical events were missed. Is that possible?

I just found in history that there was a 30 second power outage at the exact same time as when the smoke detector went off. All equipment is on UPS along with a whole home surge protection so it’s unclear how this outage could have had an event impact, but this certainly is no coincidence.

Furthermore, my UPS NUT event & power outage/restored automation also failed to trigger! This has always worked for previous outages. So four separate automations failed to trigger on events that were properly enabled and recorded. This is scary.

image

##########################################################

- id: UPS_Event
  alias: "UPS changed state"
  trigger:
    - platform: event
      event_type: nut.ups_event
  action:
    - service: script.alert_messsage
      data_template:
        title: "Lake Home UPS event"
        message: "{{ trigger.event.data.notify_msg }}"
    - delay: 60
##########################################################
- id: Power_Outage_Alert
  alias: Power Outage alert
  initial_state: True
  trigger:
    platform: state
    entity_id: sensor.power_outage
    to: 'True'
  action:
    - service: script.alert_message
      data:
        title: "Lake Home"
        message: "Lake Home Power Outage"
    - service: automation.turn_on
      entity_id: automation.power_restored_alert      
##########################################################
- id: Power_Restored_Alert
  alias: Power Restored alert
  initial_state: False
  trigger:
    platform: state
    entity_id: sensor.power_outage
    to: 'False'
  action:
    - service: script.alert_message
      data:
        title: "Lake Home"
        message: "Lake Home Power Restored"
    - service: automation.turn_off
      entity_id: automation.power_restored_alert

UPDATE: I think I now know why the triggers were missed. HASS was in the process of restarting. The current log begins with the typical warnings of custom integrations and no subsequent errors or warnings of any kind…

2021-10-24 09:59:58 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration hacs which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant

2021-10-24 09:59:58 WARNING (SyncWorker_2) [homeassistant.loader] We found a custom integration files which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant

2021-10-24 09:59:58 WARNING (SyncWorker_1) [homeassistant.loader] We found a custom integration favicon which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant

2021-10-24 09:59:58 WARNING (SyncWorker_2) [homeassistant.loader] We found a custom integration authenticated which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant

2021-10-24 10:00:12 WARNING (MainThread) [homeassistant.components.camera] Setup of camera platform amcrest is taking over 10 seconds.

The NUT power outage and smoke detector events occurred at 10:00:02 during the restart, so the automations likely weren’t processed yet. Why and how a restart could have triggered a phantom power outage AND smoke detector is another question. How weird is that?

Below is the previous homeassistant.log.1 that shows some serious errors that include “Client error on /homeassistant/restart request Server disconnected” and the Vera integration. I had not noticed that this is automatically saved now (great feature!). The Vera hub is used only to communicate via serial to the security panel for hardwired door/window/smoke sensors and has worked flawlessly for years. (All Zwave connections were moved off it to Zwave-JS).

It’s not clear that the Vera Integration is at fault, but perhaps its thread was a victim of the shutdown/restart. How a restart could somehow trigger phantom events which in turn instructed the security panel (via Vera) to fire off its loud siren. Just an insane series of events.

2021-10-24 09:59:42 ERROR (MainThread) [homeassistant.components.hassio.handler] Client error on /homeassistant/restart request Server disconnected
2021-10-24 09:59:42 WARNING (Thread-9) [homeassistant.util.executor] Thread[SyncWorker_4] is still running at shutdown: File "/usr/local/lib/python3.9/threading.py", line 930, in _bootstrap
    self._bootstrap_inner()
  File "/usr/local/lib/python3.9/threading.py", line 973, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.9/threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 77, in _worker
    work_item.run()
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/vera/common.py", line 80, in _run_poll_server
    if not self.poll_server_once():
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 1669, in poll_server_once
    device_data, new_timestamp = self.get_device_data(self._last_updated)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 1646, in get_device_data
    return self._controller.get_changed_devices(last_updated)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 335, in get_changed_devices
    response = self.data_request(payload, TIMEOUT * 2)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 121, in data_request
    response = requests.get(request_url, timeout=timeout, params=payload)
  File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 440, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/lib/python3.9/http/client.py", line 1371, in getresponse
    response.begin()
  File "/usr/local/lib/python3.9/http/client.py", line 319, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python3.9/http/client.py", line 280, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/local/lib/python3.9/socket.py", line 704, in readinto
    return self._sock.recv_into(b)
2021-10-24 09:59:43 WARNING (Thread-9) [homeassistant.util.executor] Thread[SyncWorker_4] is still running at shutdown: File "/usr/local/lib/python3.9/threading.py", line 930, in _bootstrap
    self._bootstrap_inner()
  File "/usr/local/lib/python3.9/threading.py", line 973, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.9/threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 77, in _worker
    work_item.run()
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/vera/common.py", line 80, in _run_poll_server
    if not self.poll_server_once():
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 1669, in poll_server_once
    device_data, new_timestamp = self.get_device_data(self._last_updated)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 1646, in get_device_data
    return self._controller.get_changed_devices(last_updated)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 335, in get_changed_devices
    response = self.data_request(payload, TIMEOUT * 2)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 121, in data_request
    response = requests.get(request_url, timeout=timeout, params=payload)
  File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 440, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/lib/python3.9/http/client.py", line 1371, in getresponse
    response.begin()
  File "/usr/local/lib/python3.9/http/client.py", line 319, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python3.9/http/client.py", line 280, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/local/lib/python3.9/socket.py", line 704, in readinto
    return self._sock.recv_into(b)
2021-10-24 09:59:50 ERROR (MainThread) [homeassistant] Error doing job: Exception in callback async_track_point_in_utc_time.<locals>.run_action(<Job HassJobT...f2e48bcc2b0>>>) at /usr/src/homeassistant/homeassistant/helpers/event.py:1170
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/asyncio/events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
  File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 1188, in run_action
    hass.async_run_hass_job(job, utc_point_in_time)
  File "/usr/src/homeassistant/homeassistant/core.py", line 436, in async_run_hass_job
    return self.async_add_hass_job(hassjob, *args)
  File "/usr/src/homeassistant/homeassistant/core.py", line 368, in async_add_hass_job
    task = self.loop.run_in_executor(  # type: ignore
  File "/usr/local/lib/python3.9/asyncio/base_events.py", line 814, in run_in_executor
    executor.submit(func, *args), loop=self)
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 161, in submit
    raise RuntimeError('cannot schedule new futures after shutdown')
RuntimeError: cannot schedule new futures after shutdown
2021-10-24 09:59:52 WARNING (MainThread) [homeassistant.util.executor] Thread[SyncWorker_4] is still running at shutdown: File "/usr/local/lib/python3.9/threading.py", line 930, in _bootstrap
    self._bootstrap_inner()
  File "/usr/local/lib/python3.9/threading.py", line 973, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.9/threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 77, in _worker
    work_item.run()
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/vera/common.py", line 80, in _run_poll_server
    if not self.poll_server_once():
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 1669, in poll_server_once
    device_data, new_timestamp = self.get_device_data(self._last_updated)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 1646, in get_device_data
    return self._controller.get_changed_devices(last_updated)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 335, in get_changed_devices
    response = self.data_request(payload, TIMEOUT * 2)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 121, in data_request
    response = requests.get(request_url, timeout=timeout, params=payload)
  File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 440, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/lib/python3.9/http/client.py", line 1371, in getresponse
    response.begin()
  File "/usr/local/lib/python3.9/http/client.py", line 319, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python3.9/http/client.py", line 280, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/local/lib/python3.9/socket.py", line 704, in readinto
    return self._sock.recv_into(b)
2021-10-24 09:59:53 ERROR (SyncWorker_4) [concurrent.futures] exception calling callback for <Future at 0x7f2e34b3e0a0 state=finished raised SystemExit>
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/vera/common.py", line 80, in _run_poll_server
    if not self.poll_server_once():
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 1669, in poll_server_once
    device_data, new_timestamp = self.get_device_data(self._last_updated)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 1646, in get_device_data
    return self._controller.get_changed_devices(last_updated)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 335, in get_changed_devices
    response = self.data_request(payload, TIMEOUT * 2)
  File "/usr/local/lib/python3.9/site-packages/pyvera/__init__.py", line 121, in data_request
    response = requests.get(request_url, timeout=timeout, params=payload)
  File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 445, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 440, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/lib/python3.9/http/client.py", line 1371, in getresponse
    response.begin()
  File "/usr/local/lib/python3.9/http/client.py", line 319, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python3.9/http/client.py", line 280, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/local/lib/python3.9/socket.py", line 704, in readinto
    return self._sock.recv_into(b)
SystemExit

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 329, in _invoke_callbacks
    callback(self)
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 398, in _call_set_state
    dest_loop.call_soon_threadsafe(_set_state, destination, source)
  File "/usr/local/lib/python3.9/asyncio/base_events.py", line 791, in call_soon_threadsafe
    self._check_closed()
  File "/usr/local/lib/python3.9/asyncio/base_events.py", line 510, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

You are probably right, I assume the sensors changed after the restart but before the automations were loaded, therefore they did not trigger.

I’d just replace one of the trigger entities with an input boolean and then turn on this input boolean.

Or press the test button on each of the smoke sensors. I do this every 12 months. Easter is a good time to do it every year.

Can you show where this is documented?

It’s the first time I have seen it.

That’s a good idea, but since the exact same logic was used for doors and windows on this same security system, that seemed to me to be a valid test. I do prefer to use the test button on smoke detectors instead as Tom suggested, but these sensors are 20 years old that came with the lake house and I don’t recall seeing any test buttons. Will certainly look again when I get back up there as well as looking to replace them.

LOL, I wish I could! I don’t remember and can’t find where I dug up the example from the forum that I copied. Setting up the security system with Vera>Hass was my very first foray into HASS automations a couple of years ago and following examples was a lot easier when learning from scratch. In any case, despite that it was working fine, I changed it to the documented multiple entity syntax.

This issue turns out to have nothing to do with how the automation was written. The best I can tell from the log, there was a HASS shutdown that somehow caused the UPS sensor to see low/no voltage and simultaneously cause one smoke detector out of 6 to an ‘on’ state. Neither was detected by the automation since this occurred while HASS was restarting. But the security system did detect the smoke sensor on state and sounded the alarm.

Don’t trust everything you read on here. There is a lot of bad advice.

I missed the commas between each entity in your list the first time I read it, that would actually make it valid.

OK, thanks for the validation.

BTW - I made a quick run to the lake house and confirmed the detectors don’t have a test button. The manual says to use canned smoke for testing (or heat gun for fire sensors), even for their newer detectors that have a test button. Reason was the test button only confirms successful communication with the security panel and does nothing to test the optical sensor sensitivity.