Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit cbae518

Browse files
committedJul 18, 2022
Fix code formatting for linter.
1 parent 3ca6e6a commit cbae518

File tree

6 files changed

+108
-67
lines changed

6 files changed

+108
-67
lines changed
 

‎aiotcloud/__init__.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,36 +21,42 @@
2121
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2323
# THE SOFTWARE.
24-
from .ucloud import AIOTClient
24+
from .ucloud import AIOTClient # noqa
2525
from .ucloud import AIOTObject
2626
from .ucloud import timestamp
27+
2728
try:
2829
import asyncio
2930
except ImportError:
3031
import uasyncio as asyncio
3132

33+
3234
class Location(AIOTObject):
3335
def __init__(self, name, **kwargs):
3436
super().__init__(name, keys={"lat", "lon"}, **kwargs)
3537

38+
3639
class Color(AIOTObject):
3740
def __init__(self, name, **kwargs):
3841
super().__init__(name, keys={"hue", "sat", "bri"}, **kwargs)
3942

43+
4044
class ColoredLight(AIOTObject):
4145
def __init__(self, name, **kwargs):
4246
super().__init__(name, keys={"swi", "hue", "sat", "bri"}, **kwargs)
4347

48+
4449
class DimmedLight(AIOTObject):
4550
def __init__(self, name, **kwargs):
4651
super().__init__(name, keys={"swi", "bri"}, **kwargs)
4752

53+
4854
class Schedule(AIOTObject):
4955
def __init__(self, name, **kwargs):
50-
kwargs.update({("runnable", True)}) # Force task creation.
56+
kwargs.update({("runnable", True)}) # Force task creation.
5157
self.on_active = kwargs.pop("on_active", None)
5258
# Uncomment to allow the schedule to change in runtime.
53-
#kwargs["on_write"] = kwargs.get("on_write", lambda aiot, value: None)
59+
# kwargs["on_write"] = kwargs.get("on_write", lambda aiot, value: None)
5460
self.active = False
5561
super().__init__(name, keys={"frm", "to", "len", "msk"}, **kwargs)
5662

