First Alert Smoke Detector and Carbon Monoxide Alarm Setup

For what it is worth, mine have started to randomly trigger the fire alarm, which is extremely annoying. If you have these and plan on using them, the recommendation from their tech support is to vacuum them out on a weekly basis to avoid dust triggering the sensor.

No thanks! I’ll just pass on the hardware!

1 Like

To add another annoyance with these (not sure if the device or ZwaveJS) but I am getting so many ‘junk’ sensors:

Hi All, I’ve had two of the zwave first alerts for about 18 months now in a rental. I thought everything was good, but this last week I realized that both units had been removed from the wall and the batteries removed. This happened at least a week ago. Yet HA is still reporting that both units are online, batteries are still at ~75%, and everything looks find. All entities are still reporting available and no changes over this time period.

Does anyone know how or why both devices would be still active/available and alive within HA yet the units had no batteries installed? How can I periodically check a device like this to make sure it’s still active within an automation considering it goes to sleep?

I would have assumed that once the batteries were pulled and after a certain sleep time, HA would have realized there was no response and change the entities to unavailable or change to a dead node.

Thanks for any help.

I would have assumed that once the batteries were pulled and after a certain sleep time, HA would have realized there was no response and change the entities to unavailable or change to a dead node.

That isn’t functionality that the z-wave integration has. The Z-Wave driver does not even support it itself. You can create your own template entities to check some property. This will vary by device. For some devices you can check last wake up time. The first generation of ZCOMBOs don’t ever wake up. There is a heartbeat message you’ll see in the above templates. New generation supports both wake up and a heartbeat.

2 Likes

Battery powered devices don’t get detected as dead, since they are asleep. But they do periodically wake-up. They also do not report their battery level unless you poll it (there are lots of thread on the forum in how to do this).

There are two techniques for detecting if a battery powered device is online.

  1. When the device wakes up its node status changes from sleeping to awake. Configure the device to wake-up once a day; then generate an alarm if the device hasn’t woken up within 2x (plus a little) that time frame - as occasionally the wake-ups may be missed.

  2. If the device is configured to periodically send a piece a data (like a temperature), then you can use a similar technique to generate an alert if more than two or three sends are missing.

Here’s an example of detecting a device that does not wake-up. The yaml is not in ideal order as I autogenerate all this from a csv file that contains my zwave devices.

####
#### Template
input_boolean:
  al_zw_garage_sensor_alert_enable:
    name: zw_garage_sensor alert enable
  al_zw_garage_sensor_batt_alert_enable:
    name: zw_garage_sensor_batt alert enable
binary_sensor:
  - platform: template
    sensors:
      al_zw_garage_sensor_alert:
        value_template: '{{ (is_state("binary_sensor.zw_garage_sensor_online", "off")) and is_state("input_boolean.al_zw_garage_sensor_alert_enable", "on") }}'
  - platform: template
    sensors:
      al_zw_garage_sensor_batt_alert:
        value_template: '{{ (states("sensor.garage_sensor_battery_level")|float < 10.0) and is_state("input_boolean.al_zw_garage_sensor_batt_alert_enable", "on") }}'
  - platform: template
    sensors:
      zw_garage_sensor_online:
        value_template: >-
          {{ ( 30240 - (states('sensor.zw_garage_sensor_latency') | int(0))) > 0  and

               states('sensor.garage_sensor_node_status') != 'dead' and
               states('sensor.garage_sensor_node_status') != 'unavailable' and
               states('sensor.garage_sensor_node_status') != 'unknown'
          }}
alert:
  al_zw_garage_sensor:
    name: zw_garage_sensor
    message: 'ALERT {{state_attr("zone.home","friendly_name")}} zw_garage_sensor Latency: {{ states("sensor.zw_garage_sensor_latency")}}'
    done_message: 'Cleared {{state_attr("zone.home","friendly_name")}} zw_garage_sensor Latency: {{ states("sensor.zw_garage_sensor_latency")}}'
    entity_id: binary_sensor.al_zw_garage_sensor_alert
    state: "on"
    repeat:
      - 1
      - 240
    can_acknowledge: true
    skip_first: true
    notifiers:
      - sms_notifiers_all
      - sms_telegram_admin
  al_zw_garage_sensor_batt:
    name: zw_garage_sensor_batt
    message: 'ALERT {{state_attr("zone.home","friendly_name")}} zw_garage_sensor_batt Battery: {{states("sensor.garage_sensor_battery_level")}}'
    done_message: 'Cleared {{state_attr("zone.home","friendly_name")}} zw_garage_sensor_batt Battery: {{states("sensor.garage_sensor_battery_level")}}'
    entity_id: binary_sensor.al_zw_garage_sensor_batt_alert
    state: "on"
    repeat:
      - 60
      - 480
    can_acknowledge: true
    skip_first: false
    notifiers:
      - sms_notifiers_all
      - sms_telegram_admin
