It’s like I can’t execute a device handler. Publish should execute the handler, right. I was using jj9.7.1 for a few years. It stopped working after 30.5 upgrade.
The stock Fibaro Door/Window Sensor DTH work fine for me. Runs locally as well.
I’m using fgk101 with jjg9.5.4 handler, no temperature reading. There is no field for temperature. When I publish this one and other handlers, it is like they don’t execute, it reverts to the stock Fibaro software, contact, battery and tamper.
Are you getting a temperature reading?
Thanks
Jim
if you want the temp reading you need to sore a local copy of the DTH and edit it.
Here is mine.
/**
- Device Type Definition File
- Device Type: Fibaro Door/Window Sensor
- File Name: fibaro-door-window-sensor.groovy
- Initial Release: 2014-12-10
- @author: Todd Wackford
- Email: todd@wackford.net
- @version: 1.0
- Copyright 2014 SmartThings
- 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.
*/
/**
-
Sets up metadata, simulator info and tile definition. The tamper tile is setup, but
-
not displayed to the user. We do this so we can receive events and display on device
-
activity. If the user wants to display the tamper tile, adjust the tile display lines
-
with the following:
-
main(["contact", "temperature", "tamper"])
-
details(["contact", "temperature", "battery", "tamper"])
-
@param none
-
@return none
*/
metadata {
definition (name: “Fibaro Door/Window Sensor”, namespace: “smartthings”, author: “SmartThings”, runLocally: true, minHubCoreVersion: ‘000.021.00001’, executeCommandsLocally: true) {
capability “Temperature Measurement” //UNCOMMENT ME IF TEMP INSTALLED
capability “Contact Sensor”
capability “Sensor”
capability “Battery”
capability “Configuration”
capability “Health Check”command "resetParams2StDefaults" command "listCurrentParams" command "updateZwaveParam" command "test" fingerprint deviceId: "0x2001", inClusters: "0x30,0x9C,0x85,0x72,0x70,0x86,0x80,0x56,0x84,0x7A,0xEF,0x2B"
}
simulator {
// messages the device returns in response to commands it receives
status “open” : “command: 2001, payload: FF”
status “closed”: “command: 2001, payload: 00”for (int i = 0; i <= 100; i += 20) { status "temperature ${i}F": new physicalgraph.zwave.Zwave().sensorMultilevelV2.sensorMultilevelReport( scaledSensorValue: i, precision: 1, sensorType: 1, scale: 1).incomingMessage() } for (int i = 0; i <= 100; i += 20) { status "battery ${i}%": new physicalgraph.zwave.Zwave().batteryV1.batteryReport( batteryLevel: i).incomingMessage() }
}
tiles {
standardTile(“contact”, “device.contact”, width: 2, height: 2) {
state “open”, label: ‘{name}', icon: "st.contact.contact.open", backgroundColor: "#e86d13" state "closed", label: '{name}’, icon: “st.contact.contact.closed”, backgroundColor: “#00A0DC”
}
valueTile(“temperature”, “device.temperature”, width: 2, height: 2, inactiveLabel: false) {
state “temperature”, label:’{currentValue}°', backgroundColors:[ [value: "", color: "#ffffff"], [value: 31, color: "#153591"], [value: 44, color: "#1e9cbb"], [value: 59, color: "#90d2a7"], [value: 74, color: "#44b621"], [value: 84, color: "#f1d801"], [value: 95, color: "#d04e00"], [value: 96, color: "#bc2323"] ] } standardTile("tamper", "device.alarm") { state("secure", label:'secure', icon:"st.locks.lock.locked", backgroundColor:"#ffffff") state("tampered", label:'tampered', icon:"st.locks.lock.unlocked", backgroundColor:"#00a0dc") } valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") { state "battery", label:'{currentValue}% battery’, unit:""
}
standardTile(“configure”, “device.configure”, inactiveLabel: false, decoration: “flat”) {
state “configure”, label:’’, action:“configuration.configure”, icon:“st.secondary.configure”
}//this will display a temperature tile for the DS18B20 sensor main(["contact"]) //COMMENT ME OUT IF NO TEMP INSTALLED details(["temperature", "contact", "battery"]) //COMMENT ME OUT IF NO TEMP INSTALLED //this will hide the temperature tile if the DS18B20 sensor is not installed //main(["contact"]) //UNCOMMENT ME IF NO TEMP INSTALLED //details(["contact", "battery"]) //UNCOMMENT ME IF NO TEMP INSTALLED
}
}
/**
- Mapping of command classes and associated versions used for this DTH
*/
private getCommandClassVersions() {
[
0x30: 1, // Sensor Binary
0x31: 2, // Sensor MultiLevel
0x56: 1, // Crc16Encap
0x60: 3, // Multi-Channel
0x70: 2, // Configuration
0x72: 2, // Manufacturer Specific
0x80: 1, // Battery
0x84: 1, // WakeUp
0x9C: 1 // Sensor Alarm
]
}
// Parse incoming device messages to generate events
def parse(String description)
{
def result =
def cmd = zwave.parse(description, commandClassVersions)
if (cmd) {
result += zwaveEvent(cmd)
}
log.debug “parsed 'description' to {result.inspect()}”
result
}
def zwaveEvent(physicalgraph.zwave.commands.crc16encapv1.Crc16Encap cmd)
{
def versions = commandClassVersions
// def encapsulatedCommand = cmd.encapsulatedCommand(versions)
def version = versions[cmd.commandClass as Integer]
def ccObj = version ? zwave.commandClass(cmd.commandClass, version) : zwave.commandClass(cmd.commandClass)
def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(cmd.data)
if (!encapsulatedCommand) {
log.debug “Could not extract command from $cmd”
} else {
return zwaveEvent(encapsulatedCommand)
}
}
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
def encapsulatedCommand = cmd.encapsulatedCommand([0x30: 2, 0x31: 2]) // can specify command class versions here like in zwave.parse
log.debug (“Command from endpoint {cmd.sourceEndPoint}: {encapsulatedCommand}”)
if (encapsulatedCommand) {
return zwaveEvent(encapsulatedCommand)
}
}
def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd)
{
def event = createEvent(descriptionText: “${device.displayName} woke up”, isStateChange: false)
def cmds =
if (!state.lastbat || now() - state.lastbat > 246060*1000) {
cmds << zwave.batteryV1.batteryGet().format()
} else {
cmds << zwave.wakeUpV1.wakeUpNoMoreInformation().format()
}
[event, response(cmds)]
}
def zwaveEvent(physicalgraph.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd)
{
def map = [:]
switch (cmd.sensorType) {
case 1:
// temperature
def cmdScale = cmd.scale == 1 ? “F” : “C”
map.value = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision)
map.unit = getTemperatureScale()
map.name = “temperature”
break;
}
createEvent(map)
}
def zwaveEvent(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.lastbat = now()
[createEvent(map), response(zwave.wakeUpV1.wakeUpNoMoreInformation())]
}
def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv1.SensorBinaryReport cmd) {
def map = [:]
map.value = cmd.sensorValue ? “open” : “closed”
map.name = “contact”
if (map.value == “closed”) {
map.descriptionText = “$device.displayName is closed”
}
else {
map.descriptionText = “$device.displayName is open”
}
createEvent(map)
}
// added so UK (non-multichannel) and US device supported by same device file.
def sensorValueEvent(value) {
if (value) {
createEvent(name: “contact”, value: “open”, descriptionText: “$device.displayName is open”)
} else {
createEvent(name: “contact”, value: “closed”, descriptionText: “$device.displayName is closed”)
}
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd)
{
sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd)
{
sensorValueEvent(cmd.value)
}
def zwaveEvent(physicalgraph.zwave.commands.sensoralarmv1.SensorAlarmReport cmd)
{
def map = [:]
map.value = cmd.sensorState ? “tampered” : “secure”
map.name = “tamper”
if (map.value == “tampered”) {
map.descriptionText = “$device.displayName has been tampered with”
}
else {
map.descriptionText = “$device.displayName is secure”
}
createEvent(map)
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
log.debug “Catchall reached for cmd: ${cmd.toString()}}”
}
def zwaveEvent(physicalgraph.zwave.commands.configurationv2.ConfigurationReport cmd) {
def result =
log.debug “{device.displayName} parameter '{cmd.parameterNumber}’ with a byte size of ‘{cmd.size}' is set to '{cmd.configurationValue}’”
if (cmd.parameterNumber == 15) {
if (cmd.configurationValue[0] == 1) { //error in temp probe
result << createEvent(name:"temperature", value:"-99")
} else if (cmd.configurationValue[0] == 255) { //no temp probe
result << createEvent(name:"temperature", value:"")
}
result += response(zwave.batteryV1.batteryGet().format()) // send this after configure() runs
}
result
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
def result =
def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
log.debug "msr: $msr"
device.updateDataValue(["MSR", msr])
result << createEvent(descriptionText: "$device.displayName MSR: $msr", isStateChange: false)
result
}
/**
-
Configures the device to settings needed by SmarthThings at device discovery time.
-
@param none
-
@return none
*/
def configure() {
log.debug “Configuring Device…”
// Device wakes up every 4 hours, this interval allows us to miss one wakeup notification before marking offline
sendEvent(name: “checkInterval”, value: 8 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: “zwave”, hubHardwareId: device.hub.hardwareID])def cmds =
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 1, size: 2).format()
// send associate to group 3 to get sensor data reported only to hub
cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()// send associate to group 2 to get tamper alarm data reported
cmds << zwave.associationV2.associationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()// turn on the tamper alarm
cmds << zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 10, size: 1).format()
//cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()// temperature change sensitivity
cmds << zwave.configurationV1.configurationSet(configurationValue: [4], parameterNumber: 12, size: 1).format()
//cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()// remove group 1 association to stop redundant BasicSet
cmds << zwave.associationV1.associationRemove(groupingIdentifier:1, nodeId:zwaveHubNodeId).format()// see if there is a temp probe on board and is it working
cmds << zwave.configurationV1.configurationGet(parameterNumber: 15).format()delayBetween(cmds, 500)
}
//used to add “test” button for simulation of user changes to parameters
def test() {
def params = [paramNumber:10,value:1,size:1]
updateZwaveParam(params)
//zwave.wakeUpV1.wakeUpIntervalSet(seconds: 30, nodeid:zwaveHubNodeId).format()
}
/**
-
This method will allow the user to update device parameters (behavior) from an app.
-
A “Zwave Tweaker” app will be developed as an interface to do this. Or the user can
-
write his/her own app to envoke this method. No type or value checking is done to
-
compare to what device capability or reaction. It is up to user to read OEM
-
documentation prio to envoking this method.
-
THIS IS AN ADVANCED OPERATION. USE AT YOUR OWN RISK! READ OEM DOCUMENTATION!
-
@param List[paramNumber:80,value:10,size:1]
-
@return none
*/
def updateZwaveParam(params) {
if ( params ) {
def pNumber = params.paramNumber
def pSize = params.size
def pValue = [params.value]
log.debug “Make sure device is awake and in recieve mode”
log.debug “Updating {device.displayName} parameter number '{pNumber}’ with value ‘{pValue}' with size of '{pSize}’”def cmds = [] cmds << zwave.configurationV1.configurationSet(configurationValue: pValue, parameterNumber: pNumber, size: pSize).format() cmds << zwave.configurationV1.configurationGet(parameterNumber: pNumber).format() delayBetween(cmds, 1000)
}
}
/**
-
Sets all of available Fibaro parameters back to the device defaults except for what
-
SmartThings needs to support the stock functionality as released. This will be
-
called from the “Fibaro Tweaker” or user’s app.
-
THIS IS AN ADVANCED OPERATION. USE AT YOUR OWN RISK! READ OEM DOCUMENTATION!
-
@param none
-
@return none
*/
def resetParams2StDefaults() {
log.debug “Resetting ${device.displayName} parameters to SmartThings compatible defaults”
def cmds =
cmds << zwave.configurationV1.configurationSet(configurationValue: [0,0], parameterNumber: 1, size: 2).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 2, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 5, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [255], parameterNumber: 7, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 9, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 10, size: 1).format() //ST Custom
cmds << zwave.configurationV1.configurationSet(configurationValue: [4], parameterNumber: 12, size: 1).format() //St Custom
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 13, size: 1).format()
cmds << zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 14, size: 1).format()delayBetween(cmds, 500)
}
/**
-
Lists all of available Fibaro parameters and thier current settings out to the
-
logging window in the IDE. This will be called from the “Fibaro Tweaker” or
-
user’s own app.
-
THIS IS AN ADVANCED OPERATION. USE AT YOUR OWN RISK! READ OEM DOCUMENTATION!
-
@param none
-
@return none
*/
def listCurrentParams() {
log.debug “Listing of current parameter settings of ${device.displayName}”
def cmds =
cmds << zwave.configurationV1.configurationGet(parameterNumber: 1).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 2).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 3).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 5).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 7).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 9).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 13).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 14).format()
cmds << zwave.configurationV1.configurationGet(parameterNumber: 15).format()delayBetween(cmds, 500)
}
Hi, ?I have created a handler with your code, published it and it acts like the other handlers that fail. I might be doing something wrong. Here’s how I add a device.
Delete any existing device handlers in API, exclude zwave device, factory reset Fibaro fgk101. Create and publish device handler, use newest app, select the plus, select Fibaro window/door device, push tkm button three times, the device shows up on the app. The app shows that I am using the stock handler (no temperature).
Thanks
Jim
Once you have included the new device successfully you need to go back into the developer portal (where you created the device handler) and edit the device to select the custom handler (one you just created). In the developer portal go to devices and then click on the device you created. Edit the device and under type you can scroll down to the bottom and select the custom handler.
I didn’t do the last step/ sentence where the device needs to have the new device handler installed. I have a temperature field now, but it is not reporting, using jjg 9.5.4 device handler.
I’m going to try yours next.
Thanks
Jim
Hi Simon,
I’m still trying to get a temperature reading from my Fibaro fgk101 v3.2 and DS18B20. I also have v2 hub using 30.5 software.
I got errors when I tried to create a device handler from your code, I’ve been trying to learn how to trouble shoot the errors, no luck.
I can’t seem to find anyone that has fgk101 v3.2 the has been successful. What version do you have?
Thanks
Jim
You are creating the handler using the “from code” option and posting the full code? If so then the most usual reason for an error is when people try to create a handler from the smartapp screen instead of the device handler screen.
I have 2 Fibaro door sensors at version 3.2 and another at version 2.1. All use the hander I shared.
Hi, here is the error I get when I copy your (all)code into groovy(from code), then post it for me. I don’t know where start looking for resolution.
Thanks
Jim
Org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: script_dth_metadata_3a62e71b_32bb_4dd3_924b_eeeabf02f081: 39: unexpected token: Door @ line 39, column 27. definition (name: “Fibaro Door/Window Sensor”, namespace: “smartthings”, author: “SmartThings”, runLocally: true, minHubCoreVersion: ‘000.021.00001’, executeCommandsLocally: true) { ^ 1 error
Not sure what the issue is here. I just copied all the code and recreated a new instance without issue. Here is a link to the file
The file that you sent published with no errors, I update the device and looked at it with the mobile app. The app shows battery%, tamper status and contact status. No temperature field. Have you seen this before?
No. do you see any events under the “Recently” tab?
If you go into the IDE and start live logging, can you get the door sensor to send an event?
The contact sensor works and reports correctly, by using the magnet to open and close it. I see the change in both the mobile app and the IDE.
I’m not sure how to start live logging, I saw it in the docs a few days ago.
Hmm, maybe the device is not sending any temp events. If you click on the device in the IDE and look at the current states section. do you see a temperature field as well as contact, battery and check interval?
Live logging is another tab in the IDE it will show all devices, but as soon as the door sensors send an event you can filter to that device only. .I would also open another browser window for the device and look at events. See if you can see a temp event. You can try to force a temp vent by holding the sensor in your hand.
No, I do not see the temperature field in current state. I just see, battery, contact and check interval.
I am looking into live logging, it looks like a good way to trouble shoot.
Btw, thanks again for your help.