8000 Merge to master by antohaUa · Pull Request #1 · blynkkk/lib-python · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on May 7, 2025. It is now read-only.

Merge to master #1

Merged
merged 32 commits into from
Mar 4, 2019
Merged
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
eb8cc90
Added initial raw base of python lib
antohaUa Feb 11, 2019
f9bf043
Added protocol error handling
antohaUa Feb 12, 2019
dc11b18
Small changes to decrease get time operations
Feb 13, 2019
5168563
Added license and copyright
antohaUa Feb 13, 2019
a29c4fb
Added virtual_pin_sync and socket timeout
antohaUa Feb 13, 2019
1fb6dc4
Added 'handle_event' decorator support
antohaUa Feb 14, 2019
358d30d
First working examples with docs
antohaUa Feb 15, 2019
817ddfc
Added flow schema to examples
antohaUa Feb 16, 2019
a80da43
Added flow schema to examples
antohaUa Feb 16, 2019
a8604e1
added on_connect/on_disconnect events and example; changed module nam…
antohaUa Feb 17, 2019
a2ff69a
Added email call and example for it.
antohaUa Feb 17, 2019
eb382cb
raw items adding for micropython support
Feb 20, 2019
01716fb
Additions for micropython compatibility
antohaUa Feb 20, 2019
12322cd
Added set_property and notify
antohaUa Feb 21, 2019
66a0f70
Corrections for p2/micropython compatibility; terminal raw example
Feb 22, 2019
2686b9f
Docs placed to separate file
antohaUa Feb 23, 2019
f84f246
Terminal example completed
antohaUa Feb 24, 2019
ef86115
small corrections for print strings
Feb 25, 2019
5f0b35f
Weather station PI3b+ example
antohaUa Feb 25, 2019
ec735c7
added how-to description for weather example
Feb 26, 2019
e91597b
Added heartbeat and max_cmd_buffer to init
antohaUa Feb 26, 2019
84877df
refactoring and optimization
Feb 27, 2019
e11189d
esp32 compatibility
antohaUa Feb 27, 2019
a582aab
Added touch button esp32 test
antohaUa Feb 28, 2019
30bbddc
code compressing
Mar 1, 2019
fb7b237
Started to write project doc
antohaUa Mar 1, 2019
5abd6a0
Added local installer and tester
antohaUa Mar 2, 2019
d3af19f
Added Project documentation
antohaUa Mar 2, 2019
ee5c34a
Added esp32 documentation
antohaUa Mar 3, 2019
b1e0db4
Corrections after review
antohaUa Mar 3, 2019
0ef2327
Added tweet call and test
Mar 4, 2019
e02fee0
Create package create preparations
antohaUa Mar 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added virtual_pin_sync and socket timeout
  • Loading branch information
antohaUa committed Feb 13, 2019
commit a29c4fb43de2b62931db5f412dca4714d9b3e0c1
147 changes: 72 additions & 75 deletions BlynkLib.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,27 @@
import sys

VERSION = '0.2.1'


# todo change globally logging

