[OBSOLETE] Raspberry Pi Device Type

Is your service running on your Pi?

@NickW, @Garnet - The firmware on my hub seems rather old, but the app thinks it’s up to date. Can you tell me what version you have?

My hub has this – the last-updated date is nearly a year ago.

Firmware Version 000.010.00246
Last Updated 2013-11-18 3:00 AM UTC

Thanks,
James

Firmware Version: 000.011.00603
Date created & updated: 2014-06-28

Thanks – then I suspect my problem is the ancient firmware.

Looks like the last firmware update was an hour after I first created the hub. So basically it’s never updated:

Firmware Version 000.010.00246
Date Created 2013-11-18 2:00 AM UTC
Last Updated 2013-11-18 3:00 AM UTC

Any ideas how to force an update? I could try deleting the hub and starting again, but I don’t want to lose all the setup.

@RobM – yes, the service is running on the Pi, I can verify that it responds by sending the POST request with telnet from a mac (see higher up in the thread).

I would try emailing support.

@JamesH - I have Firmware Version 000.011.00603 which appears to be the same @NickW.
Maybe that is the issue, and doesn’t seem like a risk to try. Good Luck and let us know.

Well, it worked! Then I broke it again somehow.

  1. The hub had not updated from 000.010.00246, as shown in the ‘My Hubs’ page of the IDE.
    When I attempted to update from the iOS app, it said 'your hub is up to date’
    After turning on the extra logging events under Support->Help Us Debug, I saw at least one failed firmware update

  2. Contacted support, they pushed an update to:

    Firmware Version 000.011.00705

  3. They also asked me to power cycle the hub, and force-quit iOS app

  4. Deleted the existing Device and Device Type, went through the setup again

    • BTW, it seems that the device loses the config input via the app on the initial setup (install)
    • so you have to re-do it via preferences (update)
    • but setting the preferences directly from the IDE works
  5. Refresh -> ‘an unexpected error occurred’

  6. Set Device Network Id manually via the IDE, to 0a0001e2:1f40

  7. Refresh -> worked … success!

So now, being such an engineer, I decided to do it all over again to get the exact steps to post. And now it doesn’t work any more.

The POST request gets sent to the Pi, the Pi responds, but the ‘parse’ function is never called in the device handler.

Here is the interaction from my packet sniffer:

===================================================================

/usr/local/bin/tshark -r request-response.pcap -q -z follow,tcp,ascii,1

===================================================================
Follow: tcp,ascii
Filter: tcp.stream eq 1
Node 0: 10.0.1.10:2346
Node 1: 10.0.1.226:8000
152
POST /macros/getData HTTP/1.1^M
Accept: /^M
User-Agent: Linux UPnP/1.0 SmartThings^M
HOST: 10.0.1.226:8000^M
Authorization: Basic d2ViaW9waTp3ZWJpb3Bp^M
^M

17

HTTP/1.0 200 OK^M

143

Server: WebIOPi/0.7.0/Python3.2^M
Date: Fri, 14 Nov 2014 15:39:22 GMT^M
Cache-Control: no-cache^M
Content-Type: text/plain^M
Content-Length: 93^M
^M

93

{
“disk_usage”: 18.9,
“mem_avail”: 291.7,
“cpu_temp”: 48.2,
“cpu_perc”: 0.6
}

I’ve tried deleting and recreating multiple times, even with different names, but it doesn’t want to work for me.

OK – back working again. I deleted the ‘Device’ and ‘Device Type’ entries again, and re-created. This time however, I moved the Pi to a different static IP, and now it works, hooray!

So, I suspect a problem routing the response message via the SmartThings cloud to the handler:

  • maybe they linked the old device instance to responses from the original static IP
  • so the new responses don’t get routed to my new device
  • maybe related to the need to set the Device Network Id manually

Maybe I’ll try breaking it again later.

In the meantime, thanks for the help…!

I’m glad you’ve got it working and thanks for the feedback.

I’ve updated the GitHub readme with reference to the firmware version checking and added a troubleshooting section.

One other minor detail – I had to add ‘from time import sleep’ to the top of the python file. Otherwise it complains about the ‘sleep(0.1)’.

Well this is entertaining – it seems that there’s a problem with re-use of Device Network Ids.

As I mentioned above, after deleting everything and starting from scratch, I had problems until I moved the static IP.

Next, I kept the ‘Device Type’ in place and deleted the ‘Device’. After re-installing, the app wasn’t working any more. But this time, I saw logs from two devices … the old (zombie) one and the new one!

