Linear Z-wave Siren device type needed

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:58 PM:
debug
Parse returned Battery Siren battery is 100%

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:58 PM:
debug
parse(zw device: 11, command: 8003, payload: 64 )

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:57 PM:
debug
sending battery refresh command

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:55 PM:
debug
Parse returned [Battery Siren switch is off, Battery Siren alarm is off]

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:55 PM:
debug
parse(zw device: 11, command: 2003, payload: 00 )

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:55 PM:
debug
testing siren

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:51 PM:
debug
Setting alarm to siren.

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:51 PM:
debug
Parse returned [Battery Siren switch is off, Battery Siren alarm is off]

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:51 PM:
debug
parse(zw device: 11, command: 2003, payload: 00 )

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:49 PM:
debug
Setting alarm to both.

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:48 PM:
debug
Setting alarm to strobe.

ddc456d1-0aa7-4b4d-b581-c74c0896f517
4:07:46 PM:
debug
Turning Alarm Off

Hmm, no errors. Does anything work? If you set a trigger in an app, does the siren go off? if so, does the off work? Does the test do anything.

No nothing happens I am trying everything I can, I donā€™t know what is going on with it. It changes status on app but does nothing with siren.

Any updates on the siren?

Thanks, Brandon

Iā€™m really at a loss at this point. I wish I could be more help. Maybe someone else here will have some ideas.

I also have this Linear Siren. Looking at the logs, it seems to send all the right commands, but the Siren doesnā€™t respond to the commands being sent. Using the generic ZWave Siren provides by Smartthings will make the siren sound, but it does not allow firing the strobe only and does not provide the ability to choose how long the siren sounds when it goes off.

Any further help with this siren would be awesome!

This version actually works with the built in security app. I need to stabilize and clean it up.

/**
 *  
 *
 *  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.
 *
 *  Linear Z-Wave Siren
 *
 *  Author: Kevin Tierney
 *  Date: 2015-07-30
 *  Updates by: Artak Kalantarian
 *  Date: 2015-10-13
 */
 

metadata {
	definition (name: "Linear Z-Wave Siren", namespace: "tierneykev", author: "Kevin Tierney") {
//		capability "Actuator"
        capability "Alarm"
        capability "Battery"
        capability "Polling"
        capability "Refresh"
        capability "Sensor"
		capability "Switch"
        
        command "strobe"
        command "siren"
        command "both"

        //Supported Command Classes
        //0x20-Basic ,0x25-Binary Switch ,0x70-Configuration , 0x72-Manufacturer Specific ,0x86-Version
//        fingerprint inClusters: "0x20,0x25,0x70,0x72,0x86"
         fingerprint deviceId:"0x1000", inClusters: "0x25,0x70,0x72,0x80,0x86"
//         0 0 0x1000 0 0 0 4 0x25 0x70 0x72 0x86
	}
   
	simulator {
		// reply messages
		reply "2001FF,2002": "command: 2002, payload: FF"
		reply "200100,2002": "command: 2002, payload: 00"
		reply "200121,2002": "command: 2002, payload: 21"
		reply "200142,2002": "command: 2002, payload: 42"
		reply "2001FF,delay 3000,200100,2002": "command: 2002, payload: 00"
	}

	tiles {
		standardTile("alarm", "device.alarm", width: 2, height: 2) {
			state "both", label:'alarm!', action:'alarm.siren', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
            state "siren", label:'siren!', action:'alarm.strobe', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
            state "strobe", label:'strobe!', action:'alarm.both', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"						
		}
 
        standardTile("off", "device.alarm", inactiveLabel: false, decoration: "flat") {
 			state "default", label:'Off', action:"off"
        } 
        standardTile("on", "device.alarm", inactiveLabel: false, decoration: "flat") {
 			state "default", label:'On', action:"on"
        } 
        valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") { 
			state "battery", label:'${currentValue}% battery', unit:""
		}
        standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
		}

       
		main "alarm"
        details(["alarm", "off", "on",  "battery","refresh"])
	}

	preferences {
    	input "autoStopTime", "enum", title: "Disarm Time",required:true,displayDuringSetup:true, options: ["30","60","120","Infinite"],default:'30'
	} 

}



def updated() {
		def autoStopTimeParameter = 0
        if (autoStopTime == '30') {
        	autoStopTimeParameter = 0
        } else if( autoStopTime == '60'){
        	autoStopTimeParameter = 1
        } else if (autoStopTime == '120') {
        	autoStopTimeParameter = 2
        } else if (autoStopTime == 'Infinite') {
        	autoStopTimeParameter = 3
        }
        log.debug "AutoStopTime - ${autoStopTimeParameter}"
	    zwave.configurationV1.configurationSet(parameterNumber: 1, size: 1, configurationValue: [autoStopTimeParameter])
}


//println org.codehaus.groovy.runtime.InvokerHelper.getVersion()


