0
votes

I am testing the connection and publishing to a thing created in the AWS IoT console. I am using the following code:

import paho.mqtt.client as mqtt
import ssl, random
from time import sleep

mqtt_url = "XXXXXX.iot.us-east-2.amazonaws.com"
root_ca = './certs/iotRootCA.pem'
public_crt = './certs/deviceCert.crt'
private_key = './certs/deviceCert.key'

connflag = False

def on_connect(client, userdata, flags, response_code):
    global connflag
    connflag = True
    print("Connected with status: {0}".format(response_code))

def on_publish(client, userdata, mid):
    client.disconnect()

def on_message(client, userdata, msg):
    print "---ON MESSAGE"
    print(msg.topic + " " + str(msg.payload))

if __name__ == "__main__":
    print "Loaded MQTT configuration information."
    print "Endpoint URL: " + mqtt_url
    print "Root Cert: " + root_ca
    print "Device Cert: " + public_crt
    print "Private Key: " + private_key

    client = mqtt.Client("aws_connector")
    client.tls_set(root_ca,
                   certfile = public_crt,
                   keyfile = private_key,
                   cert_reqs = ssl.CERT_REQUIRED,
                   tls_version = ssl.PROTOCOL_TLSv1_2,
                   ciphers = None)

    client.on_connect = on_connect
    client.on_message = on_message

    print "Connecting to AWS IoT Broker..."
    client.connect(mqtt_url, port = 8883)
    client.loop_start()

    while 1==1:
        sleep(0.5)
        if connflag == True:
            print "Publishing..."
            ap_measurement = random.uniform(25.0, 150.0)
            client.publish("ActivePower", ap_measurement, qos=1)
        else:
            print("Waiting for connection...")

My policies are described as below:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:us-east-2:338639570104:topic/sm1"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": "arn:aws:iot:us-east-2:338639570104:topic/sm1"
    }
  ]
}

Apparently, the connection is working and I am getting the following output:

Loaded MQTT configuration information.
Endpoint URL: XXXXXX.iot.us-east-2.amazonaws.com
Root Cert: ./certs/iotRootCA.pem Device Cert: ./certs/deviceCert.crt > Private Key: ./certs/deviceCert.key
Connecting to AWS IoT Broker...
Connected with status: 0
Publishing...
Publishing...
Publishing...
Publishing...
Connected with status: 0
Publishing...

The problem is I am getting no messages from the publishing process. Am I doing something wrong? Is there something missing?

1
Have you tried using aws mqtt client library? It is slightly different from the paho implementation. github.com/aws/aws-iot-device-sdk-pythonDeividi Silva
No. I tried the aws iot device sdk embedded c which has a problem in the subscribe operation. Furthermore, I saw that this python sdk also uses paho-mqtt. So, it works as a wrapper.Dalton Cézane
while 1==1: -> while True:? However, it seems 1==1 is 0.003 usecs faster on my machine. Interesting. Not worth the readability cost, however, imho.Drise
@Drise , while 1==1 == while True == while 1 == while 1>0 == ... This part of code I just got of another example I found out at github... the problem is not related to that, so, I left as it was (though I also prefer True). Good observation, btw, related to performance!Dalton Cézane
@Dalton By habit, if I see while True I instantly assocciate that with some application or thread loop (or a giant red flag). while 1==1 to me is not instantly recognizable as this, though my brain is quite lazy when reading code, so it might just be me.Drise

1 Answers

4
votes

Make sure that the AWS IoT policy associated with your IoT certificate allows publishing on the ActivePower topic.

Currently your policy only allows you to publish to topic sm1. Update it to

 {
    "Effect": "Allow",
    "Action": "iot:Publish",
    "Resource": "arn:aws:iot:us-east-2:338639570104:topic/ActivePower"
 }

or as a quick and dirty way of troubleshooting if this is a policy issue add

{
    "Effect": "Allow",
    "Action": "iot:*",
    "Resource": "*"
}

A policy this liberal is not recommended for production.

Also your subscribe policy has the wrong resource, and you need to add a policy statement for iot:Receive to be able to receive messages, if you were to subscribe to that topic.

AWS IoT policy resource documentation