First Alert Smoke Detector and Carbon Monoxide Alarm Setup

Version: 0.77.2
Type: Docker, so this might be slightly different in HASS.

I’ve been in the process of moving everything z-wave from SmartThings over to Home Assistant. I didn’t have any major problems with SmartThings, but got tired of dealing with the hacky MQTT bridge that didn’t always seem to work as expected. The last item to move was the First Alert detectors: they also happened to be the biggest pain in the ass. I pulled this from a few different sources and didn’t really document the process, so I apologize to anyone I might have grabbed bits and pieces from without giving them credit.

Step 1: removing them from SmartThings

This was actually the easiest part. Select General Exclusion from the SmartThings app, pull the battery tray on the detector, hold down the test button, and plug the tray back in while you’re holding down the button. Wait about 2 seconds and let go of the button. It’ll beep one and you should see it removed from SmartThings.

Step 2: adding them to Home Assistant

Including them was easy. Figuring out why nothing seemed to work was a whole other problem. To include them, go into the z-wave configuration panel and select Add Node Secure. Pull the battery tray, hold down the test button, and plug the tray back in while holding the button. Wait about 2 seconds and let go of the button. You should hear a beep after a few seconds. If you’re like me and want to know what it’s doing, you can tail the OZW_Log.txt file to see what’s happening.

After it’s added, you’ll see it in the list of devices, but the nodes will show up as unknown. Apparently the z-wave component isn’t sure what to do with these. At this point you’ll need to manually edit the zwcfg_xyz123.xml file and plug in some details. See the “Node:X” value that’s listed in the nodes while you’re in the z-wave configuration panel? You’ll need the number associated with the First Aler. Edit the zwcfg_xyz123.xml file and add the following with your other nodes:

<Node id="16" name="" location="" basic="4" generic="161" specific="0" type="Alarm Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" secured="true" query_stage="CacheLoad">
		<Manufacturer id="138" name="First Alert">
			<Product type="1" id="2" name="ZCombo Smoke and Carbon Monoxide Detector" />
		</Manufacturer>
		<CommandClasses>
			<CommandClass id="32" name="COMMAND_CLASS_BASIC" version="1" request_flags="4" after_mark="true" innif="true" mapping="113">
				<Instance index="1" />
			</CommandClass>
			<CommandClass id="112" name="COMMAND_CLASS_CONFIGURATION" version="1" request_flags="4" innif="true">
				<Instance index="1" />
				<Value type="list" genre="config" instance="1" index="1" label="Send double alarm messages" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" vindex="0" size="1">
					<Help>Causes the device to send double alarm messages.</Help>
					<Item label="Disable" value="0" />
					<Item label="Enable" value="1" />
				</Value>
			</CommandClass>
			<CommandClass id="113" name="COMMAND_CLASS_ALARM" version="1" request_flags="2" innif="true">
				<Instance index="1" />
				<Value type="byte" genre="user" instance="1" index="0" label="Alarm Type" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="13" />
				<Value type="byte" genre="user" instance="1" index="1" label="Alarm Level" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="255" />
			</CommandClass>
			<CommandClass id="114" name="COMMAND_CLASS_MANUFACTURER_SPECIFIC" version="1" request_flags="4" innif="true">
				<Instance index="1" />
			</CommandClass>
			<CommandClass id="128" name="COMMAND_CLASS_BATTERY" version="1" request_flags="4" innif="true">
				<Instance index="1" />
				<Value type="byte" genre="user" instance="1" index="0" label="Battery Level" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="91" />
			</CommandClass>
			<CommandClass id="132" name="COMMAND_CLASS_WAKE_UP" version="1" request_flags="2">
				<Instance index="1" />
				<Value type="int" genre="system" instance="1" index="0" label="Wake-up Interval" units="Seconds" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="-2147483648" max="2147483647" value="3600" />
			</CommandClass>
			<CommandClass id="133" name="COMMAND_CLASS_ASSOCIATION" version="1" request_flags="4" innif="true">
				<Instance index="1" />
				<Associations num_groups="1">
					<Group index="1" max_associations="1" label="Lifeline" auto="true">
						<Node id="1" />
					</Group>
				</Associations>
			</CommandClass>
			<CommandClass id="134" name="COMMAND_CLASS_VERSION" version="1" request_flags="4" innif="true">
				<Instance index="1" />
				<Value type="string" genre="system" instance="1" index="0" label="Library Version" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="6" />
				<Value type="string" genre="system" instance="1" index="1" label="Protocol Version" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="3.52" />
				<Value type="string" genre="system" instance="1" index="2" label="Application Version" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0.05" />
			</CommandClass>
		</CommandClasses>
