8000 micropython code extracted into separate library blynklib_mp.py · fgervais/lib-python@81dfc16 · GitHub
[go: up one dir, main page]

Skip to content

Commit 81dfc16

Browse files
author
amorozenko
committed
micropython code extracted into separate library blynklib_mp.py
1 parent 1e3bc4f commit 81dfc16

14 files changed

+157
-169
lines changed

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pip install --user -e .
6060
```
6161

6262
#### Testing
63-
You can run unit tests for cPython version of library (blynklib_cp.py) using the command:
63+
You can run unit tests for cPython version of library (blynklib.py) using the command:
6464

6565
python setup.py test
6666

@@ -73,14 +73,14 @@ and related installation docs can be found [here][micropython-pkg].
7373

7474

7575
## Features
76-
This library supports Python2, Python3, and Micropython.
76+
This library supports Python2, Python3 (blynklib.py) , and Micropython (blynklib_mp.py).
7777

7878
- Communication with public or local [Blynk Server][blynk-server].
7979
- Exchange any data between your hardware and app
8080
- Tested to work with: Raspberry Pi (any), ESP32, ESP8266
8181

8282
##### List of available operations:
83-
- Subscribe to connect/disconnect events (ssl connection available only for cPython lib)
83+
- Subscribe to connect/disconnect events (ssl connection supported only by cPython lib)
8484
- Subscribe to read/write events of [virtual pins][blynk-vpins]
8585
- [Virtual Pin][blynk-vpins] write
8686
- [Virtual Pin][blynk-vpins] sync
@@ -108,6 +108,7 @@ BLYNK_AUTH = '<YourAuthToken>' #insert your Auth Token here
108108
#### Usage example
109109
```python
110110
import blynklib
111+
# import blynklib_mp as blynklib # micropython import
111112

112113
BLYNK_AUTH = '<YourAuthToken>' #insert your Auth Token here
113114
# base lib init
@@ -122,6 +123,7 @@ blynk = blynklib.Blynk(BLYNK_AUTH)
122123
# blynk = blynklib.Blynk(BLYNK_AUTH, port=443, ssl_cert='<path to local blynk server certificate>')
123124
# current blynk-cloud.com certificate stored in project as
124125
# https://github.com/blynkkk/lib-python/blob/master/certificate/blynk-cloud.com.crt
126+
# Note! ssl feature supported only by cPython
125127

