11import asyncio
22import multiprocessing as mp
33import logging
4+ from typing import Optional
45from pydevlpr_protocol import DataFormatException , unwrap_packet , PacketType , DaemonSocket
56
67from .serif import DevlprSerif
78from .DaemonState import DaemonState
8- from .config import CONFIG
9+ from .config import BOARDS , Board , get_board_ids , CONFIG
910
1011server = None
11- state : DaemonState = None # Make sure to pass this to any other threads that need access to shared state
12- devlpr_serial : DevlprSerif = None
12+ state : Optional [ DaemonState ] = None # Make sure to pass this to any other threads that need access to shared state
13+ devlpr_serial : Optional [ DevlprSerif ] = None
1314
1415logging .basicConfig (level = logging .INFO )
1516
1617class DaemonController :
18+ def __init__ (self , board_id : str ) -> None :
19+ try :
20+ self .board = BOARDS [board_id ]
21+ except KeyError :
22+ logging .warning ("Invalid board ID, try get_board_ids() for options" )
23+ logging .info ('Assuming DEVLPR' )
24+ self .board = BOARDS ['DEVLPR' ]
1725
1826 def start (self , block = False ):
19- self .p = mp .Process (target = main )
27+ self .p = mp .Process (target = main , args = ( self . board ,) )
2028 self .p .start ()
2129 if block :
2230 self .p .join ()
@@ -25,8 +33,8 @@ def stop(self):
2533 if self .p is not None and self .p .is_alive ():
2634 self .p .terminate ()
2735
28- def main ():
29- asyncio .run (startup ())
36+ def main (board : Board ):
37+ asyncio .run (startup (board ))
3038
3139async def client_accept (sock : DaemonSocket ) -> None :
3240 """Delegate and process incoming messages from a websocket connection."""
@@ -40,8 +48,11 @@ async def client_accept(sock: DaemonSocket) -> None:
4048 except DataFormatException :
4149 continue # Handle an unexpected issue with the packet
4250 if command == PacketType .SUBSCRIBE :
43- logging .info ("Sub to {}" .format (data ))
44- state .subscribe (sock , data )
51+ logging .info ("Subscribing to {}" .format (data ))
52+ try :
53+ state .subscribe (sock , data )
54+ except AttributeError :
55+ logging .error ("Failed to subscribe, Daemon State is None" )
4556
4657async def client_handler (reader : asyncio .StreamReader , writer : asyncio .StreamWriter ) -> None :
4758 """Main function for socket connections. Holds the connection until the other side disconnects."""
@@ -52,10 +63,12 @@ async def client_handler(reader: asyncio.StreamReader, writer: asyncio.StreamWri
5263 await client_accept (dsock )
5364 finally :
5465 logging .info ("Disconnected from {0}" .format (dsock .get_remote_address ()))
55- state .unsubscribe_all (dsock )
66+ try :
67+ state .unsubscribe_all (dsock )
68+ except AttributeError :
69+ logging .error ("Failed to unsubscribe_all, Daemon State is None" )
5670
57-
58- async def startup () -> None :
71+ async def startup (board : Board ) -> None :
5972 """Initiallizes both the serial connection and the socket server. It then just hangs until everything is done internally before cleaning up."""
6073
6174 global server
@@ -64,17 +77,16 @@ async def startup() -> None:
6477 # we'll want the asyncio event loop for subscriptions, some processing, and publishing
6578 event_loop = asyncio .get_running_loop ()
6679 # the DaemonState requests publishes upon state change, so needs to know the event loop
67- state = DaemonState (event_loop )
80+ state = DaemonState (event_loop , board )
6881 # we initialize our serial connection, which is managed on a separate thread
69- devlpr_serial = DevlprSerif ()
82+ devlpr_serial = DevlprSerif (board )
7083 devlpr_serial .init_serial (state )
7184 # start a server, waiting for incoming subscribers to data (pydevlpr and other libraries)
7285 server = await asyncio .start_server (client_handler , CONFIG ['ADDRESS' ][0 ], CONFIG ['ADDRESS' ][1 ])
7386 try :
7487 await server .serve_forever ()
7588 except asyncio .exceptions .CancelledError :
7689 await server .wait_closed ()
77- print ("Finish up" )
7890 devlpr_serial .deinit_serial ()
7991
8092def shutdown () -> None :
@@ -89,6 +101,8 @@ def shutdown() -> None:
89101 pass
90102 try :
91103 devlpr_serial .deinit_serial ()
104+ except AttributeError :
105+ logging .warning ("Serial couldn't close because devlpr_serial is already None" )
92106 except :
93107 pass # not even sure this is necessary
94108
0 commit comments