Browse Source

multi mesh

main
gsd 4 months ago
parent
commit
416de26321
  1. 3
      .gitignore
  2. 6
      config.example.json
  3. 5
      mesht_device.py
  4. 4
      mesht_models.py
  5. 148
      service.py

3
.gitignore

@ -1,3 +1,4 @@
testenv/ testenv/
__pycache__/ __pycache__/
docker-compose.yaml docker-compose.yaml
config/

6
config.example.json

@ -0,0 +1,6 @@
[
{"uuid": "692daca8-08e4-48b5-917b-a65a0f72cc12", "transport": "tcp", "address": "192.168.1.1:1234", "alive_pool_seconds": 60},
{"uuid": "5e432648-6c04-4892-af98-f32382931645", "transport": "ble", "adapter":"hci0", "address": "00:00:00:00:00:00"},
{"uuid": "0a8aa564-2f91-4e4d-a102-0aae57881bab", "transport": "serial", "port": "/dev/tty0USB", "baudrate": 115200},
{"uuid": "c64ab2a4-5305-4c70-8776-83c74a5de796", "transport": "ws", "port": "60000"}
]

5
mesht_device.py

@ -220,7 +220,7 @@ class Channel:
class MeshtDevice: class MeshtDevice:
def __init__(self, transport): def __init__(self, transport, device_uuid, skip_init = False):
self.transport = transport self.transport = transport
self.channels = [] self.channels = []
self.lora_config = None self.lora_config = None
@ -228,6 +228,8 @@ class MeshtDevice:
self.my_node_id = "00000000" self.my_node_id = "00000000"
self.my_node_id_dec = 0 self.my_node_id_dec = 0
self.nid = None self.nid = None
self.device_uuid = device_uuid
self.skip_init = skip_init
async def start(self): async def start(self):
await self.transport.start() await self.transport.start()
@ -266,6 +268,7 @@ class MeshtDevice:
async def recv(self): async def recv(self):
data = await self.transport.recv() data = await self.transport.recv()
fr = pb.decode(data, FROMRADIO_SCHEMA) fr = pb.decode(data, FROMRADIO_SCHEMA)
fr["device_uuid"] = self.device_uuid
logger.debug(f"FromRadio: {fr}") logger.debug(f"FromRadio: {fr}")
self._maybe_store_channel(fr) self._maybe_store_channel(fr)
self._maybe_store_lora_config(fr) self._maybe_store_lora_config(fr)

4
mesht_models.py

@ -25,6 +25,10 @@ WS_TYPE_NEW = 1
WS_TYPE_FRONTEND = 2 WS_TYPE_FRONTEND = 2
async def _wait_for_config_complete(device, extraInfo = False): async def _wait_for_config_complete(device, extraInfo = False):
if device.skip_init:
logger.info(str(device), "init config skip")
return []
logger.info("wait config") logger.info("wait config")
packets = [] packets = []
while True: while True:

148
service.py

@ -35,59 +35,86 @@ class MeshArgsParse:
def __init__(self, args): def __init__(self, args):
self.args = args self.args = args
class MeshListener(MeshArgsParse): class MeshMultiListener(MeshArgsParse):
def __init__(self, args): def __init__(self, args):
super().__init__(args)
self.meshState = NOT_CONNECTED
self.PUB_CH = PUB_CH self.PUB_CH = PUB_CH
self.last_packet_catch = time() super().__init__(args)
self.devices:List[MeshtDevice] = []
self.defaultDeviceUUID = ""
self.readConfig(args.change_workdir, args.mesh_config)
if args.transport == "serial": '''
from transport_serial import SerialTransport [
self.transport = SerialTransport(port = args.serial_port, baudrate = args.serial_baudrate) {"uuid": "692daca8-08e4-48b5-917b-a65a0f72cc12", "transport": "tcp", "address": "192.168.1.1:1234", "alive_pool_seconds": 60},
elif args.transport == "ble": {"uuid": "5e432648-6c04-4892-af98-f32382931645", "transport": "ble", "adapter":"hci0", "address": "00:00:00:00:00:00"},
from transport_ble import BLETransport {"uuid": "0a8aa564-2f91-4e4d-a102-0aae57881bab", "transport": "serial", "port": "/dev/tty0USB", "baudrate": 115200},
self.transport = BLETransport(args.ble_mesh_mac, args.ble_adapter) {"uuid", "c64ab2a4-5305-4c70-8776-83c74a5de796", "transport": "ws", "port": "60000"}
elif args.transport == "tcp": ]
from transport_tcp import TCPTransport '''
ip, port = args.tcp_address.split(":") #not need async
self.transport = TCPTransport(ip, int(port), alive_pool_connect=self.args.serial_alive_pool_seconds) def readConfig(self, change_dir = True, path = "./config/mesh.json"):
else: from json import load
logger.error("Unknown mesh transport") if change_dir:
sys.exit(1) path = f"{os.path.dirname(os.path.abspath(__file__))}/{path}"
self.device = MeshtDevice(self.transport) with open(path, "r") as config:
self.json_config = load(config)
#task for device_config in self.json_config:
async def meshWorker(self, queue: asyncio.Queue): if device_config.get("uuid", "") == "":
logger.info("Start mesh queue listener") raise Exception("missed uuid section in ", device_config)
if device_config.get("transport", "") == "":
raise Exception("missed uuid section in ", device_config)
if device_config["transport"] == "serial":
logger.info("Found serial transport")
from transport_serial import SerialTransport
transport = SerialTransport(port = device_config["port"], baudrate = device_config["baudrate"])
self.devices.append(MeshtDevice(transport, device_config['uuid']))
elif device_config["transport"] == "tcp":
logger.info("Found tcp transport")
from transport_tcp import TCPTransport
ip, port = device_config["address"].split(":")
transport = TCPTransport(ip, int(port), alive_pool_connect=device_config.get("alive_pool_seconds", 60))
self.devices.append(MeshtDevice(transport, device_config['uuid']))
elif device_config["transport"] == "ble":
logger.info("Found ble transport")
from transport_ble import BLETransport
transport = BLETransport(device_config["address"], device_config["adapter"])
self.devices.append(MeshtDevice(transport, device_config['uuid']))
elif device_config["transport"] == "ws":
raise Exception("ws transport not impl")
#set default mesh
self.defaultDeviceUUID = self.json_config[0]["uuid"]
async def meshListener(self, device: MeshtDevice, queue: asyncio.Queue):
run = not self.args.disable_mesh or self.args.enable_mesh run = not self.args.disable_mesh or self.args.enable_mesh
while run: while run:
try: try:
await self.device.start() await device.start()
self.meshState = WAIT_CONFIG device.state = WAIT_CONFIG
logger.info("Mesh state: wait config") logger.info(str(device), " wait config")
self.init_data = await _wait_for_config_complete(self.device) init_data = await _wait_for_config_complete(device)
for from_radio in self.init_data: for from_radio in init_data:
await queue.put(from_radio) await queue.put(from_radio)
logger.info("Mesh state: available") logger.info(str(device), " available")
self.meshState = AVAILABLE device.state = AVAILABLE
while True: while True:
from_radio, _ = await self.device.recv() from_radio, _ = await device.recv()
#logger.debug(from_radio)
await queue.put(from_radio) await queue.put(from_radio)
self.last_packet_catch = time() device.last_packet_catch = time()
except asyncio.exceptions.CancelledError: except asyncio.exceptions.CancelledError:
logger.info("Kill mesh device") logger.info(str(device), " kill device")
run = False run = False
except: except:
logger.error("Mesh state: error") logger.error(str(device), " has connect error")
self.meshState = ERR device.state = ERR
traceback.print_exc() traceback.print_exc()
await asyncio.sleep(1) await asyncio.sleep(1)
logger.info("Mesh state: reconnect") logger.info(str(device), " device will reconnect")
self.meshState = RECONNECT device.state = RECONNECT
finally: finally:
await self.device.close() await self.device.close()
@ -131,16 +158,11 @@ class MongoDriver(MeshArgsParse):
self.tileManager = TileManager(self) self.tileManager = TileManager(self)
async def dbSaveRadio(self, new_from_radio): async def dbSaveRadio(self, new_from_radio):
'''try:
anyJson = from_radio["packet"]
except:
logger.debug(from_radio)
return'''
#logger.debug(from_radio)
#logger.debug(len(list(from_radio.keys())))
from_radio = copy.deepcopy(new_from_radio) from_radio = copy.deepcopy(new_from_radio)
for k, v in from_radio.items(): for k, v in from_radio.items():
if k == "device_uuid":
continue
if type(v) != dict: if type(v) != dict:
v = {"data": v, "ts": time()} v = {"data": v, "ts": time()}
else: else:
@ -173,29 +195,14 @@ class MongoDriver(MeshArgsParse):
v.update(v["user"]) v.update(v["user"])
del v["user"] del v["user"]
v["device_uuid"] = from_radio["device_uuid"]
await self.dbStore[k].insert_one(v) await self.dbStore[k].insert_one(v)
'''async def dbQueueListener(self, queue: asyncio.Queue): class MeshCenter(MeshMultiListener, MeshApi, MongoDriver, MeshArgsParse):
logger.info("Start db queue listener")
run = True
while run:
try:
from_radio = await queue.get()
if from_radio is None:
continue
await self.dbSaveRadio(from_radio)
except asyncio.exceptions.CancelledError:
logger.info("Kill db listener")
run = False
except:
traceback.print_exc()'''
class MeshCenter(MeshListener, MeshApi, MongoDriver, MeshArgsParse):
queue: asyncio.Queue = asyncio.Queue() queue: asyncio.Queue = asyncio.Queue()
def __init__(self, args): def __init__(self, args):
MeshListener.__init__(self, args) MeshMultiListener.__init__(self, args)
MeshArgsParse.__init__(self, args) MeshArgsParse.__init__(self, args)
MeshApi.__init__(self, args) MeshApi.__init__(self, args)
MongoDriver.__init__(self, args) MongoDriver.__init__(self, args)
@ -217,12 +224,12 @@ class MeshCenter(MeshListener, MeshApi, MongoDriver, MeshArgsParse):
except: except:
traceback.print_exc() traceback.print_exc()
def buildBackgroundTasks(self): def buildBackgroundTasks(self):
#input queue #input queue
async def mL(): for device in self.devices:
await self.meshWorker(self.queue) async def mL():
self.tasks.append(mL) await self.meshListener(device, self.queue)
self.tasks.append(mL)
#output #output
async def handlerTask(): async def handlerTask():
@ -258,9 +265,12 @@ class MeshCenter(MeshListener, MeshApi, MongoDriver, MeshArgsParse):
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
#mesh #mesh
parser.add_argument("--transport", default="tcp") parser.add_argument("--change-workdir", default=True, action="store_true")
parser.add_argument("--mesh-config", default="./config/mesh.json")
parser.add_argument("--disable-mesh", action="store_true", default=True) parser.add_argument("--disable-mesh", action="store_true", default=True)
parser.add_argument("--enable-mesh", action="store_true", default=False, help="Need to run in docker if git is bullshit updates") parser.add_argument("--enable-mesh", action="store_true", default=False, help="Need to run in docker if git is bullshit updates")
'''
parser.add_argument("--transport", default="tcp")
#serial transport #serial transport
parser.add_argument("--serial-port", default="/dev/tty.usbmodemD0CF1309DC141") parser.add_argument("--serial-port", default="/dev/tty.usbmodemD0CF1309DC141")
parser.add_argument("--serial-baudrate", default=115200) parser.add_argument("--serial-baudrate", default=115200)
@ -269,7 +279,7 @@ if __name__ == "__main__":
parser.add_argument("--ble-adapter", default=None) parser.add_argument("--ble-adapter", default=None)
parser.add_argument("--ble-mesh-mac", default="22AC1D28-5345-465E-2E82-18CDE5857A45") parser.add_argument("--ble-mesh-mac", default="22AC1D28-5345-465E-2E82-18CDE5857A45")
#tcp trasponse #tcp trasponse
parser.add_argument("--tcp-address", default="192.168.3.26:8886") parser.add_argument("--tcp-address", default="192.168.3.26:8886")'''
#fastapi #fastapi
parser.add_argument("--web-host", default="0.0.0.0") parser.add_argument("--web-host", default="0.0.0.0")
parser.add_argument("--web-port", default=8680) parser.add_argument("--web-port", default=8680)

Loading…
Cancel
Save