def strobe() {
	log.debug "Setting alarm to strobe."
    state.LastAlarmtype = 2
    zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [2]).format()
    sendEvent(name: "alarm", value: "strobe")
    on()
}

def siren() {
    log.debug "Setting alarm to siren."
    state.LastAlarmtype = 1
   sendEvent(name: "alarm", value: "siren")
   zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [1]).format()
    on()
}

def both() {
	log.debug "Setting alarm to both."
    state.LastAlarmtype = 0
    sendEvent(name: "alarm", value: "both")
	zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [0]).format()
    on()
}

def off() {
	log.debug "Ending Test"
	[
		zwave.basicV1.basicSet(value: 0x00).format(),
		zwave.basicV1.basicGet().format()
	]
}
def on() {
	log.debug "Ending Test"
	[
		zwave.basicV1.basicSet(value: 0xff).format(),
		zwave.basicV1.basicGet().format()
	]
}

def parse(String description) {

	def result = null
	def cmd = zwave.parse(description)
	log.debug "parse($description) - command is $cmd"
	if (cmd) {
		result = createEvents(cmd)
	}
	log.debug "Parse returned ${result?.descriptionText}"
	return result
}

def createEvents(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
{
	log.debug "createEvents with cmd value {$cmd.value}, LastAlarmtype: $state.LastAlarmtype"
	
	def switchValue = cmd.value ? "on" : "off"
	def alarmValue 
	if (state.LastAlarmtype == 0) {
		alarmValue = "both"
	}
	else if (state.LastAlarmtype == 2) {
		alarmValue = "strobe"
	}
	else if (state.LastAlarmtype == 1) {
		alarmValue = "siren"
	}
	else {
		alarmValue = "off"
	}
    
	def res1 = [
		createEvent([name: "switch", value: switchValue, type: "digital", displayed: false]),
		createEvent([name: "alarm", value: alarmValue, type: "digital"])
	]
	log.debug "result is: $res1"
    return res1
}

def createEvents(physicalgraph.zwave.Command cmd) {
	log.warn "UNEXPECTED COMMAND: $cmd"
}

def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
{
	def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]
	if (!state.lastbat || (new Date().time) - state.lastbat > 53*60*60*1000) {
		result << response(zwave.batteryV1.batteryGet())
		result << response("delay 1200")
	}
	result << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
	result
}

def createEvents(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
	def map = [ name: "battery", unit: "%" ]
	if (cmd.batteryLevel == 0xFF) {
		map.value = 1
		map.descriptionText = "$device.displayName has a low battery"
		map.isStateChange = true
	} else {
		map.value = cmd.batteryLevel
	}
	state.lastbatt = new Date().time
	[createEvent(map), response(zwave.wakeUpV1.wakeUpNoMoreInformation())]
}

def createEvents(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd)
{

    log.debug "CONFIGURATIONREPORT"
}


def poll() {
	if (secondsPast(state.lastbatt, 36*60*60)) {
		return zwave.batteryV1.batteryGet().format()
	} else {
		return null
	}
}

private Boolean secondsPast(timestamp, seconds) {
	if (!(timestamp instanceof Number)) {
		if (timestamp instanceof Date) {
			timestamp = timestamp.time
		} else if ((timestamp instanceof String) && timestamp.isNumber()) {
			timestamp = timestamp.toLong()
		} else {
			return true
		}
	}
	return (new Date().time - timestamp) > (seconds * 1000)
}

def refresh() {
	log.debug "sending battery refresh command"
	zwave.batteryV1.batteryGet().format()
}

@artakka,
I tried using your version of the device type on a go control siren that was part of the http://www.homedepot.com/p/GoControl-Premium-DIY-Home-Security-Kit-Z-Wave-and-Wink-Enabled-WNK01-311KIT/205785810
which I think is a rebranded Linear WA105DBZ-1.

I am able to trigger the siren manually by going into ā€œThingsā€ menu, and selecting the siren. Under which I can also switch the mode between ā€œAlarmā€, ā€œsirenā€ or ā€œstrobeā€.

However, I cannot get Smart Home Monitor to trigger the siren properly. When an intrusion was triggered, instead of sounding the siren, it only sets the siren into ā€œalarm modeā€. I can see the red led flashing confirming that the command was received.

Are you able to trigger the siren properly with SHM?

thanks,
Johnny

@jakers102 Try this version

/**
 *  
 *
 *  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.
 *
 *  Linear Z-Wave Siren
 *
 *  Author: Kevin Tierney
 *  Date: 2015-07-30
 *  Updates by: Artak Kalantarian
 *  Date: 2015-10-13
 */
 

