Propeller & SmartThings - Custom Device Handler
Jon Keinath
Posts: 146
in Propeller 1
I recently followed this post by JohnR2010 and was able to connect my Propeller to my SmartThings hub and verify that the connection was working correctly. I am attempting to make a multiple zone heating interface module that can monitor a bunch of digital inputs and outputs and provide a quick glance overview of how everything is currently running and allow some interaction from other SmartThing devices for temperatures and such. To start understanding the code, I am trying to add control of a second LED to the basic code provide in the post above. I figured I could just add a second tile to the SmartThings code and have it send a different hex code to the Propeller for the second output. Here is what I tried:
First, I added a second tile like the first...
I then modified the P1 SPIN code with a statement to do something with the new command...
After loading the code, I get the two tiles on SmartThings, but nothing happens with the second button. What am I missing? The first tile/LED still work as normal, but nothing happens on the second. I don't get any feedback from the SmartThings debugger either. I'm guessing the SmartThings (groovy) code is the issue, since the P1 code seems very straight forward and I have used it more, but I don't know where to start. I've had difficulty finding groovy code examples that combine two outputs that don't look completely different than the original example. Any ideas?
First, I added a second tile like the first...
standardTile("switch1", "device.switch", width: 2, height: 2, canChangeIcon: true) { state "off", label: '${name}', action: "Switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff" state "on", label: '${name}', action: "Switch.off", icon: "st.switches.switch.on", backgroundColor: "#0044ff" } standardTile("switch2", "device.switch", width: 2, height: 2, canChangeIcon: true) { state "off", label: '${name}', action: "Switch.on2", icon: "st.switches.switch.off", backgroundColor: "#ffffff" state "on", label: '${name}', action: "Switch.off2", icon: "st.switches.switch.on", backgroundColor: "#00ffff" }I then I added the actions (only "on" shown in this example).
def on() { log.debug "Relay 1 on()" sendEvent(name: "switch1", value: "on") "st cmd 0x${device.deviceNetworkId} 0x38 0x0006 0x1 {}" } def on2() { log.debug "Relay 2 on()" sendEvent(name: "switch2", value: "on") "st cmd 0x${device.deviceNetworkId} 0x38 0x0006 0x3 {}" }
I then modified the P1 SPIN code with a statement to do something with the new command...
if frmType == $01 AND cmdID == $01 AND attributeID == $00 ' Set device On dira[LEDPin]~~ ' Set as Output outa[LEDPin]~~ ' Set High 3.3V sendDefaultResponse (CmdID, $00, $38) ' Send Default response back to originator of command pst.str(String(CR,"LED On (Pin ")) pst.dec(LEDPin) pst.str(String(" set to 3.3v)")) if frmType == $01 AND cmdID == $03 AND attributeID == $00 ' Set device On dira[LEDPin2]~~ ' Set as Output outa[LEDPin2]~~ ' Set High 3.3V sendDefaultResponse (CmdID, $00, $38) ' Send Default response back to originator of command pst.str(String(CR,"LED2 On (Pin ")) pst.dec(LEDPin2) pst.str(String(" set to 3.3v)"))
After loading the code, I get the two tiles on SmartThings, but nothing happens with the second button. What am I missing? The first tile/LED still work as normal, but nothing happens on the second. I don't get any feedback from the SmartThings debugger either. I'm guessing the SmartThings (groovy) code is the issue, since the P1 code seems very straight forward and I have used it more, but I don't know where to start. I've had difficulty finding groovy code examples that combine two outputs that don't look completely different than the original example. Any ideas?
Comments
I was able to verify that it must be in the SmartThings code. I changed the cmdID in the working tile from $01 to $03 and the propeller responded correctly.
Just add these two lines in the metadata section at the top of your DTH:
command "on2"
command "off2"
You didn't have to define on1 and off1 as commands because they are standard commands in the switch capability.
Just as an FYI the correct way (ZigBee Standard) to send commands to a second switch is to send the on command to a different endpoint. So here are the two commands to send the on command to two relays. Notice the cluster and the command is the same only the endpoint number changes: of course your going to have to update the SPIN code to accommodate multiple endpoints.
You will also most likely need to change the way you call on2 and off2 from "Switch.on2" to "on2". Do it like this:
One more tip is to add some logging to your SmartThings DTH. Put the following line in your on2 method just before you send the ZigBee packet: You will see the logged information under logging in your SmartThings IDE. This is a good way to make sure the logic in your DTH is functioning the way you expect.
Oh one last thing. Great job on getting this far!! Your well on your way sounds like a great project!!
I set up a github for my code now too...
Yea the Aux1 On and Aux2 On are "vendor specific commands" of the 0x0101 door lock cluster (see page 344 of ZigBee spec). Sorry that is probably a bad example for the switch cluster. Each ZigBee cluster has a defined set of commands and attributes that should be used according to the spec. However, most cluster definitions also set aside a range of unused command numbers and attribute numbers for "vendor specific functions". The whole idea behind this if you say your device uses the switch cluster then any device on the ZigBee network will know how to turn your device on and off because the on and off command is defined for that cluster. So if your device uses a command number that doesn't fall into the "vendor specific function" for a unique function your device wont be ZigBee compliant. It will work OK for testing but not good practice. SmartThings will not certify it. Just an FYI. One thing I do fairly early on is map out the cluster numbers, commands, and attributes my application is going to use. I try to use standard commands and attributes where I can and "vendor specific functions" for the data or commands that don't fit.
If you have a device that is going to use the switch cluster to turn on and off more than one switch the standard way of doing that is to use multiple endpoints (one for each switch). It will actually make your code very clean. You can write a spin method that takes two parameters like this. The switchNumber variable can be the endpoint number and also the propeller pin and the onOff can be one or zero. End point numbers 0x00 and 0xFF are reserved. If a destination endpoint is 0x00 that means the packet is a ZigBee Device Objects packet (ZDO). If the destination endpoint is 0xFF that is a broadcast endpoint and your application should turn on or off all switches if it receives an 0xFF endpoint. So with one command sent to endpoint 0xFF you can turn on all your switches!!
Sounds like your project is going to work with temperature so the temperature Measurement Cluster 0x0402 on page 250 of the ZigBee spec is a good place to start.