Skip to content

Commit

Permalink
Update polaris and cloud libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
ppescher committed Oct 25, 2019
1 parent 4ff1a14 commit 488a72c
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 45 deletions.
15 changes: 14 additions & 1 deletion fortebit/iot/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def _get_rpc_request(self, timeout=20000):
self.connected = False
return None

def publish_rpc_reply(self, id, result):
def send_rpc_reply(self, id, result):
try:
res = requests.post(self._rpc_url(id), json=result, ctx=self.ctx)
except Exception as e:
Expand All @@ -140,3 +140,16 @@ def publish_rpc_reply(self, id, result):
if res.status != 200:
return False
return True

def do_rpc_request(self, method, params=None, timeout=20000):
print_d("rpc request:", method, params)
try:
obj = { "method":method, "params":params }
res = requests.post(self._rpc_url(), json=obj, ctx=self.ctx)
if res.status != 200:
return None
obj = json.loads(res.content)
except Exception as e:
print_d(e)
return None
return obj
32 changes: 16 additions & 16 deletions fortebit/iot/iot.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,10 @@ def connect(self, retry=7):
"""
.. method:: connect()
Setup a connection to the Fortebit Cloud. It can raise an exception in case of error.
"""
if self.client.connect():
return True
t = 3000
while (retry > 0):
sleep(t)
if self.client.connect():
return True
# increase (double) the delay between attempts (up to 1 minute)
if t < 30000:
t *= 2
retry -= 1
return False
Setup a connection to the Fortebit Cloud. Return *True* if successful.
"""
return self.client.connect()

def is_connected(self):
"""
Expand All @@ -85,7 +74,7 @@ def run(self):
"""
.. method:: run()
Starts the device by executing the underlying client. It can start a new thread depending on the type of client (Mqtt vs Http)
Starts the device by executing the underlying client loop.
"""
self.client.loop()
Expand Down Expand Up @@ -129,3 +118,14 @@ def send_rpc_reply(self, id, result):
Return a boolean, *False* if the message cannot be sent.
"""
return self.client.send_rpc_reply(id, result)

def do_rpc_request(self, method, params=None, timeout=15000):
"""
.. method:: do_rpc_request(method, params, timeout)
Perform an RPC request with name :samp:`method` and arguments :samp:`params`, waiting for
a reply maximum :samp:`timeout` milliseconds (only with MqttClient).
Return the result of the RPC (dictionary), *None* in case of errors.
"""
return self.client.do_rpc_request(method, params, timeout)
41 changes: 34 additions & 7 deletions fortebit/iot/mqtt_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ class MqttClient():
def __init__(self, endpoint, device_token, ctx=None):
self.endpoint = endpoint
self.ctx = ctx
self.request_id = -1
self.rpc_id = 10000
self.driver = mqtt.Client("polaris", True)
self.driver.set_username_pw(device_token)
self.attr_id = -1
self.attr_ev = threading.Event()
self.attr_obj = None
self.rpc_id = 10000
self.rpc_ev = threading.Event()
self.rpc_obj = None

def _loop_failure(self, client):
while True:
Expand All @@ -39,6 +41,8 @@ def _subscribe_cb(self, client):
# subscribe to attributes
client.subscribe("v1/devices/me/attributes/response/+", self._on_attributes, 1)
client.subscribe("v1/devices/me/rpc/request/+", self._on_rpc_request, 1)
client.subscribe("v1/devices/me/rpc/response/+", self._on_rpc_response, 1)


def connect(self):
port = 1883 if self.ctx is None else 8883
Expand All @@ -60,7 +64,7 @@ def _on_attributes(self, client, payload, topic):
print_d("> got:", topic, payload)
# len("v1/devices/me/attributes/response/") = 34
id = int(topic[34:])
if self.request_id == id:
if self.attr_id == id:
self.attr_obj = json.loads(payload)
self.attr_ev.set()

Expand All @@ -75,7 +79,7 @@ def _on_rpc_request(self, client, payload, topic):
self.on_rpc_request(id, obj['method'], obj['params'] if 'params' in obj else None)

def get_attributes(self, client, shared=None, timeout=10000):
self.request_id += 1
self.attr_id += 1
self.attr_ev.clear()
obj = {}
if client and isinstance(client, PSTRING):
Expand All @@ -87,7 +91,7 @@ def get_attributes(self, client, shared=None, timeout=10000):
else:
shared = None
obj = json.dumps(obj)
ep = 'v1/devices/me/attributes/request/' + str(self.request_id)
ep = 'v1/devices/me/attributes/request/' + str(self.attr_id)
print_d("publish:", ep, obj)
try:
self.driver.publish(ep, obj, qos=1)
Expand Down Expand Up @@ -121,7 +125,7 @@ def publish_telemetry(self, values, ts=None):
if ts is not None:
values = {'values': values, 'ts': ts}
try:
self.driver.publish("v1/devices/me/telemetry", json.dumps(values), qos=1)
self.driver.publish('v1/devices/me/telemetry', json.dumps(values), qos=1)
except Exception as e:
print_d(e)
return False
Expand All @@ -130,8 +134,31 @@ def publish_telemetry(self, values, ts=None):
def send_rpc_reply(self, id, result):
print_d("rpc reply", id, result)
try:
self.driver.publish("v1/devices/me/rpc/response/" + str(id), json.dumps(result), qos=1)
self.driver.publish('v1/devices/me/rpc/response/' + str(id), json.dumps(result), qos=1)
except Exception as e:
print_d(e)
return False
return True

def _on_rpc_response(self, client, payload, topic):
print_d("> got:", topic, payload)
# len("v1/devices/me/rpc/response/") = 27
id = int(topic[27:])
if self.rpc_id == id:
self.rpc_obj = json.loads(payload)
self.rpc_ev.set()

def do_rpc_request(self, method, params=None, timeout=15000):
self.rpc_id += 1
self.rpc_ev.clear()
print_d("rpc request:", self.rpc_id, method, params)
try:
msg = { 'method': method, 'params': params }
self.driver.publish('v1/devices/me/rpc/request/' + str(self.rpc_id), json.dumps(msg), qos=1)
obj = None
self.rpc_ev.wait(timeout)
obj = self.rpc_obj
except Exception as e:
print_d(e)
return None
return obj
55 changes: 36 additions & 19 deletions fortebit/polaris/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,29 +63,46 @@ def isRegistered(device, email):
return False


def register(device, email, imei, ssl_ctx=None):
def register(device, email):
"""
.. function:: register(device, email, imei, ssl_ctx)
.. function:: register(device, email)
Generates the board's own access token for Fortebit IoT cloud services.
Perform device registration to Fortebit IoT cloud services.
:param device: a connected instance of :any:`fortebit.iot.Device`
:param email: the device owner's email address
:param imei: the modem IMEI number (as a 15 characters string)
:param ssl_ctx: an optional SSL/TLS context (use HTTPS if present)
"""
if ssl_ctx:
url = "https://"
else:
url = "http://"
url += device.endpoint + "/script-polaris/register"
obj = {"email": email, "token": device.device_token, "imei": imei}
print("Register device", email, device.device_token, url, obj)
try:
res = requests.get(url, params=obj, ctx=ssl_ctx)
if res.status == 200:
return True
print("Registration error", res.status)
except Exception as e:
print(e)
obj = {"email": email, "token": device.device_token}
print("Register device", obj)
obj = device.do_rpc_request("register", obj)
#print(obj)
if obj and "reply" in obj and obj["reply"] == "OK":
return True
return False

# def register(device, email, imei, ssl_ctx=None):
# """
# .. function:: register(device, email, imei, ssl_ctx)