metadata {
	definition (name: "Linear Z-Wave Siren", namespace: "tierneykev", author: "Kevin Tierney") {
//		capability "Actuator"
        capability "Alarm"
        capability "Battery"
        capability "Polling"
        capability "Refresh"
        capability "Sensor"
		capability "Switch"
        
        command "strobe"
        command "siren"
        command "both"

        //Supported Command Classes
        //0x20-Basic ,0x25-Binary Switch ,0x70-Configuration , 0x72-Manufacturer Specific ,0x86-Version
//        fingerprint inClusters: "0x20,0x25,0x70,0x72,0x86"
         fingerprint deviceId:"0x1000", inClusters: "0x25,0x70,0x72,0x80,0x86"
//         0 0 0x1000 0 0 0 4 0x25 0x70 0x72 0x86
	}
   
	simulator {
		// reply messages
		reply "2001FF,2002": "command: 2002, payload: FF"
		reply "200100,2002": "command: 2002, payload: 00"
		reply "200121,2002": "command: 2002, payload: 21"
		reply "200142,2002": "command: 2002, payload: 42"
		reply "2001FF,delay 3000,200100,2002": "command: 2002, payload: 00"
	}

	tiles {
		standardTile("alarm", "device.alarm", width: 2, height: 2) {
			state "both", label:'alarm!', action:'alarm.siren', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
            state "siren", label:'siren!', action:'alarm.strobe', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
            state "strobe", label:'strobe!', action:'alarm.both', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"						
		}
 
        standardTile("off", "device.alarm", inactiveLabel: false, decoration: "flat") {
 			state "default", label:'Off', action:"off"
        } 
        standardTile("on", "device.alarm", inactiveLabel: false, decoration: "flat") {
 			state "default", label:'On', action:"on"
        } 
        valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") { 
			state "battery", label:'${currentValue}% battery', unit:""
		}
        standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
		}

       
		main "alarm"
        details(["alarm", "off", "on",  "battery","refresh"])
	}

	preferences {
    	input "autoStopTime", "enum", title: "Disarm Time",required:true,displayDuringSetup:true, options: ["30","60","120","Infinite"],default:'30'
	} 

}



def updated() {
		def autoStopTimeParameter = 0
        if (autoStopTime == '30') {
        	autoStopTimeParameter = 0
        } else if( autoStopTime == '60'){
        	autoStopTimeParameter = 1
        } else if (autoStopTime == '120') {
        	autoStopTimeParameter = 2
        } else if (autoStopTime == 'Infinite') {
        	autoStopTimeParameter = 3
        }
        log.debug "AutoStopTime - ${autoStopTimeParameter}"
	    zwave.configurationV1.configurationSet(parameterNumber: 1, size: 1, configurationValue: [autoStopTimeParameter])
}


//println org.codehaus.groovy.runtime.InvokerHelper.getVersion()


def strobe() {
	log.debug "Setting alarm to strobe."
    state.LastAlarmtype = 2
    zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [2]).format()
    sendEvent(name: "alarm", value: "strobe")
    on()
}

def siren() {
    log.debug "Setting alarm to siren."
    state.LastAlarmtype = 1
   sendEvent(name: "alarm", value: "siren")
   zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [1]).format()
    on()
}

def both() {
	log.debug "Setting alarm to both."
    state.LastAlarmtype = 0
    sendEvent(name: "alarm", value: "both")
	zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [0]).format()
    on()
}

def off() {
	log.debug "Ending Test"
	[
		zwave.basicV1.basicSet(value: 0x00).format(),
		zwave.basicV1.basicGet().format()
	]
}
def on() {
	log.debug "Ending Test"
	[
		zwave.basicV1.basicSet(value: 0xff).format(),
		zwave.basicV1.basicGet().format()
	]
}

def parse(String description) {

	def result = null
	def cmd = zwave.parse(description)
	log.debug "parse($description) - command is $cmd"
	if (cmd) {
		result = createEvents(cmd)
	}
	log.debug "Parse returned ${result?.descriptionText}"
	return result
}

def createEvents(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
{
	log.debug "createEvents with cmd value {$cmd.value}, LastAlarmtype: $state.LastAlarmtype"
	
	def switchValue = cmd.value ? "on" : "off"
	def alarmValue 
	if (state.LastAlarmtype == 0) {
		alarmValue = "both"
	}
	else if (state.LastAlarmtype == 2) {
		alarmValue = "strobe"
	}
	else if (state.LastAlarmtype == 1) {
		alarmValue = "siren"
	}
	else {
		alarmValue = "off"
	}
    
	def res1 = [
		createEvent([name: "switch", value: switchValue, type: "digital", displayed: false]),
		createEvent([name: "alarm", value: alarmValue, type: "digital"])
	]
	log.debug "result is: $res1"
    return res1
}

def createEvents(physicalgraph.zwave.Command cmd) {
	log.warn "UNEXPECTED COMMAND: $cmd"
}

def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
{
	def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]
	if (!state.lastbat || (new Date().time) - state.lastbat > 53*60*60*1000) {
		result << response(zwave.batteryV1.batteryGet())
		result << response("delay 1200")
	}
	result << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
	result
}