recorder:
  include:
    entities:
      - binary_sensor.al_zw_garage_sensor_alert
      - alert.al_zw_garage_sensor
      - input_boolean.al_zw_garage_sensor_alert_enable
      - binary_sensor.al_zw_garage_sensor_batt_alert
      - alert.al_zw_garage_sensor_batt
      - input_boolean.al_zw_garage_sensor_batt_alert_enable
      - binary_sensor.zw_garage_sensor_online
      - sensor.garage_sensor_node_status
      - sensor.garage_sensor_battery_level
      - sensor.garage_sensor_commands_dropped_rx
      - sensor.garage_sensor_commands_dropped_tx
      - sensor.garage_sensor_round_trip_time
      - sensor.garage_sensor_successful_commands_rx
      - sensor.garage_sensor_successful_commands_tx
      - sensor.garage_sensor_timed_out_responses
template:
  - trigger:
      - platform: homeassistant
        event: start
      - platform: state
        entity_id: sensor.garage_sensor_node_status
        to: awake
    sensor:
      - name: "zw_garage_sensor_last_updated"
        state: "{{ now() }} "
  - sensor:
      - name: zw_comms_garage_sensor
        state: "{{states('sensor.garage_sensor_node_status')}}"
        attributes:
          d_rx: "{{ states('sensor.garage_sensor_commands_dropped_rx')  }}"
          d_tx: "{{ states('sensor.garage_sensor_commands_dropped_tx')  }}"
          rtt: "{{ states('sensor.garage_sensor_round_trip_time')  }}"
          rx: "{{ states('sensor.garage_sensor_successful_commands_rx')  }}"
          tx: "{{ states('sensor.garage_sensor_successful_commands_tx')  }}"
          to: "{{ states('sensor.garage_sensor_timed_out_responses')  }}"
          lat: "{{ states('sensor.zw_garage_sensor_latency')  }}"
          online: "{{ states('binary_sensor.zw_garage_sensor_online')  }}"
          last: "{{ states('sensor.zw_garage_sensor_last_updated')  }}"
          nm: "garage_sensor"
sensor:
  - platform: template
    sensors:
      zw_garage_sensor_latency:
        unit_of_measurement: secs
        value_template: >-
          {%- if as_timestamp(states("sensor.zw_garage_sensor_last_updated"),0) == 0 %} 0 {%- else %} {{ ((as_timestamp(now(), 0) | int(0)) - as_timestamp(states('sensor.zw_garage_sensor_last_updated'),0) | int(0)) }} {%- endif %}

Here is an example of using a sensor change

input_boolean:
  al_zw_basement_sensor_alert_enable:
    name: zw_basement_sensor alert enable
binary_sensor:
  - platform: template
    sensors:
      al_zw_basement_sensor_alert:
        value_template: '{{ (is_state("binary_sensor.zw_basement_sensor_online", "off")) and is_state("input_boolean.al_zw_basement_sensor_alert_enable", "on") }}'
  - platform: template
    sensors:
      zw_basement_sensor_online:
        value_template: >-
          {{ ( 1600 - (states('sensor.zw_basement_sensor_latency') | int(0))) > 0  and

               states('sensor.basement_sensor_node_status') != 'dead' and
               states('sensor.basement_sensor_node_status') != 'unavailable' and
               states('sensor.basement_sensor_node_status') != 'unknown'
          }}
alert:
  al_zw_basement_sensor:
    name: zw_basement_sensor
    message: 'ALERT {{state_attr("zone.home","friendly_name")}} zw_basement_sensor Latency: {{ states("sensor.zw_basement_sensor_latency")}} Node {{ states("sensor.basement_sensor_node_status")}}'
    done_message: 'Cleared {{state_attr("zone.home","friendly_name")}} zw_basement_sensor Latency: {{ states("sensor.zw_basement_sensor_latency")}} Node {{ states("sensor.basement_sensor_node_status")}}'
    entity_id: binary_sensor.al_zw_basement_sensor_alert
    state: "on"
    repeat:
      - 1
      - 240
    can_acknowledge: true
    skip_first: true
    notifiers:
      - sms_notifiers_all
      - sms_telegram_admin
