Smoke alarms

...has been postponed until June 21st 2021. If we do come out with this technology, it will be highlighted on our website at that time

A potential product launch one year from now...hmmm...I'm not so sure I would want to put a lot of eggs in that basket. :wink:

1 Like

So first all the concerts I wanted to go to this Summer get delayed til Summer 2021, and now we'll have to wait til then to maybe see a hard-wired Z-COMBO? Thanks a lot covid... :face_with_symbols_over_mouth:

2 Likes

I received in my Heiman Z-Wave smokie.

It detected fine as a Generic Z-Wave Smoke Detector with the new in-built driver. But not getting events when tested.

Here's my version of a driver - converted from SmartThings and modified a good bit. I cant get HE to automagically detect my driver - so to use mine you need to change driver from the Generic to this one. I deselected all security FYI.

/**
 *  
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 *
 * Modified from the Smartthings Generic Z-Wave Device Handler
 *
 */
 
metadata {
	definition (name: "Heiman Z-Wave Smoke Detector", namespace: "Scruffy-sjb", author: "Scruffy-sjb and SmartThings", genericHandler: "Z-Wave") {
		capability "Smoke Detector"
		capability "Sensor"
		capability "Battery"
		
		command "resetToClear"
		command "resetBatteryReplacedDate"
		
		attribute "smoke", "string"
        attribute "batteryLastReplaced", "String"

		fingerprint deviceId: "0x1000", mfr: "0260", inClusters: "0x5E,0x85,0x8E,0x59,0x55,0x86,0x72,0x5A,0x73,0x80,0x9F,0x71,0x84,0x6C", deviceJoinName: "Heiman Z-Wave Smoke Detector HSISA-Z"
		fingerprint mfr: "0138", prod: "0001", model: "0001", deviceJoinName: "First Alert Smoke Detector" //First Alert Smoke Detector
		fingerprint mfr: "026F", prod: "0001", model: "0001", deviceJoinName: "FireAngel Smoke Detector" //FireAngel Thermoptek Smoke Alarm
		fingerprint mfr: "013C", prod: "0002", model: "001E", deviceJoinName: "Philio Smoke Detector" //Philio Smoke Alarm PSG01
		fingerprint mfr: "0154", prod: "0004", model: "0010", deviceJoinName: "POPP Smoke Detector" //POPP 10Year Smoke Sensor
		fingerprint mfr: "0154", prod: "0100", model: "0201", deviceJoinName: "POPP Smoke Detector" //POPP Smoke Detector with Siren
	}
}

def installed() {
	def cmds = []
  //This interval allows us to miss one check-in notification before marking offline
	cmds << createEvent(name: "checkInterval", value: checkInterval * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
	createSmokeEvents("smokeClear", cmds)
	cmds.each { cmd -> sendEvent(cmd) }
	
	if (!device.currentState('batteryLastReplaced')?.value)
		resetBatteryReplacedDate(true)
		
	response(initialPoll())
}

def getCheckInterval() {
	def checkIntervalValue
	switch (zwaveInfo.mfr) {
		case "0138": checkIntervalValue = 2  //First Alert checks in every hour
			break
		default: checkIntervalValue = 8
	}
	return checkIntervalValue
}


def updated() {
  //This interval allows us to miss one check-in notification before marking offline
	sendEvent(name: "checkInterval", value: checkInterval * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID])
}

def getCommandClassVersions() {
	[
			0x71: 3, // Alarm
			0x72: 1, // Manufacturer Specific
			0x80: 1, // Battery
			0x84: 1, // Wake Up
	]
}


def parse(String description) {
	def results = []
	if (description.startsWith("Err")) {
	    results << createEvent(descriptionText:description, displayed:true)
	} else {
		def cmd = zwave.parse(description, commandClassVersions)
		if (cmd) {
			zwaveEvent(cmd, results)
		}
	}
	log.debug "'$description' parsed to ${results.inspect()}"
	return results
}

def createSmokeEvents(name, results) {
	def text = null
	
	switch (name) {
		case "smoke":
			text = "$device.displayName smoke was detected!"
			// these are displayed:false because the composite event is the one we want to see in the app
			results << createEvent(name: "smoke", value: "detected", descriptionText: text)
			log.info text
			break
		case "tested":
			text = "$device.displayName was tested"
			results << createEvent(name: "smoke", value: "tested", descriptionText: text)
			log.info text
			break
		case "smokeClear":
			text = "$device.displayName smoke is clear"
			results << createEvent(name: "smoke", value: "clear", descriptionText: text)
			name = "clear"
			log.info text
			break
		case "testClear":
			text = "$device.displayName test cleared"
			results << createEvent(name: "smoke", value: "clear", descriptionText: text)
			name = "clear"
			log.info text
			break
	}
}

def zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport cmd, results) {
	if (cmd.notificationType == 0x01) {  // Smoke Alarm
		switch (cmd.event) {
			case 0x00:
			case 0xFE:
				createSmokeEvents("smokeClear", results)
				break
			case 0x01:
			case 0x02:
				createSmokeEvents("smoke", results)
				break
			case 0x03:
				createSmokeEvents("tested", results)
				break
		}
	} else switch (cmd.v1AlarmType) {
	
		case 1:
			createSmokeEvents(cmd.v1AlarmLevel ? "smoke" : "smokeClear", results)
			break
		case 12:  // test button pressed
			createSmokeEvents(cmd.v1AlarmLevel ? "tested" : "testClear", results)
			break
		case 13:  // sent every hour -- not sure what this means, just a wake up notification?
			if (cmd.v1AlarmLevel == 255) {
				results << createEvent(descriptionText: "$device.displayName checked in", isStateChange: false)
			} else {
				results << createEvent(descriptionText: "$device.displayName code 13 is $cmd.v1AlarmLevel", isStateChange: true, displayed: false)
			}

			// Clear smoke in case they pulled batteries and we missed the clear msg
			if (device.currentValue("smoke") != "clear") {
				createSmokeEvents("smokeClear", results)
			}

			// Check battery if we don't have a recent battery event
			if (!state.lastbatt || (now() - state.lastbatt) >= 48 * 60 * 60 * 1000) {
				results << response(zwave.batteryV1.batteryGet())
			}
			break
		default:
			results << createEvent(displayed: true, descriptionText: "Alarm $cmd.v1AlarmType ${cmd.v1AlarmLevel == 255 ? 'activated' : cmd.v1AlarmLevel ?: 'deactivated'}".toString())
			break
	}
}

// SensorBinary and SensorAlarm aren't tested, but included to preemptively support future smoke alarms
def zwaveEvent(hubitat.zwave.commands.sensorbinaryv2.SensorBinaryReport cmd, results) {
	if (cmd.sensorType == hubitat.zwave.commandclasses.SensorBinaryV2.SENSOR_TYPE_SMOKE) {
		createSmokeEvents(cmd.sensorValue ? "smoke" : "smokeClear", results)
	}
}

def zwaveEvent(hubitat.zwave.commands.sensoralarmv1.SensorAlarmReport cmd, results) {
	if (cmd.sensorType == 1) {
		createSmokeEvents(cmd.sensorState ? "smoke" : "smokeClear", results)
	}
	
}

def zwaveEvent(hubitat.zwave.commands.wakeupv1.WakeUpNotification cmd, results) {
	results << createEvent(descriptionText: "$device.displayName woke up", isStateChange: false)
	if (!state.lastbatt || (now() - state.lastbatt) >= 56*60*60*1000) {
		results << response([
				zwave.batteryV1.batteryGet().format(),
				"delay 2000",
				zwave.wakeUpV1.wakeUpNoMoreInformation().format()
			])
	} else {
		results << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
	}
}

def zwaveEvent(hubitat.zwave.commands.batteryv1.BatteryReport cmd, results) {
	def map = [ name: "battery", unit: "%", isStateChange: true ]
	state.lastbatt = now()
	if (cmd.batteryLevel == 0xFF) {
		map.value = 1
		map.descriptionText = "$device.displayName battery is low!"
	} else {
		map.value = cmd.batteryLevel
	}
	results << createEvent(map)
}

def zwaveEvent(hubitat.zwave.commands.securityv1.SecurityMessageEncapsulation cmd, results) {
	def encapsulatedCommand = cmd.encapsulatedCommand(commandClassVersions)
	state.sec = 1
	log.debug "encapsulated: ${encapsulatedCommand}"
	if (encapsulatedCommand) {
		zwaveEvent(encapsulatedCommand, results)
	} else {
		log.warn "Unable to extract encapsulated cmd from $cmd"
		results << createEvent(descriptionText: cmd.toString())
	}
}

def zwaveEvent(hubitat.zwave.Command cmd, results) {
	def event = [ displayed: false ]
	event.linkText = device.label ?: device.name
	event.descriptionText = "$event.linkText: $cmd"
	results << createEvent(event)
}

private command(hubitat.zwave.Command cmd) {
	if (zwaveInfo?.zw?.contains("s")) {
		zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
	} else {
		cmd.format()
	}
}

private commands(commands, delay = 200) {
	delayBetween(commands.collect { command(it) }, delay)
}

def initialPoll() {
	def request = []
	// check initial battery and smoke sensor state
	request << zwave.batteryV1.batteryGet()
	request << zwave.sensorBinaryV2.sensorBinaryGet(sensorType: zwave.sensorBinaryV2.SENSOR_TYPE_SMOKE)
	commands(request, 500) + ["delay 6000", command(zwave.wakeUpV1.wakeUpNoMoreInformation())]
}

