├── .gitignore ├── LICENSE ├── README.md ├── awsiotpub.py ├── awsiotsub.py └── iotpolicy.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | #Ipython Notebook 62 | .ipynb_checkpoints 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Mario Cannistrà 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python, paho, mqtt and AWS IoT 2 | 3 | ## Platforms supported 4 | 5 | I've tested the certificate creation commands only on Windows using the AWS CLI. I think they should work on the AWS CLI of other platforms. 6 | 7 | My python programs run perfectly on: 8 | - Raspberry PI 2 with Raspbian Jessie and Python 2.7 9 | - Debian Jessie virtual machine with Python 2.7 10 | - Windows with Python 3.4 installed by Conda 11 | 12 | ## Create a thing, certifcate, keys and attaching them to enable usage of AWS IoT hub 13 | 14 | Based on AWS docs found here: [http://docs.aws.amazon.com/iot/latest/developerguide/secure-communication.html](http://docs.aws.amazon.com/iot/latest/developerguide/secure-communication.html) 15 | 16 | Create one thing in aws IoT: 17 | ``` 18 | aws iot create-thing --thing-name "myThingName" 19 | ``` 20 | list the things you now have: 21 | ``` 22 | aws iot list-things 23 | ``` 24 | create certificate and keys: 25 | ``` 26 | aws iot create-keys-and-certificate --set-as-active --certificate-pem-outfile cert.pem --public-key-outfile publicKey.pem --private-key-outfile privkey.pem 27 | ``` 28 | take note of the **certificate-arn** in the output or, if you forgot to copy the **certificate-arn** you can get it listing the certificates with: 29 | ``` 30 | aws iot list-certificates 31 | ``` 32 | download root certificate from [this URL](https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem) using your browser and save it with filename: **aws-iot-rootCA.crt** 33 | 34 | create a policy from the file provided: 35 | ``` 36 | aws iot create-policy --policy-name "PubSubToAnyTopic" --policy-document file://iotpolicy.json 37 | ``` 38 | paste your **certificate-arn** inside the following command before entering it: 39 | ``` 40 | aws iot attach-principal-policy --principal "certificate-arn" --policy-name "PubSubToAnyTopic" 41 | ``` 42 | Two options about the configuration of your endpoint: 43 | - change the value of awshost using the returned value of "endpointAddress": 44 | ``` 45 | aws iot describe-endpoint 46 | ``` 47 | - use **data** hostname and specify the region with the one you used to create the thing and certificates. Current sample code contains data.iot.**eu-west-1**.amazonaws.com (I will try to understand which are the benefits, if any, of one over the other). 48 | 49 | At this point my sample python programs ( **awsiotpub.py** and **awsiotsub.py** ) should run correctly but the AWS documentation specifies to also enter the following to attach the certificate to the thing: 50 | ``` 51 | aws iot attach-thing-principal --thing-name "myThingName" --principal "certificate-arn" 52 | ``` 53 | ## How to test the sample Python programs 54 | 55 | - open two console windows and enter in the first **awsiotsub.py** and in the second **awsiotpub.py** 56 | - the second one will start sending random temperature values to the AWS IoT hub 57 | - the first one will display them when received from the IoT hub 58 | 59 | You can check the sources and modify the topics used by both programs to better fit your needs. 60 | Currently, **awsiotsub.py** subscribes to any topic and will show all of the received msgs. 61 | 62 | **Enjoy MQTT and AWS IoT in your Python programs!** 63 | -------------------------------------------------------------------------------- /awsiotpub.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # this source is part of my Hackster.io project: https://www.hackster.io/mariocannistra/radio-astronomy-with-rtl-sdr-raspberrypi-and-amazon-aws-iot-45b617 4 | 5 | # use this program to test the AWS IoT certificates received by the author 6 | # to participate to the spectrogram sharing initiative on AWS cloud 7 | 8 | # this program will publish test mqtt messages using the AWS IoT hub 9 | # to test this program you have to run first its companion awsiotsub.py 10 | # that will subscribe and show all the messages sent by this program 11 | 12 | import paho.mqtt.client as paho 13 | import os 14 | import socket 15 | import ssl 16 | from time import sleep 17 | from random import uniform 18 | 19 | connflag = False 20 | 21 | def on_connect(client, userdata, flags, rc): 22 | global connflag 23 | connflag = True 24 | print("Connection returned result: " + str(rc) ) 25 | 26 | def on_message(client, userdata, msg): 27 | print(msg.topic+" "+str(msg.payload)) 28 | 29 | #def on_log(client, userdata, level, buf): 30 | # print(msg.topic+" "+str(msg.payload)) 31 | 32 | mqttc = paho.Client() 33 | mqttc.on_connect = on_connect 34 | mqttc.on_message = on_message 35 | #mqttc.on_log = on_log 36 | 37 | awshost = "data.iot.eu-west-1.amazonaws.com" 38 | awsport = 8883 39 | clientId = "myThingName" 40 | thingName = "myThingName" 41 | caPath = "aws-iot-rootCA.crt" 42 | certPath = "cert.pem" 43 | keyPath = "privkey.pem" 44 | 45 | mqttc.tls_set(caPath, certfile=certPath, keyfile=keyPath, cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None) 46 | 47 | mqttc.connect(awshost, awsport, keepalive=60) 48 | 49 | mqttc.loop_start() 50 | 51 | while 1==1: 52 | sleep(0.5) 53 | if connflag == True: 54 | tempreading = uniform(20.0,25.0) 55 | mqttc.publish("temperature", tempreading, qos=1) 56 | print("msg sent: temperature " + "%.2f" % tempreading ) 57 | else: 58 | print("waiting for connection...") 59 | -------------------------------------------------------------------------------- /awsiotsub.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # this source is part of my Hackster.io project: https://www.hackster.io/mariocannistra/radio-astronomy-with-rtl-sdr-raspberrypi-and-amazon-aws-iot-45b617 4 | 5 | # use this program to test the AWS IoT certificates received by the author 6 | # to participate to the spectrogram sharing initiative on AWS cloud 7 | 8 | # this program will subscribe and show all the messages sent by its companion 9 | # awsiotpub.py using the AWS IoT hub 10 | 11 | import paho.mqtt.client as paho 12 | import os 13 | import socket 14 | import ssl 15 | 16 | def on_connect(client, userdata, flags, rc): 17 | print("Connection returned result: " + str(rc) ) 18 | # Subscribing in on_connect() means that if we lose the connection and 19 | # reconnect then subscriptions will be renewed. 20 | client.subscribe("#" , 1 ) 21 | 22 | def on_message(client, userdata, msg): 23 | print("topic: "+msg.topic) 24 | print("payload: "+str(msg.payload)) 25 | 26 | #def on_log(client, userdata, level, msg): 27 | # print(msg.topic+" "+str(msg.payload)) 28 | 29 | mqttc = paho.Client() 30 | mqttc.on_connect = on_connect 31 | mqttc.on_message = on_message 32 | #mqttc.on_log = on_log 33 | 34 | awshost = "data.iot.eu-west-1.amazonaws.com" 35 | awsport = 8883 36 | clientId = "myThingName" 37 | thingName = "myThingName" 38 | caPath = "aws-iot-rootCA.crt" 39 | certPath = "cert.pem" 40 | keyPath = "privkey.pem" 41 | 42 | mqttc.tls_set(caPath, certfile=certPath, keyfile=keyPath, cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None) 43 | 44 | mqttc.connect(awshost, awsport, keepalive=60) 45 | 46 | mqttc.loop_forever() 47 | -------------------------------------------------------------------------------- /iotpolicy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [{ 4 | "Effect": "Allow", 5 | "Action":["iot:*"], 6 | "Resource": ["*"] 7 | }] 8 | } --------------------------------------------------------------------------------