def createEvents(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
	def map = [ name: "battery", unit: "%" ]
	if (cmd.batteryLevel == 0xFF) {
		map.value = 1
		map.descriptionText = "$device.displayName has a low battery"
		map.isStateChange = true
	} else {
		map.value = cmd.batteryLevel
	}
	state.lastbatt = new Date().time
	[createEvent(map), response(zwave.wakeUpV1.wakeUpNoMoreInformation())]
}

def createEvents(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd)
{

    log.debug "CONFIGURATIONREPORT"
}


def poll() {
	if (secondsPast(state.lastbatt, 36*60*60)) {
		return zwave.batteryV1.batteryGet().format()
	} else {
		return null
	}
}

private Boolean secondsPast(timestamp, seconds) {
	if (!(timestamp instanceof Number)) {
		if (timestamp instanceof Date) {
			timestamp = timestamp.time
		} else if ((timestamp instanceof String) && timestamp.isNumber()) {
			timestamp = timestamp.toLong()
		} else {
			return true
		}
	}
	return (new Date().time - timestamp) > (seconds * 1000)
}

def refresh() {
	log.debug "sending battery refresh command"
	zwave.batteryV1.batteryGet().format()
}

Hi,
I just used the device type code above. When my GoControl siren from the same kit (Linear Sirenā€¦it says so in the instruction sheet, and includes the command instructions at the beginning of this thread) was included in the Hub, it immediately used the device type I created with the code.
If I tap the icon on the ā€œThingsā€ screen, it immediately sets off the siren and strobe. I can also toggle between alarm, siren or strobe from the ā€œThingsā€ screen, but it doesnā€™t seem to change the siren.
If I go into the Devices screen, I can turn off/on the siren, and I can toggle between the modes, but againā€¦it still just runs the siren and strobe at the same time.
Summary:
Icon: if touched, immediately sets off the siren and strobe. Toggling between mode (either in Devices screen, or Things screen) has no impact on the mode.
On/off: seems to work ok
Battery: nothing yet.

Mike

Yes, I have not fixed the type change code yet. But on / off works.

I thought maybe the actions in the state section were wrong (ie state ā€œbothā€ has action 'alarm.siren", etc), but I changed them and the toggling between states stopped working, as did on/off.

I looked at the rest of the codeā€¦the config change values look correct, per the Linear config instructions. Not sure why the siren wonā€™t change states correctly.

One additional item: I also tested it with Smart Home Monitor. Siren didnā€™t trigger (but SHM shows the Siren as activated).

Edit: Tested with ā€œZ-wave Sirenā€ device type. ā€œoff/onā€ works, as does Battery % reporting. Iā€™ll keep checking, but for some reason the configuration values (siren, strobe or both) donā€™t work.

Making progressā€¦I fixed a number of things:

  1. ā€œActuatorā€ was commented out at the beginningā€¦fixed that. That a key capability.
  2. on () command was in each of the function change def (strobe, siren, both) areas. This make the siren immediately go off each time you tried to change function. Removed the on statementsā€¦now it works fine.
  3. def strobe had an event line in the wrong area, which prevented the strobe config function from executing correctly. Moved the line up two rowsā€¦works now.

Now the following worksā€¦basically everything, except SHM (the key reason to have a siren!!!)
on/off (turns it on/off as expected)
battery reporting works
changes siren modes works
disarm time works

/**
 *  Linear Zwave Siren v2
 *
 *  Copyright 2015 Kevin Tierney
 *
 *  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.
 *
 */
metadata {
	definition (name: "Linear Z-Wave Siren", namespace: "tierneykev", author: "Kevin Tierney") {
		capability "Actuator"
        capability "Alarm"
        capability "Battery"
        capability "Polling"
        capability "Refresh"
        capability "Sensor"
		capability "Switch"
        command "strobe"
        command "siren"
        command "both"
        //Supported Command Classes
    //0x20-Basic ,0x25-Binary Switch ,0x70-Configuration , 0x72-Manufacturer Specific ,0x86-Version
//        fingerprint inClusters: "0x20,0x25,0x70,0x72,0x86"
         fingerprint deviceId:"0x1000", inClusters: "0x25,0x70,0x72,0x80,0x86"
//         0 0 0x1000 0 0 0 4 0x25 0x70 0x72 0x86
	}
	simulator {
		// reply messages
		reply "2001FF,2002": "command: 2002, payload: FF"
		reply "200100,2002": "command: 2002, payload: 00"
		reply "200121,2002": "command: 2002, payload: 21"
		reply "200142,2002": "command: 2002, payload: 42"
		reply "2001FF,delay 3000,200100,2002": "command: 2002, payload: 00"
	}
    tiles {
	standardTile("alarm", "device.alarm", width: 2, height: 2) {
        state "both", label:'alarm!', action:'alarm.siren', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
        state "siren", label:'siren!', action:'alarm.strobe', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
        state "strobe", label:'strobe!', action:'alarm.both', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"						
	}
        standardTile("off", "device.alarm", inactiveLabel: false, decoration: "flat") {
 			state "default", label:'Off', action:"off"
        } 
        standardTile("on", "device.alarm", inactiveLabel: false, decoration: "flat") {
 			state "default", label:'On', action:"on"
        } 
        valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") { 
			state "battery", label:'${currentValue}% battery', unit:""
		}
        standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
		}
       
	main "alarm"
    details(["alarm", "off", "on",  "battery","refresh"])
}

