cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Posting Property Updates from a Raspberry PI with Python Using REST

Highlighted
Level 1

Posting Property Updates from a Raspberry PI with Python Using REST

Recently a customer from the ThingWorx Academic Program sent in a sample program they were having problems with. They were trying to post data from a Raspberry PI using Python to their ThingWorx server. It turns out that their program did work just fine and was also a great example of posting data from a PI using REST.

Here is how to set up this example.

1. Import the attached "Things_TempAndHumidityThing.xml" entity file.

2. from the PI run 'sudo pip install requests'

3. from the PI run 'sudo pip install logging'

4. from the PI run 'sudo pip install http_client'

5. Create a python file call test.py that contains this example code:

#!/usr/bin/python

import requests

import json

import logging

import sys

# These two lines enable debugging at httplib level (requests->urllib3->http.client)

# You will see the REQUEST, including HEADERS and DATA, and RESPONSE with HEADERS but without DATA.

# The only thing missing will be the response.body which is not logged.

try:

    import http.client as http_client

except ImportError:

    # Python 2

    import httplib as http_client

http_client.HTTPConnection.debuglevel = 1

# You must initialize logging, otherwise you'll not see debug output.

logging.basicConfig()

logging.getLogger().setLevel(logging.DEBUG)

requests_log = logging.getLogger("requests.packages.urllib3")

requests_log.setLevel(logging.DEBUG)

requests_log.propagate = True

#NYP Webserver URL in Thingworx

NYP_Webhost = sys.argv[1]

App_Key = sys.argv[2]

ThingName = 'TempAndHumidityThing'

headers = { 'Content-Type': 'application/json', 'appKey': App_Key }

payload = { 'Prop_Temperature': 45, 'Prop_Humidity': 33 }

response = requests.put(NYP_Webhost + '/Thingworx/Things/' + ThingName + '/Properties/*', headers=headers, json=payload, verify=False)

6. From the command line run, './test.py http://twhome:8080 e9274d87-58aa-4d60-b27f-e67962f3e5c4' except substitute your server and your app key.

7. A successful response should look like:

INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): twhome

send: 'PUT /Thingworx/Things/TempAndHumidityThing/Properties/* HTTP/1.1\r\nHost: twhome:8080\r\nappKey: e9274d87-58aa-4d60-b27f-e67962f3e5c4\r\nContent-Length: 45\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.8.1\r\nConnection: keep-alive\r\nContent-Type: application/json\r\n\r\n{"Prop_Temperature": 45, "Prop_Humidity": 33}'

reply: 'HTTP/1.1 200 OK\r\n'

header: Server: Apache-Coyote/1.1

header: Set-Cookie: JSESSIONID=E7436D2E6AE81C84EC197D406E7E365A; Path=/Thingworx/; HttpOnly

header: Expires: 0

header: Cache-Control: no-store, no-cache

header: Cache-Control: post-check=0, pre-check=0

header: Pragma: no-cache

header: Content-Type: text/html;charset=UTF-8

header: Transfer-Encoding: chunked

header: Date: Mon, 09 Nov 2015 12:39:24 GMT

DEBUG:requests.packages.urllib3.connectionpool:"PUT /Thingworx/Things/TempAndHumidityThing/Properties/* HTTP/1.1" 200 None

My thanks to the customer who sent in the simple example.

19 REPLIES 19

Re: Posting Property Updates from a Raspberry PI with Python Using REST

If you are trying to post data via REST you should look into using MQTT. Here is another article I wrote that talks about MQTT and Arduino but it may still be relevant. Delivering Arduino Collected Data to ThingWorx using MQTT

Re: Posting Property Updates from a Raspberry PI with Python Using REST

hello,

I have tried the above code for connecting to thingworx.For localhost the url is working fine and data is displayed on thingworx but when tried running python code in my system and push data to other remote IP address, error message is displayed saying 403 forbidden error.

From command line i have typed following command:

python test.py http://remote-ip-address:80 (appkey)

Can you suggest me where I am getting wrong

Re: Posting Property Updates from a Raspberry PI with Python Using REST

There are a few possibilities.

1. Is your thingworx server on port 80 or port 8080. The 403 error may be coming from a server other than ThingWorx

2. You many not have an appKey or your appKey may not be present or have the privileges needed on the server you are trying to connect to.

Please attach your console output so I can be more specific.

Re: Posting Property Updates from a Raspberry PI with Python Using REST

Hi Bill,

Thanks for posting your code it's been really useful. I'm not having a similar issue as Preethi in that I was able to get my Raspberry Pi to make restful posts to a local Thingworx server I had running in a VM. I've now created a Thingworx Foundation server running in the cloud and I'm getting a '405' error - not sure what I'm doing wrong, I thin I've got the setup indentitcal but obviously not! Any help would be appreciated, thanks Pete

Console output:

INFO:urllib3.connectionpool:Starting new HTTP connection (1): 52.204.140.39

send: 'PUT //Thingworx/Things/PressureTemperatureThing/Properties/* HTTP/1.1\r\nHost: 52.204.140.39\r\nappKey: <my-app-key>\r\nContent-Length: 35\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.4.3 CPython/2.7.9 Linux/4.4.11-v7+\r\nConnection: keep-alive\r\nContent-Type: application/json\r\n\r\n{"Pressure": 23, "Temperature": 42}'

reply: 'HTTP/1.1 405 Method Not Allowed\r\n'

header: Server: Apache-Coyote/1.1

header: Expires: 0

header: Cache-Control: no-store, no-cache

header: Cache-Control: post-check=0, pre-check=0

header: Pragma: no-cache

header: Content-Type: text/html;charset=UTF-8

header: Transfer-Encoding: chunked

header: Date: Mon, 27 Jun 2016 07:36:35 GMT

DEBUG:urllib3.connectionpool:"PUT //Thingworx/Things/PressureTemperatureThing/Properties/* HTTP/1.1" 405 None

>>>

Re: Posting Property Updates from a Raspberry PI with Python Using REST

Is there anything in your application or security logs on your server?

Right now it still looks like your server may be configured to not permit this call.

Re: Posting Property Updates from a Raspberry PI with Python Using REST

Hi Bill,

Thanks for getting back to me. Quite strange - I'm logged in as 'Administrator' but I'm unable to access the logs....

I've checked on my local VM and I can't access them there either - am I missing something here?

Pete

logs.jpg

Re: Posting Property Updates from a Raspberry PI with Python Using REST

Yes. that is strange.

We need to pull in whoever is managing your system.

Do you know who that is?

Re: Posting Property Updates from a Raspberry PI with Python Using REST

Hi. I am getting an error at step 6. error.PNG

Re: Posting Property Updates from a Raspberry PI with Python Using REST

It looks like you are trying to connect on thingworx on your local machine. There is an error in your connection URL. Try http://localhost:80/Thingworx . Also try http://localhost:8080/Thingworx as this is the default port used when you first run ThingWorx.