Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit a5aa0b8

Browse files
authored
Merge pull request #479 from pycom/prep_v1.20.2.r1
Prep v1.20.2.r1
2 parents 24c3576 + 539ff1e commit a5aa0b8

File tree

6 files changed

+223
-26
lines changed

6 files changed

+223
-26
lines changed

esp32/frozen/Pybytes/_pybytes_constants.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,12 @@ class constants:
6969
__TYPE_OTA = 0x05
7070
__TYPE_FCOTA = 0x06
7171
__TYPE_PONG = 0x07
72-
__TYPE_PYMESH = 0x0D
73-
__TYPE_PYBYTES = 0x0E
74-
__TYPE_RELEASE_INFO = 0x0B
7572
__TYPE_RELEASE_DEPLOY = 0x0A
73+
__TYPE_RELEASE_INFO = 0x0B
7674
__TYPE_DEVICE_NETWORK_DEPLOY = 0x0C
75+
__TYPE_PYMESH = 0x0D
76+
__TYPE_PYBYTES = 0x0E
77+
__TYPE_ML = 0x0F
7778
__PYBYTES_PROTOCOL = ">B%ds"
7879
__PYBYTES_PROTOCOL_PING = ">B"
7980
__PYBYTES_INTERNAL_PROTOCOL = ">BBH"
@@ -90,6 +91,8 @@ class constants:
9091
__COMMAND_ANALOG_WRITE = 4
9192
__COMMAND_CUSTOM_METHOD = 5
9293
__COMMAND_CUSTOM_LOCATION = 6
94+
__COMMAND_START_SAMPLE = 7
95+
__COMMAND_DEPLOY_MODEL = 8
9396

9497
__FCOTA_COMMAND_HIERARCHY_ACQUISITION = 0x00
9598
__FCOTA_COMMAND_FILE_ACQUISITION = 0x01
@@ -105,6 +108,10 @@ class constants:
105108
__DEVICE_TYPE_LOPY_4 = 0x04
106109
__DEVICE_TYPE_UNKNOWN = 0x05
107110

111+
__FWTYPE_DEFAULT = 0x00
112+
__FWTYPE_PYMESH = 0x01
113+
__FWTYPE_PYGATE = 0x02
114+
108115
# {"ssid":"%s", "mac_addr":"%s", "channel":"%s", "power":"%s"}
109116
__WIFI_NETWORK_FORMAT = ">6sBb"
110117

esp32/frozen/Pybytes/_pybytes_library.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,18 @@ def pack_info_message(self, releaseVersion=None):
8686
body.append((release >> 8) & 0xFF)
8787
body.append(release & 0xFF)
8888

89-
if releaseVersion is not None:
90-
body.append((releaseVersion >> 8) & 0xFF)
91-
body.append(releaseVersion & 0xFF)
89+
if releaseVersion is None:
90+
releaseVersion = 0
91+
92+
body.append((releaseVersion >> 8) & 0xFF)
93+
body.append(releaseVersion & 0xFF)
94+
95+
if hasattr(os.uname(), 'pymesh'):
96+
body.append(constants.__FWTYPE_PYMESH)
97+
elif hasattr(os.uname(), 'pygate'):
98+
body.append(constants.__FWTYPE_PYGATE)
99+
else:
100+
body.append(constants.__FWTYPE_DEFAULT)
92101