preferences {
	input "autoStopTime", "enum", title: "Disarm Time",required:true,displayDuringSetup:true, options: ["30","60","120","Infinite"],default:'30'
}
}
def updated() {
		def autoStopTimeParameter = 0
        if (autoStopTime == '30') {
        	autoStopTimeParameter = 0
        } else if( autoStopTime == '60'){
        	autoStopTimeParameter = 1
        } else if (autoStopTime == '120') {
        	autoStopTimeParameter = 2
        } else if (autoStopTime == 'Infinite') {
        	autoStopTimeParameter = 3
        }
        log.debug "AutoStopTime - ${autoStopTimeParameter}"
	    zwave.configurationV1.configurationSet(parameterNumber: 1, size: 1, configurationValue: [autoStopTimeParameter])
}
//println org.codehaus.groovy.runtime.InvokerHelper.getVersion()
def strobe() {
	log.debug "Setting alarm to strobe."
    state.LastAlarmtype = 2
    sendEvent(name: "alarm", value: "strobe")
    zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [2]).format()
     
}
def siren() {
    log.debug "Setting alarm to siren."
    state.LastAlarmtype = 1
   sendEvent(name: "alarm", value: "siren")
   zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [1]).format()
     
}
def both() {
	log.debug "Setting alarm to both."
    state.LastAlarmtype = 0
    sendEvent(name: "alarm", value: "both")
	zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [0]).format()
     
}
def off() {
	log.debug "sending off"
	[
		zwave.basicV1.basicSet(value: 0x00).format(),
		zwave.basicV1.basicGet().format()
	]
}
def on() {
	log.debug "sending on"
	[
		zwave.basicV1.basicSet(value: 0xff).format(),
		zwave.basicV1.basicGet().format()
	]
}
def parse(String description) {
    def result = null
def cmd = zwave.parse(description)
log.debug "parse($description) - command is $cmd"
if (cmd) {
	result = createEvents(cmd)
}
log.debug "Parse returned ${result?.descriptionText}"
return result
}
def createEvents(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
{
	log.debug "createEvents with cmd value {$cmd.value}, LastAlarmtype: $state.LastAlarmtype"
	def switchValue = cmd.value ? "on" : "off"
	def alarmValue 
	if (state.LastAlarmtype == 0) {
		alarmValue = "both"
	}
	else if (state.LastAlarmtype == 2) {
		alarmValue = "strobe"
	}
	else if (state.LastAlarmtype == 1) {
		alarmValue = "siren"
	}
	else {
		alarmValue = "off"
	}
	def res1 = [
		createEvent([name: "switch", value: switchValue, type: "digital", displayed: false]),
		createEvent([name: "alarm", value: alarmValue, type: "digital"])
	]
	log.debug "result is: $res1"
    return res1
}
def createEvents(physicalgraph.zwave.Command cmd) {
	log.warn "UNEXPECTED COMMAND: $cmd"
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
{
	def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]
	if (!state.lastbat || (new Date().time) - state.lastbat > 53*60*60*1000) {
		result << response(zwave.batteryV1.batteryGet())
		result << response("delay 1200")
	}
	result << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
	result
}
def createEvents(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
	def map = [ name: "battery", unit: "%" ]
	if (cmd.batteryLevel == 0xFF) {
		map.value = 1
		map.descriptionText = "$device.displayName has a low battery"
		map.isStateChange = true
	} else {
		map.value = cmd.batteryLevel
	}
	state.lastbatt = new Date().time
	[createEvent(map), response(zwave.wakeUpV1.wakeUpNoMoreInformation())]
}
def createEvents(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd)
{
    log.debug "CONFIGURATIONREPORT"
}
def poll() {
	if (secondsPast(state.lastbatt, 36*60*60)) {
		return zwave.batteryV1.batteryGet().format()
	} else {
		return null
	}
}
private Boolean secondsPast(timestamp, seconds) {
	if (!(timestamp instanceof Number)) {
		if (timestamp instanceof Date) {
			timestamp = timestamp.time
		} else if ((timestamp instanceof String) && timestamp.isNumber()) {
			timestamp = timestamp.toLong()
		} else {
			return true
		}
	}
	return (new Date().time - timestamp) > (seconds * 1000)
}
def refresh() {
	log.debug "sending battery refresh command"
	zwave.batteryV1.batteryGet().format()
}
1 Like

And now I think I see why my device type commands ddinā€™t work. I was missing the format() at the end of all my zwave commands

Updated working code. I have a support ticket open with Smartthings support on integration with Smart Home Monitor. However, I got it to work with SHM, but it seems like a workaround. SHM sends a ā€œbothā€ command to turn the alarm on, when it really should be sending an ā€œonā€ command. I created separate commands to config the alarm type, then setup a ā€œdef bothā€ to get it to turn on. If Smartthings starts sending just an ā€œon()ā€ message, it should still work ok (I think).

Anyway, here ya go:
PS: Kevin, how can I paste this code in a scrolling window? Iā€™m sure itā€™s obvious, but I donā€™t see it.

/**
 *  Linear Zwave Siren v3
 *
 *  Copyright 2015 Kevin Tierney
 *
 *  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.
 *Author: Kevin Tierney
 *  Date: 2015-07-30
 *  Updates by: Mike Wilson
 *  Date: 2015-11-01
 */
metadata {
	definition (name: "Linear Z-Wave Siren v3", namespace: "tierneykev", author: "Kevin Tierney") {
		capability "Actuator"
        capability "Alarm"
        capability "Battery"
        capability "Polling"
        capability "Refresh"
        capability "Sensor"
		capability "Switch"
        command "setstrobe"
        command "setsiren"
        command "setboth"
        //Supported Command Classes
    //0x20-Basic ,0x25-Binary Switch ,0x70-Configuration , 0x72-Manufacturer Specific ,0x86-Version
//        fingerprint inClusters: "0x20,0x25,0x70,0x72,0x86"
         fingerprint deviceId:"0x1000", inClusters: "0x25,0x70,0x72,0x80,0x86"
//         0 0 0x1000 0 0 0 4 0x25 0x70 0x72 0x86
	}
	simulator {
		// reply messages
		reply "2001FF,2002": "command: 2002, payload: FF"
		reply "200100,2002": "command: 2002, payload: 00"
		reply "200121,2002": "command: 2002, payload: 21"
		reply "200142,2002": "command: 2002, payload: 42"
		reply "2001FF,delay 3000,200100,2002": "command: 2002, payload: 00"
	}
    tiles {
	standardTile("alarm", "device.alarm", width: 2, height: 2) {
    log.debug "Adjusting alarm state"
       
        state "both", label:'alarm!', action:"setsiren", icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
        state "siren", label:'siren!', action:"setstrobe", icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
        state "strobe", label:'strobe!', action:"setboth", icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"						
	}
        standardTile("off", "device.alarm", inactiveLabel: false, decoration: "flat") {
 			state "default", label:'Off', action:"off"
        } 
        standardTile("on", "device.alarm", inactiveLabel: false, decoration: "flat") {
 			state "default", label:'On', action:"on"
        } 
        valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") { 
			state "battery", label:'${currentValue}% battery', unit:""
		}
        standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
		}
       
	main "alarm"
    details(["alarm","off","on","battery","refresh"])
}

