From 6832b99f31dfa9c7c0dc98b01746b9069f9b1962 Mon Sep 17 00:00:00 2001 From: Francois Gervais Date: Sun, 31 May 2020 17:19:03 -0400 Subject: [PATCH 01/14] Ensure millisecond precision in read_response() (#35) The micropython documentation for utime.time() states that on some hardware, the function only have second precision. This is the case at least for the TinyPICO board. This means that we get an effective 1 second timeout for the read_response() function instead of the expected 50ms. In turn, it makes the run() function quite slow which delays the whole application. To get higher precision, the documentation recommends to use utime.ticks_ms() instead which is what have been implemented here. --- blynklib_mp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blynklib_mp.py b/blynklib_mp.py index 42677ca..29d8c36 100644 --- a/blynklib_mp.py +++ b/blynklib_mp.py @@ -345,8 +345,8 @@ def process(self, msg_type, msg_id, msg_len, msg_args): self.call_handler("{}{}".format(self._VPIN_READ, msg_args[1]), int(msg_args[1])) def read_response(self, timeout=0.5): - end_time = time.time() + timeout - while time.time() <= end_time: + end_time = time.ticks_ms() + int(timeout * const(1000)) + while time.ticks_diff(end_time, time.ticks_ms()) > 0: rsp_data = self.receive(self.rcv_buffer, self.SOCK_TIMEOUT) if rsp_data: self._last_rcv_time = ticks_ms() From ef36f6e71d70b328266bc1ed7f1f27a9edf90059 Mon Sep 17 00:00:00 2001 From: Francois Gervais Date: Sun, 31 May 2020 17:19:34 -0400 Subject: [PATCH 02/14] Revert socket timeout implementation (#33) --- blynklib_mp.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/blynklib_mp.py b/blynklib_mp.py index 29d8c36..a215be2 100644 --- a/blynklib_mp.py +++ b/blynklib_mp.py @@ -151,9 +151,12 @@ def __init__(self, token, server='blynk-cloud.com', port=80, heartbeat=10, rcv_b self.log = log def _set_socket_timeout(self, timeout): - p = select.poll() - p.register(self._socket) - p.poll(int(timeout * const(1000))) + if getattr(self._socket, 'settimeout', None): + self._socket.settimeout(timeout) + else: + p = select.poll() + p.register(self._socket) + p.poll(int(timeout * const(1000))) def send(self, data): retries = self.RETRIES_TX_MAX_NUM From ca5949b852765f17733d4d56f0f7718bd9a4ae53 Mon Sep 17 00:00:00 2001 From: Francois Gervais Date: Wed, 19 Aug 2020 17:08:42 -0400 Subject: [PATCH 03/14] Substract timestamps using ticks_diff() to account for wrap around (#36) From the utime documentation, ticks_diff() should be used to compare timestamps. They say the wrap around is implementation specific but on forums I see people saying it's about 298 hours/12 days which at least is the case for me on the tinypico. In this specific case, the wrap around means the deltas will be small negative numbers which in turn will make is_server_alive() return True for days without sending anymore pings to the server. We will soon after get disconnected and the application will pretty much stay forever in that state. --- blynklib_mp.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/blynklib_mp.py b/blynklib_mp.py index a215be2..6d30af3 100644 --- a/blynklib_mp.py +++ b/blynklib_mp.py @@ -186,9 +186,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): From b2cc4f56b4e4ea264d0a9eca3e14c787e57e5c2e Mon Sep 17 00:00:00 2001 From: Namik Date: Fri, 20 Nov 2020 23:50:19 +0100 Subject: [PATCH 04/14] Update blynklib.py (#39) --- blynklib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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') From f4a3caa0b5c62c7981455dc9b8f2ca98f980bfcd Mon Sep 17 00:00:00 2001 From: icetomcat Date: Tue, 12 Jan 2021 23:57:05 +0700 Subject: [PATCH 05/14] Process multiple messages from single response --- blynklib_mp.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/blynklib_mp.py b/blynklib_mp.py index 6d30af3..9f44a86 100644 --- a/blynklib_mp.py +++ b/blynklib_mp.py @@ -70,6 +70,7 @@ def _pack_msg(self, msg_type, *args, **kwargs): def parse_response(self, rsp_data, msg_buffer): msg_args = [] + msg_tail = b'' try: msg_type, msg_id, h_data = struct.unpack('!BHH', rsp_data[:self.MSG_HEAD_LEN]) except Exception as p_err: @@ -83,9 +84,10 @@ def parse_response(self, rsp_data, msg_buffer): 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_args = [itm.decode('utf-8') for itm in msg_body.split(b'\0')] + msg_tail = rsp_data[self.MSG_HEAD_LEN + h_data:] 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_tail def heartbeat_msg(self, heartbeat, rcv_buffer): return self._pack_msg(self.MSG_INTERNAL, 'ver', __version__, 'buff-in', rcv_buffer, 'h-beat', heartbeat, @@ -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,9 @@ 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, rsp_data = self.parse_response(rsp_data, self.rcv_buffer) + self.process(msg_type, msg_id, h_data, msg_args) def run(self): if not self.connected(): From d42468b1742c98179d4b84c56dc20228586a8a8f Mon Sep 17 00:00:00 2001 From: icetomcat Date: Fri, 15 Jan 2021 23:34:30 +0700 Subject: [PATCH 06/14] Process multiple messages from single response --- blynklib_mp.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/blynklib_mp.py b/blynklib_mp.py index 9f44a86..46f8897 100644 --- a/blynklib_mp.py +++ b/blynklib_mp.py @@ -70,9 +70,10 @@ def _pack_msg(self, msg_type, *args, **kwargs): def parse_response(self, rsp_data, msg_buffer): msg_args = [] - msg_tail = b'' + 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: @@ -82,12 +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')] - msg_tail = rsp_data[self.MSG_HEAD_LEN + h_data:] else: raise BlynkError("Unknown message type: '{}'".format(msg_type)) - return msg_type, msg_id, h_data, msg_args, msg_tail + 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, @@ -356,8 +356,9 @@ def read_response(self, timeout=0.5): if rsp_data: self._last_rcv_time = ticks_ms() while rsp_data: - msg_type, msg_id, h_data, msg_args, rsp_data = self.parse_response(rsp_data, self.rcv_buffer) + 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(): From 44e49df9e14f307f389ef9ccb6114aad43e91d74 Mon Sep 17 00:00:00 2001 From: Volodymyr Shymanskyy Date: Mon, 26 Jul 2021 16:27:39 +0300 Subject: [PATCH 07/14] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 79d9af0..0f0ca99 100644 --- a/README.md +++ b/README.md @@ -226,7 +226,8 @@ 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) +* [Node-RED for old Blynk](https://www.npmjs.com/package/node-red-contrib-blynk-ws) * [LabVIEW](https://github.com/juncaofish/NI-LabVIEWInterfaceforBlynk) * [C#](https://github.com/sverrefroy/BlynkLibrary) From eb068b397a0aec9824bbcf8a1392b7dd7c7ef4fe Mon Sep 17 00:00:00 2001 From: Vova Date: Wed, 4 Aug 2021 15:12:28 +0300 Subject: [PATCH 08/14] Update docs --- README.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 79d9af0..a5fddf3 100644 --- a/README.md +++ b/README.md @@ -201,13 +201,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 +[Full Blynk Documentation](https://docs.blynk.io) - 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 - -[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 +222,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) From b84dd58380c53256a20cab6b5c1ccdbc51972dba Mon Sep 17 00:00:00 2001 From: Vova Date: Wed, 4 Aug 2021 15:18:05 +0300 Subject: [PATCH 09/14] Update links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a5fddf3..e76525c 100644 --- a/README.md +++ b/README.md @@ -248,8 +248,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/ From c43df249daaee198d208efcdad4dc8a0a2b0a596 Mon Sep 17 00:00:00 2001 From: antohaUa Date: Tue, 14 Sep 2021 22:01:25 +0300 Subject: [PATCH 10/14] unit test fix --- test/test_blynk_protocol.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From e4043f0d30028b3f8808d6cb78a644fb47d8c0e3 Mon Sep 17 00:00:00 2001 From: Volodymyr Shymanskyy Date: Fri, 4 Mar 2022 00:27:08 +0200 Subject: [PATCH 11/14] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e76525c..834a452 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +![StandWithUkraine banner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner.svg) + # 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. From 517326028854c1d1cc8c7606ef1d820606689945 Mon Sep 17 00:00:00 2001 From: Volodymyr Shymanskyy Date: Fri, 4 Mar 2022 11:27:54 +0200 Subject: [PATCH 12/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 834a452..9d267a2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![StandWithUkraine banner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner.svg) +[![SWUbanner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) # 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. From 064d9b132623653a2c17a7065016708e951cdb17 Mon Sep 17 00:00:00 2001 From: Volodymyr Shymanskyy Date: Mon, 5 May 2025 16:01:29 +0300 Subject: [PATCH 13/14] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d267a2..94d2a43 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -[![SWUbanner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner-direct.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md) +> [!IMPORTANT] +> **This project has been archived and is no longer maintained.** +> No further updates or support will be provided. +> We recommend switching to the **Blynk MQTT API** for future development. +> You can explore some [useful 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. From 0329df63c414044fd51bb6f17ac9a993d853d507 Mon Sep 17 00:00:00 2001 From: Volodymyr Shymanskyy Date: Wed, 7 May 2025 20:11:22 +0300 Subject: [PATCH 14/14] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 94d2a43..b047946 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ > [!IMPORTANT] -> **This project has been archived and is no longer maintained.** -> No further updates or support will be provided. -> We recommend switching to the **Blynk MQTT API** for future development. -> You can explore some [useful examples here](https://github.com/Blynk-Technologies/Blynk-MQTT-Samples). +> **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.