Google Cloud IoT-无效的MQTT发布主题 [英] Google Cloud IoT - Invalid MQTT publish topic

查看:158
本文介绍了Google Cloud IoT-无效的MQTT发布主题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有paho-mqtt的Python客户端在以下特定的Google Cloud IoT主题中发布:projects/my_project/topics/sm1.我的代码如下,基于Google IoT文档的示例:

I am using a Python client with paho-mqtt to publish in this specific topic of Google Cloud IoT: projects/my_project/topics/sm1. My code is below, based on examples of the Google IoT documentation:

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

root_ca = './../roots.pem'
public_crt = './../my_cert.pem'
private_key = './../my_pr.pem'

mqtt_url = "mqtt.googleapis.com"
mqtt_port = 8883
mqtt_topic = "/projects/my_project/topics/sm1"
project_id   = "my_project"
cloud_region = "us-central1"
registry_id  = "sm1"
device_id    = "sm1"

connflag = False

def error_str(rc):
    """Convert a Paho error to a human readable string."""
    return "Some error occurred. {}: {}".format(rc, mqtt.error_string(rc))

def on_disconnect(unused_client, unused_userdata, rc):
    """Paho callback for when a device disconnects."""
    print("on_disconnect", error_str(rc))

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):
    print("User data: {0} -- mid: {1}".format(userdata, mid))
    #client.disconnect()

if __name__ == "__main__":

    client = mqtt.Client("projects/{}/locations/{}/registries/{}/devices/{}".format(
                         project_id,
                         cloud_region,
                         registry_id,
                         device_id))

    client.username_pw_set(username='unused',
                           password=jwt_maker.create_jwt(project_id,
                                               private_key,
                                               algorithm="RS256"))

    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_publish = on_publish
    client.on_disconnect = on_disconnect

    print("Connecting to Google IoT Broker...")
    client.connect(mqtt_url, mqtt_port, keepalive=60)
    client.loop_start() 

    while True:
        sleep(0.5)
        print connflag
        if connflag == True:
            print("Publishing...")
            ap_measurement = random.uniform(25.0, 150.0)
            #payload = "sm1/sm1-payload-{}".format(ap_measurement)
            res = client.publish(mqtt_topic, ap_measurement, qos=1)
            if not res.is_published():
               print("Data not published!!")
            else:
               print("ActivePower published: %.2f" % ap_measurement)
        else:
            print("Waiting for connection...")

当我运行时,客户端会连接但不会发布.在Google IoT控制台上,我可以看到以下错误消息:

When I run, the client connect but does not publish. At Google IoT Console, I can see the following error message:

无效的MQTT发布主题:projects/my_project/topics/sm1

Invalid MQTT publish topic: projects/my_project/topics/sm1

这是输出:

连接到Google IoT代理...
已连接,状态:0-msg:接受连接.
真实
发布中...
数据未发布!
("on_disconnect",发生了一些错误.1:内存不足.")

Connecting to Google IoT Broker...
Connected with status: 0 -- msg: Connection Accepted.
True
Publishing...
Data not published!!
('on_disconnect', 'Some error occurred. 1: Out of memory.')

这真的很奇怪,因为该主题在那里存在,已创建并具有与之关联的订阅!

It is really strange, because the topic is there, created, and have a subscription associated to it!

任何帮助将不胜感激.我已经阅读了以下文档和代码:

Any help will be appreciated. I already read the following documentation and code:

  • https://cloud.google.com/iot/docs/how-tos/mqtt-bridge#iot-core-mqtt-auth-run-python
  • https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/iot/api-client/mqtt_example/cloudiot_mqtt_example.py

推荐答案

您的主题名称不正确.

这令人困惑(我也刚打过).

It's confusing (I just hit this too).

客户端ID(如您所愿)必须为:

The client ID (as you have) must be:

"projects/{}/locations/{}/registries/{}/devices/{}".format(
  project_id,
  cloud_region,
  registry_id,
  device_id
)

主题必须采用以下形式:

The topics must then be of the form:

/devices/{}/config
/devices/{}/state
/devices/{}/events
/devices/{}/events/some/other/topic

如@ptone的评论所述:

As stated in the comment of @ptone:

在云物联网核心中,MQTT主题与云PubSub主题是多对一的.为了安全起见,设备只能发布到以其设备名称空间为前缀的MQTT主题.然后,您可以将子主题与此处提到的其他Cloud PubSub主题进行匹配,但最多只能是10.这不是为了允许1:1映射设备到PubSub主题而设计的.

In cloud iot core, MQTT topics are many-to-one with Cloud PubSub topics. For security - devices may only publish to MQTT topics prefixed with their device namespace. You can then match sub-topics to other Cloud PubSub topics as noted here, but only up to 10. This is not designed to allow a 1:1 mapping device to PubSub Topic.

希望有帮助!

这篇关于Google Cloud IoT-无效的MQTT发布主题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