# Perform device registration to Fortebit IoT cloud services.

# :param device: a connected instance of :any:`fortebit.iot.Device`
# :param email: the device owner's email address
# :param imei: the modem IMEI number (as a 15 characters string)
# :param ssl_ctx: an optional SSL/TLS context (use HTTPS if present)
# """
# if ssl_ctx:
# url = "https://"
# else:
# url = "http://"
# url += device.endpoint + "/script-polaris/register"
# obj = {"email": email, "token": device.device_token, "imei": imei}
# print("Register device", email, device.device_token, url, obj)
# try:
# res = requests.get(url, params=obj, ctx=ssl_ctx)
# if res.status == 200:
# return True
# print("Registration error", res.status)
# except Exception as e:
# print(e)
# return False
4 changes: 2 additions & 2 deletions fortebit/polaris/polaris.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ def GSM():
"""
#-if TARGET == polaris_3g
from quectel.ug96 import ug96
ug96.init(gsm.SERIAL, _PIN_NC, _PIN_NC, gsm.PIN_POWER, _PIN_NC, gsm.PIN_STATUS, gsm.PIN_KILL, 0)
ug96.init(gsm.SERIAL, _PIN_NC, _PIN_NC, gsm.PIN_POWER, gsm.PIN_KILL, gsm.PIN_STATUS, 1, 1, 0)
return ug96
#-else
##-if TARGET == polaris_2g
Expand All @@ -357,7 +357,7 @@ def GSM():
##-else
###-if TARGET == polaris_nbiot
from quectel.bg96 import bg96
bg96.init(gsm.SERIAL, _PIN_NC, _PIN_NC, gsm.PIN_POWER, gsm.PIN_KILL, gsm.PIN_STATUS, 0)
bg96.init(gsm.SERIAL, _PIN_NC, _PIN_NC, gsm.PIN_POWER, gsm.PIN_KILL, gsm.PIN_STATUS, 1, 1, 0)
bg96.gnss_init(use_uart=1)
return bg96
###-else
Expand Down

0 comments on commit 488a72c

Please sign in to comment.