Closed minusplusminus closed 4 years ago
Hi,
I'm researching if it's possible to connect Google Cloud. Could not get further than this:
First I tried with the embedded libraries of LoBo based on this tutorial:
connecting-micropython-devices-to-google-cloud-iot-core
from third_party import string import machine import network import utime from third_party import rsa from ubinascii import b2a_base64 #from machine import Pin #import ntptime from umqtt.simple import MQTTClient import ujson import config import time sta_if = network.WLAN(network.STA_IF) #led_pin = machine.Pin(config.device_config['led_pin'], Pin.OUT) # built-in LED pin #led_pin.value(1) def connect(): if not sta_if.isconnected(): print('connecting to network...') sta_if.active(True) sta_if.connect(config.wifi_config['ssid'], config.wifi_config['password']) while not sta_if.isconnected(): pass print('network config: {}'.format(sta_if.ifconfig())) # def set_time(): # ntptime.settime() # tm = utime.localtime() # tm = tm[0:3] + (0,) + tm[3:6] + (0,) # machine.RTC().datetime(tm) # print('current time: {}'.format(utime.localtime())) def b42_urlsafe_encode(payload): return string.translate(b2a_base64(payload)[:-1].decode('utf-8'), {ord('+'): '-', ord('/'): '_'}) # password generation def create_jwt(project_id, private_key, algorithm, token_ttl): print("Creating JWT...") private_key = rsa.PrivateKey(*private_key) # Epoch_offset is needed because micropython epoch is 2000-1-1 and unix is 1970-1-1. Adding 946684800 (30 years) epoch_offset = 946684800 claims = { # The time that the token was issued at 'iat': utime.time() + epoch_offset, # The time the token expires. 'exp': utime.time() + epoch_offset + token_ttl, # The audience field should always be set to the GCP project id. 'aud': project_id } # This only supports RS256 at this time. header = {"alg": algorithm, "typ": "JWT"} content = b42_urlsafe_encode(ujson.dumps(header).encode('utf-8')) content = content + '.' + b42_urlsafe_encode(ujson.dumps(claims).encode('utf-8')) signature = b42_urlsafe_encode(rsa.sign(content, private_key, 'SHA-256')) return content + '.' + signature # signed JWT def conncb(task): print("[{}] Connected".format(task)) def disconncb(task): print("[{}] Disconnected".format(task)) def subscb(task): print("[{}] Subscribed".format(task)) def pubcb(pub): print("[{}] Published: {}".format(pub[0], pub[1])) def datacb(msg): print("[{}] Data arrived from topic: {}, Message:\n".format(msg[0], msg[1]), msg[2]) connect() rtc = machine.RTC() rtc.ntp_sync(server="time.google.com") print(rtc.synced()) while rtc.synced() == False: utime.sleep_ms(1000) print(rtc.synced()) print(utime.gmtime()) print(utime.localtime()) print('starting..') jwt = create_jwt(config.google_cloud_config['project_id'], config.jwt_config['private_key'], config.jwt_config['algorithm'], config.jwt_config['token_ttl']) # mqtt = network.mqtt(name, server [optional_arguments]) print(jwt) project_id = config.google_cloud_config['project_id'] cloud_region = config.google_cloud_config['cloud_region'] registry_id = config.google_cloud_config['registry_id'] device_id = config.google_cloud_config['device_id'] client_id = 'projects/{}/locations/{}/registries/{}/devices/{}'.format(project_id, cloud_region, registry_id, device_id) print('init thing') thing = network.mqtt("googlecloud", 'mqtts://{}'.format(config.google_cloud_config['mqtt_bridge_hostname']), port=config.google_cloud_config['mqtt_bridge_port'], user=b'ignored', clientid=client_id.encode('utf-8'), password=jwt.encode('utf-8'), # cleansession=True, autoreconnect=True, disconnected_cb=disconncb, subscribed_cb=subscb, published_cb=pubcb, data_cb=datacb) thing.start() tmo = 0 while thing.status()[0] != 2: utime.sleep_ms(100) tmo += 1 #print(thing.status()) if tmo > 300: print("Not connected") break #thing.subscribe('/devices/{}/config'.format(device_id), 1) #thing.subscribe('/devices/{}/commands/#'.format(device_id), 1) # subscribe to channel # thing.subscribe(subchan) # subscribe to field # thing.subscribe(subfield) # publish to channel # Payload can include any of those fields separated b< ';': # "field1=value;field2=value;...;field8=value;latitude=value;longitude=value;elevation=value;status=value" # thing.publish(pubchan, "field1=25.2;status=On line") # Publish to field # thing.publish(pubfield, "24.5") while True: print('looping') print(thing.status()) message = { "device_id": config.google_cloud_config['device_id'], "temp": "1" } print("Publishing message " + str(ujson.dumps(message))) #led_pin.value(1) mqtt_topic = '/devices/{}/{}'.format(config.google_cloud_config['device_id'], 'events') thing.publish(mqtt_topic.encode('utf-8'), ujson.dumps(message).encode('utf-8')) #led_pin.value(0) # client.check_msg() # Check for new messages on subscription utime.sleep(10) # Delay for 10 seconds. #time.sleep_ms(5000)
the result is:
init thing [googlecloud] Disconnected [googlecloud] Disconnected (3, 'Wait timeout')
Sadly enough Google cloud console detected one time. But I don't know when this happened. "mqtt: The connection broke or was closed by the client."
Second try was with umqtt.simple
import machine from third_party import string import network import utime from third_party import rsa from umqtt.simple import MQTTClient from ubinascii import b2a_base64 from machine import Pin import ujson import config # https://github.com/GoogleCloudPlatform/iot-core-micropython/blob/master/main.py sta_if = network.WLAN(network.STA_IF) # led_pin = machine.Pin(config.device_config['led_pin'], Pin.OUT) # built-in LED pin # led_pin.value(1) def on_message(topic, message): print((topic, message)) def connect(): if not sta_if.isconnected(): print('connecting to network...') sta_if.active(True) sta_if.connect(config.wifi_config['ssid'], config.wifi_config['password']) while not sta_if.isconnected(): pass print('network config: {}'.format(sta_if.ifconfig())) def set_time(): rtc = machine.RTC() rtc.ntp_sync(server="0.nl.pool.ntp.org", tz="Europe/Amsterdam") print(rtc.synced()) while rtc.synced() == False: utime.sleep_ms(1000) print(rtc.synced()) print(utime.gmtime()) print(utime.localtime()) def b42_urlsafe_encode(payload): return string.translate(b2a_base64(payload)[:-1].decode('utf-8'), {ord('+'): '-', ord('/'): '_'}) def create_jwt(project_id, private_key, algorithm, token_ttl): print("Creating JWT...") private_key = rsa.PrivateKey(*private_key) # Epoch_offset is needed because micropython epoch is 2000-1-1 and unix is 1970-1-1. Adding 946684800 (30 years) epoch_offset = 946684800 claims = { # The time that the token was issued at 'iat': utime.time() + epoch_offset, # The time the token expires. 'exp': utime.time() + epoch_offset + token_ttl, # The audience field should always be set to the GCP project id. 'aud': project_id } # This only supports RS256 at this time. header = {"alg": algorithm, "typ": "JWT"} content = b42_urlsafe_encode(ujson.dumps(header).encode('utf-8')) content = content + '.' + b42_urlsafe_encode(ujson.dumps(claims).encode('utf-8')) signature = b42_urlsafe_encode(rsa.sign(content, private_key, 'SHA-256')) return content + '.' + signature # signed JWT 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=config.google_cloud_config['mqtt_bridge_hostname'], port= config.google_cloud_config['mqtt_bridge_port'], user=b'ignored', password=jwt.encode('utf-8'), ssl=True) client.set_callback(on_message) client.connect() channel = b'/devices/{}/config'.format(device_id) print(channel) client.subscribe(channel) # client.subscribe('/devices/{}/commands/#'.format(device_id), 1) return client connect() # Need to be connected to the internet before setting the local RTC. set_time() jwt = create_jwt(config.google_cloud_config['project_id'], config.jwt_config['private_key'], config.jwt_config['algorithm'], config.jwt_config['token_ttl']) client = get_mqtt_client(config.google_cloud_config['project_id'], config.google_cloud_config['cloud_region'], config.google_cloud_config['registry_id'], config.google_cloud_config['device_id'], jwt) while True: message = { "device_id": config.google_cloud_config['device_id'], "temp": "1" } print("Publishing message " + str(ujson.dumps(message))) # led_pin.value(1) mqtt_topic = '/devices/{}/{}'.format(config.google_cloud_config['device_id'], 'events') client.publish(mqtt_topic.encode('utf-8'), ujson.dumps(message).encode('utf-8')) # led_pin.value(0) client.check_msg() # Check for new messages on subscription utime.sleep(10) # Delay for 10 seconds.
MQTTException: 4 I don't know where the integer stand for.
MQTTException: 4
Thanks in advance
got it
epoch_offset = 0
Hi,
I'm researching if it's possible to connect Google Cloud. Could not get further than this:
First I tried with the embedded libraries of LoBo based on this tutorial:
connecting-micropython-devices-to-google-cloud-iot-core
the result is:
Sadly enough Google cloud console detected one time. But I don't know when this happened. "mqtt: The connection broke or was closed by the client."
Second try was with umqtt.simple
MQTTException: 4
I don't know where the integer stand for.Thanks in advance