Note that there are two ‘Raspberry Pi’ instances, and the request and response messages have different values for the key on the left.

Clicking the first ‘Raspberry Pi’ shows the sender (new Device):

Clicking the second ‘Raspberry Pi’ shows the responses being processed by the old (zombie) Device:

So… I have to conclude that the response message received by the TCP/IP stack on the hub is being routed to the first Device that registered the DNI, and the routing doesn’t get updated when that device is deleted. And it doesn’t get updated when the new Device runs (perhaps related to the need to set the DNI manually in the IDE).

When I changed the port from 8000 to 8001, it still sends the responses to the zombie, until I manually changed the DNI in the IDE. Then it all works again, because the DNI is different, never used before:

So there is definitely a problem with setting the device network id in this code, and maybe a problem with the SmartThings cloud as well.

Repository updated. Thanks for the feedback.

I wonder if we need to implicitly delete the old device during the uninstall. See the bottom of this page under “Implicit Removal of Child Devices”. Maybe we need to make the Raspberry Pi app as a device manager app instead similar to the Sonos (connect) SmartApp.

That does look promising. Also, there is a mention of the need to use a SmartApp when using LAN.
http://docs.smartthings.com/en/latest/introduction/what-can-developers-do/smartapp-overview.html

I did try getting a SmartApp to pass the device network id without success, but that was last week, when everything was a mystery. Unlike now when it all makes perfect sense, ha ha.

Related – it looks like a SmartApp can call the runIn() method, which would allow for a callback after a respectable period to check for a response. That doesn’t seem to be available to devices. I’ve not figured out how to get a callback after a delay.

Also related, I made some changes to your code, to reduce activity log updates and add a feature:

  • Send values as integers - the temp/mem/utilization values are displayed as integers on the icons anyhow, and sending integers in the events reduces the number of changes in the activity log.
  • Set the switch state based on request/response timestamps. Store timestamps at POST and parse(). At POST, if the last request was later than the last response → set switch to ‘off’. Each parse() implies a response from a happy Pi, so set switch to ‘on’. When the Pi goes down, the on/off state will update on the next poll, or when the user presses ‘refresh’ again. Since the on/off state is stable (though delayed), triggers for push notifications would make sense.
  • Added a button to switch a device controlled by the pi, and use the response to confirm. A button press changes from ‘off’ to ‘>on’ (orange), and updates to ‘on’ (green) at the response from the Pi. Same for ‘on’ to ‘>off’ to ‘off’.

I’ll send you the changes later.

@JamesH, @NickW: Maybe a adding a SmartApp is the right approach. I have been trying to get delayed responses and callbacks from the Raspberry Pi in the Device Type and it doesn’t seem to work. Specifically, any response more than 5 seconds old is ignored, and ST requires your device handler code to complete in 20 seconds or it literally times it out.
The Raspberry Pi really needs an event callback (Ex: door opened) capability initiated from the Pi which could then be used to create any type of device with the Pi - Door Sensors, inexpensive IP Camera, Garage Door Controller and Monitor (I have the Controller part working already), Flood monitor, etc. (These events call be easily initiated in the loop() function of WebIOPi)
ST does reference Registering for Callbacks: If you’d like to hear back from a LAN connected device upon a particular event, you need to register for a callback. You can subscribe to an event of the device, passing the device your hubs IP address as well as a path to callback to subscribeAction()

@Garnet, I noticed that the WeMo Motion device uses that callback to receive upnp events. So using that would allow the webiopi/python code to send messages to the smartthings device.

I don’t know if webiopi can generate upnp events already, but presumably there must be a python module for upnp.

Thanks @JamesH. I have looked at this, but it may beyond my ability. I understand the concept of sever-sent events, but figuring how to really get this to work on Raspberry Pi is another thing. Thanks again though.

Excellent write up @NickW - it was easy to follow. I was up and running in an hour. Thank you for putting this together.

I’m hoping to wire this up to trigger a relay attached to a specific GPIO port. Similar project: https://www.youtube.com/watch?v=3Pikhq99q5E

Does anyone have a starting point or documentation of where I should look so I can rework Nick’s raspberry pi device type groovy code to expose one of the GPIO ports for output as a SmartThings Switch I can use in a SmartApp?

Thank you!

If I’m not mistaken the method would be to write a macro in Nick’s python script on github that sets a GPIO port for output and then sets the state to be on or off. Then program panel code in Nick’s raspberry pi device type groovy code to expose the macro as a switch that can be incorporated into a SmartApp?