‎aiotcloud/ntptime.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@
2222
THE SOFTWARE.
2323
"""
2424
try:
25-
import usocket as socket
26-
except:
2725
import socket
28-
try:
29-
import ustruct as struct
30-
except:
3126
import struct
27+
except ImportError:
28+
import usocket as socket
29+
import ustruct as struct
3230

3331
# (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
3432
NTP_DELTA = 3155673600
@@ -44,7 +42,7 @@ def time():
4442
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
4543
try:
4644
s.settimeout(1)
47-
res = s.sendto(NTP_QUERY, addr)
45+
s.sendto(NTP_QUERY, addr)
4846
msg = s.recv(48)
4947
finally:
5048
s.close()

‎aiotcloud/ucloud.py

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from kpn_senml import SenmlPack
2727
from kpn_senml import SenmlRecord
2828
from aiotcloud.umqtt import MQTTClient
29+
2930
try:
3031
import logging
3132
import asyncio
@@ -36,27 +37,31 @@
3637
import uasyncio as asyncio
3738
from aiotcloud import ntptime
3839
from uasyncio.core import CancelledError
40+
3941
# MicroPython doesn't have this exception
4042
class InvalidStateError(Exception):
4143
pass
4244

45+
4346
def timestamp():
4447
return int(time.time())
4548

49+
4650
class AIOTObject(SenmlRecord):
4751
def __init__(self, name, **kwargs):
48-
self.on_read = kwargs.pop("on_read", None)
52+
self.on_read = kwargs.pop("on_read", None)
4953
self.on_write = kwargs.pop("on_write", None)
5054
self.interval = kwargs.pop("interval", 1.0)
5155
self._runnable = kwargs.pop("runnable", False)
5256
value = kwargs.pop("value", None)
53-
if keys := kwargs.pop("keys", {}): # Create a complex object (with sub-records).
54-
mkrec = lambda k, v: AIOTObject(f"{name}:{k}", value=v, callback=self.senml_callback)
55-
value = {k : mkrec(k, v) for (k, v) in {k: kwargs.pop(k, None) for k in keys}.items()}
57+
if keys := kwargs.pop("keys", {}):
58+
value = { # Create a complex object (with sub-records).
59+
k: AIOTObject(f"{name}:{k}", value=v, callback=self.senml_callback)
60+
for (k, v) in {k: kwargs.pop(k, None) for k in keys}.items()
61+
}
5662
self._updated = False
5763
self.on_write_scheduled = False
5864
self.timestamp = timestamp()
59-
self.dtype = type(value) # NOTE: must be set before calling super
6065
callback = kwargs.pop("callback", self.senml_callback)
6166
for key in kwargs: # kwargs should be empty by now, unless a wrong attr was used.
6267
raise TypeError(f"'{self.__class__.__name__}' got an unexpected keyword argument '{key}'")
@@ -94,15 +99,17 @@ def runnable(self):
9499
@SenmlRecord.value.setter
95100
def value(self, value):
96101
if value is not None:
97-
if self.dtype is type(None):
98-
self.dtype = type(value)
99-
elif not isinstance(value, self.dtype):
100-
raise TypeError(f"record: {self.name} invalid data type. Expected {self.dtype} not {type(value)}")
101-
else:
102+
if self.value is not None:
103+
if not isinstance(self.value, type(value)):
104+
raise TypeError(
105+
f"record: {self.name} invalid data type. Expected {type(self.value)} not {type(value)}"
106+
)
102107
self._updated = True
103108
self.timestamp = timestamp()
104-
logging.debug(f"record: {self.name} %s: {value} ts: {self.timestamp}"
105-
%("initialized" if self.value is None else "updated"))
109+
logging.debug(
110+
f"record: {self.name} %s: {value} ts: {self.timestamp}"
111+
% ("initialized" if self.value is None else "updated")
112+
)
106113
self._value = value
107114

108115
def __getattr__(self, attr):
@@ -119,7 +126,7 @@ def __setattr__(self, name, value):
119126
def _build_rec_dict(self, naming_map, appendTo):
120127
if isinstance(self.value, dict):
121128
for r in self.value.values():
122-
if r.value is not None: # NOTE: should filter by updated when it's supported.
129+
if r.value is not None: # NOTE: should filter by updated when it's supported.
123130
r._build_rec_dict(naming_map, appendTo)
124131
else:
125132
super()._build_rec_dict(naming_map, appendTo)
@@ -128,7 +135,7 @@ def add_to_pack(self, pack):
128135
if isinstance(self.value, dict):
129136
for r in self.value.values():
130137
# NOTE: If record value is None it can still be added to the pack for initialization.
131-
pack.add(r) # NOTE: should filter by updated when it's supported.
138+
pack.add(r) # NOTE: should filter by updated when it's supported.
132139
else:
133140
pack.add(self)
134141
self.updated = False
@@ -143,14 +150,15 @@ def senml_callback(self, record, **kwargs):
143150

144151
async def run(self, aiot):
145152
while True:
146-
if (self.on_read is not None):
153+
if self.on_read is not None:
147154
self.value = self.on_read(aiot)
148-
if (self.on_write is not None and self.on_write_scheduled):
155+
if self.on_write is not None and self.on_write_scheduled:
149156
self.on_write_scheduled = False
150157
self.on_write(aiot, self if isinstance(self.value, dict) else self.value)
151158
await asyncio.sleep(self.interval)
152159

153-
class AIOTClient():
160+
161+
class AIOTClient:
154162
def __init__(self, device_id, ssl_params=None, server="mqtts-sa.iot.oniudra.cc", port=8883, keepalive=10):
155163
self.tasks = {}
156164
self.records = {}
@@ -159,7 +167,7 @@ def __init__(self, device_id, ssl_params=None, server="mqtts-sa.iot.oniudra.cc",
159167
self.update_systime()
160168
self.last_ping = timestamp()
161169
self.device_topic = b"/a/d/" + device_id + b"/e/i"
162-
self.senmlpack = SenmlPack("urn:uuid:"+device_id.decode("utf-8"), self.senml_generic_callback)
170+
self.senmlpack = SenmlPack("urn:uuid:" + device_id.decode("utf-8"), self.senml_generic_callback)
163171
self.mqtt = MQTTClient(device_id, server, port, ssl_params, keepalive=keepalive, callback=self.mqtt_callback)
164172
# Note: the following internal objects are initialized by the cloud.
165173
for name in ["thing_id", "tz_offset", "tz_dst_until"]:
@@ -183,11 +191,8 @@ def get(self, key, default=None):
183191

184192
def update_systime(self):
185193
try:
186-
from aiotcloud import ntptime
187194
ntptime.settime()
188195
logging.info("RTC time set from NTP.")
189-
except ImportError:
190-
pass
191196
except Exception as e:
192197
logging.error(f"Failed to set RTC time from NTP: {e}.")
193198

@@ -239,8 +244,8 @@ async def discovery_task(self, interval=0.100):
239244
self.mqtt.check_msg()
240245
if self.records.get("thing_id").value is not None:
241246
self.thing_id = self.records.pop("thing_id").value
242-
if not self.thing_id: # Empty thing ID should not happen.
243-
raise(Exception("Device is not linked to a Thing ID."))
247+
if not self.thing_id: # Empty thing ID should not happen.
248+
raise (Exception("Device is not linked to a Thing ID."))
244249

245250
self.topic_out = self.create_topic("e", "o")
246251
self.mqtt.subscribe(self.create_topic("e", "i"))
@@ -249,7 +254,7 @@ async def discovery_task(self, interval=0.100):
249254
lastval_record.add_to_pack(self.senmlpack)
250255
self.mqtt.subscribe(self.create_topic("shadow", "i"))
251256
self.mqtt.publish(self.create_topic("shadow", "o"), self.senmlpack.to_cbor(), qos=True)
252-
logging.info(f"Device configured via discovery protocol.")
257+
logging.info("Device configured via discovery protocol.")
253258
await asyncio.sleep(interval)
254259

255260
async def mqtt_task(self, interval=0.100):
@@ -258,30 +263,28 @@ async def mqtt_task(self, interval=0.100):
258263
if self.thing_id is not None:
259264
self.senmlpack.clear()
260265
for record in self.records.values():
261-
if (record.updated):
266+
if record.updated:
262267
record.add_to_pack(self.senmlpack)
263268
if len(self.senmlpack._data):
264269
logging.debug("Pushing records to AIoT Cloud:")
265-
if (self.debug):
266-
for record in self.senmlpack:
267-
logging.debug(f" ==> record: {record.name} value: {str(record.value)[:48]}...")
270+
for record in self.senmlpack:
271+
logging.debug(f" ==> record: {record.name} value: {str(record.value)[:48]}...")
268272
self.mqtt.publish(self.topic_out, self.senmlpack.to_cbor(), qos=True)
269273
self.last_ping = timestamp()
270-
elif (self.keepalive and (timestamp() - self.last_ping) > self.keepalive):
274+
elif self.keepalive and (timestamp() - self.last_ping) > self.keepalive:
271275
self.mqtt.ping()
272276
self.last_ping = timestamp()
273277
logging.debug("No records to push, sent a ping request.")
274278
await asyncio.sleep(interval)
275-
276-
async def run(self, user_main=None, debug=False):
277-
self.debug = debug
279+
280+
async def run(self, user_main=None):
278281
logging.info("Connecting to AIoT cloud...")
279282
if not self.mqtt.connect():
280283
logging.error("Failed to connect AIoT cloud.")
281284
return
282285

283286
self.mqtt.subscribe(self.device_topic)
284-
if (user_main is not None):
287+
if user_main is not None:
285288
self.create_task("user_main", user_main, self)
286289
self.create_task("mqtt_task", self.mqtt_task)
287290
self.create_task("discovery", self.discovery_task)
@@ -291,8 +294,8 @@ async def run(self, user_main=None, debug=False):
291294
await asyncio.gather(*self.tasks.values(), return_exceptions=False)
292295
logging.info("All tasks finished!")
293296
break
294-
except Exception as e:
295-
pass #import traceback; traceback.print_exc()
297+
except Exception:
298+
pass # import traceback; traceback.print_exc()
296299

297300
for name in list(self.tasks):
298301
task = self.tasks[name]
@@ -301,4 +304,5 @@ async def run(self, user_main=None, debug=False):
301304
self.tasks.pop(name)
302305
self.records.pop(name, None)
303306
logging.error(f"Removed task: {name}. Raised exception: {task.exception()}.")
304-
except (CancelledError, InvalidStateError) as e: pass
307+
except (CancelledError, InvalidStateError):
308+
pass

‎aiotcloud/umqtt.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
# Based on: https://github.com/micropython/micropython-lib/tree/master/micropython/umqtt.simple
2424

2525
import time
26+
2627
try:
2728
import socket
2829
import struct
@@ -34,12 +35,23 @@
3435
import ulogging as logging
3536
from ussl import wrap_socket
3637

38+
3739
class MQTTException(Exception):
3840
pass
3941

42+
4043
class MQTTClient:
41-
def __init__(self, client_id, server, port, ssl_params,
42-
user=None, password=None, keepalive=0, callback=None):
44+
def __init__(
45+
self,
46+
client_id,
47+
server,
48+
port,
49+
ssl_params,
50+
user=None,
51+
password=None,
52+
keepalive=0,
53+
callback=None,
54+
):
4355
self.client_id = client_id
4456
self.server = server
4557
self.port = port
@@ -86,7 +98,7 @@ def _connect(self, clean_session=True):
8698
self.sock = socket.socket()
8799
self.sock = wrap_socket(self.sock, **self.ssl_params)
88100
self.sock.connect(addr)
89-
except:
101+
except Exception:
90102
self.sock.close()
91103
self.sock = socket.socket()
92104
self.sock.connect(addr)
@@ -211,7 +223,7 @@ def subscribe(self, topic, qos=0):
211223
# messages processed internally.
212224
def wait_msg(self):
213225
res = self.sock.read(1)
214-
if res == b"" or res == None:
226+
if res == b"" or res is None:
215227
return None
216228
self.sock.setblocking(True)
217229
if res == b"\xd0": # PINGRESP

‎aiotcloud/ussl.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2323
# THE SOFTWARE.
2424
#
25-
# ussl module with m2crypto backend for HSM support.
25+
# ussl module with m2crypto backend for HSM support.
2626

27-
from M2Crypto import Engine, m2, BIO, SSL
27+
from M2Crypto import Engine, m2, SSL
2828

2929
_key = None
3030
_cert = None
@@ -33,6 +33,7 @@
3333
ENGINE_PATH = "/usr/lib/engines-1.1/libpkcs11.so"
3434
MODULE_PATH = "/usr/lib/softhsm/libsofthsm2.so"
3535

36+
3637
def init(pin, certfile, keyfile, engine_path, module_path):
3738
global _key, _cert
3839
Engine.load_dynamic_engine("pkcs11", engine_path)
@@ -43,12 +44,22 @@ def init(pin, certfile, keyfile, engine_path, module_path):
4344
_key = pkcs11.load_private_key(keyfile)
4445
_cert = pkcs11.load_certificate(certfile)
4546

46-
def wrap_socket(sock_in, pin, certfile, keyfile, ca_certs=None, ciphers=None, engine_path=ENGINE_PATH, module_path=MODULE_PATH):
47+
48+
def wrap_socket(
49+
sock_in,
50+
pin,
51+
certfile,
52+
keyfile,
53+
ca_certs=None,
54+
ciphers=None,
55+
engine_path=ENGINE_PATH,
56+
module_path=MODULE_PATH,
57+
):
4758
if _key is None or _cert is None:
4859
init(pin, certfile, keyfile, engine_path, module_path)
4960

5061
# Create SSL context
51-
ctx = SSL.Context('tls')
62+
ctx = SSL.Context("tls")
5263
ctx.set_default_verify_paths()
5364
ctx.set_allow_unknown_ca(False)
5465

@@ -57,7 +68,7 @@ def wrap_socket(sock_in, pin, certfile, keyfile, ca_certs=None, ciphers=None, en
5768

5869
if ca_certs is not None:
5970
if ctx.load_verify_locations(ca_certs) != 1:
60-
raise Exception('Failed to load CA certs')
71+
raise Exception("Failed to load CA certs")
6172
ctx.set_verify(SSL.verify_peer, depth=9)
6273

6374
# Set key/cert

‎aiotcloud_example.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
# This file is part of the Python Arduino IoT Cloud.
2424

2525
import time
26+
2627
try:
2728
import logging
2829
import asyncio
@@ -41,11 +42,12 @@
4142

4243
DEBUG_ENABLED = True
4344

44-
KEY_URI = "pkcs11:token=arduino"
45-
CERT_URI = "pkcs11:token=arduino"
46-
CA_PATH = "ca-root.pem"
45+
KEY_URI = "pkcs11:token=arduino"
46+
CERT_URI = "pkcs11:token=arduino"
47+
CA_PATH = "ca-root.pem"
4748
DEVICE_ID = b"25deeda1-3fda-4d06-9c3c-dd31be382cd2"
4849

50+
4951
async def user_main(aiot):
5052
"""
5153
Add your code here.
@@ -59,21 +61,27 @@ async def user_main(aiot):
5961
aiot["user"] = choice(["=^.. ^=", "=^ ..^="])
6062
await asyncio.sleep(1.0)
6163

