Fibaro - Universal Binary Sensor - Does it work with Smart Things

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
}
1 Like

OK - figured out how to pass data back and forth between the driver and the smart app.
Progress is slow but it is progress
 :wink:

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 :smiley: 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 ::stuck_out_tongue:
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 :frowning:

it works :smiley:

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

/**

  • Dual Relay Adapter (i.e. Enerwave ZWN-RSM2 Adapter, Monoprice Dual Relay, Philio PAN04)
  • Copyright 2014 Joel Tamkin
  • 2015-10-29: erocm123 - I removed the scheduled refreshes for my Philio PAN04 as it supports instant
  • status updates with my custom device type
  • 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.

*/
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 :frowning:

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

1 Like

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 :smiley:

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