Hi @SteveWard
Do you fancy sharing your code?
Iâm not sure Iâve much worth sharing at the moment. Iâve just got back to it now and am messing around, the trouble is I donât know how a lot of it works. Documentation seems very poor, thereâs no deconstruction of any of the commands sent and so Iâm having to experiment to try and figure out what it all does.
At the moment the only things I have that I know work are to send the following in configure:
zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
This appears puts the device into a mode that sends âproperâ individual commands for each channel, then I can parse them with the following code which sends commands that I can read in a smart app (or a virtual device - I think, havenât tried that yet).
Main thing I canât figure out is whether I can send commands back to the driver from the smart app or how to set up configuration data that can be set by the driver (if itâs even possible).
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
def result
if (cmd.commandClass == 32) {
if (cmd.parameter == [0]) {
if (cmd.sourceEndPoint == 1) {
result = createEvent(name: "switch1", value: "closed")
log.debug "switch 1 closed"
}
else
if (cmd.sourceEndPoint == 2) {
result = createEvent(name: "switch2", value: "closed")
log.debug "switch 2 closed"
}
}
if (cmd.parameter == [255]) {
if (cmd.sourceEndPoint == 1) {
result = createEvent(name: "switch1", value: "open")
log.debug "switch 1 open"
}
else
if (cmd.sourceEndPoint == 2) {
result = createEvent(name: "switch2", value: "open")
log.debug "switch 2 open"
}
}
}
return result
}
OK - figured out how to pass data back and forth between the driver and the smart app.
Progress is slow but it is progressâŠ
FWIW, I figured out the virtual device stuff. So now I have a device driver for the UBS I can use which links to a smart app and operates two virtual switches. These can then be passed to any other smart app that needs a switch.
I can also set the switches to be either momentary (pass through) or toggle from the smart app.
Bad bits. I canât seem to make the temperature bit work - donât need it but itâd be nice for completeness and my driver has a lot of stuff missing compared to other drivers Iâve looked at.
This is almost certainly because I still have a lot to figure out - but then it does work so it canât be missing anything important⊠Can it? HmmmâŠ
Hi @SteveWard
Looks like you are getting along very well. if you need any help testing it please let me know.
Hi @SteveWard
Would you share your device type code with all by any chance???
I am trying to integrate one of these sensors to detect a gate open/close positions and so far I canât even get input 1 to work for some reason.
Thanks
Carlos
Ok,
I finally got both inputs working
Hereâs the code for the device type for what is worth:
metadata {
definition (name: âFUSâ, namespace: âCarlosâ, author: âCarlosâ) {
capability "Sensor"
command "report"
command "singleSet"
command "singleRemove"
command "multiSet"
command "multiRemove"
fingerprint deviceId: â0x2001â, inClusters: â0x30 0x60 0x85 0x8E 0x72 0x70 0x86 0x7A 0xEF 0x2Bâ
}
simulator {
// These show up in the IDE simulator âmessagesâ drop-down to test
// sending event messages to your device handler
status âopenâ : "zw device: 02, command: 2001, payload: 00"
status âclosedâ: "zw device: 02, command: 2001, payload: FF"
status âbasic report onâ:
zwave.basicV1.basicReport(value:0xFF).incomingMessage()
status âbasic report offâ:
zwave.basicV1.basicReport(value:0).incomingMessage()
status âdimmer switch on at 70%â:
zwave.switchMultilevelV1.switchMultilevelReport(value:70).incomingMessage()
status âbasic set onâ:
zwave.basicV1.basicSet(value:0xFF).incomingMessage()
status âtemperature report 70°Fâ:
zwave.sensorMultilevelV2.sensorMultilevelReport(scaledSensorValue: 70.0, precision: 1, sensorType: 1, scale: 1).incomingMessage()
status âlow battery alertâ:
zwave.batteryV1.batteryReport(batteryLevel:0xFF).incomingMessage()
status âmultichannel sensorâ:
zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1).encapsulate(zwave.sensorBinaryV1.sensorBinaryReport(sensorValue:0)).incomingMessage()
// simulate turn on
reply â2001FF,delay 5000,2002â: âcommand: 2503, payload: FFâ
// simulate turn off
reply "200100,delay 5000,2002": "command: 2503, payload: 00"
}
tiles {
standardTile(âSwitch1â, âdevice.Switch1â, width: 1, height: 1) {
state âopenâ, label: â${name}â, icon: âst.contact.contact.openâ, backgroundColor: "#ffa81e"
state âclosedâ, label: â${name}â, icon: âst.contact.contact.closedâ, backgroundColor: â#79b821â
}
standardTile(âSwitch2â, âdevice.Switch2â, width: 1, height: 1) {
state âopenâ, label: â${name}â, icon: âst.contact.contact.openâ, backgroundColor: "#ffa81e"
state âclosedâ, label: â${name}â, icon: âst.contact.contact.closedâ, backgroundColor: â#79b821â
}
main(["Switch1","Switch2"])
details(["Switch1","Switch2"])
}
}
def parse(String description)
{
def result = null
def cmd = zwave.parse(description, [ 0x60: 3])
if (cmd) {
result = zwaveEvent(cmd)
}
log.debug "parsed â$descriptionâ to result: ${result}"
result
}
def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv1.ManufacturerSpecificReport cmd) {
log.debug(âManufacturerSpecificReport ${cmd.inspect()}â)
}
def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
log.debug(âConfigurationReport ${cmd.inspect()}â)
}
def report() {
// zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
//
delayBetween([
zwave.configurationV1.configurationGet(parameterNumber: 5).format(),
zwave.configurationV1.configurationGet(parameterNumber: 6).format()
])
}
def configTest() {
log.debug "configTest"
zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
//zwave.associationV2.associationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
}
def singleSet() {
def cmds = []
//cmds << zwave.associationV2.associationSet(groupingIdentifier:1, nodeId:[zwaveHubNodeId]).format()
//cmds << zwave.associationV2.associationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
delayBetween(cmds, 500)
}
def singleRemove() {
def cmds = []
//cmds << zwave.associationV2.associationRemove(groupingIdentifier:1, nodeId:[zwaveHubNodeId]).format()
//cmds << zwave.associationV2.associationRemove(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.associationV2.associationRemove(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
delayBetween(cmds, 500)
}
def multiSet() {
def cmds = []
//cmds << zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:1, nodeId:[zwaveHubNodeId]).format()
//cmds << zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
delayBetween(cmds, 500)
}
def multiRemove() {
def cmds = []
//cmds << zwave.multiChannelAssociationV2.multiChannelAssociationRemove(groupingIdentifier:1, nodeId:[zwaveHubNodeId]).format()
//cmds << zwave.multiChannelAssociationV2.multiChannelAssociationRemove(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
cmds << zwave.multiChannelAssociationV2.multiChannelAssociationRemove(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
delayBetween(cmds, 500)
}
def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd)
{
log.debug "BasicSet V1 ${cmd.inspect()}"
if (cmd.value) {
createEvent(name: âSwitch1â, value: âopenâ, descriptionText: â$device.displayName is openâ)
} else {
createEvent(name: âSwitch1â, value: âclosedâ, descriptionText: â$device.displayName is closedâ)
}
}
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
log.debug "ZWaveEvent V3 ${cmd.inspect()}"
def result
if (cmd.commandClass == 32) {
if (cmd.parameter == [0]) {
if (cmd.sourceEndPoint == 1) {
result = createEvent(name: âSwitch1â, value: âclosedâ, descriptionText: â$device.displayName is closedâ)
log.debug âSwitch 1 closedâ
}
else
if (cmd.sourceEndPoint == 2) {
result = createEvent(name: âSwitch2â, value: âclosedâ, descriptionText: â$device.displayName is closedâ)
log.debug âSwitch 2 closedâ
}
}
if (cmd.parameter == [255]) {
if (cmd.sourceEndPoint == 1) {
result = createEvent(name: âSwitch1â, value: âopenâ, descriptionText: â$device.displayName is openâ)
log.debug âSwitch 1 openâ
}
else
if (cmd.sourceEndPoint == 2) {
result = createEvent(name: âSwitch2â, value: âopenâ, descriptionText: â$device.displayName is openâ)
log.debug âSwitch 2 openâ
}
}
}
return result
}
def zwaveEvent(physicalgraph.zwave.Command cmd) {
// This will capture any commands not handled by other instances of zwaveEvent
// and is recommended for development so you can see every command the device sends
return createEvent(descriptionText: â${device.displayName}: ${cmd}â)
}
Hi Carlos, sorry for the tardy response Iâve only just got back to looking at this stuffâŠ
Looks like youâre doing OK at any rate, all I have currently is what I published above which functionally isnât much different to what you appear to have.
If I figure out anything else Iâll put it on this thread but it looks as though itâll work for what I want it to do.
I havenât managed to get the temperature function to work and I may need to be able to change the configuration but wont know until I come to use them in anger (theyâll fit between the PIRâs on my alarm and the panel itself so I can use the alarm PIRâs to trigger events in the system).
Cheers.
Thanks for sharing all the work guys.
Iâve just started trying to integrate the same Fibaro UBS but using the temperature sensors, to monitor the status of my hot water tank, much like in this post -
Itâs a shame itâs not yet supported. If anyone has any updates on using this device with ST Iâd love to hear. It works well for me using a RaZberry controller, so I may end up having to keep the UBS on the RaZberry only.
This is starting to look good, I can get input1 to change state but not input2. also is it possible to have both inputs show as contact sensor? or do we need an app and 2 virtual devices?
Thanks
Paul
You donât need an app. I could get both to report open close, however I wired my sensors IN2 to a PIR as I want a contact and motion sensor. I have also wire in the temp sensor, but so far only the contact sensor works.
But I need to start looking into it again soon
Hi @Fuzzyligic
Which code did you use? and did you make any changes to it?
With @carlos.ir33 code I can only make input 1 work and they is nothing in the log file.
what I am working towards is both inputs working as independent contactSensors that can be used with Rule Machine
Thanks
Paul
i started with his code, but i want happy with the configuration functions as they did not work for me, so i got rid of them and created my own configure block to ensure the correct association group was set. let me clean up the code i am using and set it back to be for dual contact sensor inputs. iâll post the link to the code here shortly
Ok the code is here
I cannot test it unfortunately, my 1 and only universal sensor is soldered in place unfortunately, but this should work, both the sensors have been changed to NC, which should be the correct input for a contact sensor.
you need to make sure you execute the configuration block once the sensor is in inclusion mode.
but if when you open the first sensor you get a line in the logs that starts with âBasicSet V1â then the configuration hasnât taken and you need to retry the configuration set again as only the first sensor will work, the line should start with âZWaveEvent V3â for both sensors to work.
if you still have no luck you can always try and list the parameters using the ListCurrentParams Function which should confirm if the configuration is set correctly, this is executed from the IDE once you install the device type on the sensor, just place the sensor into inclusion before you hit the button. if you post the output here i can help
Hi @Fuzzyligic
That is now reporting in the logs ok
when input 1 is switched in the device icons both change, but when input 2 is switched neither icons update. also do you know how to make the 2nd input to be usable in smartthings?
Thanks for your help.
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â17: debug parsed 'zw device: 30, command: 600D, payload: 02 02 20 01 FF â to result: [name:contact2, value:open, descriptionText:Alarm9 is open, isStateChange:true, displayed:true, linkText:Alarm9]
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â17: debug Contact is open
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â17: debug ZWaveEvent V3 MultiChannelCmdEncap(bitAddress: false, command: 1, commandClass: 32, destinationEndPoint: 2, parameter: [255], sourceEndPoint: 2)
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â16: debug parsed 'zw device: 30, command: 600D, payload: 02 02 20 01 00 â to result: [name:contact2, value:closed, descriptionText:Alarm9 is closed, isStateChange:true, displayed:true, linkText:Alarm9]
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â16: debug Contact is closed
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â16: debug ZWaveEvent V3 MultiChannelCmdEncap(bitAddress: false, command: 1, commandClass: 32, destinationEndPoint: 2, parameter: [0], sourceEndPoint: 2)
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â10: debug parsed 'zw device: 30, command: 600D, payload: 01 01 20 01 FF â to result: [name:contact, value:open, descriptionText:Alarm9 is open, isStateChange:true, displayed:true, linkText:Alarm9]
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â10: debug Contact is open
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â10: debug ZWaveEvent V3 MultiChannelCmdEncap(bitAddress: false, command: 1, commandClass: 32, destinationEndPoint: 1, parameter: [255], sourceEndPoint: 1)
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â10: debug parsed 'zw device: 30, command: 600D, payload: 01 01 20 01 00 â to result: [name:contact, value:closed, descriptionText:Alarm9 is closed, isStateChange:true, displayed:true, linkText:Alarm9]
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â10: debug Contact is closed
f3899422-ed24-463c-a9b4-ed3504606cee â10â:â56â:â10: debug ZWaveEvent V3 MultiChannelCmdEncap(bitAddress: false, command: 1, commandClass: 32, destinationEndPoint: 1, parameter: [0], sourceEndPoint: 1)
ok cool you have the correct config and you are seeing individual actions for each contact sensor. I made a mistake with the tile i believe, Iâve just pushed a new version of the code, give it a try, each tile should update individually. to use the sensors because they are the same capability? i really donât know how they would appear in the likes of rule machine or in the advanced features (you will need to add capability âactuatorâ to the top of the device type to try it).
but i definitely will be interested soon enough as i was going to purchase another universal sensor as a cheap way to put two contact sensors on my two garage doors.
you can be my guinea pig :
anyway best of luck, let me know how you get on. sorry i cant really help much further as i donât have a device to test on
it works
With some other fibaro devices that I have 2 outputs, I used a custom device, then a smart app and 2 virtual switches to make it all work.
so far I have
your code for the device.
I have hacked the on/off tile to make it
/**
Copyright 2015 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.
On/Off Button Tile
Author: SmartThings
Date: 2013-05-01
*/
metadata {
definition (name: âOn/Off Sensor Tileâ, namespace: âsmartthingsâ, author: âPaul Crookesâ) {
capability "Contact Sensor"
capability "Switch"
capability âSensorâ
}
// simulator metadata
simulator {
}
// UI tile definitions
tiles {
standardTile(âcontactâ, âdevice.contactâ, width: 2, height: 2) {
state âopenâ, label: â${name}â, icon: âst.contact.contact.openâ, backgroundColor: "#ffa81e"
state âclosedâ, label: â${name}â, icon: âst.contact.contact.closedâ, backgroundColor: â#79b821â
}
main "contact"
details "contact"
}
}
def parse(String description) {
}
def on() {
sendEvent(name: âswitchâ, value: âonâ)
}
def off() {
sendEvent(name: âswitchâ, value: âoffâ)
}
and then the custom app
/**
http://www.apache.org/licenses/LICENSE-2.0
*/
definition(
name: âFibaro Universal Sensor Appâ,
namespace: ââ,
author: âPaul Crookesâ,
description: âAssociates Dual Relay Switch Modules with one or two standard SmartThings âswitchâ devices for compatibility with standard control and automation techniquesâ,
category: âMy Appsâ,
iconUrl: âhttps://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.pngâ,
iconX2Url: âhttps://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.pngâ)
preferences {
section(âZWN-RSM2 Module:â) {
input ârsmâ, âcapability.contactSensorâ, title: âWhich FUS Module?â, multiple: false, required: true
input âswitch1â, âcapability.contactSensorâ, title: âFirst Switch?â, multiple: false, required: true
input âswitch2â, âcapability.contactSensorâ, title: âSecond Switch?â, multiple: false, required: false
}
}
def installed() {
log.debug âInstalled!â
//subscribe(rsm, âswitchâ, rsmHandler)
subscribe(rsm, âswitch1â, rsmHandler)
subscribe(rsm, âswitch2â, rsmHandler)
subscribe(switch1, âswitchâ, switchHandler)
subscribe(switch2, âswitchâ, switchHandler)
initialize()
}
def updated() {
log.debug "Updated!"
unsubscribe()
subscribe(rsm, âswitchâ, rsmHandler)
subscribe(rsm, âswitch1â, rsmHandler)
subscribe(rsm, âswitch2â, rsmHandler)
subscribe(switch1, âswitchâ, switchHandler)
subscribe(switch2, âswitchâ, switchHandler)
initialize()
}
def switchHandler(evt) {
//log.debug "switchHandler: ${evt.value}, ${evt.deviceId}, ${evt.source}, ${switch2.id}"
switch (evt.deviceId) {
case switch1.id:
switch (evt.value) {
case âopenâ:
log.debug "switch1 open"
rsm.open1()
break
case âclosedâ:
log.debug "switch1 closed"
rsm.closed1()
break
}
break
case switch2.id:
switch (evt.value) {
case âopenâ:
log.debug "switch2 open"
rsm.open2()
break
case âclosedâ:
log.debug "switch2 closed"
rsm.closed2()
break
}
break
default:
pass
}
}
def rsmHandler(evt) {
log.debug "$evt.name $evt.value"
if (evt.name == âswitch1â) {
switch (evt.value) {
case âopenâ:
Switch1.open()
break
case âclosedâ:
switch1.closed()
break
}
}
else if (evt.name == âswitch2â) {
switch (evt.value) {
case âopenâ:
switch2.open()
break
case âclosedâ:
switch2.closed()
break
}
}
}
def rsmRefresh() {
rsm.refresh()
}
def initialize() {
unschedule()
//def exp = â* * * * * ?â
//log.debug âScheduling RSM refreshesâ
//schedule(exp, rsmRefresh)
// TODO: subscribe to attributes, devices, locations, etc.
}
just need to make it all workâŠ
Paul
After 4 hours, of tinkering I am finished for the moment. will have another look in the week. if anyone else want to chime in please feel free.
I know what is needed but my skills let me down
we need the device app (done by @Fuzzyligic)
2 virtual devices and an app to link the 2 together,
if I get it going I will update you all.
Paul
Hi,
One thing I forgot to mention is that after saving and publishing the code make sure to press the config button to ensure the correct association to group 2 is stablished.
You can also do this by using the simulator, installing the device type in the physical device and then, under Tools, click on the custom button âmultisetâ
This way the 2 inputs should work ok.
Done it
Here is the custom device type, install it then apply to the device and make sure you click configure.
Create 2 simulated contact sensors and then use this app to link the 3 item together:
Paul