From 52688772f9a8d3d39dab8c0ac992ef8d7f597c33 Mon Sep 17 00:00:00 2001 From: Nick Art Date: Wed, 11 Dec 2024 19:05:17 -0500 Subject: [PATCH 1/6] Trying to fix networking.... Haven't found all the bugs yet. --- software/main/boot.py | 37 ++-- software/main/main.py | 28 ++-- software/networking/networking.py | 54 +++--- software/networking/networking_test.py | 223 +++++++++++++++++++++++++ software/networking/ssp_networking.py | 31 +++- 5 files changed, 321 insertions(+), 52 deletions(-) create mode 100644 software/networking/networking_test.py diff --git a/software/main/boot.py b/software/main/boot.py index 4b4d73d..6569c01 100644 --- a/software/main/boot.py +++ b/software/main/boot.py @@ -3,13 +3,14 @@ from config import config import gc + gc.collect() import network print("Running boot.py") -#just to be safe +# just to be safe sta = network.WLAN(network.STA_IF) ap = network.WLAN(network.AP_IF) sta.active(True) @@ -19,19 +20,20 @@ from ssp_networking import SSP_Networking -#Network -infmsg = False -dbgmsg = False +# Network +infmsg = True +dbgmsg = True 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( @@ -39,39 +41,43 @@ networking.config["name"], networking.config["id"], networking.config["configuration"], - networking.sta.mac(), - networking.ap.mac(), + networking.config["ap_mac"], + networking.config["sta_mac"], networking.config["version"] )) if configuration == "AM1": lastPressed = 0 - message="Boop!" + message = "Boop!" def boop(pin): global lastPressed - if(time.ticks_ms()-lastPressed>1000): + 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) + networking.commands.ping(peer_mac) + networking.commands.echo(peer_mac, message) + networking.commands.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 + 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 deinit(): networking.cleanup() try: @@ -79,3 +85,4 @@ def deinit(): except Exception as e: print(e) machine.reset() + diff --git a/software/main/main.py b/software/main/main.py index 8168039..a2865ab 100644 --- a/software/main/main.py +++ b/software/main/main.py @@ -3,13 +3,14 @@ from config import config import gc + gc.collect() import network -print("Running pyscript main") +print("Running main.py") -#just to be safe +# just to be safe sta = network.WLAN(network.STA_IF) ap = network.WLAN(network.AP_IF) sta.active(True) @@ -19,19 +20,20 @@ from ssp_networking import SSP_Networking -#Network +# 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( @@ -39,8 +41,8 @@ networking.config["name"], networking.config["id"], networking.config["configuration"], - networking.sta.mac(), - networking.ap.mac(), + networking.config["ap_mac"], + networking.config["sta_mac"], networking.config["version"] )) @@ -48,19 +50,20 @@ def idle(): lastPressed = 0 - message="Boop!" + message = "Boop!" def boop(pin): global lastPressed - if(time.ticks_ms()-lastPressed>1000): + 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 + 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) @@ -73,6 +76,7 @@ def heartbeat(timer): timer = machine.Timer(0) timer.init(period=5000, mode=machine.Timer.PERIODIC, callback=heartbeat) + def deinit(): networking.cleanup() try: @@ -81,6 +85,7 @@ def deinit(): print(e) machine.reset() + def run_config_module(module_name): try: with open(module_name + ".py") as f: @@ -89,6 +94,7 @@ def run_config_module(module_name): except Exception as e: print(f"Error running {module_name}: {e}") + # cases for different configurations if configuration == "AM1": print("idle") diff --git a/software/networking/networking.py b/software/networking/networking.py index 6367a4f..226f559 100644 --- a/software/networking/networking.py +++ b/software/networking/networking.py @@ -201,10 +201,10 @@ def update_peer(self, peer_mac, peer_config=None, channel=None, ifidx=None): 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 @@ -214,9 +214,15 @@ def add_peer(self, peer_mac, peer_config=None, channel=None, ifidx=None): self.master.dprint("aen.add_peer") 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, 'timestamp': None}) + 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 +240,19 @@ def remove_peer(self, peer_mac): def peers(self): self.master.dprint("aen.peers") + rssi_table = self._aen.peers_table + for key in rssi_table: + 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 @@ -271,7 +284,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) @@ -360,29 +373,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}") diff --git a/software/networking/networking_test.py b/software/networking/networking_test.py new file mode 100644 index 0000000..83eeaa3 --- /dev/null +++ b/software/networking/networking_test.py @@ -0,0 +1,223 @@ +gc.collect() +print(gc.mem_free()) + +import time +from machine import Pin +from networking import Networking +import network + +from config import config + +import urandom +import os + +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 +configuration = config["configuration"] +if configuration == "AM1": + infmsg = True + +#Network +networking = SSP_Networking(infmsg, dbgmsg, errmsg) +peer_mac = b'\xff\xff\xff\xff\xff\xff' + + +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.networking.sta.mac(), + networking.networking.ap.mac(), + networking.config["version"] +)) + +message_str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +print(f"String: {message_str}") +message_int = int(''.join(str(urandom.getrandbits(4)) for _ in range(300))) +print(f"Int: {message_int}") +message_float = float(str(message_int) + ".0123456789") +print(f"Float: {message_float}") +message_dict = {f"key_{i}": urandom.getrandbits(16) for i in range(50)} +print(f"Dict: {message_dict}") +message_list = [urandom.getrandbits(16) for _ in range(75)] +print(f"List: {message_list}") +message_bytes = os.urandom(1000) +print(f"Bytes: {message_bytes}") +message_bytearray = bytearray(os.urandom(1000)) +print(f"Bytearray: {message_bytearray}") + +lastPressed = 0 +start_time = time.ticks_ms() + +message = "Boop!" + + +test = True +waiting = False + +if test: + + def receive(): + global waiting + for mac, message, rtime in messages: + print(f"\033[34mMessage received: {mac, message, rtime}\033[0m") + waiting = False + + networking.irq(receive) + + try: + networking.networking.aen.add_peer(peer_mac) + print("\033[32mTest add_peer passed\033[0m") + except Exception as e: + print(f"\033[31mTest add_peer failed: {e}\033[0m") + try: + networking.networking.aen.update_peer(peer_mac) + print("\033[32mTest update_peer passed\033[0m") + except Exception as e: + print(f"\033[31mTest update_peer failed: {e}\033[0m") + try: + networking.networking.aen.remove_peer(peer_mac) + print("\033[32mTest remove_peer passed\033[0m") + except Exception as e: + print(f"\033[31mTest remove_peer failed: {e}\033[0m") + + try: + print(networking.peers()) + print("\033[32mTest peers passed\033[0m") + except Exception as e: + print(f"\033[31mTest peersfailed: {e}\033[0m") + try: + print(networking.rssi()) + print("\033[32mTest rssi passed\033[0m") + except Exception as e: + print(f"\033[31mTest rssifailed: {e}\033[0m") + + try: + networking.commands.ping(peer_mac) + print("\033[34mWaiting for pong\033[0m") + time.sleep(0.02) + print("\033[32mTest ping passed\033[0m") + except Exception as e: + print(f"\033[31mTest ping failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message) + print("\033[34mWaiting for echo\033[0m") + time.sleep(0.02) + print("\033[32mTest echo passed\033[0m") + except Exception as e: + print(f"\033[31mTest echo failed: {e}\033[0m") +# try: +# networking.aen.broadcast(message) +# print("\033[32mTest broadcast passed\033[0m") +# except Exception as e: +# print(f"\033[31mTest broadcast failed: {e}\033[0m") + + try: + networking.commands.echo(peer_mac, message_str) + print("\033[34mWaiting for echo\033[0m") + time.sleep(2) + + print("\033[32mTest long string passed\033[0m") + except Exception as e: + print(f"\033[31mTest long string failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_int) + print("\033[34mWaiting for echo\033[0m") + time.sleep(2) + print("\033[32mTest long int passed\033[0m") + except Exception as e: + print(f"\033[31mTest long int failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_float) + print("\033[34mWaiting for echo\033[0m") + time.sleep(2) + print("\033[32mTest long float passed\033[0m") + except Exception as e: + print(f"\033[31mTest long float failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_dict) + print("\033[34mWaiting for echo\033[0m") + time.sleep(2) + print("\033[32mTest long dict passed\033[0m") + except Exception as e: + print(f"\033[31mTest long dict failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_list) + print("\033[34mWaiting for echo\033[0m") + time.sleep(2) + print("\033[32mTest long list passed\033[0m") + except Exception as e: + print(f"\033[31mTest long list failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_bytes) + print("\033[34mWaiting for echo\033[0m") + time.sleep(3) + print("\033[32mTest long bytes passed\033[0m") + except Exception as e: + print(f"\033[31mTest long bytes failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_bytearray) + print("\033[34mWaiting for echo\033[0m") + time.sleep(3) + print("\033[32mTest long bytearray passed\033[0m") + except Exception as e: + print(f"\033[31mTest long bytearray failed: {e}\033[0m") + + try: + print(networking.check_messages()) + print("\033[32mTest check_messages passed\033[0m") + except Exception as e: + print(f"\033[31mTest check_messages failed: {e}\033[0m") + try: + print(networking.return_message()) + print("\033[32mTest return_message passed\033[0m") + except Exception as e: + print(f"\033[31mTest return_message failed: {e}\033[0m") + try: + print(networking.return_messages()) + print("\033[32mTest return_messages passed\033[0m") + except Exception as e: + print(f"\033[31mTest return_messages failed: {e}\033[0m") + + networking.irq(None) + + +def boop(pin): + global lastPressed + if(time.ticks_ms()-lastPressed>1000): + lastPressed = time.ticks_ms() + networking.commands.send(peer_mac, message) +# print(f"Sent {random_bytes} to {peer_mac}") + +switch_select = Pin(9, Pin.IN, Pin.PULL_UP) + +#Buttons +switch_select = Pin(9, Pin.IN, Pin.PULL_UP) +switch_select.irq(trigger=Pin.IRQ_FALLING, handler=boop) + +print(networking.rssi()) + +while True: + print(f"{int(time.ticks_ms()-start_time)/1000}: {gc.mem_free()}") + #networking.commands.ping(peer_mac) + #print(f"Sent ping to {peer_mac}") + time.sleep(0.1) + if networking.check_messages(): + print("Received the following messages:") + n = 1 + for mac, message, rtime in networking.return_messages(): + print(f"{n}. At: {rtime} From: {mac} Length: {len(message)} Message: {message}") + n += 1 + gc.collect() diff --git a/software/networking/ssp_networking.py b/software/networking/ssp_networking.py index 58d34e3..6db9a78 100644 --- a/software/networking/ssp_networking.py +++ b/software/networking/ssp_networking.py @@ -15,11 +15,36 @@ 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() + config["sta_mac"] = self.networking.sta.mac() self.networking.config = config + self.config = self.networking.config self.version = version self.commands = self.Commands(self) self.orders = self.Orders(self) - + self.inittime = self.networking.inittime + + def rssi(self): + return self.networking.aen.rssi() + + def peers(self): + return self.networking.aen.peers() + + 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() + class Commands: def __init__(self, master): self.master = master @@ -48,7 +73,7 @@ def echo(self, mac, message, channel=None, ifidx=None): self.master.networking.aen.echo(mac, message, channel, ifidx) def boop(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("aen.boop") + self.master.networking.dprint("net.cmd.boop") self.master.networking.aen.boop(mac, channel, ifidx, sudo) def send(self, mac, message, channel=None, ifidx=None): @@ -510,4 +535,4 @@ def custom_ack_handler(sender_mac, subtype, send_timestamp, receive_timestamp, p 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) From c2b30b84b92ab44269c502c2a84d8d08e61d7330 Mon Sep 17 00:00:00 2001 From: Nick Art Date: Mon, 16 Dec 2024 13:16:41 -0500 Subject: [PATCH 2/6] I did it? I fixed networking --- software/.DS_Store | Bin 12292 -> 12292 bytes software/archive/networkingtest.py | 28 +-- software/main/boot.py | 6 +- software/main/main.py | 20 +- software/networking/networking.py | 163 +++++++------ software/networking/networking_test.py | 104 +++----- software/networking/ssp_networking.py | 271 +++++++++++---------- software/networking/ssp_networking_test.py | 223 +++++++++++++++++ 8 files changed, 506 insertions(+), 309 deletions(-) create mode 100644 software/networking/ssp_networking_test.py diff --git a/software/.DS_Store b/software/.DS_Store index 3b6d6820e63e4eec46d4c50fdbe20c8aca8ec933..475298ea9191f8bd6315d7d368b42702e00d6d81 100644 GIT binary patch delta 125 zcmZokXi1phRCV7EM@;AS3$NlY9jrlvXyhK7cdUn delta 74 zcmZokXi1phdGV7EM@z-AtWNlY9@#%4x33MQtL3q@rne-KvL{7k8uX|gbj@a9RX TvW%N2iWM_%X3>acMHK=7TE!Mk diff --git a/software/archive/networkingtest.py b/software/archive/networkingtest.py index e3f9a75..7cb0452 100644 --- a/software/archive/networkingtest.py +++ b/software/archive/networkingtest.py @@ -9,7 +9,7 @@ import os #Network -networking = Networking() +networking = Networking(True, True, True) peer_mac = b'\xff\xff\xff\xff\xff\xff' message_str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." @@ -33,7 +33,7 @@ message = "Boop!" -test = True +test = False waiting = False if test: @@ -177,15 +177,15 @@ def boop(pin): print(networking.aen.rssi()) -while True: - print(f"{int(time.ticks_ms()-start_time)/1000}: {gc.mem_free()}") - #networking.aen.ping(peer_mac) - #print(f"Sent ping to {peer_mac}") - time.sleep(0.1) - if networking.aen.check_messages(): - print("Received the following messages:") - n = 1 - for mac, message, rtime in networking.aen.return_messages(): - print(f"{n}. At: {rtime} From: {mac} Length: {len(message)} Message: {message}") - n += 1 - gc.collect() +# while True: +# print(f"{int(time.ticks_ms()-start_time)/1000}: {gc.mem_free()}") +# #networking.aen.ping(peer_mac) +# #print(f"Sent ping to {peer_mac}") +# time.sleep(0.1) +# if networking.aen.check_messages(): +# print("Received the following messages:") +# n = 1 +# for mac, message, rtime in networking.aen.return_messages(): +# print(f"{n}. At: {rtime} From: {mac} Length: {len(message)} Message: {message}") +# n += 1 +# gc.collect() diff --git a/software/main/boot.py b/software/main/boot.py index 6569c01..4f6b5d7 100644 --- a/software/main/boot.py +++ b/software/main/boot.py @@ -55,9 +55,9 @@ def boop(pin): global lastPressed if (time.ticks_ms() - lastPressed > 1000): lastPressed = time.ticks_ms() - networking.commands.ping(peer_mac) - networking.commands.echo(peer_mac, message) - networking.commands.send(peer_mac, message) + 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()}") diff --git a/software/main/main.py b/software/main/main.py index a2865ab..f067d0f 100644 --- a/software/main/main.py +++ b/software/main/main.py @@ -8,7 +8,7 @@ import network -print("Running main.py") +print("Running boot.py") # just to be safe sta = network.WLAN(network.STA_IF) @@ -21,7 +21,7 @@ from ssp_networking import SSP_Networking # Network -infmsg = False +infmsg = True dbgmsg = False errmsg = True configuration = config["configuration"] @@ -47,8 +47,10 @@ )) + +lastPressed = 0 + def idle(): - lastPressed = 0 message = "Boop!" @@ -56,9 +58,9 @@ 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) + 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()}") @@ -67,12 +69,14 @@ def boop(pin): 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) @@ -85,7 +89,6 @@ def deinit(): print(e) machine.reset() - def run_config_module(module_name): try: with open(module_name + ".py") as f: @@ -94,12 +97,11 @@ def run_config_module(module_name): except Exception as e: print(f"Error running {module_name}: {e}") - # cases for different configurations if configuration == "AM1": print("idle") idle() -elif configuration == "SM3": +elif configuration == "S M3": print("sm3") run_config_module("sm3") elif configuration == "SL1": diff --git a/software/networking/networking.py b/software/networking/networking.py index 226f559..938161e 100644 --- a/software/networking/networking.py +++ b/software/networking/networking.py @@ -196,6 +196,8 @@ 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: @@ -212,6 +214,8 @@ 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] = {} @@ -241,7 +245,7 @@ def remove_peer(self, peer_mac): def peers(self): self.master.dprint("aen.peers") rssi_table = self._aen.peers_table - for key in rssi_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 @@ -292,6 +296,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: @@ -334,8 +339,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: @@ -420,30 +425,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() @@ -484,31 +488,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") @@ -517,13 +500,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: @@ -532,6 +515,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...") @@ -554,8 +539,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 @@ -565,9 +550,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") @@ -583,7 +568,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!") @@ -591,21 +576,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')) + 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": @@ -613,9 +615,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]) @@ -631,28 +632,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)) @@ -661,15 +661,14 @@ 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]}") @@ -690,10 +689,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 @@ -701,9 +701,10 @@ 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/networking/networking_test.py b/software/networking/networking_test.py index 83eeaa3..7cb0452 100644 --- a/software/networking/networking_test.py +++ b/software/networking/networking_test.py @@ -4,45 +4,14 @@ import time from machine import Pin from networking import Networking -import network - -from config import config import urandom import os -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 -configuration = config["configuration"] -if configuration == "AM1": - infmsg = True - #Network -networking = SSP_Networking(infmsg, dbgmsg, errmsg) +networking = Networking(True, True, True) peer_mac = b'\xff\xff\xff\xff\xff\xff' - -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.networking.sta.mac(), - networking.networking.ap.mac(), - networking.config["version"] -)) - message_str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." print(f"String: {message_str}") message_int = int(''.join(str(urandom.getrandbits(4)) for _ in range(300))) @@ -64,7 +33,7 @@ message = "Boop!" -test = True +test = False waiting = False if test: @@ -75,44 +44,44 @@ def receive(): print(f"\033[34mMessage received: {mac, message, rtime}\033[0m") waiting = False - networking.irq(receive) + networking.aen.irq(receive) try: - networking.networking.aen.add_peer(peer_mac) + networking.aen.add_peer(peer_mac) print("\033[32mTest add_peer passed\033[0m") except Exception as e: print(f"\033[31mTest add_peer failed: {e}\033[0m") try: - networking.networking.aen.update_peer(peer_mac) + networking.aen.update_peer(peer_mac) print("\033[32mTest update_peer passed\033[0m") except Exception as e: print(f"\033[31mTest update_peer failed: {e}\033[0m") try: - networking.networking.aen.remove_peer(peer_mac) + networking.aen.remove_peer(peer_mac) print("\033[32mTest remove_peer passed\033[0m") except Exception as e: print(f"\033[31mTest remove_peer failed: {e}\033[0m") try: - print(networking.peers()) + print(networking.aen.peers()) print("\033[32mTest peers passed\033[0m") except Exception as e: print(f"\033[31mTest peersfailed: {e}\033[0m") try: - print(networking.rssi()) + print(networking.aen.rssi()) print("\033[32mTest rssi passed\033[0m") except Exception as e: print(f"\033[31mTest rssifailed: {e}\033[0m") try: - networking.commands.ping(peer_mac) + networking.aen.ping(peer_mac) print("\033[34mWaiting for pong\033[0m") time.sleep(0.02) print("\033[32mTest ping passed\033[0m") except Exception as e: print(f"\033[31mTest ping failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message) + networking.aen.echo(peer_mac, message) print("\033[34mWaiting for echo\033[0m") time.sleep(0.02) print("\033[32mTest echo passed\033[0m") @@ -125,50 +94,49 @@ def receive(): # print(f"\033[31mTest broadcast failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_str) + networking.aen.echo(peer_mac, message_str) print("\033[34mWaiting for echo\033[0m") time.sleep(2) - print("\033[32mTest long string passed\033[0m") except Exception as e: print(f"\033[31mTest long string failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_int) + networking.aen.echo(peer_mac, message_int) print("\033[34mWaiting for echo\033[0m") time.sleep(2) print("\033[32mTest long int passed\033[0m") except Exception as e: print(f"\033[31mTest long int failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_float) + networking.aen.echo(peer_mac, message_float) print("\033[34mWaiting for echo\033[0m") time.sleep(2) print("\033[32mTest long float passed\033[0m") except Exception as e: print(f"\033[31mTest long float failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_dict) + networking.aen.echo(peer_mac, message_dict) print("\033[34mWaiting for echo\033[0m") time.sleep(2) print("\033[32mTest long dict passed\033[0m") except Exception as e: print(f"\033[31mTest long dict failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_list) + networking.aen.echo(peer_mac, message_list) print("\033[34mWaiting for echo\033[0m") time.sleep(2) print("\033[32mTest long list passed\033[0m") except Exception as e: print(f"\033[31mTest long list failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_bytes) + networking.aen.echo(peer_mac, message_bytes) print("\033[34mWaiting for echo\033[0m") time.sleep(3) print("\033[32mTest long bytes passed\033[0m") except Exception as e: print(f"\033[31mTest long bytes failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_bytearray) + networking.aen.echo(peer_mac, message_bytearray) print("\033[34mWaiting for echo\033[0m") time.sleep(3) print("\033[32mTest long bytearray passed\033[0m") @@ -176,29 +144,29 @@ def receive(): print(f"\033[31mTest long bytearray failed: {e}\033[0m") try: - print(networking.check_messages()) + print(networking.aen.check_messages()) print("\033[32mTest check_messages passed\033[0m") except Exception as e: print(f"\033[31mTest check_messages failed: {e}\033[0m") try: - print(networking.return_message()) + print(networking.aen.return_message()) print("\033[32mTest return_message passed\033[0m") except Exception as e: print(f"\033[31mTest return_message failed: {e}\033[0m") try: - print(networking.return_messages()) + print(networking.aen.return_messages()) print("\033[32mTest return_messages passed\033[0m") except Exception as e: print(f"\033[31mTest return_messages failed: {e}\033[0m") - networking.irq(None) + networking.aen.irq(None) def boop(pin): global lastPressed if(time.ticks_ms()-lastPressed>1000): lastPressed = time.ticks_ms() - networking.commands.send(peer_mac, message) + networking.aen.send(peer_mac, message) # print(f"Sent {random_bytes} to {peer_mac}") switch_select = Pin(9, Pin.IN, Pin.PULL_UP) @@ -207,17 +175,17 @@ def boop(pin): switch_select = Pin(9, Pin.IN, Pin.PULL_UP) switch_select.irq(trigger=Pin.IRQ_FALLING, handler=boop) -print(networking.rssi()) - -while True: - print(f"{int(time.ticks_ms()-start_time)/1000}: {gc.mem_free()}") - #networking.commands.ping(peer_mac) - #print(f"Sent ping to {peer_mac}") - time.sleep(0.1) - if networking.check_messages(): - print("Received the following messages:") - n = 1 - for mac, message, rtime in networking.return_messages(): - print(f"{n}. At: {rtime} From: {mac} Length: {len(message)} Message: {message}") - n += 1 - gc.collect() +print(networking.aen.rssi()) + +# while True: +# print(f"{int(time.ticks_ms()-start_time)/1000}: {gc.mem_free()}") +# #networking.aen.ping(peer_mac) +# #print(f"Sent ping to {peer_mac}") +# time.sleep(0.1) +# if networking.aen.check_messages(): +# print("Received the following messages:") +# n = 1 +# for mac, message, rtime in networking.aen.return_messages(): +# print(f"{n}. At: {rtime} From: {mac} Length: {len(message)} Message: {message}") +# n += 1 +# gc.collect() diff --git a/software/networking/ssp_networking.py b/software/networking/ssp_networking.py index 6db9a78..c318f8b 100644 --- a/software/networking/ssp_networking.py +++ b/software/networking/ssp_networking.py @@ -15,12 +15,11 @@ 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() - config["sta_mac"] = self.networking.sta.mac() + 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) self.inittime = self.networking.inittime @@ -30,6 +29,10 @@ def rssi(self): def peers(self): return self.networking.aen.peers() + def wpeers(self): + networking_peer_info = f"networking_peers_info_start{self.networking.aen.peers()}networking_peers_info_end" + print(networking_peer_info) + def irq(self, func): self.networking.aen.irq(func) @@ -45,131 +48,127 @@ def return_messages(self): def cleanup(self): self.networking.cleanup() - 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.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]: + self.networking.iprint(f"Sending {msg_subkey} ({bytes([msg_subcodes[msg_key][msg_subkey]])}) command to {mac} ({self.master.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.master.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, sudo) + + def send(self, mac, message, channel=None, ifidx=None): + self.networking.dprint("net.cmd.message") + self.networking.aen.send(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 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 reboot(self, mac, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.reboot") + self.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.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.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.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.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.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.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.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.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.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.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.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.networking.aen.send_command("Directory-Get", mac, None, channel, ifidx, sudo) + + # resend cmd + + def wifi_connect(self, mac, name, password, channel=None, ifidx=None, sudo=False): + self.networking.dprint("net.cmd.wifi_connect") + self.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.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.networking.aen.send_command("AP-Enable", mac, [name, password], channel, ifidx, sudo) - 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) - 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) - - 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 boop(self, mac, channel=None, ifidx=None, sudo=False): - self.master.networking.dprint("net.cmd.boop") - self.master.networking.aen.boop(mac, channel, ifidx, sudo) - - 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 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_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 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.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.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.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.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.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.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.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.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.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.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.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.master.networking.dprint("net.cmd.directory_get") - self.master.networking.aen.send_command("Directory-Get", mac, None, channel, ifidx, sudo) - - # resend cmd - - 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.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.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.networking.aen.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.networking.aen.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.networking.aen.send_command("Resume", mac, None, channel, ifidx, sudo) class Orders: @@ -187,15 +186,16 @@ 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)})") @@ -298,8 +298,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) @@ -523,16 +523,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) diff --git a/software/networking/ssp_networking_test.py b/software/networking/ssp_networking_test.py new file mode 100644 index 0000000..83eeaa3 --- /dev/null +++ b/software/networking/ssp_networking_test.py @@ -0,0 +1,223 @@ +gc.collect() +print(gc.mem_free()) + +import time +from machine import Pin +from networking import Networking +import network + +from config import config + +import urandom +import os + +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 +configuration = config["configuration"] +if configuration == "AM1": + infmsg = True + +#Network +networking = SSP_Networking(infmsg, dbgmsg, errmsg) +peer_mac = b'\xff\xff\xff\xff\xff\xff' + + +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.networking.sta.mac(), + networking.networking.ap.mac(), + networking.config["version"] +)) + +message_str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +print(f"String: {message_str}") +message_int = int(''.join(str(urandom.getrandbits(4)) for _ in range(300))) +print(f"Int: {message_int}") +message_float = float(str(message_int) + ".0123456789") +print(f"Float: {message_float}") +message_dict = {f"key_{i}": urandom.getrandbits(16) for i in range(50)} +print(f"Dict: {message_dict}") +message_list = [urandom.getrandbits(16) for _ in range(75)] +print(f"List: {message_list}") +message_bytes = os.urandom(1000) +print(f"Bytes: {message_bytes}") +message_bytearray = bytearray(os.urandom(1000)) +print(f"Bytearray: {message_bytearray}") + +lastPressed = 0 +start_time = time.ticks_ms() + +message = "Boop!" + + +test = True +waiting = False + +if test: + + def receive(): + global waiting + for mac, message, rtime in messages: + print(f"\033[34mMessage received: {mac, message, rtime}\033[0m") + waiting = False + + networking.irq(receive) + + try: + networking.networking.aen.add_peer(peer_mac) + print("\033[32mTest add_peer passed\033[0m") + except Exception as e: + print(f"\033[31mTest add_peer failed: {e}\033[0m") + try: + networking.networking.aen.update_peer(peer_mac) + print("\033[32mTest update_peer passed\033[0m") + except Exception as e: + print(f"\033[31mTest update_peer failed: {e}\033[0m") + try: + networking.networking.aen.remove_peer(peer_mac) + print("\033[32mTest remove_peer passed\033[0m") + except Exception as e: + print(f"\033[31mTest remove_peer failed: {e}\033[0m") + + try: + print(networking.peers()) + print("\033[32mTest peers passed\033[0m") + except Exception as e: + print(f"\033[31mTest peersfailed: {e}\033[0m") + try: + print(networking.rssi()) + print("\033[32mTest rssi passed\033[0m") + except Exception as e: + print(f"\033[31mTest rssifailed: {e}\033[0m") + + try: + networking.commands.ping(peer_mac) + print("\033[34mWaiting for pong\033[0m") + time.sleep(0.02) + print("\033[32mTest ping passed\033[0m") + except Exception as e: + print(f"\033[31mTest ping failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message) + print("\033[34mWaiting for echo\033[0m") + time.sleep(0.02) + print("\033[32mTest echo passed\033[0m") + except Exception as e: + print(f"\033[31mTest echo failed: {e}\033[0m") +# try: +# networking.aen.broadcast(message) +# print("\033[32mTest broadcast passed\033[0m") +# except Exception as e: +# print(f"\033[31mTest broadcast failed: {e}\033[0m") + + try: + networking.commands.echo(peer_mac, message_str) + print("\033[34mWaiting for echo\033[0m") + time.sleep(2) + + print("\033[32mTest long string passed\033[0m") + except Exception as e: + print(f"\033[31mTest long string failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_int) + print("\033[34mWaiting for echo\033[0m") + time.sleep(2) + print("\033[32mTest long int passed\033[0m") + except Exception as e: + print(f"\033[31mTest long int failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_float) + print("\033[34mWaiting for echo\033[0m") + time.sleep(2) + print("\033[32mTest long float passed\033[0m") + except Exception as e: + print(f"\033[31mTest long float failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_dict) + print("\033[34mWaiting for echo\033[0m") + time.sleep(2) + print("\033[32mTest long dict passed\033[0m") + except Exception as e: + print(f"\033[31mTest long dict failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_list) + print("\033[34mWaiting for echo\033[0m") + time.sleep(2) + print("\033[32mTest long list passed\033[0m") + except Exception as e: + print(f"\033[31mTest long list failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_bytes) + print("\033[34mWaiting for echo\033[0m") + time.sleep(3) + print("\033[32mTest long bytes passed\033[0m") + except Exception as e: + print(f"\033[31mTest long bytes failed: {e}\033[0m") + try: + networking.commands.echo(peer_mac, message_bytearray) + print("\033[34mWaiting for echo\033[0m") + time.sleep(3) + print("\033[32mTest long bytearray passed\033[0m") + except Exception as e: + print(f"\033[31mTest long bytearray failed: {e}\033[0m") + + try: + print(networking.check_messages()) + print("\033[32mTest check_messages passed\033[0m") + except Exception as e: + print(f"\033[31mTest check_messages failed: {e}\033[0m") + try: + print(networking.return_message()) + print("\033[32mTest return_message passed\033[0m") + except Exception as e: + print(f"\033[31mTest return_message failed: {e}\033[0m") + try: + print(networking.return_messages()) + print("\033[32mTest return_messages passed\033[0m") + except Exception as e: + print(f"\033[31mTest return_messages failed: {e}\033[0m") + + networking.irq(None) + + +def boop(pin): + global lastPressed + if(time.ticks_ms()-lastPressed>1000): + lastPressed = time.ticks_ms() + networking.commands.send(peer_mac, message) +# print(f"Sent {random_bytes} to {peer_mac}") + +switch_select = Pin(9, Pin.IN, Pin.PULL_UP) + +#Buttons +switch_select = Pin(9, Pin.IN, Pin.PULL_UP) +switch_select.irq(trigger=Pin.IRQ_FALLING, handler=boop) + +print(networking.rssi()) + +while True: + print(f"{int(time.ticks_ms()-start_time)/1000}: {gc.mem_free()}") + #networking.commands.ping(peer_mac) + #print(f"Sent ping to {peer_mac}") + time.sleep(0.1) + if networking.check_messages(): + print("Received the following messages:") + n = 1 + for mac, message, rtime in networking.return_messages(): + print(f"{n}. At: {rtime} From: {mac} Length: {len(message)} Message: {message}") + n += 1 + gc.collect() From 97e235bfd62be64db322bb08ba73a9c4cdb4c3ed Mon Sep 17 00:00:00 2001 From: Nick Art Date: Tue, 17 Dec 2024 22:40:03 -0500 Subject: [PATCH 3/6] Small updates to networking --- software/networking/networking.py | 9 +++++---- software/networking/ssp_networking.py | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/software/networking/networking.py b/software/networking/networking.py index 938161e..16f4961 100644 --- a/software/networking/networking.py +++ b/software/networking/networking.py @@ -225,7 +225,7 @@ def add_peer(self, peer_mac, peer_config=None, channel=None, ifidx=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, 'timestamp': None}) + self._peers[peer_mac].update({'rssi': None, 'timestamp': None}) 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}") @@ -246,7 +246,7 @@ 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({'rssi': rssi_table[key][0]}) self._peers[key].update({'time': rssi_table[key][1]-self.master.inittime}) return self._peers @@ -591,7 +591,7 @@ def __process_message(self, sender_mac, message, receive_timestamp): 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')) + 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: @@ -673,7 +673,7 @@ def __handle_ack(self, sender_mac, subtype, send_timestamp, receive_timestamp, p 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]}") @@ -708,3 +708,4 @@ def __handle_ack(self, sender_mac, subtype, send_timestamp, receive_timestamp, p # 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/networking/ssp_networking.py b/software/networking/ssp_networking.py index c318f8b..236e3b3 100644 --- a/software/networking/ssp_networking.py +++ b/software/networking/ssp_networking.py @@ -30,6 +30,7 @@ def peers(self): return self.networking.aen.peers() def wpeers(self): + self.networking.iprint(f"time.ticks_ms(): {time.ticks_ms()}") networking_peer_info = f"networking_peers_info_start{self.networking.aen.peers()}networking_peers_info_end" print(networking_peer_info) From 624145af90b237a8208d63657d179ead3c75410b Mon Sep 17 00:00:00 2001 From: Nick Art Date: Thu, 19 Dec 2024 17:52:32 -0500 Subject: [PATCH 4/6] various networking fixes --- software/networking/networking.py | 10 ++- software/networking/ssp_networking.py | 86 +++++++++++++--------- software/networking/ssp_networking_test.py | 25 +++---- software/release/config.py | 2 + 4 files changed, 74 insertions(+), 49 deletions(-) diff --git a/software/networking/networking.py b/software/networking/networking.py index 16f4961..5cb6edd 100644 --- a/software/networking/networking.py +++ b/software/networking/networking.py @@ -225,7 +225,7 @@ def add_peer(self, peer_mac, peer_config=None, channel=None, ifidx=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, 'timestamp': None}) + 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}") @@ -277,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") diff --git a/software/networking/ssp_networking.py b/software/networking/ssp_networking.py index 236e3b3..618aaa2 100644 --- a/software/networking/ssp_networking.py +++ b/software/networking/ssp_networking.py @@ -31,7 +31,9 @@ def peers(self): def wpeers(self): self.networking.iprint(f"time.ticks_ms(): {time.ticks_ms()}") - networking_peer_info = f"networking_peers_info_start{self.networking.aen.peers()}networking_peers_info_end" + 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): @@ -58,10 +60,13 @@ def send_command(self, msg_subkey, mac, payload=None, channel=None, ifidx=None, else: payload = [payload, "sudo"] if (msg_key := "cmd") and msg_subkey in msg_subcodes[msg_key]: - self.networking.iprint(f"Sending {msg_subkey} ({bytes([msg_subcodes[msg_key][msg_subkey]])}) command to {mac} ({self.master.networking.aen.peer_name(mac)})") + if isinstance(mac, list): + self.networking.iprint(f"Sending {msg_subkey} ({bytes([msg_subcodes[msg_key][msg_subkey]])}) command to {mac}") + else: + 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.master.iprint(f"Command {msg_subkey} not found") + self.networking.iprint(f"Command {msg_subkey} not found") gc.collect() def ping(self, mac, channel=None, ifidx=None): @@ -74,7 +79,7 @@ def echo(self, mac, message, channel=None, ifidx=None): def boop(self, mac, channel=None, ifidx=None, sudo=False): self.networking.dprint("net.cmd.boop") - self.networking.aen.boop(mac, channel, ifidx, sudo) + self.networking.aen.boop(mac, channel, ifidx) def send(self, mac, message, channel=None, ifidx=None): self.networking.dprint("net.cmd.message") @@ -85,91 +90,99 @@ def broadcast(self, message, channel=None, ifidx=None): mac = b'\xff\xff\xff\xff\xff\xff' self.send(mac, message, channel, ifidx) - 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 + 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 reboot(self, mac, channel=None, ifidx=None, sudo=False): self.networking.dprint("net.cmd.reboot") - self.networking.aen.send_command("Reboot", mac, None, channel, ifidx, sudo) + self.send_command("Reboot", mac, None, channel, ifidx, sudo) + + 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 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 firmware_update(self, mac, channel=None, ifidx=None, sudo=False): self.networking.dprint("net.cmd.firmware_update") - self.networking.aen.send_command("Firmware-Update", mac, None, channel, ifidx, sudo) + self.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.networking.aen.send_command("File-Update", mac, None, channel, ifidx, sudo) + self.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.networking.aen.send_command("File-Download", mac, [link, file_list], channel, ifidx, sudo) + self.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.networking.aen.send_command("Web-Repl", mac, [ap_name, password], channel, ifidx, sudo) + 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 file_run(self, mac, filename, channel=None, ifidx=None, sudo=False): self.networking.dprint("net.cmd.file_run") - self.networking.aen.send_command("File-Run", mac, filename, channel, ifidx, sudo) + self.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.networking.aen.send_command("Admin-Set", mac, new_bool, channel, ifidx, sudo) + self.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.networking.aen.send_command("Whitelist-Add", mac, mac_list, channel, ifidx, sudo) + self.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.networking.aen.send_command("Config-Change", mac, [new_config, hardcode], channel, ifidx, sudo) + self.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.networking.aen.send_command("Name-Change", mac, [new_name, hardcode], channel, ifidx, sudo) + self.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.networking.aen.send_command("Pair", mac, key, channel, ifidx) + self.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.networking.aen.send_command("Set-Pair", mac, pair_bool, channel, ifidx, sudo) + self.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.networking.aen.send_command("Directory-Get", mac, None, channel, ifidx, sudo) + self.send_command("Directory-Get", mac, None, channel, ifidx, sudo) # resend cmd def wifi_connect(self, mac, name, password, channel=None, ifidx=None, sudo=False): self.networking.dprint("net.cmd.wifi_connect") - self.networking.aen.send_command("Wifi-Connect", mac, [name, password], channel, ifidx, sudo) + self.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.networking.aen.send_command("Wifi-Disconnect", mac, None, channel, ifidx, sudo) + self.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.networking.aen.send_command("AP-Enable", mac, [name, password], channel, ifidx, sudo) + self.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.networking.aen.send_command("AP-Disable", mac, None, channel, ifidx, sudo) + self.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.networking.aen.send_command("Pause", mac, None, channel, ifidx, sudo) + self.send_command("Pause", mac, None, channel, ifidx, sudo) def resume(self, mac, channel=None, ifidx=None, sudo=False): self.networking.dprint("net.cmd.resume") - self.networking.aen.send_command("Resume", mac, None, channel, ifidx, sudo) + self.send_command("Resume", mac, None, channel, ifidx, sudo) class Orders: @@ -198,16 +211,24 @@ 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 @@ -219,8 +240,7 @@ def custom_cmd_handler(self, data): 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 @@ -232,8 +252,7 @@ def custom_cmd_handler(self, data): 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: @@ -252,8 +271,7 @@ def custom_cmd_handler(self, data): 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: diff --git a/software/networking/ssp_networking_test.py b/software/networking/ssp_networking_test.py index 83eeaa3..74265f3 100644 --- a/software/networking/ssp_networking_test.py +++ b/software/networking/ssp_networking_test.py @@ -25,8 +25,6 @@ dbgmsg = False errmsg = True configuration = config["configuration"] -if configuration == "AM1": - infmsg = True #Network networking = SSP_Networking(infmsg, dbgmsg, errmsg) @@ -105,14 +103,14 @@ def receive(): print(f"\033[31mTest rssifailed: {e}\033[0m") try: - networking.commands.ping(peer_mac) + networking.ping(peer_mac) print("\033[34mWaiting for pong\033[0m") time.sleep(0.02) print("\033[32mTest ping passed\033[0m") except Exception as e: print(f"\033[31mTest ping failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message) + networking.echo(peer_mac, message) print("\033[34mWaiting for echo\033[0m") time.sleep(0.02) print("\033[32mTest echo passed\033[0m") @@ -125,50 +123,49 @@ def receive(): # print(f"\033[31mTest broadcast failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_str) + networking.echo(peer_mac, message_str) print("\033[34mWaiting for echo\033[0m") time.sleep(2) - print("\033[32mTest long string passed\033[0m") except Exception as e: print(f"\033[31mTest long string failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_int) + networking.echo(peer_mac, message_int) print("\033[34mWaiting for echo\033[0m") time.sleep(2) print("\033[32mTest long int passed\033[0m") except Exception as e: print(f"\033[31mTest long int failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_float) + networking.echo(peer_mac, message_float) print("\033[34mWaiting for echo\033[0m") time.sleep(2) print("\033[32mTest long float passed\033[0m") except Exception as e: print(f"\033[31mTest long float failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_dict) + networking.echo(peer_mac, message_dict) print("\033[34mWaiting for echo\033[0m") time.sleep(2) print("\033[32mTest long dict passed\033[0m") except Exception as e: print(f"\033[31mTest long dict failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_list) + networking.echo(peer_mac, message_list) print("\033[34mWaiting for echo\033[0m") time.sleep(2) print("\033[32mTest long list passed\033[0m") except Exception as e: print(f"\033[31mTest long list failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_bytes) + networking.echo(peer_mac, message_bytes) print("\033[34mWaiting for echo\033[0m") time.sleep(3) print("\033[32mTest long bytes passed\033[0m") except Exception as e: print(f"\033[31mTest long bytes failed: {e}\033[0m") try: - networking.commands.echo(peer_mac, message_bytearray) + networking.echo(peer_mac, message_bytearray) print("\033[34mWaiting for echo\033[0m") time.sleep(3) print("\033[32mTest long bytearray passed\033[0m") @@ -198,7 +195,7 @@ def boop(pin): global lastPressed if(time.ticks_ms()-lastPressed>1000): lastPressed = time.ticks_ms() - networking.commands.send(peer_mac, message) + networking.send(peer_mac, message) # print(f"Sent {random_bytes} to {peer_mac}") switch_select = Pin(9, Pin.IN, Pin.PULL_UP) @@ -211,7 +208,7 @@ def boop(pin): while True: print(f"{int(time.ticks_ms()-start_time)/1000}: {gc.mem_free()}") - #networking.commands.ping(peer_mac) + #networking.ping(peer_mac) #print(f"Sent ping to {peer_mac}") time.sleep(0.1) if networking.check_messages(): diff --git a/software/release/config.py b/software/release/config.py index e2e1be1..c342527 100644 --- a/software/release/config.py +++ b/software/release/config.py @@ -39,6 +39,8 @@ "Directory-Get": 0x14, "Echo": 0x15, "Resend": 0x16, + "Send-Configure": 0x17, + "Receive-Configure": 0x18, "WiFi-Connect": 0x21, "WiFi-Disconnect": 0x22, "AP-Enable": 0x23, From 4b3262891e85d303d6a5f07ba3a377f4688966eb Mon Sep 17 00:00:00 2001 From: Nick Art Date: Thu, 19 Dec 2024 18:25:45 -0500 Subject: [PATCH 5/6] small code update --- .DS_Store | Bin 14340 -> 14340 bytes software/.DS_Store | Bin 12292 -> 12292 bytes software/main/.DS_Store | Bin 6148 -> 6148 bytes software/main/.idea/.name | 2 +- software/main/boot.py | 47 +++++++++------ software/main/hm1.py | 2 + software/main/main.py | 112 ------------------------------------ software/release/README.qmd | 8 ++- software/release/config.py | 7 ++- 9 files changed, 41 insertions(+), 137 deletions(-) create mode 100644 software/main/hm1.py delete mode 100644 software/main/main.py diff --git a/.DS_Store b/.DS_Store index 57e317ed5c8498af23f061e26177c7aa84d4e9e8..7bf95952b7c953e011afac60c8aca43933ec5aad 100644 GIT binary patch delta 33 gcmZoEXerpRLYm#gz(_~I#B%d`>7V=vj&>*y0KdWtdjJ3c delta 33 gcmZoEXerpRLYm#ez(PmC)Nu29>7V=vj&>*y0KjhwfdBvi diff --git a/software/.DS_Store b/software/.DS_Store index 475298ea9191f8bd6315d7d368b42702e00d6d81..62e3246dbc7d97084497d4a35d1d0d7fe1425f3f 100644 GIT binary patch delta 337 zcmZokXi1ph&uF+YU^hRb{A2+Z$<3+)M$D6a#7o&t42*RYOe`lCiaJad5$P3SVaR1j zWXNR5D+?~l%gN76XJBBMd`?ty^EMG~W}s>#xM~gwt;t`N^tHsqB}65qq^05ogp(4J zv(t<6OY>5k^Kn~A zRdxu42ylo%XgJ9jl9!*C%Bk!S01@J3;9$^ZaAfdh2xG`*sA8DNFqdH^!)}HX40jpc zGyG&^XB1#mV$^0dVYFqmXY^nUWDH_VX3SvBWGtGzPDORHszl#pR|$R|B=0e9-Y8+s ax|v&HDck0mVj7G{zSP*vuCWqBR22ZTV^MAZ delta 107 zcmZokXi1phRCU^hRb%wz!;$<3+)M$D5nl}b5{j17!*6fDe4CO;6Do}8hkGFe!p zce0?E=;pH`+{}|3McpUMOK43tk!sw0M@pY{V}mBsW^RS0Y@3gZ2{Hnuoj0>+tU>Sq Duj?R$ diff --git a/software/main/.DS_Store b/software/main/.DS_Store index dffefc3cd560dc99cb3dc6701f62b6a05a77cff6..b084c50f2019496a3b1c7459b4f461c00403a9bf 100644 GIT binary patch literal 6148 zcmeHKyH3L}6g`GgUQ0(7r2IgO3JYUEmKKAvwc6{R4H2||YXjXv|fH@|?!UD4iChd~OY|42SiAMWq?6o={s^|cH8DaS723b&|E zQ&&Kc@>M2{oJ>}v(59KD4B%Q3wxsG-5O21_Tb$LOlJ&G}s5 zhW;*Fh1Fr*Mz!gY$Q^R}*rhjOtl3f!y7f66vMk)&&o`5MmTk7b*tM)&R{wO_X>CgvI(+vtJgL;C3m)tO-|0*fa#n`On8Y!4PoYvV=c&0yu_r&wm=HR&|zYc9-99n NpfdQ(EAXQVd;q{v%QFA~ delta 115 zcmZoMXfc=|#>B)qu~2NHo+2ar#(>?7jO>$nSfaJr8FCpC88R9281xtl7%Dw;@{^Nt z@{<@C7zBXW8Hn}&g8>7>=6P(HjGGlW*jXkvux@7O;O77uxml3oJM(0I5l0T7QU*o_ L2A0hcB5Rldvnm{_ diff --git a/software/main/.idea/.name b/software/main/.idea/.name index 11a5d8e..d8613ef 100644 --- a/software/main/.idea/.name +++ b/software/main/.idea/.name @@ -1 +1 @@ -main.py \ No newline at end of file +am1.py \ No newline at end of file diff --git a/software/main/boot.py b/software/main/boot.py index 4f6b5d7..10fe88d 100644 --- a/software/main/boot.py +++ b/software/main/boot.py @@ -1,7 +1,7 @@ from machine import Pin import machine from config import config - +import time import gc gc.collect() @@ -22,20 +22,17 @@ # Network infmsg = True -dbgmsg = 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) -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"], @@ -46,9 +43,8 @@ networking.config["version"] )) -if configuration == "AM1": +def idle(): lastPressed = 0 - message = "Boop!" def boop(pin): @@ -66,23 +62,38 @@ def boop(pin): 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() +def run_config_module(module_name): try: - timer.deinit() + with open(module_name + ".py") as f: + code = f.read() + exec(code) except Exception as e: - print(e) - machine.reset() + 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/main/hm1.py b/software/main/hm1.py new file mode 100644 index 0000000..139597f --- /dev/null +++ b/software/main/hm1.py @@ -0,0 +1,2 @@ + + diff --git a/software/main/main.py b/software/main/main.py deleted file mode 100644 index f067d0f..0000000 --- a/software/main/main.py +++ /dev/null @@ -1,112 +0,0 @@ -from machine import Pin -import machine -from config import config - -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 -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.config["ap_mac"], - networking.config["sta_mac"], - networking.config["version"] -)) - - - -lastPressed = 0 - -def idle(): - - 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 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 == "S M3": - print("sm3") - run_config_module("sm3") -elif configuration == "SL1": - print("sl1") - run_config_module("sl1") -else: - print("idle") - idle() diff --git a/software/release/README.qmd b/software/release/README.qmd index 9f8142b..bae1050 100644 --- a/software/release/README.qmd +++ b/software/release/README.qmd @@ -36,7 +36,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 | @@ -45,7 +49,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/config.py b/software/release/config.py index c342527..76a52f1 100644 --- a/software/release/config.py +++ b/software/release/config.py @@ -1,11 +1,12 @@ config = { "name": "Nickname", "configuration": "AM1", + "hive": False, "id": None, "version": None } version = {'adxl345.py': 3, - 'ssp_networking.py': 1, + 'ssp_networking.py': 1, 'files.py': 2, 'icons.py': 2, 'prefs.py': 2, @@ -15,8 +16,8 @@ 'sm3.py': 1, 'sl1.py': 1, 'smartlight.py': 1, -'networking.py': 3, -'main.py': 1, + 'networking.py': 3, + 'main.py': 1, 'boot.py': 0 } mysecrets = {"SSID": "Tufts_Robot", "key": ""} From f9286d9451375a39781b0cc9cac9dfd3912acacf Mon Sep 17 00:00:00 2001 From: Nick Art Date: Thu, 19 Dec 2024 18:28:20 -0500 Subject: [PATCH 6/6] hm1 outlines --- software/.DS_Store | Bin 12292 -> 12292 bytes software/main/.idea/.name | 2 +- software/main/hm1.py | 4 ++++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/software/.DS_Store b/software/.DS_Store index 62e3246dbc7d97084497d4a35d1d0d7fe1425f3f..1dd1296f05db3c6b4edfcfa2c72545e02c6b8542 100644 GIT binary patch delta 16 XcmZokXi3;`PI&Syao5elA|IszKpqDP delta 14 VcmZokXi3;`PMFbn^Lb%Y82~Nc1#|!a diff --git a/software/main/.idea/.name b/software/main/.idea/.name index d8613ef..e837c0e 100644 --- a/software/main/.idea/.name +++ b/software/main/.idea/.name @@ -1 +1 @@ -am1.py \ No newline at end of file +hm1.py \ No newline at end of file diff --git a/software/main/hm1.py b/software/main/hm1.py index 139597f..3339fa1 100644 --- a/software/main/hm1.py +++ b/software/main/hm1.py @@ -1,2 +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