recorder:
  include:
    entities:
      - binary_sensor.al_zw_basement_sensor_alert
      - alert.al_zw_basement_sensor
      - input_boolean.al_zw_basement_sensor_alert_enable
      - binary_sensor.zw_basement_sensor_online
      - sensor.basement_sensor_node_status
      - sensor.basement_sensor_commands_dropped_rx
      - sensor.basement_sensor_commands_dropped_tx
      - sensor.basement_sensor_round_trip_time
      - sensor.basement_sensor_successful_commands_rx
      - sensor.basement_sensor_successful_commands_tx
      - sensor.basement_sensor_timed_out_responses
template:
  - trigger:
      - platform: homeassistant
        event: start
      - platform: zwave_js.value_updated
        entity_id:
          - sensor.basement_temperature
        command_class: 49
        property: Air temperature
    sensor:
      - name: "zw_basement_sensor_last_updated"
        state: "{{ now() }} "
  - sensor:
      - name: zw_comms_basement_sensor
        state: "{{states('sensor.basement_sensor_node_status')}}"
        attributes:
          d_rx: "{{ states('sensor.basement_sensor_commands_dropped_rx')  }}"
          d_tx: "{{ states('sensor.basement_sensor_commands_dropped_tx')  }}"
          rtt: "{{ states('sensor.basement_sensor_round_trip_time')  }}"
          rx: "{{ states('sensor.basement_sensor_successful_commands_rx')  }}"
          tx: "{{ states('sensor.basement_sensor_successful_commands_tx')  }}"
          to: "{{ states('sensor.basement_sensor_timed_out_responses')  }}"
          lat: "{{ states('sensor.zw_basement_sensor_latency')  }}"
          online: "{{ states('binary_sensor.zw_basement_sensor_online')  }}"
          last: "{{ states('sensor.zw_basement_sensor_last_updated')  }}"
          nm: "basement_sensor"
sensor:
  - platform: template
    sensors:
      zw_basement_sensor_latency:
        unit_of_measurement: secs
        value_template: >-
          {%- if as_timestamp(states("sensor.zw_basement_sensor_last_updated"),0) == 0 %} 0 {%- else %} {{ ((as_timestamp(now(), 0) | int(0)) - as_timestamp(states('sensor.zw_basement_sensor_last_updated'),0) | int(0)) }} {%- endif %}

Yielding a dashboard like this.

4 Likes

wow okay. good to know. I can look at my logs for the Node status and I can see about 1.5 months ago the note status changes from asleep to awake about every hour then stops and never shows awake again. The odd thing is there is no battery low indication.

So you’re saying I need to create my own entity that changes when there is no awake for a certain time? Then add an automation to be notified along with low battery and alarm.

The odd thing to me is that HA was restarted weeks after the last “awake” status, so even after a HA reboot the note would still appear alive? Other zwave devices I have I thought show up as unavailable until they are seen on the network again (but maybe I’m mixing that up with my zigbee devices).

Z-Wave JS also exposes a “lastSeen” fields in both the statistics events and part of the node state. The latter is not yet supported by HA. As for the event:

{
  "type": "event",
  "event": {
    "source": "node",
    "event": "statistics updated",
    "nodeId": 21,
    "statistics": {
      "commandsTX": 20,
      "commandsRX": 12,
      "commandsDroppedRX": 0,
      "commandsDroppedTX": 0,
      "timeoutResponse": 0,
      "rtt": 29.4,
      "lastSeen": "2023-11-03T18:18:36.705Z",
      "rssi": -72,
      "lwr": {
        "protocolDataRate": 2,
        "repeaters": [],
        "rssi": -71,
        "repeaterRSSI": []
      }
    }
  }
}

https://zwave-js.github.io/node-zwave-js/#/api/node?id=quotstatistics-updatedquot

/** The last time a command was received from or successfully sent to the node. */
    lastSeen?: Date;
2 Likes

Yes, because the criteria for what constitutes a dead device when it comes to battery devices, is up to you. The difficulty in this case is avoiding false positives. Keying off of expected wake up times is a good option, but this may be different for every device.

I have some devices that never wake up. One is a door sensor that might not be active for days. What’s the criteria for making that unavailable? BTW, when entities become unavailable it’s impossible to interact with the device. This functionality has been very controversial, especially WRT to dead mains-powered devices (search for Ping thread). This should not be without certainty, which isn’t the case with battery devices. Because of this, I don’t think it would be a good idea for HA to do without better support from the driver.

There is an enhancement request in the driver to better detect dead devices, including battery. It’s not exactly simple, if you want to avoid false positives.

2 Likes

Thanks for the yaml, i’ll take a look at that.
I do have an automation to poll the battery level for both devices, but it sounds like that’s not enough. At the time the unit stopped changing to “awake” the battery was still reporting 78%. I also have no report of the low battery entity changing.

