SwannOne Key Fob Support (updated 2019 DTH in post #51)

So far, I haven’t. Approval of my device is pending these system changes. Don’t know if I’ll need to make any changes yet

Scott, do you have a ZigBee sniffer you can fire up and see what is going on? I don’t have any of these devices and my free sniffer software has expired anyway.

I could never get the sniffed traffic decrypted, so it was of limited use. I think I tried Ubiqua trial, but that was short-lived.

Total speculation but:
It might be something with how ST joins to zigbee remotes since it seems they all try to join constantly. Maybe ST doesn’t identify the hub as an end device at all, so the outClusters of these remotes think they’re unpaired. Some remotes like the Lutron and Securifi will work anyway, but others think there’s a problem.

1 Like

I have noticed when a device sends a device announce packet it triggers the hub’s ID process and the hub says its joining the network. Normally battery powered devices don’t send a device announce every time they are activated. I wonder if something is causing the fob to be orphaned and it sends a device announce when it finds a new parent or reconnects to the old one. I have seen other devices that have extend sleep cycles get orphaned by ZigBee routers. My gut tells me it has something to do with that parent child poll timeout. But I’m just guessing without a trace to look at.

1 Like

Unsure if this helps… Forgot I saved these logs from this past weekend.
Here is the fingerprint:
rawDescription desc: 01 0104 0401 00 05 0000 0003 0001 0500 0000 02 0003 0501

Below is the log during the enroll process and me pushing different buttons:
975bea70-1699-4de3-a762-459b9f6b8396 2:13:44 PM: debug SmartShield(clusterId: 0x0501, command: 0x00, data: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], destinationEndpoint: 0x01, direction: 0x00, isClusterSpecific: true, isManufacturerSpecific: false, manufacturerId: 0x0000, messageType: 0x00, number: null, options: 0x0100, profileId: 0x0104, senderShortId: 0x8a97, sourceEndpoint: 0x01, text: null)
975bea70-1699-4de3-a762-459b9f6b8396 2:13:44 PM: debug [raw:0104 0501 01 01 0100 00 8A97 01 00 0000 00 00 00000000000000000000, profileId:0104, clusterId:0501, clusterInt:1281, sourceEndpoint:01, destinationEndpoint:01, options:0100, messageType:00, dni:8A97, isClusterSpecific:true, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[00, 00, 00, 00, 00, 00, 00, 00, 00, 00]]
975bea70-1699-4de3-a762-459b9f6b8396 2:13:44 PM: debug Parsing 'catchall: 0104 0501 01 01 0100 00 8A97 01 00 0000 00 00 00000000000000000000’
975bea70-1699-4de3-a762-459b9f6b8396 2:13:42 PM: debug Parse returned Swann One Key Fob button 2 was pushed
975bea70-1699-4de3-a762-459b9f6b8396 2:13:42 PM: debug Away button Pushed
975bea70-1699-4de3-a762-459b9f6b8396 2:13:42 PM: debug SmartShield(clusterId: 0x0501, command: 0x00, data: [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], destinationEndpoint: 0x01, direction: 0x00, isClusterSpecific: true, isManufacturerSpecific: false, manufacturerId: 0x0000, messageType: 0x00, number: null, options: 0x0100, profileId: 0x0104, senderShortId: 0x8a97, sourceEndpoint: 0x01, text: null)
975bea70-1699-4de3-a762-459b9f6b8396 2:13:42 PM: debug [raw:0104 0501 01 01 0100 00 8A97 01 00 0000 00 00 03000000000000000000, profileId:0104, clusterId:0501, clusterInt:1281, sourceEndpoint:01, destinationEndpoint:01, options:0100, messageType:00, dni:8A97, isClusterSpecific:true, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[03, 00, 00, 00, 00, 00, 00, 00, 00, 00]]
975bea70-1699-4de3-a762-459b9f6b8396 2:13:42 PM: debug Parsing 'catchall: 0104 0501 01 01 0100 00 8A97 01 00 0000 00 00 03000000000000000000’
975bea70-1699-4de3-a762-459b9f6b8396 2:13:40 PM: debug Parse returned Swann One Key Fob button 3 was pushed
975bea70-1699-4de3-a762-459b9f6b8396 2:13:40 PM: debug Night button Pushed
975bea70-1699-4de3-a762-459b9f6b8396 2:13:40 PM: debug SmartShield(clusterId: 0x0501, command: 0x00, data: [0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], destinationEndpoint: 0x01, direction: 0x00, isClusterSpecific: true, isManufacturerSpecific: false, manufacturerId: 0x0000, messageType: 0x00, number: null, options: 0x0100, profileId: 0x0104, senderShortId: 0x8a97, sourceEndpoint: 0x01, text: null)
975bea70-1699-4de3-a762-459b9f6b8396 2:13:40 PM: debug [raw:0104 0501 01 01 0100 00 8A97 01 00 0000 00 00 02000000000000000000, profileId:0104, clusterId:0501, clusterInt:1281, sourceEndpoint:01, destinationEndpoint:01, options:0100, messageType:00, dni:8A97, isClusterSpecific:true, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[02, 00, 00, 00, 00, 00, 00, 00, 00, 00]]
975bea70-1699-4de3-a762-459b9f6b8396 2:13:40 PM: debug Parsing 'catchall: 0104 0501 01 01 0100 00 8A97 01 00 0000 00 00 02000000000000000000’
975bea70-1699-4de3-a762-459b9f6b8396 2:13:10 PM: debug Parse returned Swann One Key Fob button 1 was pushed
975bea70-1699-4de3-a762-459b9f6b8396 2:13:10 PM: debug Home button Pushed
975bea70-1699-4de3-a762-459b9f6b8396 2:13:10 PM: debug SmartShield(clusterId: 0x0500, command: 0x0b, data: [0x00, 0x00], destinationEndpoint: 0x01, direction: 0x01, isClusterSpecific: false, isManufacturerSpecific: false, manufacturerId: 0x0000, messageType: 0x00, number: null, options: 0x0140, profileId: 0x0104, senderShortId: 0x8a97, sourceEndpoint: 0x01, text: null)
975bea70-1699-4de3-a762-459b9f6b8396 2:13:10 PM: debug [raw:0104 0500 01 01 0140 00 8A97 00 00 0000 0B 01 0000, profileId:0104, clusterId:0500, clusterInt:1280, sourceEndpoint:01, destinationEndpoint:01, options:0140, messageType:00, dni:8A97, isClusterSpecific:false, isManufacturerSpecific:false, manufacturerId:0000, command:0B, direction:01, data:[00, 00]]
975bea70-1699-4de3-a762-459b9f6b8396 2:13:10 PM: debug Parsing 'catchall: 0104 0500 01 01 0140 00 8A97 00 00 0000 0B 01 0000’
975bea70-1699-4de3-a762-459b9f6b8396 2:13:10 PM: debug Parse returned Swann One Key Fob button 1 was pushed
975bea70-1699-4de3-a762-459b9f6b8396 2:13:10 PM: debug Home button Pushed
975bea70-1699-4de3-a762-459b9f6b8396 2:13:10 PM: debug SmartShield(clusterId: 0x0501, command: 0x00, data: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], destinationEndpoint: 0x01, direction: 0x00, isClusterSpecific: true, isManufacturerSpecific: false, manufacturerId: 0x0000, messageType: 0x00, number: null, options: 0x0100, profileId: 0x0104, senderShortId: 0x8a97, sourceEndpoint: 0x01, text: null)
975bea70-1699-4de3-a762-459b9f6b8396 2:13:10 PM: debug [raw:0104 0501 01 01 0100 00 8A97 01 00 0000 00 00 00000000000000000000, profileId:0104, clusterId:0501, clusterInt:1281, sourceEndpoint:01, destinationEndpoint:01, options:0100, messageType:00, dni:8A97, isClusterSpecific:true, isManufacturerSpecific:false, manufacturerId:0000, command:00, direction:00, data:[00, 00, 00, 00, 00, 00, 00, 00, 00, 00]]
975bea70-1699-4de3-a762-459b9f6b8396 2:13:10 PM: debug Parsing 'catchall: 0104 0501 01 01 0100 00 8A97 01 00 0000 00 00 00000000000000000000’
975bea70-1699-4de3-a762-459b9f6b8396 2:13:08 PM: debug enroll response: [raw 0x500 {01 23 00 00 00}, delay 200, send 0x8A97 01 1]
975bea70-1699-4de3-a762-459b9f6b8396 2:13:08 PM: debug Sending enroll response
975bea70-1699-4de3-a762-459b9f6b8396 2:13:08 PM: debug [:]
975bea70-1699-4de3-a762-459b9f6b8396 2:13:08 PM: debug Parsing 'enroll request endpoint 0x01 : data 0x0015’
975bea70-1699-4de3-a762-459b9f6b8396 2:12:41 PM: debug parse description: updated
975bea70-1699-4de3-a762-459b9f6b8396 2:12:41 PM: debug [:]
975bea70-1699-4de3-a762-459b9f6b8396 2:12:41 PM: debug Parsing 'updated’
975bea70-1699-4de3-a762-459b9f6b8396 2:12:41 PM: debug Config Called