preferences {
	input "autoStopTime", "enum", title: "Disarm Time",required:true,displayDuringSetup:true, options: ["30","60","120","Infinite"],default:'30'
}
}
def updated() {
		def autoStopTimeParameter = 0
        if (autoStopTime == '30') {
        	autoStopTimeParameter = 0
        } else if( autoStopTime == '60'){
        	autoStopTimeParameter = 1
        } else if (autoStopTime == '120') {
        	autoStopTimeParameter = 2
        } else if (autoStopTime == 'Infinite') {
        	autoStopTimeParameter = 3
        }
        log.debug "AutoStopTime - ${autoStopTimeParameter}"
	    zwave.configurationV1.configurationSet(parameterNumber: 1, size: 1, configurationValue: [autoStopTimeParameter])
}
//println org.codehaus.groovy.runtime.InvokerHelper.getVersion()



def setstrobe() {
	log.debug "Setting alarm to strobe."
    state.LastAlarmtype = 2
    sendEvent(name: "alarm", value: "strobe")
    zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [2]).format()
     
}
def setsiren() {
    log.debug "Setting alarm to siren."
    state.LastAlarmtype = 1
   sendEvent(name: "alarm", value: "siren")
   zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [1]).format()
     
}
def setboth() {
	log.debug "Setting alarm to both."
    state.LastAlarmtype = 0
    sendEvent(name: "alarm", value: "both")
	zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [0]).format()
 
     
}


def off() {
	log.debug "sending off"
	[
		zwave.basicV1.basicSet(value: 0x00).format(),
		zwave.basicV1.basicGet().format()
	]
}
def on() {
	log.debug "sending on"
	[
		zwave.basicV1.basicSet(value: 0xff).format(),
		zwave.basicV1.basicGet().format()
	]
}

def both() {
	log.debug "sending alarm on via both"
	[
		zwave.basicV1.basicSet(value: 0xff).format(),
		zwave.basicV1.basicGet().format()
	]
}