93102
return self.__pack_message(constants.__TYPE_INFO, body)
94103

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
'''
2+
Copyright (c) 2020, Pycom Limited.
3+
This software is licensed under the GNU GPL version 3 or any
4+
later version, with permitted additional terms. For more information
5+
see the Pycom Licence v1.0 document supplied with this file, or
6+
available at https://www.pycom.io/opensource/licensing
7+
'''
8+
9+
import math
10+
import json
11+
12+
try:
13+
from pybytes_debug import print_debug
14+
except:
15+
from _pybytes_debug import print_debug
16+
17+
try:
18+
import urequest
19+
except:
20+
import _urequest as urequest
21+
22+
try:
23+
from pybytes_constants import constants
24+
except:
25+
from _pybytes_constants import constants
26+
27+
import pycom
28+
29+
try:
30+
from LIS2HH12 import *
31+
except:
32+
print_debug(5, "LIS2HH12 not imported")
33+
34+
# 20 seconds, max window in time for recording
35+
MAX_LEN_MSEC = const(20000)
36+
37+
# 350Hz, max frequency
38+
MAX_FREQ_HZ = const(350)
39+
40+
41+
class MlFeatures():
42+
def __init__(self, pybytes_protocol=None, parameters=None):
43+
if parameters is not None:
44+
self.__length = parameters["length"]
45+
self.__label = parameters["label"]
46+
self.__sampleName = parameters["sampleName"]
47+
self.__type = parameters["type"]
48+
self.__device = parameters["device"]
49+
self.__model = parameters["model"]
50+
self.__mlSample = parameters["mlSample"]
51+
self.__frequency = parameters["frequency"]
52+
self.__pybytes_protocol = pybytes_protocol
53+
self.__data = []
54+
55+
def _debug_hack(self, pybytes):
56+
self.__pybytes = pybytes
57+
58+
def start_sampling(self, pin):
59+
# here define the required libraries
60+
try:
61+
from pysense import Pysense
62+
except:
63+
print_debug(5, "pysense not imported")
64+
65+
try:
66+
from pytrack import Pytrack
67+
except:
68+
print_debug(5, "pytrack not imported")
69+
70+
lib = False
71+
try:
72+
py = Pysense()
73+
lib = True
74+
except NameError:
75+
print_debug(5, "Pysense not defined")
76+
77+
if not lib:
78+
try:
79+
py = Pytrack()
80+
except NameError:
81+
print_debug(5, "Check if Pysense/Pytrack libraries are loaded")
82+
return
83+
84+
try:
85+
li = LIS2HH12(py)
86+
except NameError:
87+
print_debug(5, "LIS2HH12 library are not loaded")
88+
return
89+
li.set_odr(ODR_400_HZ)
90+
91+
# make the max record length to 20 seconds
92+
self.__length = min(MAX_LEN_MSEC, self.__length)
93+
94+
# make the max frequency to 350Hz
95+
self.__frequency = min(MAX_FREQ_HZ, self.__frequency)
96+
97+
# compute time interval between 2 consecutive samples
98+
delta_t_us = int(1000000.0 / self.__frequency)
99+
# compute the number of samples to be acquisition
100+
samples_num = math.ceil(self.__length * self.__frequency / 1000) + 1
101+
102+
pycom.heartbeat(False)
103+
pycom.rgbled(0x7f7f00)
104+
time.sleep(0.5)
105+
106+
self.__data = []
107+
index = 0
108+
print("Start acquisition data for %d msec, freq %d Hz" % (self.__length, self.__frequency))
109+
110+
next_ts = time.ticks_us()
111+
ts_orig = next_ts
112+
while True:
113+
while time.ticks_diff(next_ts, time.ticks_us()) > 0:
114+
pass
115+
acc = li.acceleration()
116+
ts = next_ts
117+
self.__data.append((ts - ts_orig, acc))
118+
next_ts = ts + delta_t_us
119+
index += 1
120+
if index >= samples_num:
121+
break # done
122+
123+
print("Done acquisition %d samples, real freq %.1f Hz" % (index, index / (self.__length / 1000)))
124+
self._parse_data(pin)
125+
126+
def _send_data(self, data, pin, acc, ts):
127+
if self.__pybytes_protocol is not None:
128+
if self.__type == 2:
129+
self.__label = self.__sampleName
130+
self.__pybytes_protocol.send_pybytes_custom_method_values(pin, [
131+
data],
132+
'sample/{}/{}/{}/{}/{}'.format(self.__label, self.__type, self.__model, self.__device, self.__mlSample))
133+
else:
134+
self.__pybytes.send_signal(pin & 0xFF, str((int(ts / 1000), acc)))
135+
136+
def _parse_data(self, pin):
137+
print("_parse_data, %d samples" % len(self.__data))
138+
pycom.rgbled(0x8d05f5)
139+
data = ['{"data": "ml"}']
140+
for (ts, acc) in self.__data:
141+
data.append('{' + '"data": [{},{},{}], "ms": {}'.format(acc[0], acc[1], acc[2], int(ts / 1000)) + '}')
142+
if len(data) > 25:
143+
self._send_data(data, pin, acc, ts)
144+
data = ['{"data": "ml"}']
145+
self._send_data(data, pin, acc, ts)
146+
pycom.heartbeat(True)
147+
148+
def deploy_model(self, modelId, silent=False):
149+
try:
150+
file = '/flash/model_definition.json'
151+
modelDefinition = {}
152+
url = '{}://{}/ml/{}'.format(
153+
constants.__DEFAULT_PYCONFIG_PROTOCOL,
154+
constants.__DEFAULT_PYCONFIG_DOMAIN,
155+
modelId
156+
)
157+
print_debug(2, '{}'.format(url))
158+
result = urequest.get(url, headers={'content-type': 'application/json'})
159+
modelDefinition = json.loads(result.content.decode())
160+
print_debug(2, 'modelDefinition: {}'.format(modelDefinition))
161+
f = open(file, 'w')
162+
f.write(json.dumps(modelDefinition).encode('utf-8'))
163+
f.close()
164+
print_debug(2, "Model definition written to {}".format(file))
165+
except Exception as e:
166+
if not silent:
167+
print_debug(2, "Exception: {}".format(e))