126128
# register handler for Virtual Pin V22 reading by Blynk App.
127129
# when a widget in Blynk App asks Virtual Pin data from server within given configurable interval (1,2,5,10 sec etc)
@@ -168,7 +170,7 @@ Examples can be found **[here][blynk-py-examples]** Check them all to get famili
168170
- [08_blynk_timer.py](https://github.com/blynkkk/lib-python/blob/master/examples/08_blynk_timer.py): How send data periodically from hardware by using **[Blynk Timer][blynktimer-doc]**
169171
- [09_sync_virtual_pin.py](https://github.com/blynkkk/lib-python/blob/master/examples/09_sync_virtual_pin.py): How to sync virtual pin states and properties
170172
- [10_rtc_sync.py](https://github.com/blynkkk/lib-python/blob/master/examples/10_rtc_sync.py): How to perform RTC sync with blynk server
171-
- [11_ssl_socket.py](https://github.com/blynkkk/lib-python/blob/master/examples/11_ssl_socket.py): SSL server connection. Feature available only fo cPython.
173+
- [11_ssl_socket.py](https://github.com/blynkkk/lib-python/blob/master/examples/11_ssl_socket.py): SSL server connection. Feature supported only by cPython library.
172174

173175
##### Raspberry Pi (any):
174176
Read [Raspberry Pi guide](https://github.com/blynkkk/lib-python/tree/master/examples/raspberry) first.

blynklib.py

Lines changed: 66 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,12 @@
22
# Copyright (c) 2015-2019 Volodymyr Shymanskyy.
33
# See the file LICENSE for copying permission.
44

5-
__version__ = '0.2.5'
5+
__version__ = '0.2.6'
66

7-
try:
8-
import usocket as socket
9-
import utime as time
10-
import ustruct as struct
11-
import uselect as select
12-
from micropython import const
13-
14-
ticks_ms = time.ticks_ms
15-
sleep_ms = time.sleep_ms
16-
17-
IOError = OSError
18-
except ImportError:
19-
import socket
20-
import time
21-
import struct
22-
import select
23-
24-
const = lambda x: x
25-
ticks_ms = lambda: int(time.time() * 1000)
26-
sleep_ms = lambda x: time.sleep(x // 1000)
7+
import socket
8+
import ssl
9+
import struct
10+
import time
2711

2812
LOGO = """
2913
___ __ __
@@ -37,6 +21,14 @@ def stub_log(*args):
3721
pass
3822

3923

24+
def ticks_ms():
25+
return int(time.time() * 1000)
26+
27+
28+
def sleep_ms(ms):
29+
time.sleep(ms // 1000)
30+
31+
4032
class BlynkError(Exception):
4133
pass
4234

@@ -48,32 +40,32 @@ def __init__(self, server, port):
4840

4941

5042
class Protocol(object):
51-
MSG_RSP = const(0)
52-
MSG_LOGIN = const(2)
53-
MSG_PING = const(6)
54-
MSG_TWEET = const(12)
55-
MSG_EMAIL = const(13)
56-
MSG_NOTIFY = const(14)
57-
MSG_BRIDGE = const(15)
58-
MSG_HW_SYNC = const(16)
59-
MSG_INTERNAL = const(17)
60-
MSG_PROPERTY = const(19)
61-
MSG_HW = const(20)
62-
MSG_REDIRECT = const(41)
63-
MSG_HEAD_LEN = const(5)
64-
65-
STATUS_INVALID_TOKEN = const(9)
66-
STATUS_NO_DATA = const(17)
67-
STATUS_OK = const(200)
68-
VPIN_MAX_NUM = const(32)
69-
70-
_msg_id = 1
43+
MSG_RSP = 0
44+
MSG_LOGIN = 2
45+
MSG_PING = 6
46+
MSG_TWEET = 12
47+
MSG_EMAIL = 13
48+
MSG_NOTIFY = 14
49+
MSG_BRIDGE = 15
50+
MSG_HW_SYNC = 16
51+
MSG_INTERNAL = 17
52+
MSG_PROPERTY = 19
53+
MSG_HW = 20
54+
MSG_REDIRECT = 41
55+
MSG_HEAD_LEN = 5
56+
57+
STATUS_INVALID_TOKEN = 9
58+
STATUS_NO_DATA = 17
59+
STATUS_OK = 200
60+
VPIN_MAX_NUM = 32
61+
62+
_msg_id = 0
7163

7264
def _get_msg_id(self, **kwargs):
7365
if 'msg_id' in kwargs:
7466
return kwargs['msg_id']
7567
self._msg_id += 1
76-
return self._msg_id if self._msg_id <= 0xFFFF else 1
68+
return self._msg_id if self._msg_id <= 0xFFFF else 0
7769

7870
def _pack_msg(self, msg_type, *args, **kwargs):
7971
data = ('\0'.join([str(curr_arg) for curr_arg in args])).encode('utf-8')
@@ -134,40 +126,35 @@ def internal_msg(self, *args):
134126

135127

136128
class Connection(Protocol):
137-
SOCK_MAX_TIMEOUT = const(5)
129+
SOCK_MAX_TIMEOUT = 5
138130
SOCK_TIMEOUT = 0.05
139-
EAGAIN = const(11)
140-
ETIMEDOUT = const(60)
141-
RETRIES_TX_DELAY = const(2)
142-
RETRIES_TX_MAX_NUM = const(3)
143-
RECONNECT_SLEEP = const(1)
144-
TASK_PERIOD_RES = const(50)
145-
DISCONNECTED = const(0)
146-
CONNECTING = const(1)
147-
AUTHENTICATING = const(2)
148-
AUTHENTICATED = const(3)
131+
SOCK_SSL_TIMEOUT = 1
132+
EAGAIN = 11
133+
ETIMEDOUT = 60
134+
RETRIES_TX_DELAY = 2
135+
RETRIES_TX_MAX_NUM = 3
136+
RECONNECT_SLEEP = 1
137+
TASK_PERIOD_RES = 50
138+
DISCONNECTED = 0
139+
CONNECTING = 1
140+
AUTHENTICATING = 2
141+
AUTHENTICATED = 3
149142

150143
_state = None
151144
_socket = None
152145
_last_rcv_time = 0
153146
_last_ping_time = 0
154147
_last_send_time = 0
155148

156-
def __init__(self, token, server='blynk-cloud.com', port=80, heartbeat=10, rcv_buffer=1024, log=stub_log):
149+
def __init__(self, token, server='blynk-cloud.com', port=80, ssl_cert=None, heartbeat=10, rcv_buffer=1024,
150+
log=stub_log):
157151
self.token = token
158152
self.server = server
159153
self.port = port
160154
self.heartbeat = heartbeat
161155
self.rcv_buffer = rcv_buffer
162156
self.log = log
163-
164-
def _set_socket_timeout(self, timeout):
165-
if getattr(self._socket, 'settimeout', None):
166-
self._socket.settimeout(timeout)
167-
else:
168-
p = select.poll()
169-
p.register(self._socket)
170-
p.poll(int(timeout * 1000))
157+
self.ssl_cert = ssl_cert
171158

172159
def send(self, data):
173160
retries = self.RETRIES_TX_MAX_NUM
@@ -182,13 +169,13 @@ def send(self, data):
182169
def receive(self, length, timeout):
183170
d_buff = b''
184171
try:
185-
self._set_socket_timeout(timeout)
172+
self._socket.settimeout(timeout)
186173
d_buff += self._socket.recv(length)
187174
if len(d_buff) >= length:
188175
d_buff = d_buff[:length]
189176
return d_buff
190177
except (IOError, OSError) as err:
191-
if str(err) == 'timed out':
178+
if 'timed out' in str(err):
192179
return b''
193180
if str(self.EAGAIN) in str(err) or str(self.ETIMEDOUT) in str(err):
194181
return b''
@@ -213,7 +200,16 @@ def _get_socket(self):
213200
self._state = self.CONNECTING
214201
self._socket = socket.socket()
215202
self._socket.connect(socket.getaddrinfo(self.server, self.port)[0][4])
216-
self._set_socket_timeout(self.SOCK_TIMEOUT)
203+
self._socket.settimeout(self.SOCK_TIMEOUT)
204+
if self.ssl_cert:
205+
# system’s default CA certificates case
206+
if self.ssl_cert == "default":
207+
self.ssl_cert = None
208+
self.log('Using SSL socket...')
209+
ssl_context = ssl.create_default_context(cafile=self.ssl_cert)
210+
ssl_context.verify_mode = ssl.CERT_REQUIRED
211+
self._socket.settimeout(self.SOCK_SSL_TIMEOUT)
212+
self._socket = ssl_context.wrap_socket(sock=self._socket, server_hostname=self.server)
217213
self.log('Connected to blynk server')
218214
except Exception as g_exc:
219215
raise BlynkError('Connection with the Blynk server failed: {}'.format(g_exc))
@@ -250,7 +246,7 @@ def connected(self):
250246

251247

252248
class Blynk(Connection):
253-
_CONNECT_TIMEOUT = const(30) # 30sec
249+
_CONNECT_TIMEOUT = 30 # 30sec
254250
_VPIN_WILDCARD = '*'
255251
_VPIN_READ = 'read v'
256252
_VPIN_WRITE = 'write v'
@@ -300,6 +296,7 @@ def disconnect(self, err_msg=None):
300296
self._state = self.DISCONNECTED
301297
if err_msg:
302298
self.log('[ERROR]: {}\nConnection closed'.format(err_msg))
299+
self._msg_id = 0
303300
time.sleep(self.RECONNECT_SLEEP)
304301

305302
def virtual_write(self, v_pin, *val):
@@ -351,11 +348,11 @@ def process(self, msg_type, msg_id, msg_len, msg_args):
351348
elif msg_type == self.MSG_PING:
352349
self.send(self.response_msg(self.STATUS_OK, msg_id=msg_id))
353350
elif msg_type in (self.MSG_HW, self.MSG_BRIDGE, self.MSG_INTERNAL):
354-
if msg_type == self.MSG_INTERNAL and len(msg_args) >= const(2):
351+
if msg_type == self.MSG_INTERNAL and len(msg_args) >= 2:
355352
self.call_handler("{}{}".format(self._INTERNAL, msg_args[0]), msg_args[1:])
356-
elif len(msg_args) >= const(3) and msg_args[0] == 'vw':
353+
elif len(msg_args) >= 3 and msg_args[0] == 'vw':
357354
self.call_handler("{}{}".format(self._VPIN_WRITE, msg_args[1]), int(msg_args[1]), msg_args[2:])
358-
elif len(msg_args) == const(2) and msg_args[0] == 'vr':
355+
elif len(msg_args) == 2 and msg_args[0] == 'vr':
359356
self.call_handler("{}{}".format(self._VPIN_READ, msg_args[1]), int(msg_args[1]))
360357

361358
def read_response(self, timeout=0.5):

0 commit comments

Comments
 (0)
0