def resetBatteryReplacedDate(paired) {
	def newlyPaired = paired ? " for newly paired sensor" : ""
	sendEvent(name: "batteryLastReplaced", value: new Date())
	log.debug "Setting Battery Last Replaced to current date${newlyPaired}"
}

def resetToClear() {
	sendEvent(name:"smoke", value:"clear")
    log.debug "Resetting to Clear..."
}

/**
 *  Default event handler -  Called for all unhandled events
 */
def zwaveEvent(hubitat.zwave.Command cmd) {
    if (state.debug) {
	log.debug "Unhandled in this driver: $cmd"
	createEvent(descriptionText: "${device.displayName}: ${cmd}")
    }
    else {
	[:]
    }
}
3 Likes

Hi @simon

Thanks my Z-wave smoke detector is working now with the updates platform drivers. If a press the test button, I get "smoke detected" for about half a second then all clear message. I might give yours a try as well.

Thanks once again for the effort.

Maybe the link was bad so either HEIMAN Zigbee Smoke Detector - Domótica Económica or https://www.domoticaeconomica.com/en/shop/smoke-detector-zigbee-xiaomi-honeywell/ Anyone got thoughts on which one is better?

As an update - this device really works well.

We're having work done in our house (our kitchen remodel) and yesterday the dust from the re-nailing of the subfloor after the old tile was removed set off the new smoke alarms, which was picked up by the FF-ZWAVE5 and in turn set off my rules on Hubitat. The alert on my phone came under a second after the smoke alarms starting blaring, and Alexa announced things also.

Although my wife was not pleased with Alexa saying "Fire! Fire! Run for the hills". I'll have to change that.

4 Likes

What do you mean she wasn't pleased?! I love that...they should bake that warning into the firmware. :wink:

2 Likes

A feature I also like about these smoke detectors.
Another advantage is the Dual Spectrum Optical sensors, these are the best option security wise. They use two lasers - one that can see large particles and the other to detect small particles. They are good at detecting fast burning fires as well as slow smouldering fire with thick smoke.

In my research I also stumbled upon the Fibaro Smoke alerts, they seem the cheapest smart Hubitat compatible solution I've found so far.

1 Like

Hi all, somehow related question. I now have 4x Heiman HS1SA Zigbee smoke detectors using drivers by @simon (thanks for these!). Do you guys know if there is an app or a way to write a rule that would trigger all 4 alarms if any / only one of them detects smoke?

TIA!

Not that I know of.
From a communications point of view these devices are fast asleep most of the time.

Never heard of a zigbee (or z-wave) smoke detector that has a wireless interconnect function, which is essentially what you're asking for. Have to go with something like Nest Protect, or detectors with proprietary wireless interconnects, AFAIK (but I'm unfamiliar with what's available in the UK).

Yeah, the more research on this I am doing the more I am arriving at a conclusion I should probably leave my main smoke detectors dumb and mains-powered.

Initially I was hoping to replace all of my four dumb mains-powered, interconnected smoke detectors by 4x Heiman ZIgbee ones. And while they are compliant with British regulations as far as smoke detectors go, doing what I planned on doing wouldn't be compliant with British building regulations (as far as I can tell...). Looks like I need my smoke detectors to be mains-powered and interconnected.

So it looks like I will need to stay with mains-powered dumb detectors and only enhance the overall protection with Heiman Zigbeen ones...

2 Likes

If your driver has a test command you could trigger it from RM. It may only sound the alarm for a short period but should be easily programmed to re-sound until turned off.

Other than never giving false alarms, it’s one of the reasons I like the Nest so much. They are interconnected by design using thread, whether mains powered or the battery versions.

1 Like

There are FireAngel Zigbee and Z-Wave modules that work with their mains powered smoke detectors

Search for FireAngel Zigbee Module/FireAngel Z-Wave Module

But I am not sure if these can be interconnected other than via a mains loop

They also provide products with built in modules on their own wireless protocol that does support wireless interlinking and remote testing

Look up: FireAngel Pro Connected Smart Smoke Alarm, Mains Powered with Wireless Interlink and 10 Year Life Back-Up Battery, FP1640W2-R on Amazon

I got a Nexa z-wave smoke alarm ZSD-109. Has anyone got it working? I have tried different drivers but can't get it to work. I have tried different drivers and push the test button but no response from safety monitor

Well it seems to work with generic z-wave plus smoke driver. But trigger the test button on the device will not trigger safety monitor notifications. But with a real smoke test the alarm triggers and sent me the notifications.

Has anyone used the Fibaro Smoke Sensors? They look really nice, but they appear to only be available via distribution. I'm not sure if I want to go with these or the more readily available z-combo's.

That's really weird. Last time I called when I had a bad one, they just sent a new one out

I guess they just didn't like me? Whatever, never buying their bourgeois $100 smoke detectors again.