From 185129302d36de28b8155079b25584f6cc8c4ecf Mon Sep 17 00:00:00 2001 From: Enrico Gueli Date: Sat, 17 Aug 2019 15:35:54 +0200 Subject: [PATCH 1/3] Add support for redirect command --- blynklib.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/blynklib.py b/blynklib.py index 906eb5c..7a87417 100644 --- a/blynklib.py +++ b/blynklib.py @@ -40,6 +40,11 @@ def stub_log(*args): class BlynkError(Exception): pass +class RedirectError(Exception): + def __init__(self, server, port): + self.server = server + self.port = port + class Protocol(object): MSG_RSP = const(0) @@ -53,9 +58,11 @@ class Protocol(object): MSG_INTERNAL = const(17) MSG_PROPERTY = const(19) MSG_HW = const(20) + MSG_REDIRECT = const(41) MSG_HEAD_LEN = const(5) STATUS_INVALID_TOKEN = const(9) + STATUS_NO_DATA = const(17) STATUS_OK = const(200) VPIN_MAX_NUM = const(32) @@ -83,7 +90,7 @@ def parse_response(self, rsp_data, msg_buffer): raise BlynkError('Command too long. Length = {}'.format(h_data)) elif msg_type in (self.MSG_RSP, self.MSG_PING, self.MSG_INTERNAL): pass - elif msg_type in (self.MSG_HW, self.MSG_BRIDGE): + elif msg_type in (self.MSG_HW, self.MSG_BRIDGE, self.MSG_REDIRECT): msg_body = rsp_data[self.MSG_HEAD_LEN: self.MSG_HEAD_LEN + h_data] msg_args = [itm.decode('utf-8') for itm in msg_body.split(b'\0')] else: @@ -214,10 +221,12 @@ def _authenticate(self): rsp_data = self.receive(self.rcv_buffer, self.SOCK_MAX_TIMEOUT) if not rsp_data: raise BlynkError('Auth stage timeout') - _, _, status, _ = self.parse_response(rsp_data, self.rcv_buffer) + _, _, status, args = self.parse_response(rsp_data, self.rcv_buffer) if status != self.STATUS_OK: if status == self.STATUS_INVALID_TOKEN: raise BlynkError('Invalid Auth Token') + if status == self.STATUS_NO_DATA: + raise RedirectError(*args) raise BlynkError('Auth stage failed. Status={}'.format(status)) self._state = self.AUTHENTICATED self.log('Access granted') @@ -247,6 +256,8 @@ class Blynk(Connection): _VPIN_READ_ALL = '{}{}'.format(_VPIN_READ, _VPIN_WILDCARD) _VPIN_WRITE_ALL = '{}{}'.format(_VPIN_WRITE, _VPIN_WILDCARD) _events = {} + _token = None + _connection_args = None def __init__(self, token, **kwargs): Connection.__init__(self, token, **kwargs) @@ -255,6 +266,8 @@ def __init__(self, token, **kwargs): self._last_send_time = ticks_ms() self._last_ping_time = ticks_ms() self._state = self.DISCONNECTED + self._token = token + self._connection_args = kwargs print(LOGO) def connect(self, timeout=_CONNECT_TIMEOUT): @@ -271,6 +284,12 @@ def connect(self, timeout=_CONNECT_TIMEOUT): except BlynkError as b_err: self.disconnect(b_err) sleep_ms(self.TASK_PERIOD_RES) + except RedirectError as r_err: + self.disconnect() + sleep_ms(self.TASK_PERIOD_RES) + self._connection_args['server'] = r_err.server + self._connection_args['port'] = r_err.port + Connection.__init__(self, self._token, **self._connection_args) if time.time() >= end_time: return False From f38c1c5c940b46c0373c9d99947181758221582c Mon Sep 17 00:00:00 2001 From: Enrico Gueli Date: Mon, 26 Aug 2019 15:42:32 +0200 Subject: [PATCH 2/3] A simpler way to send new connection info after redirect --- blynklib.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/blynklib.py b/blynklib.py index 7a87417..6b1c286 100644 --- a/blynklib.py +++ b/blynklib.py @@ -256,8 +256,6 @@ class Blynk(Connection): _VPIN_READ_ALL = '{}{}'.format(_VPIN_READ, _VPIN_WILDCARD) _VPIN_WRITE_ALL = '{}{}'.format(_VPIN_WRITE, _VPIN_WILDCARD) _events = {} - _token = None - _connection_args = None def __init__(self, token, **kwargs): Connection.__init__(self, token, **kwargs) @@ -266,8 +264,6 @@ def __init__(self, token, **kwargs): self._last_send_time = ticks_ms() self._last_ping_time = ticks_ms() self._state = self.DISCONNECTED - self._token = token - self._connection_args = kwargs print(LOGO) def connect(self, timeout=_CONNECT_TIMEOUT): @@ -286,10 +282,9 @@ def connect(self, timeout=_CONNECT_TIMEOUT): sleep_ms(self.TASK_PERIOD_RES) except RedirectError as r_err: self.disconnect() + self.server = r_err.server + self.port = r_err.port sleep_ms(self.TASK_PERIOD_RES) - self._connection_args['server'] = r_err.server - self._connection_args['port'] = r_err.port - Connection.__init__(self, self._token, **self._connection_args) if time.time() >= end_time: return False From 876f456dda8ef724d565c318396afaadf41b2f8e Mon Sep 17 00:00:00 2001 From: Enrico Gueli Date: Mon, 26 Aug 2019 16:09:38 +0200 Subject: [PATCH 3/3] look better for MSG_REDIRECT command --- blynklib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blynklib.py b/blynklib.py index 6b1c286..f9de30a 100644 --- a/blynklib.py +++ b/blynklib.py @@ -221,11 +221,11 @@ def _authenticate(self): rsp_data = self.receive(self.rcv_buffer, self.SOCK_MAX_TIMEOUT) if not rsp_data: raise BlynkError('Auth stage timeout') - _, _, status, args = self.parse_response(rsp_data, self.rcv_buffer) + msg_type, _, status, args = self.parse_response(rsp_data, self.rcv_buffer) if status != self.STATUS_OK: if status == self.STATUS_INVALID_TOKEN: raise BlynkError('Invalid Auth Token') - if status == self.STATUS_NO_DATA: + if msg_type == self.MSG_REDIRECT: raise RedirectError(*args) raise BlynkError('Auth stage failed. Status={}'.format(status)) self._state = self.AUTHENTICATED