Polling the battery isn’t effective on its own because if the battery device stays offline, you’ll just never get an answer back.

BTW, Z-Wave JS already automatically refreshes stale battery values, and my 1st gen ZCOMBO reports battery on its own.

1 Like

Yeah, I thought the First Alert would change the “low battery level” to “low” when the battery would be low regardless of what the battery level reports. Is that changed by First Alert device or is it just based on what the battery level is within HA?

So looking at the logs from both devices, it appears one died a week ago, and the other about 1.5 months ago. I was able to go back and correlate basically when the First Alert starts chirping because of low battery to when the hourly “awake” messages stop. The battery still reported 78% and the “low battery level” never changed from just before that. Is that expected? This is why I was really confused why the First Alert appear to die without noticing. I thought the battery level would be much lower % and I thought the “low battery level” would change to “low”. When the batteries were replaced with bad batteries the First Alert device reported 0% battery and “low battery level” changed to low.

On top of that, when the detector is removed from the wall, does any one know if a message is sent for that?
Maybe the unit was removed from the wall and batteries pulled so no messages were sent?

“low battery” is reported by the device.

SERIAL « 0x011100a8000001000a0380035c00c7007f7f56                            (19 bytes)
SERIAL » [ACK]                                                                   (0x06)
CNTRLR   [Node 010] [~] [Battery] level: 92 => 92                          [Endpoint 0]
CNTRLR   [Node 010] [~] [Battery] isLow: false => false                    [Endpoint 0]
DRIVER « [Node 010] [REQ] [BridgeApplicationCommand]
         │ RSSI: -57 dBm
         └─[BatteryCCReport]
             level:  92
             is low: false

From the tech doc (search for BRK_ZCOMBO_Z-Wave_Specification_11.0) I have for the gen2 ZCOMBO:

On top of that, when the detector is removed from the wall, does any one know if a message is sent for that?

The devices don’t have built-in shock/tilt sensors. There is a malfunction notification, but that doesn’t include moving the sensor around (I tried).

Maybe the unit was removed from the wall and batteries pulled so no messages were sent?

If the batteries were removed, it would certainly have a tough time sending any messages. :stuck_out_tongue:

There’s no tamper sensor for just pulling out the battery drawer. The battery drawer does have a simple lock mechanism.

1 Like

Thanks for all the details. What/Where is the tech doc to see this information? Ultimately, I would have never thought that 75% battery is considered low or when the batteries should be replaced. So I’ll update that in my automations. I would also never assume or think the unit would chirp locally before sending the “low” battery indicator. For good design, when chirping is enabled the low battery message indicator should also be sent so you know it’s chirping remotely.

So it sounds like what I saw was normal. The units started chirping at 77% (which they were at) but I never received the “Low battery level” message because the units were removed from the wall and batteries removed before the battery actually dipped below 75%. Poor design choice by First Alert. And lack of knowledge of what the battery levels meant on my part.

Thanks feshcoast! for all the details!

Search for BRK_ZCOMBO_Z-Wave_Specification_11.0. There are a couple of download links. Seems First Alert removed it from their site.

Agreed, current implementation doesn’t make much sense. Probably configuring an alert in HA with something over 78% would be the way to go then.

2 Likes

I do this to determine when the battery was last updated

template:
  - trigger:
      - platform: zwave_js.value_updated
        entity_id:
          - sensor.garage_sensor_battery_level
        command_class: 128
        property: level
    sensor:
      - name: "garage_sensor_battery_last_updated"
        state: "{{now().strftime('%Y-%m-%d %H:%M:%S')}}"

recorder:
  include:
    entities:
      - sensor.garage_sensor_battery_last_updated

Alert if it hasn’t reported in a couple of days. And then a dashboard

2 Likes

I’m quite new to HA and just added the 2nd Gen First Alert detector.

Right now I’m monitoring on my dashboard:
binary_sensor.zcombo_g_smoke_co_alarm_smoke_detected
binary_sensor.zcombo_g_smoke_co_alarm_carbon_monoxide_detected
sensor.zcombo_g_smoke_co_alarm_battery_level

I’d like to set up an alert for these. Has anyone been able to test and make sure these are the correct entities?

You don’t need to know the specific entities you can just do device triggers:

alias: Notification - Detector CO
description: ""
trigger:
  - type: co
    platform: device
    device_id: REDACTED
    entity_id: REDACTED
    domain: binary_sensor
condition: []
action:
  - service: notify.mobile_app_REDACTED_phone
    data:
      data:
        ttl: 0
        priority: high
      title: ☠☠☠ CO DETECTED IN HOUSE ☠☠☠
      message: " "
mode: single