64+
6265
def on_switch_changed(aiot, value):
6366
"""
6467
This is a write callback for the switch that toggles the LED variable. The LED
6568
variable can be accessed via the aiot cloud object passed in the first argument.
6669
"""
6770
if value and not hasattr(on_switch_changed, "init"):
68-
on_switch_changed.init=True
69-
logging.info(f"Someone left the lights on!")
71+
on_switch_changed.init = True
72+
logging.info("Someone left the lights on!")
7073
aiot["led"] = value
7174

75+
7276
def on_clight_changed(aiot, clight):
73-
logging.info(f"ColoredLight changed. Switch: {clight.swi} Bright: {clight.bri} Sat: {clight.sat} Hue: {clight.hue}")
77+
logging.info(f"ColoredLight changed. Swi: {clight.swi} Bri: {clight.bri} Sat: {clight.sat} Hue: {clight.hue}")
78+
7479

7580
async def main():
76-
aiot = AIOTClient(device_id=DEVICE_ID, ssl_params = {"pin":"1234", "keyfile":KEY_URI, "certfile":CERT_URI, "ca_certs":CA_PATH})
81+
aiot = AIOTClient(
82+
device_id=DEVICE_ID,
83+
ssl_params={"pin": "1234", "keyfile": KEY_URI, "certfile": CERT_URI, "ca_certs": CA_PATH},
84+
)
7785
# This cloud object is initialized with its last known value from the cloud.
7886
aiot.register("sw1", value=None, on_write=on_switch_changed, interval=0.250)
7987