That’s what we would expect to see, so nothing interesting there. I have an idea.

Can someone add this bit of code to a refresh() command? Then after pairing the device and confirming ST sees the button presses, try pressing refresh and posting the response here.

“st rattr 0x${device.deviceNetworkId} ${endpointId} 3 1”

Scott, this device type doesn’t have a refresh function in it. Can it be placed in config or elsewhere?

This attribute should get updated during the join process, so I don’t want to include it with Configure and there aren’t any other functions. Refresh is easily added though.

At the top with the other capabilities:
capability "Refresh"

Somewhere in the body:
def refresh() { "st rattr 0x${device.deviceNetworkId} ${endpointId} 3 1" }

If you need a tile to call the function, you can add this to the tiles section:
standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
}

And then modify the details line to:

details (["button","refresh"])

OK added the function to the device type, repaired the device and clicked the refresh button. Only 1 entry appeared in the log confirming I pressed the refresh button. Here is that event:

refresh command was sent to Swann One Key Fob
Name Value
archivable true
commandId 392
date 2016-01-13 11:47:09.970 AM EST (2016-01-13T16:47:09.970Z)
description refresh command was sent to Swann One Key Fob
deviceId cafc18b2-5e6b-482e-8946-8595d0d60626
displayed false
eventSource COMMAND
hubId 831b43e3-70c7-4e2c-ae70-06116d5c9c17
id 49c9a720-ba15-11e5-b531-22000bf92232
isStateChange true
isVirtualHub false
linkText refresh
locationId cc5850ed-51c3-405b-8a5a-6cc8abcf18aa
rawDescription refresh
translatable false
unixTime 1452703629970
value refresh
viewed false