esp32/frozen/Pybytes/_pybytes_protocol.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
except:
3232
from _pybytes_pymesh_config import PybytesPymeshConfig
3333

34+
try:
35+
from pybytes_machine_learning import MlFeatures
36+
except:
37+
from _pybytes_machine_learning import MlFeatures
38+
3439
try:
3540
from pybytes_config_reader import PybytesConfigReader
3641
except:
@@ -281,10 +286,10 @@ def __process_recv_message(self, message):
281286
splittedBody = bodyString.split(',')
282287
if (len(splittedBody) >= 2):
283288
path = splittedBody[0]
284-
print_debug(2, path[len(path)-7:len(path)])
285-
if (path[len(path)-7:len(path)] != '.pymakr'):
289+
print_debug(2, path[len(path) - 7:len(path)])
290+
if (path[len(path) - 7:len(path)] != '.pymakr'):
286291
self.send_fcota_ping('updating file...')
287-
newContent = bodyString[len(path)+1:len(body)]
292+
newContent = bodyString[len(path) + 1:len(body)]
288293
if (self.__FCOTA.update_file_content(path, newContent) is True): # noqa
289294
size = self.__FCOTA.get_file_size(path)
290295
self.send_fcota_file(newContent, path, size)
@@ -319,7 +324,18 @@ def __process_recv_message(self, message):
319324
if (len(body) > 3):
320325
value = body[2] << 8 | body[3]
321326

322-
if (command == constants.__COMMAND_PIN_MODE):
327+
if (command == constants.__COMMAND_START_SAMPLE):
328+
parameters = ujson.loads(body[2: len(body)].decode("utf-8"))
329+
sampling = MlFeatures(self, parameters=parameters)
330+
sampling.start_sampling(pin=parameters["pin"])
331+
self.send_ota_response(result=2, topic='sample')
332+
elif (command == constants.__COMMAND_DEPLOY_MODEL):
333+
parameters = ujson.loads(body[2: len(body)].decode("utf-8"))
334+
sampling = MlFeatures()
335+
sampling.deploy_model(modelId=parameters["modelId"])
336+
self.send_ota_response(result=2, topic='deploymlmodel')
337+
338+
elif (command == constants.__COMMAND_PIN_MODE):
323339
pass
324340

325341
elif (command == constants.__COMMAND_DIGITAL_READ):

esp32/frozen/Pybytes/_pybytes_pymesh_config.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,6 @@ def pymesh_init(self):
5353
# initialize Pymesh
5454
self.__pymesh = Pymesh(self.__pymesh_config, self.pymesh_new_message_cb)
5555