</Node>

You’ll want to change that Node id="16" at the beginning to match the number for the previous step, otherwise this isn’t going to work. Now, because the naming convention isn’t always the best with z-wave, you’ll want to take a few more steps to clean this up a bit. But first:

docker restart home-assistant

You’ll then need to wait for z-wave to come back up again. We’ll do this a few times.

Step 2: clean up the names in Home Assistant

I know this is supposed to be done in the UI, but I’m happy making changes directly in the file. Go into your Home Assistant directory and type vi .storage/core.entity_registry so we can tweak a few items. Scroll down to the bottom, and you should see three entries for your First Alert device: the root device, the alarm type, and the alarm level. It’ll look something like this:

            {
                "config_entry_id": null,
                "device_id": null,
                "entity_id": "zwave.first_alert_upstairs",
                "name": "Smoke Upstairs",
                "platform": "zwave",
                "unique_id": "node-16"
            },
            {
                "config_entry_id": null,
                "device_id": null,
                "entity_id": "sensor.first_alert_upstairs_alarm_type",
                "name": "Smoke Upstairs Alarm Type",
                "platform": "zwave",
                "unique_id": "16-72057594312409089"
            },
            {
                "config_entry_id": null,
                "device_id": null,
                "entity_id": "sensor.first_alert_upstairs_alarm_level",
                "name": "Smoke Upstairs Alarm Level",
                "platform": "zwave",
                "unique_id": "16-72057594312409105"
            }

Mine probably looks much cleaner than what you’re seeing. By default, it’ll use a long-ass name related to the full product description. I shorted them to something a bit more manageable and added a friendly name. Yes, I’m still aware this was supposed to be done through the UI, but this was much faster. You’ll will need the “Type” and “Level” names in the next step. And now our favorite step again:

docker restart home-assistant

Step 3: ensuring they show up in states.

Check your states to ensure they look something like this:

sensor.first_alert_upstairs_alarm_level 255
sensor.first_alert_upstairs_alarm_type 13

As best as I could tell, that means they’re idle. However, to figure out what they’re really trying to say, you’ll need templating to keep your sanity. Basically Type 1 is smoke, Type 2 is CO, and Level 255 combined with either means you might want to evacuate the household. But back to the templates:

smoke_upstairs_status:
      friendly_name: 'Smoke Upstairs Status'
      value_template: >-
        {% if is_state("sensor.first_alert_upstairs_alarm_level", "255") and is_state("sensor.first_alert_upstairs_alarm_type", "1")%}
          smoke
        {% elif is_state("sensor.first_alert_upstairs_alarm_level", "255") and is_state("sensor.first_alert_upstairs_alarm_type", "2")%}
          co
        {% else %}
          idle
        {% endif %}
      icon_template: >-
        {% if is_state("sensor.first_alert_upstairs_alarm_level", "255") and is_state("sensor.first_alert_upstairs_alarm_type", "1")%}
          mdi:fire
        {% elif is_state("sensor.first_alert_upstairs_alarm_level", "255") and is_state("sensor.first_alert_upstairs_alarm_type", "2")%}
          mdi:cloud-outline
        {% else %}
          mdi:smoke-detector
        {% endif %}

It basically says create a new sensor called smoke_upstairs_status. If it’s a 1 and a 255, then smoke has been detected. If it’s a 2 and a 255, that means CO has been detected. You can now use those values in automations, e.g. IF smoke_upstairs_status == smoke THEN run away. Personally I use them in NodeRed to turn on all the lights, unlock the front door, trigger a loud siren alarm, and send Pushover alerts to everyone’s phone. Kind of difficult to ignore at that point.

But on to the last piece: the battery template. It helps to know when they need to be changed.

smoke_upstairs_battery_template:
      friendly_name: 'Smoke Upstairs Battery'
      value_template: '{{ states.zwave.first_alert_upstairs.attributes.battery_level }}'
      icon_template: 'mdi:battery-outline'
      unit_of_measurement: '%'

…and one more time:

docker restart home-assistant

Hopefully this was helpful and will save everyone from piecing all of this together. At this point smoke_upstairs_status will spit out either smoke, co, or idle for automation components.

24 Likes

This is helpful. Thanks for sharing. I am brand new so forgive me if the questions are basic.

  • Does the smoke_upstairs_status code go in sensor in configuration.yaml?
  • Would you mind adding a trigger/action that you use? Im trying to get a phone notification but I can’t seem to get everything to click.

I’ve got all of my sensors in a directory names sensors that’s referenced in configuration.yaml like this:

sensor: !include_dir_merge_list sensors

In the sensors directory there’s a templates.yaml file that starts with the following:

- platform: template
  sensors:

…with the code in my original post listed after that.

Would you mind adding a trigger/action that you use? Im trying to get a phone notification but I can’t seem to get everything to click.

I actually use Node-RED for all of my automations. It wouldn’t make much sense since it’s custom to my environment, but I use the Pushover Node-RED module for sending alerts. There’s a bunch of notification platforms though, so take your pick. I’ve tried Telegraph, Pushbullet, Slack, and a few others, but Pushover has been rock solid and has all of the options that I need. Hope this helps.

This was incredibly useful! Thanks for this.

One thing to add: if you do a test, the alarm type will change to 12 and the alarm level will change to zero. This won’t affect the functioning of the sensor template mentioned above, but these values can be useful if you want to execute any kind of action based on someone hitting the test button. It will also report type 12 twice: once for the smoke test, and once for the CO test.

Also it does not return to alarm type 13 and alarm level 255 (the default) after the test until the device wakes up and sends updated values (default one hour); I assume it probably would after a battery pull. So I’m guessing 12 + 0 means there was a previously successful test within the last wakeup period and power cycle, and 13 + 255 means back to idle.

hi, thank you so much for putting this together. When I paired my devices, I only see one of the 3 entries in the core.entity_registry file. Should I add the other 2 entries by copying yours and changing the node? Thank you.

Anyone having issues with their detector beeping every 6ish hours? My battery is reporting at 91% so I don’t think that is the issue. Just got this detector last week.

Is it just a chirp or a full blown alarm? Either way, I’ve had my alarm for over a year and haven’t seen any behavior like that. If it were the low battery alarm it should chirp once every minute.

The battery level value will also only update by either running a test, or manually waking up the alarm. I have personally never seen the battery level go below 90%, even when the battery alarm starts chirping, but maybe I haven’t been testing often enough.

I’d probably put in a set of brand new batteries and see if the behavior continues. If so, maybe it’s a bad device.

Sorry for the false alert, turns out the issue was with my other smoke detectors not the new one.

This was really helpful. I edited the zwcfg xml file and edited for my particular node value. But when I went to edit the core.entity_registry file, I only saw two entries… one for the root device, the second for the alarm_type. Any suggestion for obtaining the alarm_level to also appear in the core.entity_registry file?

Did you figure this out? When I follow these steps, I don’t get the sensors listed under states.

Noob here, but think I might have some useful contributions. Going with the verbose version here.

My setup thus far:
Raspberry Pi 3 B+
hassos 2.11
homeassistant 0.92.1
Aeotec Z-Stick Gen5
2X First Alert Smoke/CO2 z-wave enabled

On first thought I was going to describe everything I went through to add the First Alarm detectors… but I’ll spare you dear reader and leave that for my techno-therapist.

I don’t think these bad boys every fully pair after first pairing. Albeit, this is from two devices over three pairings experience. Somebody who’s gone through this pain and wrote about it somewhere and for whom I’m going to fail to give recognition to (sorry!) indicated that these detectors are battery sensitive (for arguably good reason) and will only remain awake for only 30 seconds. That 30 seconds doesn’t seem to be enough time to pair AND transfer all the necessary information. This is why you may see only one or no entities for the node.

It seems you can awaken the detector by putting it back in pair mode (with battery bay open, hold test button and slide close – release button once it beeps [Also prepare yourself for the soul-shocking second beep that will occur ~5 seconds later]) and from within the Z-wave integration in HA have the node selected, click on refresh node and then heal node. I recommend tailing the OZW_log to see that one command has completed before starting the next. I’m not sure which of these is cause the entites to update; maybe one or neither is necessary, but it does seem to cause them to appear. My second detector required two rounds of this. Also, as OP noted, restart HA between each pairing/update.

Mine seem to settle into “CacheLoad” status once they loaded both Type and Level entities. For me, both devices are reporting 13 for type and 255 for level; I’ll see if this makes sense with the OP’s template once I re-add one so it can show as secured="true" in zconfig_*** :unamused:.

3 Likes

D8R, your contribution was very useful. I couldn’t get two of my five detectors showing the proper entities, therefore couldn’t get them to report anything useful. Your procedure (battery pull, press button, battery insert, release button, wait for 2 beeps, refresh that node, heal that node, wait a few seconds, restart HA) worked like a charm. Thanks so much for leaving this note.

1 Like

I have three of these smoke detectors and I have my template configured based on your sample.
However, whenever I restart home assistant I get notifications that I have a smoke/co event. I assume that this is because on restart, my system does not have values yet from the zwave smoke/co detector. Does anyone have the same issue, is there anyway to build in a delay or set these template values to say idle until the zwave network is up?

Thanks,
Dan

Unfortunately I don’t have an answer here. I’d switched all of my Z-Wave back to SmartThings once I had Home Assistant Cloud. I could never get Z-Wave stable in HA to my liking. The codes that these smoke detectors would spit out didn’t always make sense either. The codes are listed here if you’re feeling adventurous.

They looks somewhat similar to what I have above:

status "smoke": "command: 7105, payload: 01 FF"
status "clear": "command: 7105, payload: 01 00"

For example, 01 FF translates to 01 255 aka smoke detected, which matches the original template I’d put together.

Thanks. After posting I had a new thought and I think I see what is going on. I have a nodered node watching for a state change on this sensor and then sending a notification to telegram on that state change…so when homeassistant reboots…it sets to idle and that is why the notification is being sent. Looks like maybe I need to tweak the nodered side of things to only send the notification when its a Smoke or CO i.e. don’t alert when in idle state.

Dan

Pairing these z-wave First Alert Smoke and Carbon Alarms in Home Assistant drove me to drink more than a couple bottles. And this is not like a door, we need these to be able to work and have the proper readings.

I am running HA on hassio on a pi3b+ with an aeotec z-wave stick. Have over 40 devices and running smooth, these smoke detectors devices were a challenge. But we as a community always prevail, bada-bing!

First off, these things go to sleep in about 10 seconds from the time you pair. So when you check the status in the z-wave network you will see them idle or cache loaded, but they are sleeping.

1 - Tail the last 40 lines or so of the Z-Wave OZW Log. This is a must.
2 - Get the device ready with the batteries in the proper way and the tray out.
3 - Hit the Add Node Secure button in the Z-Wave network management console.
4 - Flip to the log and you will see that you hit the add button
5 - Hold the Test/Silence button down on the device and put the tray in, you will hear a beep, then immediately let go.
6 - Keep watching the log, when you see it stop, go to configuration, general, server management and click restart.

When you go in to Z-Wave Devices after you reboot, it will be idle or in a wacky state.

Now it is time to get the config, lovelace and node red alerts working.

This is my configuration.yaml that I wrote to include all the states icons for a good visual on the dash.

binary_sensor:

  • platform: template
    sensors:
    smoke_garage_status:
    friendly_name: ‘Garage Smoke Detector Status’
    value_template: >-
    {% if is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_level_2”, “255”) and is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_type_2”, “1”)%}
    smoke
    {% elif is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_level_2”, “255”) and is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_type_2”, “2”)%}
    co
    {% elif is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_level_2”, “0”) and is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_type_2”, “12”)%}
    test
    {% elif is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_level_2”, “255”) and is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_type_2”, “13”)%}
    idle
    {% else %}
    idle
    {% endif %}
    icon_template: >-
    {% if is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_level_2”, “255”) and is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_type_2”, “1”)%}
    mdi:fire
    {% elif is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_level_2”, “255”) and is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_type_2”, “2”)%}
    mdi:cloud-outline
    {% elif is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_level_2”, “0”) and is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_type_2”, “12”)%}
    mdi:alert-octagram
    {% elif is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_level_2”, “255”) and is_state(“sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_type_2”, “13”)%}
    mdi:smoke-detector
    {% endif %}

After you update your configuration.yaml, always go to configuration, general and check config (HA 0.96.3+ new versions need to enable advanced options for this check). Once you have a green Configuration Valid! Go on to the next step.

REBOOT again just as you did above.

Open Lovelace, add a manual card and paste this code. Keep in mind you will have to edit the sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_level_2 and sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_type_2 to _3 or maybe no _number at all. This value is your entity_id

entities:

  • entity: binary_sensor.smoke_garage_status
  • entity: >-
    sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_level_2
  • entity: >-
    sensor.first_alert_brk_brands_inc_zcombo_smoke_and_carbon_monoxide_detector_alarm_type_2
    show_header_toggle: false
    title: Smoke
    type: entities

At this point you should see a Smoke card with a picture that says Garage Smoke Status Off with a circle icon and Alarm Level value of 0 and Alarm Type value of 0, this means it is brand new. Now hold the test button in, you will hear a beep then the 2 values will change and the icon will update to test.

Once the test is over, the status will stay in idle mode for about 2-4 hours. If you want to speed this up, simple slide the battery tray out. Now that the batteries are out, hit the test button, you may or may not hear a faint beep to fully discharge the device. Now just push the tray back in and the device will be back to normal. What a pain, I really hopes this helps. There was nothing step by step in once place that I could find so I put this all together. Figured I would document in case I needed to reproduce. Good Luck. Now you just add to node red for all the different values.

5 Likes

First of all thank you so much for putting in the time to figure this out with these stupid smoke alarms; I’ve been putting off moving them from ST because I didn’t know how to make them actually show me useful info. I haven’t worked with templates very much so this was a learning experience, I don’t know why your quotes threw errors for me but I’ve pasted my code below in YAML markup so it’s easier for the next person to copy and paste with all the right spacing and indentations, just change the sensor names as appropriate. (FYI it’s 3 hash marks eg. ``` wrapped around your code to format)

- platform: template
  sensors:
    basement_smoke_status:
      friendly_name: basement smoke status
      value_template: >-
        {% if is_state('sensor.basement_smoke_alarm_level', '255') and is_state('sensor.basement_smoke_alarm_type', '1') %}
          smoke
        {% elif is_state('sensor.basement_smoke_alarm_level', '255') and is_state('sensor.basement_smoke_alarm_type', '2') %}
          co
        {% elif is_state('sensor.basement_smoke_alarm_level', '0') and is_state('sensor.basement_smoke_alarm_type', '12') %}
          test
        {% elif is_state('sensor.basement_smoke_alarm_level', '255') and is_state('sensor.basement_smoke_alarm_type', '13') %}
          idle
        {% endif %}
      icon_template: >- 
        {% if is_state('sensor.basement_smoke_alarm_level', '255') and is_state('sensor.basement_smoke_alarm_type', '1') %}
          mdi:fire
        {% elif is_state('sensor.basement_smoke_alarm_level', '255') and is_state('sensor.basement_smoke_alarm_type', '2') %}
          mdi:cloud-outline
        {% elif is_state('sensor.basement_smoke_alarm_level', '0') and is_state('sensor.basement_smoke_alarm_type', '12') %}
          mdi:alert-octagram
        {% elif is_state('sensor.basement_smoke_alarm_level', '255') and is_state('sensor.basement_smoke_alarm_type', '13') %}
          mdi:smoke-detector
        {% endif %}
8 Likes

Just a big THANK YOU for this thread, would have never figured it out myself !

This is great! I only had to remove the “binary…” part of the sensor definition in the Lovelace card to get it to work. If you want to go even further, one could put the indications in for when alarms are silenced (makes the level go from 255 to 0, so similar to “test”). Thanks for figuring this out.
EDIT: Does anyone know if the battery status is sent each time the unit wakes up to send the alarm level and status? Mine is still at the default (every hour), but the battery data, when I click on the entity info that shows the history graph, says “3 days ago”. The alarm entities show recent time (within an hour always).
Thanks!

Hello, i have two sets of first alert co + smoke sensors i am trying to pair with my Everspring SA413 Z-Wave Plus USB Adapter Stick. They are however not even being detected. My Yale lock pairs fine on the other hand.

i just dont see much activity in the logs and no new node is added in the list. here is a dump of my log when i try to “add secure node” and then insert the batteries with test button presses and immediately release after a beep. i wait for log to update but nothing happens and restearing HASSIO also doesnt make any new nodes appear.

2019-09-28 01:20:37.387 Info, contrlr, FUNC_ID_ZW_ADD_NODE_TO_NETWORK:
2019-09-28 01:20:37.387 Info, contrlr, ADD_NODE_STATUS_LEARN_READY
2019-09-28 01:20:37.387 Detail, Node001,   Expected callbackId was received
2019-09-28 01:20:37.387 Detail, Node001,   Expected reply was received
2019-09-28 01:20:37.387 Detail, Node001,   Message transaction complete
2019-09-28 01:20:37.387 Detail,
2019-09-28 01:20:37.387 Detail, contrlr, Removing current message
2019-09-28 01:20:37.387 Detail, Notification: ControllerCommand - Waiting
2019-09-28 01:20:37.388 Info, WriteNextMsg Controller nothing to do

any help will be appreicated.


UPDATE: I might have overlooked one very important detail. i bought the sensors from US. and The stick and everything else is UK. could that be a reason