Search code examples
pythonibm-cloudiot

IoT Python app with a Raspberry Pi and Bluemix: Cannot turn on/off lights and send message using the button


I did the following tutorial to connect my Raspberry Pi with an application on Bluemix using the IoT Foundation:

https://developer.ibm.com/bluemix/2015/04/02/tutorial-using-a-raspberry-pi-python-iot-twilio-bluemix/

I had everything up and running except the client.py (step 36 in the tutorial). I got the following error message:

client.py:9: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  GPIO.setup(17, GPIO.OUT)
Traceback (most recent call last):
  File "client.py", line 23, in <module>
    options = ibmiotf.application.ParseConfigFile("/home/pi/device.cfg")
  File "/usr/local/lib/python2.7/dist-packages/ibmiotf/application.py", line 501, in ParseConfigFile
    appType = parms.get(sectionHeader, "type", "standalone")
  File "/usr/lib/python2.7/ConfigParser.py", line 618, in get
    raise NoOptionError(option, section)
ConfigParser.NoOptionError: No option 'type' in section: 'application'

I found out the the error came from the missing "type" section in the config file (device.cfg).

The file structure listed in step 35 of the tutorial doesn't say, that you need a "type". I used the device type (raspberrypi) that I created before in the IoT Foundation.

Now I did connect to the IoT Foundation successfully.

The problem that I have now is, that nothing is happening when I either press the button on my Raspberry Pi or the "Turn light on/off" buttons of the web application.

If I check the logs of the python app using "./cf logs myappname -recent" I get the following output:

2016-01-29T08:38:49.10+0100 [App/0]      OUT on
2016-01-29T08:38:49.10+0100 [App/0]      ERR 75.126.37.74 - - [29/Jan/2016 07:38:49] "POST /light/on HTTP/1.1"; 302 -
2016-01-29T08:38:49.34+0100 [App/0]      ERR 75.126.52.20 - - [29/Jan/2016 07:38:49] "GET / HTTP/1.1"; 200 -
2016-01-29T08:38:49.56+0100 [RTR/1]      OUT myappname.mybluemix.net - [29/01/2016:07:38:49 +0000] "GET / HTTP/1.1" 200 0 751 "http://myappname.mybluemix.net/&quot; ";Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36" 108.168.250.151:39460 x_forwarded_for:&quot;46.5.2.236"x_forwarded_proto:"http&quot; vcap_request_id:myrequestid response_time:0.31228492 app_id:myapp_id x_global_transaction_id:mytransactionid;
2016-01-29T08:40:08.32+0100 [App/0]      OUT off
2016-01-29T08:40:08.33+0100 [App/0]      ERR 75.126.37.74 - - [29/Jan/2016 07:40:08] "POST /light/off HTTP/1.1" 302 -
2016-01-29T08:40:08.51+0100 [App/0]      ERR 75.126.23.243 - - [29/Jan/2016 07:40:08] "GET / HTTP/1.1" 200 -`

The writer of the tutorial, Jeff, said that I should double check that the Pi and the app in Bluemix are both listening on the same topic. And in the IoT service I should be able to see messages coming through.

I don't know what this means or how I do this.

We already had an discussion about my problems in the comment section of the youtube video of the blog post (https://www.youtube.com/watch?v=YHDhn5hGnn8) and Jeff told me we should move to StackOverflow with it (makes sense).

I appreciate your help.

// edit for additional information // This is the output I get on the Pi, when I start the application: sudo python client.py

2016-02-01 14:36:23,221   ibmiotf.application.Client  WARNING Unable to encrypt messages because TLSv1.2 is unavailable (MQTT over SSL requires at least Python v2.7.9 or 3.4 and openssl v1.0.1)
2016-02-01 14:36:23,716   ibmiotf.application.Client  INFO    Connected successfully: A:69wm3f:aaaafdsfsd45641safsda2313

If I press the on/off buttons for the first time after the client has started I get the following output on the Pi:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 505, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2287, in _thread_main
    self.loop_forever()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1261, in loop_forever
    rc = self.loop(timeout, max_packets)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 811, in loop
    rc = self.loop_read(max_packets)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1073, in loop_read
    rc = self._packet_read()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1475, in _packet_read
    rc = self._packet_handle()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1943, in _packet_handle
    return self._handle_publish()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2118, in _handle_publish
    self._handle_on_message(message)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2268, in _handle_on_message
    t[1](self, self._userdata, message)
  File "/usr/local/lib/python2.7/dist-packages/ibmiotf/application.py", line 423, in __onDeviceEvent
    if self.deviceEventCallback: self.deviceEventCallback(event)
  File "client.py", line 17, in myCommandCallback
    command = cmd.payload["d"]["command"]
TypeError: string indices must be integers, not str

It looks like the messages from the IoT Foundation are reaching the client.

I set the following IDs on the IoT Foundation, the environment variable of the Bluemix Python app and on the Raspberry Pi:

  • IoT Foundation ID: afdsfsd45641safsda2313
  • Bluemix Python app ID: afdsfsd45641safsda2313
  • Raspberry Pi ID in device.cfg: afdsfsd45641safsda2313

All three IDs are the same.

// edit 2 // Logging output after adding the print cmd statements from the comment section:

<ibmiotf.application.Event instance at 0x76526738>
light
{"command": "on"}

Stacktrace after changing

command = cmd.payload["d"]["command"]

to

command = cmd.payload["command"]

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 505, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2287, in _thread_main
    self.loop_forever()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1261, in loop_forever
    rc = self.loop(timeout, max_packets)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 811, in loop
    rc = self.loop_read(max_packets)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1073, in loop_read
    rc = self._packet_read()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1475, in _packet_read
    rc = self._packet_handle()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 1943, in _packet_handle
    return self._handle_publish()
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2118, in _handle_publish
    self._handle_on_message(message)
  File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2268, in _handle_on_message
    t[1](self, self._userdata, message)
  File "/usr/local/lib/python2.7/dist-packages/ibmiotf/application.py", line 423, in __onDeviceEvent
    if self.deviceEventCallback: self.deviceEventCallback(event)
  File "client.py", line 18, in myCommandCallback
    command = cmd.payload["command"]
TypeError: string indices must be integers, not str

Solution

  • Turns out the IBM IoT Foundation library changed in the way it parses JSON...

    Change line 15

    command = cmd.payload["d"]["command"]
    

    to

    payload = json.loads(cmd.payload)
    command = payload["command"]