代码之家  ›  专栏  ›  技术社区  ›  Dalton Cézane

Google云IoT-无效的MQTT发布主题

  •  2
  • Dalton Cézane  · 技术社区  · 6 年前

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

    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控制台,我可以看到以下错误消息:

    无效的MQTT发布主题:projects/my\u project/topics/sm1

    以下是输出:

    正在连接到Google IoT Broker。。。
    已连接,状态:0--消息:已接受连接。
    符合事实的
    正在发布。。。
    数据未发布!!
    ('on\u disconnect','发生了一些错误。1:内存不足。“)

    这真的很奇怪,因为主题就在那里,创建了,并且有一个与之关联的订阅!

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

    2 回复  |  直到 6 年前
        1
  •  6
  •   halfer Rahul Baradia    3 年前

    您的主题名称不正确。

    这很让人困惑(我也打了这个)。

    客户端ID(如您所拥有的)必须是:

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

    主题必须采用以下形式:

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

    如@ptone的评论所述:

    在云物联网核心中,MQTT主题与云PubSub主题是多对一主题。为了安全起见,设备只能发布到以其设备名称空间为前缀的MQTT主题。然后您可以匹配 sub-topics to other Cloud PubSub topics as noted here ,但最多只有10个。这不是为了允许将设备1:1映射到PubSub主题。

        2
  •  0
  •   Dat    6 年前

    当我更改 mqtt_topic 从…起 events state .在本例中,我试图将当前温度和湿度从我的设备上载到Google IoT Core。

      ...
      data =  {'temp': temperature, 'humid': humidity}
      device_id = 'freedgePrototype'
      topic = 'state'
    
      mqtt_topic = '/devices/{}/{}'.format(device_id, topic)
      payload = json.dumps(data)
      print('Publishing message  {}'.format(payload))
    
      client.publish(mqtt_topic, payload, qos=1)
    

    结果是这样的。

    enter image description here