diff --git a/README.md b/README.md index 79d9af0..b047946 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +> [!IMPORTANT] +> **This project is still available for exploration, but is no longer actively maintained or updated.** +> We recommend switching to the Blynk MQTT API for a robust and future-proof experience. +> Support for this project will be phased out over time. +> You can explore some [useful MQTT examples here](https://github.com/Blynk-Technologies/Blynk-MQTT-Samples). + # Blynk Python Library This library provides API to connect IoT hardware that supports Micropython/Python to Blynk Cloud and communiate with Blynk apps (iOS and Android). You can send raw and processed sensor data and remotely control anything that is connected to your hardware (relays, motors, servos) from anywhere in the world. @@ -201,13 +207,9 @@ Read [this document][esp8266-readme] to get more information. ## Documentation and other helpful links -[Full Blynk Documentation](http://docs.blynk.cc/#blynk-firmware) - a complete guide on Blynk features - -[Community (Forum)](http://community.blynk.cc) - join a 500,000 Blynk community to ask questions and share ideas - -[Help Center](http://help.blynk.cc) - helpful articles on various Blynk aspects +[Full Blynk Documentation](https://docs.blynk.io) - a complete guide on Blynk features -[Code Examples Browser](http://examples.blynk.cc) - browse examples to explore Blynk possibilities +[Community (Forum)](https://community.blynk.cc) - join a 1'000'000 Blynk community to ask questions and share ideas [Official Website](https://blynk.io) @@ -226,7 +228,7 @@ Read [this document][esp8266-readme] to get more information. * [Lua, OpenWrt, NodeMCU](https://github.com/vshymanskyy/blynk-library-lua) * [OpenWrt packages](https://github.com/vshymanskyy/blynk-library-openwrt) * [MBED](https://developer.mbed.org/users/vshymanskyy/code/Blynk/) -* [Node-RED](https://www.npmjs.com/package/node-red-contrib-blynk-ws) +* [Node-RED for Blynk IoT](https://flows.nodered.org/node/node-red-contrib-blynk-iot) * [LabVIEW](https://github.com/juncaofish/NI-LabVIEWInterfaceforBlynk) * [C#](https://github.com/sverrefroy/BlynkLibrary) @@ -252,8 +254,8 @@ This project is released under The MIT License (MIT) [blynk-server-public]: http://blynk-cloud.com [blynk-docs]: https://docs.blynk.cc/ [blynk-py-examples]: https://github.com/blynkkk/lib-python/blob/master/examples - [blynk-app-android]: https://play.google.com/store/apps/details?id=cc.blynk - [blynk-app-ios]: https://itunes.apple.com/us/app/blynk-control-arduino-raspberry/id808760481?ls=1&mt=8 + [blynk-app-android]: https://play.google.com/store/apps/details?id=cloud.blynk + [blynk-app-ios]: https://apps.apple.com/us/app/blynk-iot/id1559317868 [blynk-vpins]: http://help.blynk.cc/getting-started-library-auth-token-code-examples/blynk-basics/what-is-virtual-pins [python-org]: https://www.python.org/downloads/ [micropython-org]: https://micropython.org/ diff --git a/blynklib.py b/blynklib.py index ab5f253..1f15a30 100644 --- a/blynklib.py +++ b/blynklib.py @@ -65,7 +65,7 @@ def _get_msg_id(self, **kwargs): if 'msg_id' in kwargs: return kwargs['msg_id'] self._msg_id += 1 - return self._msg_id if self._msg_id <= 0xFFFF else 0 + return self._msg_id if self._msg_id <= 0xFFFF else 1 def _pack_msg(self, msg_type, *args, **kwargs): data = ('\0'.join([str(curr_arg) for curr_arg in args])).encode('utf-8') diff --git a/blynklib_mp.py b/blynklib_mp.py index a215be2..46f8897 100644 --- a/blynklib_mp.py +++ b/blynklib_mp.py @@ -70,8 +70,10 @@ def _pack_msg(self, msg_type, *args, **kwargs): def parse_response(self, rsp_data, msg_buffer): msg_args = [] + msg_len = 0 try: msg_type, msg_id, h_data = struct.unpack('!BHH', rsp_data[:self.MSG_HEAD_LEN]) + msg_len = self.MSG_HEAD_LEN + h_data except Exception as p_err: raise BlynkError('Message parse error: {}'.format(p_err)) if msg_id == 0: @@ -81,11 +83,11 @@ def parse_response(self, rsp_data, msg_buffer): elif msg_type in (self.MSG_RSP, self.MSG_PING): pass elif msg_type in (self.MSG_HW, self.MSG_BRIDGE, self.MSG_INTERNAL, self.MSG_REDIRECT): - msg_body = rsp_data[self.MSG_HEAD_LEN: self.MSG_HEAD_LEN + h_data] + msg_body = rsp_data[self.MSG_HEAD_LEN: msg_len] msg_args = [itm.decode('utf-8') for itm in msg_body.split(b'\0')] else: raise BlynkError("Unknown message type: '{}'".format(msg_type)) - return msg_type, msg_id, h_data, msg_args + return msg_type, msg_id, h_data, msg_args, msg_len def heartbeat_msg(self, heartbeat, rcv_buffer): return self._pack_msg(self.MSG_INTERNAL, 'ver', __version__, 'buff-in', rcv_buffer, 'h-beat', heartbeat, @@ -186,9 +188,9 @@ def receive(self, length, timeout): def is_server_alive(self): now = ticks_ms() h_beat_ms = self.heartbeat * const(1000) - rcv_delta = now - self._last_rcv_time - ping_delta = now - self._last_ping_time - send_delta = now - self._last_send_time + rcv_delta = time.ticks_diff(now, self._last_rcv_time) + ping_delta = time.ticks_diff(now, self._last_ping_time) + send_delta = time.ticks_diff(now, self._last_send_time) if rcv_delta > h_beat_ms + (h_beat_ms // const(2)): return False if (ping_delta > h_beat_ms // const(10)) and (send_delta > h_beat_ms or rcv_delta > h_beat_ms): @@ -214,7 +216,7 @@ def _authenticate(self): rsp_data = self.receive(self.rcv_buffer, self.SOCK_MAX_TIMEOUT) if not rsp_data: raise BlynkError('Auth stage timeout') - msg_type, _, 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') @@ -229,7 +231,7 @@ def _set_heartbeat(self): rcv_data = self.receive(self.rcv_buffer, self.SOCK_MAX_TIMEOUT) if not rcv_data: raise BlynkError('Heartbeat stage timeout') - _, _, status, _ = self.parse_response(rcv_data, self.rcv_buffer) + _, _, status, _, _ = self.parse_response(rcv_data, self.rcv_buffer) if status != self.STATUS_OK: raise BlynkError('Set heartbeat returned code={}'.format(status)) self.log('Heartbeat = {} sec. MaxCmdBuffer = {} bytes'.format(self.heartbeat, self.rcv_buffer)) @@ -353,8 +355,10 @@ def read_response(self, timeout=0.5): rsp_data = self.receive(self.rcv_buffer, self.SOCK_TIMEOUT) if rsp_data: self._last_rcv_time = ticks_ms() - msg_type, msg_id, h_data, msg_args = self.parse_response(rsp_data, self.rcv_buffer) - self.process(msg_type, msg_id, h_data, msg_args) + while rsp_data: + msg_type, msg_id, h_data, msg_args, msg_len = self.parse_response(rsp_data, self.rcv_buffer) + self.process(msg_type, msg_id, h_data, msg_args) + rsp_data = rsp_data[msg_len:] def run(self): if not self.connected(): diff --git a/test/test_blynk_protocol.py b/test/test_blynk_protocol.py index 6be589b..a838e33 100644 --- a/test/test_blynk_protocol.py +++ b/test/test_blynk_protocol.py @@ -23,7 +23,7 @@ def test_get_msg_id_before_loop(self, pb): def test_get_msg_id_after_loop(self, pb): pb._msg_id = 0xFFFF msg_id = pb._get_msg_id() - assert msg_id == 0 + assert msg_id == 1 def test_get_msg_id_defined(self, pb): pb._msg_id = 0xFFFF