for itm in ('from machine import idle', 'getattr(time, "ticks_ms")'):
try:
exec itm
except ImportError:
idle = lambda: 0
continue
except AttributeError:
ticks_ms = lambda: int(time.time() * 1000)
sleep_ms = lambda x: time.sleep(x // 1000)
ticks_diff = lambda x, y: y - x

# def time_ms():
# return getattr(time, 'ticks_ms', lambda: int(time.time() * 1000))()
#
#
# def sleep_ms(ms):
# return getattr(time, 'sleep_ms', lambda x: time.sleep(x // 1000))(ms)
#
#
# def time_diff_ms(start_t, end_t):
# return getattr(time, 'ticks_diff', lambda x, y: y - x)(start_t, end_t)
# todo think about why this is needed
# MPY_SUPPORT_INSTRUCTION_1 = 'import machine'
# for itm in [MPY_SUPPORT_INSTRUCTION_1]:
# try:
# exec itm
# except ImportError:
# continue
# except AttributeError:
# pass


def ticks_ms():
return getattr(time, 'ticks_ms', lambda: int(time.time() * 1000))()


def sleep_ms(ms):
return getattr(time, 'sleep_ms', lambda x: time.sleep(x // 1000))(ms)


LOGO = """
Expand Down Expand Up @@ -102,14 +100,14 @@ def heartbeat_msg(self):
def login_msg(self, token):
return self._pack_msg(self.MSG_LOGIN, token)

def ping_reply_msg(self, msg_id, status):
return self._pack_msg(self.MSG_RSP, msg_id, status)

def virtual_write_msg(self, v_pin, *val):
return self._pack_msg(self.MSG_HW, 'vw', v_pin, *val)

def virtual_read_msg(self, v_pin):
return self._pack_msg(self.MSG_HW, 'vr', v_pin)

def ping_reply_msg(self, msg_id, status):
return self._pack_msg(self.MSG_RSP, msg_id, status)
def virtual_sync_msg(self, *pins):
return self._pack_msg(self.MSG_HW_SYNC, 'vr', *pins)

# todo review
# def VIRTUAL_READ(blynk, pin):
Expand Down Expand Up @@ -139,17 +137,16 @@ def ping_reply_msg(self, msg_id, status):
class Connection(Protocol):
SOCK_MIN_TIMEOUT = 1 # 1 second
SOCK_MAX_TIMEOUT = 5 # 5 seconds, must be < self.HEARTBEAT_PERIOD
SOCK_NON_BLOCK_TIMEOUT = 0
SOCK_CONNECTION_TIMEOUT = 0.05
SOCK_RECONNECT_DELAY = 1 # 1 second
SOCK_EAGAIN = 11
STATE_DISCONNECTED = 0
STATE_CONNECTING = 1
STATE_AUTHENTICATING = 2
STATE_AUTHENTICATED = 3
CONNECTION_TIMEOUT = 0.05

RETRIES_TX_DELAY = 2
RETRIES_TX_MAX_NUM = 3
IDLE_TIME_MS = 20
TASK_PERIOD_RES = 50 # 50ms
CONNECT_CALL_TIMEOUT = 30 # 30sec

Expand All @@ -175,7 +172,7 @@ def send(self, data):
curr_retry_num += 1

# todo think about error handling
def receive(self, length, timeout=0):
def receive(self, length, timeout=0.0):
try:
rcv_buffer = b''
self.socket.settimeout(timeout)
Expand Down Expand Up @@ -213,18 +210,11 @@ def _get_socket(self, ssl_flag):
# todo add ssl support
raise NotImplementedError
self.socket.connect(socket.getaddrinfo(self.server, self.port)[0][4])
self.socket.settimeout(self.CONNECTION_TIMEOUT)
self.socket.settimeout(self.SOCK_CONNECTION_TIMEOUT)
print('Blynk connection socket created')
except Exception as g_exc:
raise BlynkException('Connection with the Blynk servers failed: {}'.format(g_exc))

# todo maybe remove
def wait(self, start_time, delay):
while ticks_diff(start_time, ticks_ms()) < delay:
#sleep_ms(self.IDLE_TIME_MS)
idle()
return start_time + delay

# todo add invalid auth token STA_INVALID_TOKEN =(9)
def _authenticate(self):
print('Authenticating device...')
Expand All @@ -247,7 +237,7 @@ def _set_heartbeat(self):
msg_type, msg_id, status, _ = self.parse_response(rsp_data, expected_msg_type=self.MSG_RSP)
if status != self.STATUS_SUCCESS:
raise BlynkException('Heartbeat operation status= {}'.format(status))
print("Heartbeat period = {} seconds. Happy Blynking!".format(self.HEARTBEAT_PERIOD))
print("Heartbeat period = {} seconds. Happy Blynking!\n".format(self.HEARTBEAT_PERIOD))

def connect(self, timeout=CONNECT_CALL_TIMEOUT):
"""
Expand Down Expand Up @@ -301,7 +291,10 @@ def __init__(self, token, server=BLYNK_SERVER, port=BLYNK_HTTP_PORT, ssl=True):
self.port = port
self.ssl = ssl
self.state = self.STATE_DISCONNECTED
self._start_time = 0
self._start_time = ticks_ms()
self._last_receive_time = self._start_time
self._last_send_time = self._start_time
self._last_ping_time = self._start_time
print(LOGO)

def config(self, token, server=BLYNK_SERVER, port=BLYNK_HTTP_PORT, ssl=False):
Expand All @@ -327,14 +320,13 @@ def virtual_write(self, v_pin, *val):
"""
return self.send(self.virtual_write_msg(v_pin, *val))

# todo hmm maybe here some trick with parse response
def virtual_read(self, v_pin):
def virtual_sync(self, *v_pin):
"""
Read data from virtual pin
@param v_pin: pin number: Integer
Sync virtual pin/pins to get actual data. For HW this is equal to read data from virtual pin/pins operation
@param v_pin: single pin or multiple pins number
@return: Returns the number of bytes sent
"""
return self.send(self.virtual_read_msg(v_pin))
return self.send(self.virtual_sync_msg(*v_pin))

# todo think about name
def process(self, msg_type, msg_id, msg_len, extra_data):
Expand All @@ -351,39 +343,42 @@ def process(self, msg_type, msg_id, msg_len, extra_data):
elif msg_type == self.MSG_INTERNAL:
pass

# todo remove this description for run
# Blynk.run()
#
# This function should be called frequently to process incoming commands
# and perform housekeeping of Blynk connection. It is usually called in void loop() {}.

def run(self):
self._start_time = ticks_ms()
self._last_receive_time = self._start_time
self._last_send_time = self._start_time
self._last_ping_time = self._start_time
"""
This function should be called frequently to process incoming commands
and perform housekeeping of Blynk connection.
@return:
"""
# todo out queue and input queues
# todo add keyboard interrupt
while True:
if not self.connected():
self.connect()
while self.connected():
try:
rsp_data = self.receive(self.MSG_HEAD_LEN, self.SOCK_NON_BLOCK_TIMEOUT)
self._last_receive_time = ticks_ms()
if rsp_data:
msg_type, msg_id, h_data, extra_data = self.parse_response(rsp_data)
self.process(msg_type, msg_id, h_data, extra_data)
else:
#time.sleep(self.IDLE_TIME_MS//1000)
#sleep_ms(self.IDLE_TIME_MS)
#self._start_time = self._start_time + self.IDLE_TIME_MS
self._start_time = self.wait(self._start_time, self.IDLE_TIME_MS)
if not self.is_server_alive():
self.disconnect('Blynk server is offline')
break
except Exception as g_exc:
print(g_exc)
self.disconnect(g_exc)
else:
try:
rsp_data = self.receive(self.MAX_CMD_BUFFER, self.SOCK_CONNECTION_TIMEOUT)
self._last_receive_time = ticks_ms()
if rsp_data:
msg_type, msg_id, h_data, extra_data = self.parse_response(rsp_data)
self.process(msg_type, msg_id, h_data, extra_data)
if not self.is_server_alive():
self.disconnect('Blynk server is offline')
except KeyboardInterrupt:
print("\nKeyboardInterrupt: process terminated by user")
sys.exit(0)
except Exception as g_exc:
print(g_exc)
self.disconnect(g_exc)

# todo remove
# def run1(self):
# self.connect(timeout=20)
# self.virtual_write(4, 127)
# val = self.virtual_sync(4)
# print(val)
# rsp_data = self.receive(self.MAX_CMD_BUFFER, 10)
# if rsp_data:
# msg_type, msg_id, h_data, extra_data = self.parse_response(rsp_data)
# print(msg_type, msg_id, h_data, extra_data)


# todo remove this test block after all
Expand All @@ -396,4 +391,6 @@ def run(self):
# print(BLYNK.connected())
# BLYNK.disconnect('Testing disconnect')
# print(BLYNK.connected())
BLYNK.run()
while True:
BLYNK.run()
# BLYNK.run1()
0