@@ -82,11 +90,11 @@ async def main():
8290
aiot.register("led", value=None)
8391

8492
# This is a periodic cloud object that gets updated every 1 second.
85-
aiot.register("pot", value=None, on_read=lambda x:randint(0, 1024), interval=1.0)
93+
aiot.register("pot", value=None, on_read=lambda x: randint(0, 1024), interval=1.0)
8694

8795
# This is a periodic cloud object that gets updated every 1 second,
8896
# with the formatted current time value.
89-
aiot.register("clk", value=None, on_read=lambda x:strftime("%H:%M:%S", time.localtime()), interval=1.0)
97+
aiot.register("clk", value=None, on_read=lambda x: strftime("%H:%M:%S", time.localtime()), interval=1.0)
9098

9199
# This variable is an example for a composite object (a colored light object in this case),
92100
# which is composed of multiple variables. Once initialized, the object's variables can be
@@ -105,11 +113,13 @@ async def main():
105113
aiot.register(Schedule("schedule", on_active=lambda aiot, value: logging.info(f"Schedule activated {value}!")))
106114

107115
# Start the AIoT client.
108-
await aiot.run(user_main, debug=DEBUG_ENABLED)
116+
await aiot.run(user_main)
117+
109118

110119
if __name__ == "__main__":
111120
logging.basicConfig(
112-
datefmt="%H:%M:%S",
113-
format="%(asctime)s.%(msecs)03d %(message)s",
114-
level=logging.DEBUG if DEBUG_ENABLED else logging.INFO)
121+
datefmt="%H:%M:%S",
122+
format="%(asctime)s.%(msecs)03d %(message)s",
123+
level=logging.DEBUG if DEBUG_ENABLED else logging.INFO,
124+
)
115125
asyncio.run(main())

0 commit comments

Comments
 (0)
Please sign in to comment.