def parse(String description) {
    def result = null
def cmd = zwave.parse(description)
log.debug "parse($description) - command is $cmd"
if (cmd) {
	result = createEvents(cmd)
}
log.debug "Parse returned ${result?.descriptionText}"
return result
}
def createEvents(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
{
	log.debug "createEvents with cmd value {$cmd.value}, LastAlarmtype: $state.LastAlarmtype"
	def switchValue = cmd.value ? "on" : "off"
	def alarmValue 
	if (state.LastAlarmtype == 0) {
		alarmValue = "both"
	}
	else if (state.LastAlarmtype == 2) {
		alarmValue = "strobe"
	}
	else if (state.LastAlarmtype == 1) {
		alarmValue = "siren"
	}
	else {
		alarmValue = "off"
	}
	[
		createEvent([name: "switch", value: switchValue, type: "digital", displayed: false]),
		createEvent([name: "alarm", value: alarmValue, type: "digital"])
	]
}
def createEvents(physicalgraph.zwave.Command cmd) {
	log.warn "UNEXPECTED COMMAND: $cmd"
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
{
	def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]
	if (!state.lastbat || (new Date().time) - state.lastbat > 53*60*60*1000) {
		result << response(zwave.batteryV1.batteryGet())
		result << response("delay 1200")
	}
	result << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
	result
}
def createEvents(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
	def map = [ name: "battery", unit: "%" ]
	if (cmd.batteryLevel == 0xFF) {
		map.value = 1
		map.descriptionText = "$device.displayName has a low battery"
		map.isStateChange = true
	} else {
		map.value = cmd.batteryLevel
	}
	state.lastbatt = new Date().time
	[createEvent(map), response(zwave.wakeUpV1.wakeUpNoMoreInformation())]
}
def createEvents(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd)
{
    log.debug "CONFIGURATIONREPORT"
}
def poll() {
	if (secondsPast(state.lastbatt, 36*60*60)) {
		return zwave.batteryV1.batteryGet().format()
	} else {
		return null
	}
}
private Boolean secondsPast(timestamp, seconds) {
	if (!(timestamp instanceof Number)) {
		if (timestamp instanceof Date) {
			timestamp = timestamp.time
		} else if ((timestamp instanceof String) && timestamp.isNumber()) {
			timestamp = timestamp.toLong()
		} else {
			return true
		}
	}
	return (new Date().time - timestamp) > (seconds * 1000)
}
def refresh() {
	log.debug "sending battery refresh command"
	zwave.batteryV1.batteryGet().format()
}
1 Like

Here it is with the scoller. Paste all the code in, then highlight your code and either do Ctrl-K or Click on the </>

It also works if you put your code in github and paste a link to it

/**
* Linear Zwave Siren v3
*
* Copyright 2015 Mike Wilson
*
* 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.
*
*/
metadata {
definition (name: "Linear Z-Wave Siren v3", namespace: "miketx", author: "Mike Wilson") {
capability "Actuator"
capability "Alarm"
capability "Battery"
capability "Polling"
capability "Refresh"
capability "Sensor"
capability "Switch"
command "setstrobe"
command "setsiren"
command "setboth"
//Supported Command Classes
//0x20-Basic ,0x25-Binary Switch ,0x70-Configuration , 0x72-Manufacturer Specific ,0x86-Version
// fingerprint inClusters: "0x20,0x25,0x70,0x72,0x86"
fingerprint deviceId:"0x1000", inClusters: "0x25,0x70,0x72,0x80,0x86"
// 0 0 0x1000 0 0 0 4 0x25 0x70 0x72 0x86
}
simulator {
// reply messages
reply "2001FF,2002": "command: 2002, payload: FF"
reply "200100,2002": "command: 2002, payload: 00"
reply "200121,2002": "command: 2002, payload: 21"
reply "200142,2002": "command: 2002, payload: 42"
reply "2001FF,delay 3000,200100,2002": "command: 2002, payload: 00"
}
tiles {
standardTile("alarm", "device.alarm", width: 2, height: 2) {
log.debug "Adjusting alarm state"

    state "both", label:'alarm!', action:"setsiren", icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
    state "siren", label:'siren!', action:"setstrobe", icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"
    state "strobe", label:'strobe!', action:"setboth", icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"						
}
    standardTile("off", "device.alarm", inactiveLabel: false, decoration: "flat") {
		state "default", label:'Off', action:"off"
    } 
    standardTile("on", "device.alarm", inactiveLabel: false, decoration: "flat") {
		state "default", label:'On', action:"on"
    } 
    valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") { 
		state "battery", label:'${currentValue}% battery', unit:""
	}
    standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat") {
		state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
	}

main "alarm"
details(["alarm","off","on","battery","refresh"])
}