That was in Live Logging? Or List Events?

I was expecting (maybe hoping) for a response back from the remote, so you’d see messages similar to what you see in the logs you posted above.

List events with polling turned on. Live Logging doesn’t appear to be working at the moment for me as nothing appears there other than “waiting for events…”. Maybe ST is having an issue with live logging at the moment.

Edit: even verified my motions are not showing up in live logging either. I am happy to try this later as well.

Ok, I think Live Logging is needed because the real info will be in a “debug” line and I don’t think those are ever presented in the List Events.

Post back if you get it working.

(How nice it would be if Live Logging always worked…)

Scott, just tried live logging and its seems to be working again. I got immediate updates for all my button presses. I clicked the refresh button and nothing showed up in live logging. Just to confirm my device code, here it is:
https://github.com/mlritchie/SmartThings-1/blob/master/devicetypes/RudiP/Swann-One-Key-Fob.src/Swann-One-Key-Fob.groovy

Bummer…What if you change the 1 to a 0 at the end of the code portion? This could verify that it’s working since 0 is a mandatory attribute.

Scott, I changed the last digit to a 0 and unfortunately that isn’t logging anything additional either. I see the refresh command in the event list, but nothing shows up in the live logging. Should I have any additional debug statements in the code to capture what you are looking for?

I didn’t think so. It should have caught the last debug in the second else section. You can try adding log.debug description as the first line in parse, so it’s not contingent on the if() blocks.

Also, press refresh shortly after pressing one of the buttons on the fob. It may not be staying “awake” long enough, so closer to a button should help.

If that still doesn’t work, we can try adding it to the configure section so it fires during the join process. The device will definitely be awake then.

We should be getting some kind of response even if it’s the zigbee version of “unsupported attribute”.

Unfortunately I am not getting anything even after hitting refresh just after a fob button press. I added a debug statement to the top of the parse function and I don’t get anything when I hit the refresh tile on my phone. I do get this output when I press a button on the fob in case it helps:
SmartShield(clusterId: 0x0501, command: 0x00, data: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], destinationEndpoint: 0x01, direction: 0x00, isClusterSpecific: true, isManufacturerSpecific: false, manufacturerId: 0x0000, messageType: 0x00, number: null, options: 0x0100, profileId: 0x0104, senderShortId: 0x56aa, sourceEndpoint: 0x01, text: null)

Edit: I even put in a log.debug “Refresh hit” in my refresh function to make sure it was getting registered and I did get this in the live logging.

Finally! Looked in GitHub at other refresh functions and changed it to the following:
def refresh() {
log.debug “Refresh hit”
[
“st rattr 0x${device.deviceNetworkId} ${device.endpointId} 3 1”,
]
}

Changing ${endpiontId} to ${device.endpointId} seemed to do the trick. Below showed up in the log.

parse description: read attr - raw: 56AA01000306010086, dni: 56AA, endpoint: 01, cluster: 0003, size: 06, attrId: 0001, result: unsupported attr

I also just updated the code in GitHub too, see post 33, with my entire device handler just in case. I changed all of the ${endpointId}'s to ${device.endpointId} and reset the device and then readded it. Hoping maybe that will make a difference with some of the config commands too. I will know in the morning if this device is still connected.

There’s that unsupported message. I was afraid we’d get that. It means that attribute wasn’t implemented.

That attribute was the optional CommissionState Attribute. I found it in the zigbee home automation spec and it talked about when a device would decide it wasn’t paired. That attribute was one factor a device should consider. It is basically an indicator that the device paired and is in an operational state. I thought maybe it wasn’t being populated and we could manually do it.

Sorry, I’m out of ideas. Hopefully your updated code helps; otherwise we might have to wait for ST to figure it out.

1 Like