diff --git a/README.md b/README.md index 07b3732..96ea8a7 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ The repository has the following directory tree. ├── README.md ├── README.qmd ├── README.rmarkdown - ├── current_version.json ├── docs ├── file_list.txt ├── firmware diff --git a/software/README.md b/software/README.md index eaae705..c68cae5 100644 --- a/software/README.md +++ b/software/README.md @@ -59,6 +59,7 @@ The repository has the following directory tree. │ ├── README.md │ ├── README.qmd │ ├── boot.py + │ ├── hm1.py │ ├── main.py │ ├── sl1.py │ └── sm3.py @@ -67,15 +68,19 @@ The repository has the following directory tree. │ ├── README.qmd │ ├── examples │ ├── networking.py - │ └── ssp_networking.py + │ ├── networking_test.py + │ ├── ssp_networking.py + │ └── ssp_networking_test.py └── release ├── README.md ├── README.qmd ├── __pycache__ ├── adxl345.py + ├── boot.py ├── config.py ├── file_list.py ├── files.py + ├── hm1.py ├── icons.py ├── main.py ├── networking.py diff --git a/software/main/README.md b/software/main/README.md index a7342df..090532d 100644 --- a/software/main/README.md +++ b/software/main/README.md @@ -17,6 +17,7 @@ The repository has the following directory tree. ├── README.qmd ├── README.rmarkdown ├── boot.py + ├── hm1.py ├── main.py ├── sl1.py └── sm3.py diff --git a/software/networking/README.md b/software/networking/README.md index b4dbd8c..2b78fac 100644 --- a/software/networking/README.md +++ b/software/networking/README.md @@ -31,7 +31,9 @@ The repository has the following directory tree. │ ├── example.py │ └── long_message_example.py ├── networking.py - └── ssp_networking.py + ├── networking_test.py + ├── ssp_networking.py + └── ssp_networking_test.py A short description of the directories can be found below. diff --git a/software/release/README.md b/software/release/README.md index 5b0620d..ec73791 100644 --- a/software/release/README.md +++ b/software/release/README.md @@ -19,9 +19,11 @@ The repository has the following directory tree. ├── __pycache__ │ └── config.cpython-310.pyc ├── adxl345.py + ├── boot.py ├── config.py ├── file_list.py ├── files.py + ├── hm1.py ├── icons.py ├── main.py ├── networking.py @@ -40,7 +42,11 @@ A short description of the directories can be found below. | name | description | contribution | |----|----|----| | release/config.py | Smart Module Configuration File | Nick | -| main/main.py | Smart Module Main.py | Nick | +| main/boot.py | Smart Module boot.py | Nick | +| main/main.py | Smart Module main.py | Nick | +| main/hm1.py | Smart hive program | Nick | +| main/sl1.py | Smart light module main program | Milan | +| main/sm3.py | Smart motor module main program | Milan | | networking/networking.py | This is the main networking code that builds on ESP-NOW. There are many prepared functionalities (and some more that I am working on), such as long message support, sending of various variable types (bytes, bytearray, dicts, lists, int, float, char, string), as well as different types of messages such as ping, echo and more. There are also various features in place to make the networking more robust. | Nick | | networking/ssp_networking.py | This is the ssp networking module. It needs config.py to function. | Nick | | libraries/adxl345.py | Support for the built in accelerometer https://github.com/DFRobot/micropython-dflib/blob/master/ADXL345/user_lib/ADXL345.py | Milan | @@ -49,7 +55,5 @@ A short description of the directories can be found below. | libraries/sensors.py | Sensor support for the smart motor module | Milan | | libraries/servo.py | Servo support for the smart motor module | Milan | | libraries/smartlight.py | Smart light support for smart light module | Milan | -| main/sl1.py | Smart light module main program | Milan | -| main/sm3.py | Smart motor module main program | Milan | | libraries/ssd1306.py | Support for the built in OLED screen https://github.com/stlehmann/micropython-ssd1306/blob/master/ssd1306.py | Milan | | libraries/variableLED.py | Library that powers the variable LED grid | Sophie | diff --git a/software/release/boot.py b/software/release/boot.py new file mode 100644 index 0000000..10fe88d --- /dev/null +++ b/software/release/boot.py @@ -0,0 +1,99 @@ +from machine import Pin +import machine +from config import config +import time +import gc + +gc.collect() + +import network + +print("Running boot.py") + +# just to be safe +sta = network.WLAN(network.STA_IF) +ap = network.WLAN(network.AP_IF) +sta.active(True) +ap.active(True) +sta.active(False) +ap.active(False) + +from ssp_networking import SSP_Networking + +# Network +infmsg = True +dbgmsg = False +errmsg = True +global timer +peer_mac = b'\xff\xff\xff\xff\xff\xff' +configuration = config["configuration"] +hive = config["hive"] +if configuration == "AM1": + infmsg = True + +networking = SSP_Networking(infmsg, dbgmsg, errmsg) + +print("{:.3f} Name: {}, ID: {}, Configuration: {}, Sta mac: {}, Ap mac: {}, Version: {}".format( + (time.ticks_ms() - networking.inittime) / 1000, + networking.config["name"], + networking.config["id"], + networking.config["configuration"], + networking.config["ap_mac"], + networking.config["sta_mac"], + networking.config["version"] +)) + +def idle(): + lastPressed = 0 + message = "Boop!" + + def boop(pin): + global lastPressed + if (time.ticks_ms() - lastPressed > 1000): + lastPressed = time.ticks_ms() + networking.ping(peer_mac) + networking.echo(peer_mac, message) + networking.send(peer_mac, message) + print(f"{(time.ticks_ms() - networking.inittime) / 1000:.3f} Networking Tool: Sent {message} to {peer_mac}") + print( + f"{(time.ticks_ms() - networking.inittime) / 1000:.3f} Networking Tool: RSSI table: {networking.rssi()}") + + # Buttons + switch_select = Pin(9, Pin.IN, Pin.PULL_UP) + switch_select.irq(trigger=Pin.IRQ_FALLING, handler=boop) + + def heartbeat(timer): + print("") + print(f"{(time.ticks_ms() - networking.inittime) / 1000:.3f} Networking Tool Heartbeat: {gc.mem_free()} bytes") + print("") + gc.collect() + + timer = machine.Timer(0) + timer.init(period=5000, mode=machine.Timer.PERIODIC, callback=heartbeat) + +def run_config_module(module_name): + try: + with open(module_name + ".py") as f: + code = f.read() + exec(code) + except Exception as e: + print(f"Error running {module_name}: {e}") + +# cases for different configurations +if not hive: + if configuration == "AM1": + print("am1") + idle() + elif configuration == "SM3": + print("sm3") + run_config_module("sm3") + elif configuration == "SL1": + print("sl1") + run_config_module("sl1") + else: + print("idle") + idle() +else: + run_config_module("hm1") + # insert code here to run in case of hive motor! + diff --git a/software/release/config.py b/software/release/config.py index 76a52f1..06abc74 100644 --- a/software/release/config.py +++ b/software/release/config.py @@ -6,7 +6,8 @@ "version": None } version = {'adxl345.py': 3, - 'ssp_networking.py': 1, + 'hm1.py': 1, +'ssp_networking.py': 2, 'files.py': 2, 'icons.py': 2, 'prefs.py': 2, @@ -16,8 +17,8 @@ 'sm3.py': 1, 'sl1.py': 1, 'smartlight.py': 1, - 'networking.py': 3, - 'main.py': 1, +'networking.py': 4, +'main.py': 2, 'boot.py': 0 } mysecrets = {"SSID": "Tufts_Robot", "key": ""} diff --git a/software/release/hm1.py b/software/release/hm1.py new file mode 100644 index 0000000..3339fa1 --- /dev/null +++ b/software/release/hm1.py @@ -0,0 +1,6 @@ +#variable to save matrix input output logic in + +#irq to send sensor data to defined mac + +#irq to use newly received sensor data to change output + diff --git a/software/release/main.py b/software/release/main.py index 8168039..e69de29 100644 --- a/software/release/main.py +++ b/software/release/main.py @@ -1,104 +0,0 @@ -from machine import Pin -import machine -from config import config - -import gc -gc.collect() - -import network - -print("Running pyscript main") - -#just to be safe -sta = network.WLAN(network.STA_IF) -ap = network.WLAN(network.AP_IF) -sta.active(True) -ap.active(True) -sta.active(False) -ap.active(False) - -from ssp_networking import SSP_Networking - -#Network -infmsg = False -dbgmsg = False -errmsg = True -configuration = config["configuration"] -if configuration == "AM1": - infmsg = True - -networking = SSP_Networking(infmsg, dbgmsg, errmsg) - -peer_mac = b'\xff\xff\xff\xff\xff\xff' - -import time -global timer - -print("{:.3f} Name: {}, ID: {}, Configuration: {}, Sta mac: {}, Ap mac: {}, Version: {}".format( - (time.ticks_ms() - networking.inittime) / 1000, - networking.config["name"], - networking.config["id"], - networking.config["configuration"], - networking.sta.mac(), - networking.ap.mac(), - networking.config["version"] -)) - - -def idle(): - lastPressed = 0 - - message="Boop!" - - def boop(pin): - global lastPressed - if(time.ticks_ms()-lastPressed>1000): - lastPressed = time.ticks_ms() - networking.aen.ping(peer_mac) - networking.aen.echo(peer_mac, message) - networking.aen.send(peer_mac, message) - print(f"{(time.ticks_ms() - networking.inittime) / 1000:.3f} Networking Tool: Sent {message} to {peer_mac}") - print(f"{(time.ticks_ms() - networking.inittime) / 1000:.3f} Networking Tool: RSSI table: {networking.aen.rssi()}") - - #Buttons - switch_select = Pin(9, Pin.IN, Pin.PULL_UP) - switch_select.irq(trigger=Pin.IRQ_FALLING, handler=boop) - - def heartbeat(timer): - print("") - print(f"{(time.ticks_ms() - networking.inittime) / 1000:.3f} Networking Tool Heartbeat: {gc.mem_free()} bytes") - print("") - gc.collect() - - timer = machine.Timer(0) - timer.init(period=5000, mode=machine.Timer.PERIODIC, callback=heartbeat) - -def deinit(): - networking.cleanup() - try: - timer.deinit() - except Exception as e: - print(e) - machine.reset() - -def run_config_module(module_name): - try: - with open(module_name + ".py") as f: - code = f.read() - exec(code) - except Exception as e: - print(f"Error running {module_name}: {e}") - -# cases for different configurations -if configuration == "AM1": - print("idle") - idle() -elif configuration == "SM3": - print("sm3") - run_config_module("sm3") -elif configuration == "SL1": - print("sl1") - run_config_module("sl1") -else: - print("idle") - idle() diff --git a/software/release/networking.py b/software/release/networking.py index 6367a4f..5cb6edd 100644 --- a/software/release/networking.py +++ b/software/release/networking.py @@ -196,15 +196,17 @@ def cleanup(self): def update_peer(self, peer_mac, peer_config=None, channel=None, ifidx=None): self.master.dprint("aen.update_peer") + if peer_mac == b'\xff\xff\xff\xff\xff\xff': + return if peer_mac in self._peers: try: if peer_config is not None: self._peers[peer_mac].update(peer_config) if channel is not None: - self._peers[peer_mac]['channel'] = channel + self._peers[peer_mac].update({'channel': channel}) if ifidx is not None: - self._peers[peer_mac]['ifidx'] = ifidx - self.master.dprint(f"Peer {peer_mac} updated to channel {channel}, ifidx {ifidx} and name {self._peers[peer_mac]['name']}") + self._peers[peer_mac].update({'ifidx': ifidx}) + self.master.dprint(f"Peer {peer_mac} updated to channel {channel}, ifidx {ifidx} and name {self.peer_name(peer_mac)}") except OSError as e: self.master.eprint(f"Error updating peer {peer_mac}: {e}") return @@ -212,11 +214,19 @@ def update_peer(self, peer_mac, peer_config=None, channel=None, ifidx=None): def add_peer(self, peer_mac, peer_config=None, channel=None, ifidx=None): self.master.dprint("aen.add_peer") + if peer_mac == b'\xff\xff\xff\xff\xff\xff': + return if peer_mac not in self._peers: try: - self._peers[peer_mac] = {'channel': channel, 'ifidx': ifidx} - self._peers[peer_mac].update(peer_config) - self.master.dprint(f"Peer {peer_mac} added with channel {channel}, ifidx {ifidx} and name {self._peers[peer_mac]['name']}") + self._peers[peer_mac] = {} + if channel is not None: + self._peers[peer_mac].update({'channel': channel}) + if ifidx is not None: + self._peers[peer_mac].update({'ifidx': ifidx}) + if peer_config is not None: + self._peers[peer_mac].update(peer_config) + self._peers[peer_mac].update({'rssi': None, 'time': None, 'last_ping': 0}) + self.master.dprint(f"Peer {peer_mac} added with channel {channel}, ifidx {ifidx} and name {self.peer_name(peer_mac)}") except OSError as e: self.master.eprint(f"Error adding peer {peer_mac}: {e}") else: @@ -234,12 +244,19 @@ def remove_peer(self, peer_mac): def peers(self): self.master.dprint("aen.peers") + rssi_table = self._aen.peers_table + for key in self._peers: + self._peers[key].update({'rssi': rssi_table[key][0]}) + self._peers[key].update({'time': rssi_table[key][1]-self.master.inittime}) return self._peers def peer_name(self, key): self.master.dprint("aen.name") if key in self._peers: - return self._peers[key]['name'] + if 'name' in self._peers[key]: + return self._peers[key]['name'] + else: + return None else: return None @@ -260,6 +277,14 @@ def ping(self, mac, channel=None, ifidx=None): #Ping else: send_channel = self.master.sta.channel() self.send_command(0x01, 0x10, mac, [send_channel, self.ifidx, self.master.config], channel, ifidx) # sends channel, ifidx and name + if isinstance(mac, list): + for key in mac: + self._peers[key].update({'last_ping': time.ticks_ms()}) + elif mac == b'\xff\xff\xff\xff\xff\xff': + for key in self._peers: + self._peers[key].update({'last_ping': time.ticks_ms()}) + else: + self._peers[mac].update({'last_ping': time.ticks_ms()}) def boop(self, mac, channel=None, ifidx=None): #"RSSI/Status/Config-Boop" self.master.dprint("aen.boop") @@ -271,7 +296,7 @@ def echo(self, mac, message, channel=None, ifidx=None): try: self.master.iprint(f"Sending echo ({message}) to {mac} ({self.peer_name(mac)})") except Exception as e: - self.master.eprint(f"Sending echo to {mac} ({self.peer_name(mac)}), but error printing message content: {e}") + self.master.eprint(f"Sending echo to {mac}, but error printing message content: {e}") else: self.master.iprint(f"Sending echo ({message}) to {mac} ({self.peer_name(mac)})") self.send_command(0x01, 0x15, mac, message, channel, ifidx) @@ -279,6 +304,7 @@ def echo(self, mac, message, channel=None, ifidx=None): def send_message(self, mac, message, channel=None, ifidx=None): self.send(mac, message, channel, ifidx) + def send(self, mac, message, channel=None, ifidx=None): self.master.dprint("aen.send_message") if len(str(message)) > 241: @@ -321,8 +347,8 @@ def return_messages(self): gc.collect() return messages return [(None, None, None)] - - def _irq(self): + + def _irq(self, espnow): self.master.dprint("aen._irq") if self.master.admin: try: @@ -360,29 +386,24 @@ def ack(self, func): def _send(self, peers_mac, messages, channel, ifidx): self.master.dprint("aen._send") - if isinstance(peers_mac, bytes): peers_mac = [peers_mac] for peer_mac in peers_mac: try: - if channel is not None and ifidx is not None: - self._aen.add_peer(peer_mac, channel=channel, ifidx=ifidx) - elif channel is not None: + if channel is None: if peer_mac in self._peers: - self._aen.add_peer(peer_mac, channel=channel, ifidx=self._peers[peer_mac]['ifidx']) + if 'channel' in self._peers[peer_mac]: + channel=self._peers[peer_mac]['channel'] else: - self._aen.add_peer(peer_mac, channel=channel, ifidx=self.ifidx) - elif ifidx is not None: + channel = 0 + elif ifidx is None: if peer_mac in self._peers: - self._aen.add_peer(peer_mac, channel=self._peers[peer_mac]['channel'], ifidx=ifidx) + if 'ifidx' in self._peers[peer_mac]: + ifidx=self._peers[peer_mac]['ifidx'] else: - self._aen.add_peer(peer_mac, channel=0, ifidx=ifidx) - elif peer_mac in self._peers: - self._aen.add_peer(peer_mac, channel=self._peers[peer_mac]['channel'], - ifidx=self._peers[peer_mac]['ifidx']) - else: - self._aen.add_peer(peer_mac, channel=0, ifidx=self.ifidx) - self.master.dprint(f"Added {peer_mac} to espnow buffer") + ifidx=self.ifidx + self._aen.add_peer(peer_mac, channel=channel, ifidx=ifidx) + self.master.dprint(f"Added {peer_mac} to espnow buffer with channel {channel} and ifidx {ifidx}") except Exception as e: self.master.eprint(f"Error adding {peer_mac} to espnow buffer: {e}") @@ -412,30 +433,29 @@ def _compose(self, peer_mac, payload=None, msg_type=0x02, subtype=0x22, channel= self.add_peer(peer_macs, None, channel, ifidx) elif peer_mac not in self._peers: self.add_peer(peer_mac, None, channel, ifidx) - - def __encode_payload(): - self.master.dprint("aen.__encode_payload") - if payload is None: # No payload type - return b'\x00', b'' - elif isinstance(payload, bytearray): # bytearray - return b'\x01', bytes(payload) - elif isinstance(payload, bytes): # bytes - return b'\x01', payload - elif isinstance(payload, bool): # bool - return b'\x02', (b'\x01' if payload else b'\x00') - elif isinstance(payload, int): # int - return b'\x03', struct.pack('>i', payload) - elif isinstance(payload, float): # float - return b'\x04', struct.pack('>f', payload) - elif isinstance(payload, str): # string - return b'\x05', payload.encode('utf-8') - elif isinstance(payload, dict) or isinstance(payload, list): # json dict or list - json_payload = json.dumps(payload) - return b'\x06', json_payload.encode('utf-8') - else: - raise ValueError("Unsupported payload type") - - payload_type, payload_bytes = __encode_payload() + + payload_type, payload_bytes = None, None + self.master.dprint("aen.__encode_payload") + if payload is None: # No payload type + payload_type, payload_bytes = b'\x00', b'' + elif isinstance(payload, bytearray): # bytearray + payload_type, payload_bytes = b'\x01', bytes(payload) + elif isinstance(payload, bytes): # bytes + payload_type, payload_bytes = b'\x01', payload + elif isinstance(payload, bool): # bool + payload_type, payload_bytes = b'\x02', (b'\x01' if payload else b'\x00') + elif isinstance(payload, int): # int + payload_type, payload_bytes = b'\x03', struct.pack('>i', payload) + elif isinstance(payload, float): # float + payload_type, payload_bytes = b'\x04', struct.pack('>f', payload) + elif isinstance(payload, str): # string + payload_type, payload_bytes = b'\x05', payload.encode('utf-8') + elif isinstance(payload, dict) or isinstance(payload, list): # json dict or list + json_payload = json.dumps(payload) + payload_type, payload_bytes = b'\x06', json_payload.encode('utf-8') + else: + raise ValueError("Unsupported payload type") + messages = [] identifier = 0x2a timestamp = time.ticks_ms() @@ -476,31 +496,10 @@ def __encode_payload(): gc.collect() self._send(peer_mac, messages, channel, ifidx) - def _receive(self): # Processes all the messages in the buffer + def _receive(self): self.master.dprint("aen._receive") - def __decode_payload(payload_type, payload_bytes): - self.master.dprint("aen.__decode_payload") - if payload_type == b'\x00': # None - return None - elif payload_type == b'\x01': # bytearray or bytes - return bytes(payload_bytes) - elif payload_type == b'\x02': # bool - return payload_bytes[0:1] == b'\x01' - elif payload_type == b'\x03': # int - return struct.unpack('>i', payload_bytes)[0] - elif payload_type == b'\x04': # float - return struct.unpack('>f', payload_bytes)[0] - elif payload_type == b'\x05': # string - return payload_bytes.decode('utf-8') - elif payload_type == b'\x06': # json dict or list - return json.loads(payload_bytes.decode('utf-8')) - elif payload_type == b'\x07': # Long byte array - return bytes(payload_bytes) - else: - raise ValueError(f"Unsupported payload type: {payload_type} Message: {payload_bytes}") - - def __process_message(sender_mac, message, receive_timestamp): + def __process_message(self, sender_mac, message, receive_timestamp): self.master.dprint("aen.__process_message") if message[0] != 0x2a: # Unique Message Identifier Check self.master.dprint("Invalid message: Message ID Fail") @@ -509,13 +508,13 @@ def __process_message(sender_mac, message, receive_timestamp): self.master.dprint("Invalid message: too short") return None - msg_type = bytes(message[1:2]) - subtype = bytes(message[2:3]) + msg_type = int.from_bytes(message[1:2], 'big') + subtype = subtype = int.from_bytes(message[2:3], 'big') send_timestamp = int.from_bytes(message[3:7], 'big') payload_type = bytes(message[7:8]) - payload = message[8:-1] + payload_bytes = message[8:-1] checksum = message[-1] - self.master.dprint(f"{type(msg_type)}: {msg_type}, {type(subtype)}: {subtype}, {type(send_timestamp)}: {send_timestamp}, {type(payload_type)}: {payload_type}, {type(payload)}: {payload}, {type(checksum)}: {checksum}") + self.master.dprint(f"{type(msg_type)}: {msg_type}, {type(subtype)}: {subtype}, {type(send_timestamp)}: {send_timestamp}, {type(payload_type)}: {payload_type}, {type(payload_bytes)}: {payload_bytes}, {type(checksum)}: {checksum}") # Checksum if checksum != sum(message[:-1]) % 256: @@ -524,6 +523,8 @@ def __process_message(sender_mac, message, receive_timestamp): if sender_mac not in self._peers: self.add_peer(sender_mac) + + payload = None if payload_type == b'\x07': self.master.dprint("Long message received, processing...") @@ -546,8 +547,8 @@ def __process_message(sender_mac, message, receive_timestamp): if key in self._long_buffer: # If the part is None, add the payload if self._long_buffer[key][part_n] is None: - self._long_buffer[key][part_n] = payload - self._long_buffer_size[key] = self._long_buffer_size[key] + len(payload) + self._long_buffer[key][part_n] = payload_bytes + self._long_buffer_size[key] = self._long_buffer_size[key] + len(payload_bytes) self.master.dprint( f"Long message: Key found, message added to entry in long_message_buffer, {sum(1 for item in self._long_buffer[key] if item is not None)} out of {total_n} packages received") # If there are still missing parts, return @@ -557,9 +558,9 @@ def __process_message(sender_mac, message, receive_timestamp): else: # Initialize the long message buffer for this key payloads = [None] * total_n - payloads[part_n] = payload + payloads[part_n] = payload_bytes self._long_buffer[key] = payloads - self._long_buffer_size[key] = len(payload) + self._long_buffer_size[key] = len(payload_bytes) self.master.dprint( f"Long message: Key not found and new entry created in long_message_buffer, {sum(1 for item in self._long_buffer[key] if item is not None)} out of {total_n} packages received") @@ -575,7 +576,7 @@ def __process_message(sender_mac, message, receive_timestamp): if not any(value is None for value in self._long_buffer[key]): payload = bytearray() for i in range(0, total_n): - payload.extend(self._long_buffer[key][i]) + payload_bytes.extend(self._long_buffer[key][i]) del self._long_buffer[key] del self._long_buffer_size[key] self.master.dprint("Long message: All packages received!") @@ -583,21 +584,38 @@ def __process_message(sender_mac, message, receive_timestamp): self.master.dprint("Long Message: Safeguard triggered, code should not have gotten here") gc.collect() return + + self.master.dprint("aen.__decode_payload") + if payload_type == b'\x00': # None + payload = None + elif payload_type == b'\x01': # bytearray or bytes + payload = bytes(payload_bytes) + elif payload_type == b'\x02': # bool + payload = payload_bytes[0:1] == b'\x01' + elif payload_type == b'\x03': # int + payload = struct.unpack('>i', payload_bytes)[0] + elif payload_type == b'\x04': # float + payload = struct.unpack('>f', payload_bytes)[0] + elif payload_type == b'\x05': # string + payload = payload_bytes.decode('utf-8') + elif payload_type == b'\x06': # json dict or list + payload = json.loads(payload_bytes.decode('utf-8')) #use eval instead? #FIX + elif payload_type == b'\x07': # Long byte array + payload = bytes(payload_bytes) + else: + raise ValueError(f"Unsupported payload type: {payload_type} Message: {payload_bytes}") # Handle the message based on type if msg_type == (msg_key := 0x01): # Command Message - __handle_cmd(sender_mac, subtype, send_timestamp, receive_timestamp, payload_type, - payload if payload else None, msg_key) + __handle_cmd(self, sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key) elif msg_type == (msg_key := 0x02): # Informational Message - __handle_inf(sender_mac, subtype, send_timestamp, receive_timestamp, payload_type, - payload if payload else None, msg_key) + __handle_inf(self, sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key) elif msg_type == (msg_key := 0x03): # Acknowledgement Message - __handle_ack(sender_mac, subtype, send_timestamp, receive_timestamp, payload_type, - payload if payload else None, msg_key) + __handle_ack(self, sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key) else: self.master.iprint(f"Unknown message type from {sender_mac} ({self.peer_name(sender_mac)}): {message}") - def __send_confirmation(msg_type, recipient_mac, msg_subkey_type, payload=None, error=None): + def __send_confirmation(self, msg_type, recipient_mac, msg_subkey_type, payload=None, error=None): if msg_type == "Success": self._compose(recipient_mac, [msg_subkey_type, payload], 0x03, 0x11) elif msg_type == "Fail": @@ -605,9 +623,8 @@ def __send_confirmation(msg_type, recipient_mac, msg_subkey_type, payload=None, else: self._compose(recipient_mac, [msg_subkey_type, payload], 0x03, 0x13) - def __handle_cmd(sender_mac, subtype, send_timestamp, receive_timestamp, payload_type, payload, msg_key): + def __handle_cmd(self, sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key): self.master.dprint(f"aen.__handle_cmd") - payload = __decode_payload(payload_type, payload) if (msg_subkey := "Ping") and subtype == 0x01 or subtype == 0x10: # Ping self.master.iprint(f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.peer_name(sender_mac)})") self.add_peer(sender_mac, payload[2], payload[0], payload[1]) @@ -623,28 +640,27 @@ def __handle_cmd(sender_mac, subtype, send_timestamp, receive_timestamp, payload try: self._compose(sender_mac, [self.master.config, self.master.version, self.master.sta.mac, self.master.ap.mac, self.rssi()], 0x02, 0x20) # [ID, Name, Config, Version, sta mac, ap mac, rssi] except Exception as e: - __send_confirmation("Fail", sender_mac, f"{msg_subkey} ({subtype})", payload, e) + __send_confirmation(self, "Fail", sender_mac, f"{msg_subkey} ({subtype})", payload, e) elif (msg_subkey := "Echo") and subtype == subtype == 0x02 or subtype == 0x15: # Echo - self.master.iprint(f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.peer_name(sender_mac)}): {__decode_payload(payload_type, payload)}") # Check i or d + self.master.iprint(f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.peer_name(sender_mac)}): {payload}") # Check i or d self._compose(sender_mac, payload, 0x03, 0x15) else: self.master.iprint(f"Unknown command subtype from {sender_mac} ({self.peer_name(sender_mac)}): {subtype}") if self.custom_cmd: - self.custom_cmd(sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key) + self.custom_cmd([sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key]) - def __handle_inf(sender_mac, subtype, send_timestamp, receive_timestamp, payload_type, payload, msg_key): + def __handle_inf(self, sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key): self.master.dprint("aen.__handle_inf") - payload = __decode_payload(payload_type, payload) if (msg_subkey := "RSSI/Status/Config-Boop") and subtype == 0x00 or subtype == 0x20: # RSSI/Status/Config-Boop self.master.iprint(f"{msg_subkey} ({subtype}) data received from {sender_mac} ({self.peer_name(sender_mac)}): {payload}") self.received_rssi_data[sender_mac] = payload - # __send_confirmation("Confirm", sender_mac, f"{msg_subkey} ({subtype})", payload) #confirm message recv + # __send_confirmation(self, "Confirm", sender_mac, f"{msg_subkey} ({subtype})", payload) #confirm message recv elif (msg_subkey := "Data") and subtype == 0x01 or subtype == 0x21: # Sensor Data payload["time_sent"] = send_timestamp payload["time_recv"] = receive_timestamp self.master.iprint(f"{msg_subkey} ({subtype}) data received from {sender_mac} ({self.peer_name(sender_mac)}): {payload}") self.received_sensor_data[sender_mac] = payload - # __send_confirmation("Confirm", sender_mac, f"{msg_subkey} ({subtype})", payload) #confirm message recv + # __send_confirmation(self, "Confirm", sender_mac, f"{msg_subkey} ({subtype})", payload) #confirm message recv elif (msg_subkey := "Message") and subtype == 0x02 or subtype == 0x22: # Message / Other self.master.iprint(f"{msg_subkey} ({subtype}) received from {sender_mac} ({self.peer_name(sender_mac)}): {payload}") self._received_messages.append((sender_mac, payload, receive_timestamp)) @@ -653,20 +669,19 @@ def __handle_inf(sender_mac, subtype, send_timestamp, receive_timestamp, payload self.master.dprint(f"Maximum buffer size reached: {len(self._received_messages)}, {sum(self._received_messages_size)} bytes; Reducing!") self._received_messages.pop(0) self._received_messages_size.pop(0) - # __send_confirmation("Confirm", sender_mac, f"{msg_subkey} ({subtype})", payload) #confirm message recv + # __send_confirmation(self, "Confirm", sender_mac, f"{msg_subkey} ({subtype})", payload) #confirm message recv else: self.master.iprint(f"Unknown info subtype from {sender_mac} ({self.peer_name(sender_mac)}): {subtype}") if self.custom_inf: - self.custom_inf(sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key) + self.custom_inf([sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key]) - def __handle_ack(sender_mac, subtype, send_timestamp, receive_timestamp, payload_type, payload, msg_key): + def __handle_ack(self, sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key): self.master.dprint("aen.__handle_ack") - payload = __decode_payload(payload_type, payload) if (msg_subkey := "Pong") and subtype == 0x10: # Pong self.add_peer(sender_mac, payload[2], payload[0], payload[1]) self.master.iprint(f"{msg_subkey} ({subtype}) received from {sender_mac} ({self.peer_name(sender_mac)}), {receive_timestamp - payload[3]}") elif (msg_subkey := "Echo") and subtype == 0x15: # Echo - self.master.iprint(f"{msg_subkey} ({subtype}) received from {sender_mac} ({self.peer_name(sender_mac)}), {__decode_payload(payload_type, payload)}") + self.master.iprint(f"{msg_subkey} ({subtype}) received from {sender_mac} ({self.peer_name(sender_mac)}), {payload}") elif (msg_subkey := "Success") and subtype == 0x11: # Success # payload should return a list with a cmd type and payload self.master.iprint(f"{msg_subkey} ({subtype}) received from {sender_mac} ({self.peer_name(sender_mac)}) for type {payload[0]} with payload {payload[1]}") @@ -682,10 +697,11 @@ def __handle_ack(sender_mac, subtype, send_timestamp, receive_timestamp, payload else: self.master.iprint(f"Unknown ack subtype from {sender_mac} ({self.peer_name(sender_mac)}): {subtype}, Payload: {payload}") if self.custom_ack: - self.custom_ack(sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key) + self.custom_ack([sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key]) # Insert more acknowledgement logic here and/or add message to acknowledgement buffer if self._aen.any(): + timestamp = time.ticks_ms() for mac, data in self._aen: self.master.dprint(f"Received {mac, data}") if mac is None: # mac, msg will equal (None, None) on timeout @@ -693,9 +709,11 @@ def __handle_ack(sender_mac, subtype, send_timestamp, receive_timestamp, payload if data: if mac and data is not None: # self._received_messages.append((sender_mac, data, receive_timestamp))#Messages will be saved here, this is only for debugging purposes - __process_message(mac, data, time.ticks_ms()) + __process_message(self, mac, data, timestamp) if not self._aen.any(): # this is necessary as the for loop gets stuck and does not exit properly. break # message structure (what kind of message types do I need?: Command which requires me to do something (ping, pair, change state(update, code, mesh mode, run a certain file), Informational Message (Sharing Sensor Data and RSSI Data) # | Header (1 byte) | Type (1 byte) | Subtype (1 byte) | Timestamp(ms ticks) (4 bytes) | Payload type (1) | Payload (variable) | Checksum (1 byte) | + + diff --git a/software/release/ssp_networking.py b/software/release/ssp_networking.py index 58d34e3..618aaa2 100644 --- a/software/release/ssp_networking.py +++ b/software/release/ssp_networking.py @@ -15,136 +15,174 @@ def __init__(self, infmsg=False, dbgmsg=False, errmsg=False, admin=False, initti self.networking = Networking(infmsg, dbgmsg, errmsg, admin, inittime) config["id"] = ubinascii.hexlify(machine.unique_id()).decode() config["version"] = ''.join(str(value) for value in version.values()) + config["ap_mac"] = self.networking.ap.mac_decoded() + config["sta_mac"] = self.networking.sta.mac_decoded() self.networking.config = config + self.config = self.networking.config self.version = version - self.commands = self.Commands(self) self.orders = self.Orders(self) - - class Commands: - def __init__(self, master): - self.master = master - - def send_command(self, msg_subkey, mac, payload=None, channel=None, ifidx=None, sudo=False): - self.master.dprint("aen.send_command") - if sudo and isinstance(payload, list): - payload.append("sudo") - elif sudo and payload is None: - payload = ["sudo"] - else: - payload = [payload, "sudo"] - if (msg_key := "cmd") and msg_subkey in msg_subcodes[msg_key]: - self.master.networking.iprint(f"Sending {msg_subkey} ({bytes([msg_subcodes[msg_key][msg_subkey]])}) command to {mac} ({self.master.networking.aen.peer_name(mac)})") - self.master.networking.aen.send_command(msg_codes[msg_key], msg_subcodes[msg_key][msg_subkey], mac, payload, channel, ifidx) + self.inittime = self.networking.inittime + + def rssi(self): + return self.networking.aen.rssi() + + def peers(self): + return self.networking.aen.peers() + + def wpeers(self): + self.networking.iprint(f"time.ticks_ms(): {time.ticks_ms()}") + original_dict = self.networking.aen.peers() + #decoded_dict = {ubinascii.hexlify(key, ':').decode(): value for key, value in original_dict.items()} + networking_peer_info = f"networking_peers_info_start{original_dict}networking_peers_info_end" + print(networking_peer_info) + + def irq(self, func): + self.networking.aen.irq(func) + + def check_messages(self): + return self.networking.aen.check_messages() + + def return_message(self): + return self.networking.aen.return_message() + + def return_messages(self): + return self.networking.aen.return_messages() + + def cleanup(self): + self.networking.cleanup() + + def send_command(self, msg_subkey, mac, payload=None, channel=None, ifidx=None, sudo=False): + self.networking.dprint("aen.send_command") + if sudo and isinstance(payload, list): + payload.append("sudo") + elif sudo and payload is None: + payload = ["sudo"] + else: + payload = [payload, "sudo"] + if (msg_key := "cmd") and msg_subkey in msg_subcodes[msg_key]: + if isinstance(mac, list): + self.networking.iprint(f"Sending {msg_subkey} ({bytes([msg_subcodes[msg_key][msg_subkey]])}) command to {mac}") else: - self.master.iprint(f"Command {msg_subkey} not found") - gc.collect() - - def ping(self, mac, channel=None, ifidx=None): - self.master.networking.dprint("net.cmd.ping") - self.master.networking.aen.ping(mac, channel, ifidx) + self.networking.iprint(f"Sending {msg_subkey} ({bytes([msg_subcodes[msg_key][msg_subkey]])}) command to {mac} ({self.networking.aen.peer_name(mac)})") + self.networking.aen.send_command(msg_codes[msg_key], msg_subcodes[msg_key][msg_subkey], mac, payload, channel, ifidx) + else: + self.networking.iprint(f"Command {msg_subkey} not found") + gc.collect() + + def ping(self, mac, channel=None, ifidx=None): + self.networking.dprint("net.cmd.ping") + self.networking.aen.ping(mac, channel, ifidx) + + def echo(self, mac, message, channel=None, ifidx=None): + self.networking.dprint("net.cmd.echo") + self.networking.aen.echo(mac, message, channel, ifidx) + + def boop(self, mac, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.boop") + self.networking.aen.boop(mac, channel, ifidx) + + def send(self, mac, message, channel=None, ifidx=None): + self.networking.dprint("net.cmd.message") + self.networking.aen.send(mac, message, channel, ifidx) - def echo(self, mac, message, channel=None, ifidx=None): - self.master.networking.dprint("net.cmd.echo") - self.master.networking.aen.echo(mac, message, channel, ifidx) + def broadcast(self, message, channel=None, ifidx=None): + self.networking.dprint("net.cmd.broadcast") + mac = b'\xff\xff\xff\xff\xff\xff' + self.send(mac, message, channel, ifidx) - def boop(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("aen.boop") - self.master.networking.aen.boop(mac, channel, ifidx, sudo) + def send_data(self, mac, message, channel=None, ifidx=None): # message is a dict, key is the sensor type and the value is the sensor value + self.networking.dprint("net.cmd.message") + self.networking.aen.send_data(mac, message, channel, ifidx) - def send(self, mac, message, channel=None, ifidx=None): - self.master.networking.dprint("net.cmd.message") - self.master.networking.aen.send(mac, message, channel, ifidx) + def reboot(self, mac, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.reboot") + self.send_command("Reboot", mac, None, channel, ifidx, sudo) - def broadcast(self, message, channel=None, ifidx=None): - self.master.networking.dprint("net.cmd.broadcast") - mac = b'\xff\xff\xff\xff\xff\xff' - self.send(mac, message, channel, ifidx) + def send_configure(self, mac, configuration, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.send_configure") + self.send_command("Send-Configure", mac, configuration, channel, ifidx, sudo) - def send_data(self, mac, message, channel=None,ifidx=None): # message is a dict, key is the sensor type and the value is the sensor value - self.master.networking.dprint("net.cmd.message") - self.master.networking.aen.send_data(mac, message, channel, ifidx) + def receive_configure(self, mac, configuration, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.send_configure") + self.send_command("Receive-Configure", mac, configuration, channel, ifidx, sudo) - def reboot(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.reboot") - self.master.networking.aen.send_command("Reboot", mac, None, channel, ifidx, sudo) + def firmware_update(self, mac, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.firmware_update") + self.send_command("Firmware-Update", mac, None, channel, ifidx, sudo) - def firmware_update(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.firmware_update") - self.master.networking.aen.send_command("Firmware-Update", mac, None, channel, ifidx, sudo) + def file_update(self, mac, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.file_update") + self.send_command("File-Update", mac, None, channel, ifidx, sudo) - def file_update(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.file_update") - self.master.networking.aen.send_command("File-Update", mac, None, channel, ifidx, sudo) + def file_download(self, mac, link, file_list=None, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.file_download") + self.send_command("File-Download", mac, [link, file_list], channel, ifidx, sudo) - def file_download(self, mac, link, file_list=None, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.file_download") - self.master.networking.aen.send_command("File-Download", mac, [link, file_list], channel, ifidx, sudo) + def web_repl(self, mac, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.web_repl") + self.networking.ap.set_ap(ap_name := self.networking.config["name"], password := networking_keys["default_ap_key"]) + self.send_command("Web-Repl", mac, [ap_name, password], channel, ifidx, sudo) + # await success message and if success False disable AP or try again - def web_repl(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.web_repl") - self.master.networking.ap.set_ap(ap_name := self.master.networking.config["name"], password := networking_keys["default_ap_key"]) - self.master.networking.aen.send_command("Web-Repl", mac, [ap_name, password], channel, ifidx, sudo) - # await success message and if success False disable AP or try again + def file_run(self, mac, filename, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.file_run") + self.send_command("File-Run", mac, filename, channel, ifidx, sudo) - def file_run(self, mac, filename, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.file_run") - self.master.networking.aen.send_command("File-Run", mac, filename, channel, ifidx, sudo) + def admin_set(self, mac, new_bool, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.admin_set") + self.send_command("Admin-Set", mac, new_bool, channel, ifidx, sudo) - def admin_set(self, mac, new_bool, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.admin_set") - self.master.networking.aen.send_command("Admin-Set", mac, new_bool, channel, ifidx, sudo) + def whitelist_add(self, mac, mac_list=None, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.whitelist_add") + if mac_list is not None: + mac_list = [self.networking.sta.mac_decoded, self.networking.ap.mac_decoded] + self.send_command("Whitelist-Add", mac, mac_list, channel, ifidx, sudo) - def whitelist_add(self, mac, mac_list=None, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.whitelist_add") - if mac_list is not None: - mac_list = [self.master.networking.sta.mac, self.master.networking.ap.mac] - self.master.networking.aen.send_command("Whitelist-Add", mac, mac_list, channel, ifidx, sudo) + def config_change(self, mac, new_config, hardcode=False, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.config_change") + self.send_command("Config-Change", mac, [new_config, hardcode], channel, ifidx, sudo) - def config_change(self, mac, new_config, hardcode=False, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.config_change") - self.master.networking.aen.send_command("Config-Change", mac, [new_config, hardcode], channel, ifidx, sudo) + def name_change(self, mac, new_name, hardcode=False, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.name_change") + self.send_command("Name-Change", mac, [new_name, hardcode], channel, ifidx, sudo) - def name_change(self, mac, new_name, hardcode=False, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.name_change") - self.master.networking.aen.send_command("Name-Change", mac, [new_name, hardcode], channel, ifidx, sudo) + def pair(self, mac, key=networking_keys["handshake_key1"], channel=None, ifidx=None): + self.networking.dprint("net.cmd.pair") + self.send_command("Pair", mac, key, channel, ifidx) - def pair(self, mac, key=networking_keys["handshake_key1"], channel=None, ifidx=None): - self.master.networking.dprint("net.cmd.pair") - self.master.networking.aen.send_command("Pair", mac, key, channel, ifidx) + def pair_enable(self, mac, pair_bool, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.pair") + self.send_command("Set-Pair", mac, pair_bool, channel, ifidx, sudo) - def pair_enable(self, mac, pair_bool, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.pair") - self.master.networking.aen.send_command("Set-Pair", mac, pair_bool, channel, ifidx, sudo) + def directory_get(self, mac, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.directory_get") + self.send_command("Directory-Get", mac, None, channel, ifidx, sudo) - def directory_get(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.directory_get") - self.master.networking.aen.send_command("Directory-Get", mac, None, channel, ifidx, sudo) + # resend cmd - # resend cmd + def wifi_connect(self, mac, name, password, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.wifi_connect") + self.send_command("Wifi-Connect", mac, [name, password], channel, ifidx, sudo) - def wifi_connect(self, mac, name, password, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.wifi_connect") - self.master.networking.aen.send_command("Wifi-Connect", mac, [name, password], channel, ifidx, sudo) + def wifi_disconnect(self, mac, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.wifi_disconnect") + self.send_command("Wifi-Disconnect", mac, None, channel, ifidx, sudo) - def wifi_disconnect(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.wifi_disconnect") - self.master.networking.aen.send_command("Wifi-Disconnect", mac, None, channel, ifidx, sudo) + def ap_enable(self, mac, name, password, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.ap_enable") + self.send_command("AP-Enable", mac, [name, password], channel, ifidx, sudo) - def ap_enable(self, mac, name, password, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.ap_enable") - self.master.networking.aen.send_command("AP-Enable", mac, [name, password], channel, ifidx, sudo) + def ap_disable(self, mac, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.ap_disable") + self.send_command("AP-Disable", mac, None, channel, ifidx, sudo) - def ap_disable(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.ap_disable") - self.master.networking.aen.send_command("AP-Disable", mac, None, channel, ifidx, sudo) + def pause(self, mac, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.pause") + self.send_command("Pause", mac, None, channel, ifidx, sudo) - def pause(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.pause") - self.master.networking.aen.send_command("Pause", mac, None, channel, ifidx, sudo) - - def resume(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.resume") - self.master.networking.aen.send_command("Resume", mac, None, channel, ifidx, sudo) + def resume(self, mac, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.resume") + self.send_command("Resume", mac, None, channel, ifidx, sudo) class Orders: @@ -162,26 +200,35 @@ def __init__(self, master): self._paired_macs = [] self._running = True - def __check_authorisation(sender_mac, payload): + def __check_authorisation(self, sender_mac, payload): return sender_mac in self._whitelist or payload == "sudo" or payload[-1] == "sudo" - def __send_confirmation(msg_type, recipient_mac, msg_subkey_type, payload=None, error=None): + def __send_confirmation(self, msg_type, recipient_mac, msg_subkey_type, payload=None, error=None): self.master.networking.dprint("net.order.__send_confirmation") self.master.networking.aen.__send_confirmation(msg_type, recipient_mac, msg_subkey_type, payload, error) - def custom_cmd_handler(sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key): + def custom_cmd_handler(self, data): self.master.networking.dprint("net.order.custom_cmd_handler") + sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key = data if (msg_subkey := "Reboot") and subtype == msg_subcodes[msg_key][msg_subkey]: # Reboot - self.master.iprint( - f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") + self.master.iprint(f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") if __check_authorisation(sender_mac, payload): __send_confirmation("Confirm", sender_mac, f"{msg_subkey} ({subtype})", payload) machine.reset() else: __send_confirmation("Fail", sender_mac, f"{msg_subkey} ({subtype})", payload, "Not authorised") + elif (msg_subkey := "Send-Configure") and subtype == msg_subcodes[msg_key][msg_subkey]: # Send-Configure + self.master.iprint(f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") + if __check_authorisation(sender_mac, payload): + send_configuration = payload[0] + #setup the function to send the sensor data to the specified mac(s) + elif (msg_subkey := "Receive-Configure") and subtype == msg_subcodes[msg_key][msg_subkey]: # Receive-Configure + self.master.iprint(f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") + if __check_authorisation(sender_mac, payload): + receive_configuration = payload[0] + # setup the function to calculate output based on the received sensor data (and own sensor data?) elif (msg_subkey := "Firmware-Update") and subtype == msg_subcodes[msg_key][msg_subkey]: # Firmware-Update - self.master.iprint( - f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") + self.master.iprint(f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") if __check_authorisation(sender_mac, payload): try: # Insert update logic here @@ -193,8 +240,7 @@ def custom_cmd_handler(sender_mac, subtype, send_timestamp, receive_timestamp, p else: __send_confirmation("Fail", sender_mac, f"{msg_subkey} ({subtype})", payload, "Not authorised") elif (msg_subkey := "File-Update") and subtype == msg_subcodes[msg_key][msg_subkey]: # File-Update - self.master.iprint( - f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") + self.master.iprint(f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") if __check_authorisation(sender_mac, payload): try: # Insert update logic here @@ -206,8 +252,7 @@ def custom_cmd_handler(sender_mac, subtype, send_timestamp, receive_timestamp, p else: __send_confirmation("Fail", sender_mac, f"{msg_subkey} ({subtype})", payload, "Not authorised") elif (msg_subkey := "File-Download") and subtype == msg_subcodes[msg_key][msg_subkey]: # File-Download - self.master.iprint( - f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") + self.master.iprint(f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") # should return a list with a link and the list of files to download if __check_authorisation(sender_mac, payload): try: @@ -226,8 +271,7 @@ def custom_cmd_handler(sender_mac, subtype, send_timestamp, receive_timestamp, p else: __send_confirmation("Fail", sender_mac, f"{msg_subkey} ({subtype})", payload, "Not authorised") elif (msg_subkey := "Web-Repl") and subtype == msg_subcodes[msg_key][msg_subkey]: # Web-Repl - self.master.iprint( - f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") + self.master.iprint(f"{msg_subkey} ({subtype}) command received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)})") # should be a list with name and password if __check_authorisation(sender_mac, payload): try: @@ -273,8 +317,8 @@ def custom_cmd_handler(sender_mac, subtype, send_timestamp, receive_timestamp, p self.master.iprint( f"Received add admin macs to _whitelist command, added {payload[0]} and {payload[1]}") try: - self._whitelist.append(payload[0]) - self._whitelist.append(payload[1]) + self._whitelist.append(ubinascii.unhexlify(payload[0].replace(':', ''))) + self._whitelist.append(ubinascii.unhexlify(payload[1].replace(':', ''))) __send_confirmation("Success", sender_mac, f"{msg_subkey} ({subtype})", payload) except Exception as e: __send_confirmation("Fail", sender_mac, f"{msg_subkey} ({subtype})", payload, e) @@ -498,16 +542,19 @@ def ___list_all_files(path): self.master.iprint( f"Unknown command subtype from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)}): {subtype}") - def custom_inf_handler(sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key): + def custom_inf_handler(self, data): self.master.networking.dprint("net.order.custom_inf_handler") + sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key = data if (msg_subkey := "Directory") and subtype == msg_subcodes[msg_key][msg_subkey]: # File Directory self.master.iprint(f"{msg_subkey} ({subtype}) data received from {sender_mac} ({self.master.networking.aen.peer_name(sender_mac)}): {payload}") # __send_confirmation("Confirm", sender_mac, f"{msg_subkey} ({subtype})", payload) #confirm message recv - - def custom_ack_handler(sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key): + def custom_ack_handler(self, data): self.master.networking.dprint("net.order.custom_ack_handler") - + sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key = data + # data contains [sender_mac, subtype, send_timestamp, receive_timestamp, payload, msg_key] + + self.master.networking.aen.cmd(custom_cmd_handler) self.master.networking.aen.inf(custom_inf_handler) - self.master.networking.aen.ack(custom_ack_handler) \ No newline at end of file + self.master.networking.aen.ack(custom_ack_handler)