preferences {
input "autoStopTime", "enum", title: "Disarm Time",required:true,displayDuringSetup:true, options: ["30","60","120","Infinite"],default:'30'
}
}
def updated() {
def autoStopTimeParameter = 0
if (autoStopTime == '30') {
autoStopTimeParameter = 0
} else if( autoStopTime == '60'){
autoStopTimeParameter = 1
} else if (autoStopTime == '120') {
autoStopTimeParameter = 2
} else if (autoStopTime == 'Infinite') {
autoStopTimeParameter = 3
}
log.debug "AutoStopTime - ${autoStopTimeParameter}"
zwave.configurationV1.configurationSet(parameterNumber: 1, size: 1, configurationValue: [autoStopTimeParameter])
}
//println org.codehaus.groovy.runtime.InvokerHelper.getVersion()

def setstrobe() {
log.debug "Setting alarm to strobe."
state.LastAlarmtype = 2
sendEvent(name: "alarm", value: "strobe")
zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [2]).format()

}
def setsiren() {
log.debug "Setting alarm to siren."
state.LastAlarmtype = 1
sendEvent(name: "alarm", value: "siren")
zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [1]).format()

}
def setboth() {
log.debug "Setting alarm to both."
state.LastAlarmtype = 0
sendEvent(name: "alarm", value: "both")
zwave.configurationV1.configurationSet(parameterNumber: 0, size: 1, configurationValue: [0]).format()

}

def off() {
log.debug "sending off"
[
zwave.basicV1.basicSet(value: 0x00).format(),
zwave.basicV1.basicGet().format()
]
}
def on() {
log.debug "sending on"
[
zwave.basicV1.basicSet(value: 0xff).format(),
zwave.basicV1.basicGet().format()
]
}

def both() {
log.debug "sending alarm on via both"
[
zwave.basicV1.basicSet(value: 0xff).format(),
zwave.basicV1.basicGet().format()
]
}

def parse(String description) {
def result = null
def cmd = zwave.parse(description)
log.debug "parse($description) - command is $cmd"
if (cmd) {
result = createEvents(cmd)
}
log.debug "Parse returned ${result?.descriptionText}"
return result
}
def createEvents(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
{
log.debug "createEvents with cmd value {$cmd.value}, LastAlarmtype: $state.LastAlarmtype"
def switchValue = cmd.value ? "on" : "off"
def alarmValue 
if (state.LastAlarmtype == 0) {
alarmValue = "both"
}
else if (state.LastAlarmtype == 2) {
alarmValue = "strobe"
}
else if (state.LastAlarmtype == 1) {
alarmValue = "siren"
}
else {
alarmValue = "off"
}
[
createEvent([name: "switch", value: switchValue, type: "digital", displayed: false]),
createEvent([name: "alarm", value: alarmValue, type: "digital"])
]
}
def createEvents(physicalgraph.zwave.Command cmd) {
log.warn "UNEXPECTED COMMAND: $cmd"
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
{
def result = [createEvent(descriptionText: "${device.displayName} woke up", isStateChange: false)]
if (!state.lastbat || (new Date().time) - state.lastbat > 53*60*60*1000) {
result << response(zwave.batteryV1.batteryGet())
result << response("delay 1200")
}
result << response(zwave.wakeUpV1.wakeUpNoMoreInformation())
result
}
def createEvents(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
def map = [ name: "battery", unit: "%" ]
if (cmd.batteryLevel == 0xFF) {
map.value = 1
map.descriptionText = "$device.displayName has a low battery"
map.isStateChange = true
} else {
map.value = cmd.batteryLevel
}
state.lastbatt = new Date().time
[createEvent(map), response(zwave.wakeUpV1.wakeUpNoMoreInformation())]
}
def createEvents(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd)
{
log.debug "CONFIGURATIONREPORT"
}
def poll() {
if (secondsPast(state.lastbatt, 36*60*60)) {
return zwave.batteryV1.batteryGet().format()
} else {
return null
}
}
private Boolean secondsPast(timestamp, seconds) {
if (!(timestamp instanceof Number)) {
if (timestamp instanceof Date) {
timestamp = timestamp.time
} else if ((timestamp instanceof String) && timestamp.isNumber()) {
timestamp = timestamp.toLong()
} else {
return true
}
}
return (new Date().time - timestamp) > (seconds * 1000)
}
def refresh() {
log.debug "sending battery refresh command"
zwave.batteryV1.batteryGet().format()
}
3 Likes

Coolā€¦thanks Kevin! I fixed my post above so it wouldnā€™t take up so much space!

I just updated device type. I can choose alert ( strobe, siren,alarm) and they display properly in app and api, but regardless of which is chosen both siren and strobe activate when triggered :frowning:

Did you use the latest code I posted? I just did a quick test again and everything functions as it should, including with SHM. After you set the alarm type, did you try it with the on/off buttons and did that work?

My Linear siren is model ZM1601US (comes in the GoControl kitā€¦battery operated model (not AC model, which is Linear WA105DBZ-1, but both support the same configuration commands and function the same, per the instruction sheet).