Google IoT and MQTT



  • Re: [SiPy](Micropython and Google IoT Core MQTT)

    I was able to make this work. What made this doable is using the new pycom ucrypto library. Previously it would take ~5 minutes to generate a JWT signature. The following repository has what should be placed in /flash/lib

    https://github.com/innoagg/pycom_google_iot

    Next you need to setup your Google IoT registry and download the private key from that process. See these steps:

    https://cloud.google.com/iot/docs/how-tos/mqtt-bridge#downloading_mqtt_server_certificates

    From the steps above you should have created a private key for the device. Place this key in /flash/cert

    Next you must build a configuration file with details from the Google IoT instance. here is an example mqtt_config.py that I used:

    google_cloud_config = {
        'project_id':'XXX',
        'cloud_region':'us-central1',
        'registry_id':'XXX',
        'device_id':'XXX',
        'mqtt_bridge_hostname':'mqtt.googleapis.com',
        'mqtt_bridge_port':8883
    }
    
    jwt_config = {
        'algorithm':'RS256',
        'token_ttl': 43200, #12 hours
        'private_key':""
    }
    
    try:
        log.info("Loading RSA Private Key...")
        with open('/flash/cert/private_key.pem','rb') as f:
            jwt_config['private_key'] = f.read()
            print(jwt_config['private_key'])
        f.close()
        log.info("RSA Private Key Loaded")
    except Exception as e:
        log.error("Error Loading RSA Private Key: {}".format(e))
        jwt_config['private_key']
    

    Finally, use a similar procedure to return an MQTT client:

    import mqtt_config
    import microjwt
    from umqtt.simple import MQTTClient
    import machine
    import time
    from network import WLAN
    from machine import RTC
    import ujson
    
    print("connect wifi")
    
    wlan = WLAN(mode=WLAN.STA)
    wlan.connect("XXX", auth=(WLAN.WPA2, "XXX"), timeout=5000)
    
    while not wlan.isconnected():
        machine.idle()
    
    rtc = RTC()
    rtc.init()
    
    if not rtc.synced():
        rtc.ntp_sync("pool.ntp.org")
        while not rtc.synced():
            print("RTC Syncing...")
            time.sleep_ms(500)
    
    print("RTC Time:{}".format(time.time()))
    
    print(wlan.ifconfig())
    
    print("wifi connected")
    
    def on_message(topic, msg):
       print("Topic:{}  Msg:{}".format(topic, msg))
    
    def get_mqtt_client(project_id, cloud_region, registry_id, device_id, jwt):
        """Create our MQTT client. The client_id is a unique string that identifies
        this device. For Google Cloud IoT Core, it must be in the format below."""
        client_id = 'projects/{}/locations/{}/registries/{}/devices/{}'.format(project_id, cloud_region, registry_id, device_id)
        print('Sending message with password {}'.format(jwt))
        client = MQTTClient(client_id.encode('utf-8'),server=mqtt_config.google_cloud_config['mqtt_bridge_hostname'],port=mqtt_config.google_cloud_config['mqtt_bridge_port'],user=b'unused',password=jwt.encode('utf-8'),ssl=True)
        client.set_callback(on_message)
        client.connect(clean_session=True)
        client.subscribe('/devices/{}/config'.format(device_id), 1)
        client.subscribe('/devices/{}/commands/#'.format(device_id), 1)
        return client
    
    print("generate jwt")
    jwtObj = microjwt.new(mqtt_config.google_cloud_config['project_id'], mqtt_config.jwt_config['private_key'], 'RS256', mqtt_config.jwt_config['token_ttl'])
    jwt = jwtObj.encodedValue()
    
    client = get_mqtt_client(mqtt_config.google_cloud_config['project_id'], mqtt_config.google_cloud_config['cloud_region'], mqtt_config.google_cloud_config['registry_id'], mqtt_config.google_cloud_config['device_id'], jwt)
    
    temp = 0;
    def pub():
        global temp
        temp = temp + 1
        message = {
            "device_id": mqtt_config.google_cloud_config['device_id'],
            "temp": temp
        }
        print("Publishing message "+str(ujson.dumps(message)))
        mqtt_topic = '/devices/{}/{}'.format(mqtt_config.google_cloud_config['device_id'], 'events')
        client.publish(mqtt_topic.encode('utf-8'), ujson.dumps(message).encode('utf-8'))
    
    def checkMessages():
        print("Check Messages...")
        client.check_msg()
        time.sleep(1)
    
    

  • Pybytes Beta

    Hey @panda are you still out there? What firmware version did you test this on? I can't get any other Google IoT libraries to work due to various firmware bugs and want to try your implementation.



  • Also refer to the mqtt library used and included in my repository:

    https://github.com/micropython/micropython-lib/tree/master/umqtt.simple


Log in to reply
 

Pycom on Twitter