56-
while not self.__pymesh.is_connected():
57-
print(self.__pymesh.status_str())
58-
time.sleep(3)
59-
60-
# send message to the Node having MAC address 5
61-
self.__pymesh.send_mess(2, "Hello World")
62-
print("Done Pymesh init, forever loop, exit/stop with Ctrl+C multiple times")
6356
self.__pymesh_br_enabled = False
6457

6558
if self.__pymesh_config.get("br_ena", False):
@@ -69,8 +62,6 @@ def pymesh_init(self):
6962
print_debug(99, "Set as border router")
7063
self.__pymesh.br_set(PymeshConfig.BR_PRIORITY_NORM, self.pymesh_new_br_message_cb)
7164

72-
self.__pybytes.send_signal(1, str(self.__pymesh.mac()) + " : " + str(time.time()) + "s, " + str(pycom.get_free_heap()))
73-
print_debug(99, "Send to Pyb,", pycom.get_free_heap())
7465
else: # not connected anymore to pybytes
7566
if self.__pymesh_br_enabled:
7667
self.__pymesh_br_enabled = False
@@ -88,8 +79,13 @@ def unpack_pymesh_message(self, signal_number, value):
8879
pyb_ip = '1:2:3::' + hex(pyb_port)[2:]
8980
pkt_start = self.__pack_tocken_prefix + self.__pack_tocken_sep + deviceID + self.__pack_tocken_sep
9081

91-
self.__pymesh.send_mess_external(pyb_ip, pyb_port, pkt_start + monitoringData)
92-
self.__pymesh.send_mess_external(pyb_ip, pyb_port, pkt_start + value)
82+
# send data to the port equal with signal_number
83+
self.__pymesh.send_mess_external(pyb_ip, signal_number, pkt_start + value)
84+
85+
time.sleep(3) # shouldn't send too fast to BR
86+
87+
# hardcode monitoring data to be sent on signal #2
88+
self.__pymesh.send_mess_external(pyb_ip, 2, pkt_start + monitoringData)
9389

9490
def pymesh_new_message_cb(self, rcv_ip, rcv_port, rcv_data):
9591
''' callback triggered when a new packet arrived '''
@@ -122,9 +118,11 @@ def pymesh_new_br_message_cb(self, rcv_ip, rcv_port, rcv_data, dest_ip, dest_por
122118
if len(x) > 2:
123119
token = x[1]
124120
rcv_data = rcv_data[len(self.__pack_tocken_prefix) + len(token) + len(self.__pack_tocken_sep):]
125-
pkt = 'BR %d B from %s (%s), to %s ( %d): %s' % (len(rcv_data), token, rcv_ip, dest_ip, dest_port, str(rcv_data))
126-
print_debug(99, 'Pymesh node packet: {} '.format(pkt))
127-
self.__pybytes.send_node_signal(1, str(rcv_data.decode()).replace("#", ""), token.decode())
121+
122+
# send data to Pybytes only if it's coded properly
123+
pkt = 'BR %d B from %s (%s), to %s ( %d): %s' % (len(rcv_data), token, rcv_ip, dest_ip, dest_port, str(rcv_data))
124+
print_debug(99, 'Pymesh node packet: {} '.format(pkt))
125+
self.__pybytes.send_node_signal(dest_port & 0xFF, str(rcv_data.decode()).replace("#", ""), token.decode())
128126
return
129127

130128
def get_config(self, token, silent=False):

esp32/pycom_version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010
#ifndef VERSION_H_
1111
#define VERSION_H_
1212

13-
#define SW_VERSION_NUMBER "1.20.2.r0"
13+
#define SW_VERSION_NUMBER "1.20.2.r1"
1414

1515
#define LORAWAN_VERSION_NUMBER "1.0.2"
1616

1717
#define SIGFOX_VERSION_NUMBER "1.0.1"
1818

1919
#if (VARIANT == PYBYTES)
20-
#define PYBYTES_VERSION_NUMBER "1.5.1"
20+
#define PYBYTES_VERSION_NUMBER "1.6.0"
2121
#endif
2222

2323
#endif /* VERSION_H_ */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy