fix launch sleep

fix device connect
This commit is contained in:
remilia 2025-04-19 21:05:29 +08:00
parent 41b0e01d7d
commit 339194200c
6 changed files with 115 additions and 88 deletions

View File

@ -1,5 +1,7 @@
import logging
import zmq import zmq
from zmq import Context from zmq import Context, Socket
from flandre.utils.Msg import Msg, InterruptMsg from flandre.utils.Msg import Msg, InterruptMsg
@ -17,6 +19,7 @@ class BusClient:
poller=False, poller=False,
req_socket_str: str = None, req_socket_str: str = None,
): ):
self.sub: Socket = None
if ctx is None: if ctx is None:
self.ctx: Context = zmq.Context() self.ctx: Context = zmq.Context()
else: else:
@ -38,9 +41,14 @@ class BusClient:
self.pub.connect(f'tcp://127.0.0.1:{self.fp}') self.pub.connect(f'tcp://127.0.0.1:{self.fp}')
self.req_socket = None self.req_socket = None
if req_socket_str is not None: if req_socket_str is not None:
self.poller2 = zmq.Poller()
self.sub2 = self.ctx.socket(zmq.SUB)
self.sub2.setsockopt(zmq.SUBSCRIBE, InterruptMsg.magic() + InterruptMsg.eid())
# self.sub2.connect(f'tcp://127.0.0.1:{self.bp}')
self.req_socket_str = req_socket_str self.req_socket_str = req_socket_str
self.poller.register(self.req_socket, zmq.POLLIN)
self.req_socket = self.ctx.socket(zmq.REQ) self.req_socket = self.ctx.socket(zmq.REQ)
self.poller2.register(self.req_socket, zmq.POLLIN)
self.poller2.register(self.sub2, zmq.POLLIN)
self.req_socket.connect(req_socket_str) self.req_socket.connect(req_socket_str)
# todo fix poller # todo fix poller
@ -48,6 +56,11 @@ class BusClient:
b = self.sub.recv() b = self.sub.recv()
return Msg.decode_msg(b) return Msg.decode_msg(b)
def poll(self, timeout):
b = self.sub.poll(timeout)
if b != 0:
return self.recv()
def send(self, msg: Msg): def send(self, msg: Msg):
return self.pub.send(msg.encode_msg()) return self.pub.send(msg.encode_msg())
@ -58,17 +71,34 @@ class BusClient:
async def send_async(self, msg: Msg): async def send_async(self, msg: Msg):
return self.pub.send(msg.encode_msg()) return self.pub.send(msg.encode_msg())
def req_interrupt(self, b: bytes, interrupt_name: str, timeout=3000): def req_interrupt(self,
while True: data: bytes,
self.req_socket.send(b) interrupt_name: str,
r = dict(self.poller.poll(timeout)) timeout=3000,
retry_times=114514,
cb_retry=None,
):
self.sub2.connect(f'tcp://127.0.0.1:{self.bp}')
for _ in range(retry_times):
self.req_socket.send(data)
r = dict(self.poller2.poll(timeout))
if self.req_socket in r: if self.req_socket in r:
self.sub2.disconnect(f'tcp://127.0.0.1:{self.bp}')
return self.req_socket.recv() return self.req_socket.recv()
if cb_retry is not None:
cb_retry()
self.poller2.unregister(self.req_socket)
self.req_socket.close() self.req_socket.close()
self.req_socket = self.ctx.socket(zmq.REQ) self.req_socket = self.ctx.socket(zmq.REQ)
self.poller2.register(self.req_socket, zmq.POLLIN)
self.req_socket.connect(self.req_socket_str) self.req_socket.connect(self.req_socket_str)
if self.sub in r: if self.sub2 in r:
msg = self.recv() msg = Msg.decode_msg(self.sub2.recv())
if isinstance(msg, InterruptMsg): if isinstance(msg, InterruptMsg):
if msg.value == interrupt_name: if msg.value == interrupt_name:
self.sub2.disconnect(f'tcp://127.0.0.1:{self.bp}')
return None return None
logging.warning('timeout')
self.sub2.disconnect(f'tcp://127.0.0.1:{self.bp}')
return 'timeout'

View File

@ -20,7 +20,7 @@ from flandre.nodes.ImageFFMPEG import ImageFFMPEG
from flandre.nodes.ImageQt import ImageQt from flandre.nodes.ImageQt import ImageQt
from flandre.nodes.Midi import Midi from flandre.nodes.Midi import Midi
from flandre.nodes.Mi import Mi from flandre.nodes.Mi import Mi
from flandre.utils.Msg import KillMsg, NodeOnlineMsg, Msg1 from flandre.utils.Msg import KillMsg, NodeOnlineMsg, Msg1, Msg2
from flandre.config import CONFIG_FOLDER from flandre.config import CONFIG_FOLDER
@ -58,18 +58,28 @@ def launch(arg: dict[LaunchComponent, dict]):
c = BusClient(KillMsg, NodeOnlineMsg) c = BusClient(KillMsg, NodeOnlineMsg)
cnt = 0 cnt = 0
ready = False
dd = dict()
while True: while True:
msg = c.recv() if ready:
msg = c.recv()
else:
c.send(Msg2())
msg = c.poll(100)
if msg is None:
continue
if isinstance(msg, KillMsg): if isinstance(msg, KillMsg):
if msg.name == '': if msg.name == '':
break break
if isinstance(msg, NodeOnlineMsg): if not ready:
cnt += 1 if isinstance(msg, NodeOnlineMsg):
logging.info(msg) if msg.name not in dd:
if cnt == len(ps): logging.info(msg)
logging.info(f'launcher stand by ready') dd[msg.name] = 1
c.send(Msg1()) if dd.keys().__len__() == len(ps):
logging.info(f'launcher stand by ready')
c.send(Msg1())
ready = True
for p in pps: for p in pps:
p.kill() p.kill()
bp.kill() bp.kill()

View File

@ -7,12 +7,11 @@ from threading import Thread
import zmq import zmq
from flandre.BusClient import BusClient
from flandre.config import C from flandre.config import C
from flandre.nodes.Node import Node from flandre.nodes.Node import Node
from flandre.utils.Msg import ImageArgMsg, KillMsg, SetDeviceConnectedMsg, SetDeviceEnabledMsg, DeviceEnabledMsg, \ from flandre.utils.Msg import ImageArgMsg, KillMsg, SetDeviceConnectedMsg, SetDeviceEnabledMsg, DeviceEnabledMsg, \
DeviceConnectedMsg, SetDeviceConfigMsg, DeviceOnlineMsg, DeviceConfigListMsg, RequestRfFrameMsg, \ DeviceConnectedMsg, SetDeviceConfigMsg, DeviceOnlineMsg, DeviceConfigListMsg, RequestRfFrameMsg, \
DeviceZero, SetDeviceSwitchMsg, DeviceSwitchMsg, SeqMetaMsg, RefreshDeviceMsg, RfFrameMsg DeviceZero, DeviceSwitchMsg, SeqMetaMsg, RfFrameMsg
from flandre.utils.RfFrame import RfFrameMemory from flandre.utils.RfFrame import RfFrameMemory
from flandre.utils.RfMeta import RfFrameMeta, RfSequenceMeta from flandre.utils.RfMeta import RfFrameMeta, RfSequenceMeta
@ -42,10 +41,9 @@ class Device(Node):
] ]
def __init__(self, level=logging.INFO): def __init__(self, level=logging.INFO):
super(Device, self).__init__(level=level) super(Device, self).__init__(level=level, req=C.live_rep_socket)
self.arg = ImageArgMsg('', t_start=0, t_end=1499) self.arg = ImageArgMsg('', t_start=0, t_end=1499)
self.seq_meta: RfSequenceMeta | None = None self.seq_meta: RfSequenceMeta | None = None
self.req_driver_socket: zmq.Socket = None
self.rep_socket: zmq.Socket = None self.rep_socket: zmq.Socket = None
self.ok = b'ok\x00' self.ok = b'ok\x00'
self.loop2_t = None self.loop2_t = None
@ -56,53 +54,42 @@ class Device(Node):
self.online() self.online()
time.sleep(1) time.sleep(1)
def d2b(self, cmd: DeviceCmd, v: bytes = b''):
return struct.pack('i', self.magic) + struct.pack('i', cmd.value) + v
def device_cmd(self, cmd: DeviceCmd, v: bytes = b''): def device_cmd(self, cmd: DeviceCmd, v: bytes = b''):
self.req_driver_socket.send(struct.pack('i', self.magic) + struct.pack('i', cmd.value) + v) return self.c.req_interrupt(
self.d2b(cmd, v),
interrupt_name='device123',
retry_times=5,
cb_retry=lambda : logger.warning(f'retry {cmd}'),
)
def connect(self): def connect(self):
temp_client = BusClient(SetDeviceSwitchMsg, RefreshDeviceMsg, poller=True) # r = self.c.req_interrupt(
temp_client.poller.register(self.req_driver_socket, zmq.POLLIN) # self.d2b(DeviceCmd.SetConnectionOn),
self.device_cmd(DeviceCmd.SetConnectionOn) # retry_times=3,
logger.warning('onn') # interrupt_name='device123',
d = dict(temp_client.poller.poll()) # cb_retry=lambda: logger.warning('retry'))
r = self.device_cmd(DeviceCmd.SetConnectionOn)
if self.req_driver_socket in d: if r == self.ok:
rb = self.req_driver_socket.recv() self.send(DeviceConnectedMsg(True))
if rb == self.ok: else:
self.send(DeviceConnectedMsg(True)) if r is None:
logger.error('interrupt')
else: else:
logger.error(f"Device msg: {rb}") logger.error(f"Device msg: {r}")
if temp_client.sub in d: self.send(DeviceConnectedMsg(False))
msg = temp_client.recv()
if isinstance(msg, SetDeviceSwitchMsg):
if not msg.value:
self.switch = False
logger.warning(f"interrupt connecting")
self.req_driver_socket.close()
self.context.term()
self.context = zmq.Context()
self.req_driver_socket = self.context.socket(zmq.REQ)
self.req_driver_socket.connect(C.live_rep_socket)
if isinstance(msg, RefreshDeviceMsg):
self.switch = False
logger.warning(f"interrupt connecting")
self.req_driver_socket.close()
self.context.term()
self.context = zmq.Context()
self.req_driver_socket = self.context.socket(zmq.REQ)
self.req_driver_socket.connect(C.live_rep_socket)
def disconnect(self): def disconnect(self):
self.device_cmd(DeviceCmd.SetConnectionOff) rb = self.device_cmd(DeviceCmd.SetConnectionOff)
rb = self.req_driver_socket.recv()
if rb == self.ok: if rb == self.ok:
self.send(DeviceConnectedMsg(False)) self.send(DeviceConnectedMsg(False))
else: else:
logger.error(f"Device msg: {rb}") logger.error(f"Device msg: {rb}")
def enable(self): def enable(self):
self.device_cmd(DeviceCmd.SetEnableOn) rb = self.device_cmd(DeviceCmd.SetEnableOn)
rb = self.req_driver_socket.recv()
if rb == self.ok: if rb == self.ok:
self.send(DeviceEnabledMsg(True)) self.send(DeviceEnabledMsg(True))
return True return True
@ -111,8 +98,7 @@ class Device(Node):
return False return False
def disable(self): def disable(self):
self.device_cmd(DeviceCmd.SetEnableOff) rb = self.device_cmd(DeviceCmd.SetEnableOff)
rb = self.req_driver_socket.recv()
if rb == self.ok: if rb == self.ok:
self.send(DeviceEnabledMsg(False)) self.send(DeviceEnabledMsg(False))
return True return True
@ -133,8 +119,7 @@ class Device(Node):
return True return True
def get_enable(self): def get_enable(self):
self.device_cmd(DeviceCmd.GetEnable) rb = self.device_cmd(DeviceCmd.GetEnable)
rb = self.req_driver_socket.recv()
match rb: match rb:
case b'true': case b'true':
self.send(DeviceEnabledMsg(True)) self.send(DeviceEnabledMsg(True))
@ -146,16 +131,14 @@ class Device(Node):
logger.error(f"Device msg: {rb}") logger.error(f"Device msg: {rb}")
def get_seq_meta_name(self): def get_seq_meta_name(self):
self.device_cmd(DeviceCmd.GetName) rb = self.device_cmd(DeviceCmd.GetName)
rb = self.req_driver_socket.recv()
name = rb.decode() name = rb.decode()
self.seq_meta = RfSequenceMeta.from_name(name) self.seq_meta = RfSequenceMeta.from_name(name)
if rb != b'': if rb != b'':
self.send(SeqMetaMsg('live', name)) self.send(SeqMetaMsg('live', name))
def get_connection(self): def get_connection(self):
self.device_cmd(DeviceCmd.GetConnection) rb = self.device_cmd(DeviceCmd.GetConnection)
rb = self.req_driver_socket.recv()
match rb: match rb:
case b'true': case b'true':
self.send(DeviceConnectedMsg(True)) self.send(DeviceConnectedMsg(True))
@ -178,9 +161,8 @@ class Device(Node):
def set_name_and_file_only(self, name: str, txt: str): def set_name_and_file_only(self, name: str, txt: str):
name_encoded = name.encode() name_encoded = name.encode()
self.device_cmd(DeviceCmd.SetNameAndFileOnly, rb = self.device_cmd(DeviceCmd.SetNameAndFileOnly,
struct.pack('I', name_encoded.__len__()) + name.encode() + txt.encode()) struct.pack('I', name_encoded.__len__()) + name.encode() + txt.encode())
rb = self.req_driver_socket.recv()
if rb == self.ok: if rb == self.ok:
return True return True
else: else:
@ -188,21 +170,17 @@ class Device(Node):
return False return False
def get_data(self): def get_data(self):
self.device_cmd(DeviceCmd.GetData)
return self.req_driver_socket.recv() return self.device_cmd(DeviceCmd.GetData)
def set_zero(self): def set_zero(self):
self.device_cmd(DeviceCmd.SetZero) return self.device_cmd(DeviceCmd.SetZero)
return self.req_driver_socket.recv()
def custom_setup(self): def custom_setup(self):
self.rep_socket = self.context.socket(zmq.REP) self.rep_socket = self.context.socket(zmq.REP)
self.rep_socket.bind(f"tcp://localhost:{C.driver_rep_port}") self.rep_socket.bind(f"tcp://localhost:{C.driver_rep_port}")
self.c.poller.register(self.rep_socket, zmq.POLLIN) self.c.poller.register(self.rep_socket, zmq.POLLIN)
self.req_driver_socket = self.context.socket(zmq.REQ)
self.req_driver_socket.connect(C.live_rep_socket)
def loop(self): def loop(self):
self.loop2_t = Thread(target=self.loop2) self.loop2_t = Thread(target=self.loop2)
self.loop2_t.start() self.loop2_t.start()

View File

@ -120,13 +120,12 @@ class Adv(QMainWindow, Ui_MainWindow):
self.b_probe_stop.clicked.connect(self.on_probe('stop')) self.b_probe_stop.clicked.connect(self.on_probe('stop'))
self.b_device_zero.clicked.connect(lambda: self.p.send(DeviceZero())) self.b_device_zero.clicked.connect(lambda: self.p.send(DeviceZero()))
self.b_us_switch.clicked.connect(self.on_deivce_switch)
self.b_us_refresh.clicked.connect(self.on_deivce_refresh)
self.mi_req_socket = zmq.Context().socket(zmq.REQ) self.mi_req_socket = zmq.Context().socket(zmq.REQ)
self.mi_req_socket.connect(C.mi_rep_socket) self.mi_req_socket.connect(C.mi_rep_socket)
def on_deivce_switch(self): @pyqtSlot()
def on_b_us_switch_clicked(self):
match self.device_switch_state: match self.device_switch_state:
case LinkStatus.RED: case LinkStatus.RED:
self.p.send(SetDeviceSwitchMsg(True)) self.p.send(SetDeviceSwitchMsg(True))
@ -134,7 +133,8 @@ class Adv(QMainWindow, Ui_MainWindow):
case LinkStatus.GREEN | LinkStatus.YELLOW | LinkStatus.ORANGE: case LinkStatus.GREEN | LinkStatus.YELLOW | LinkStatus.ORANGE:
self.p.send(SetDeviceSwitchMsg(False)) self.p.send(SetDeviceSwitchMsg(False))
def on_deivce_refresh(self): @pyqtSlot()
def on_b_us_refresh_clicked(self):
match self.device_switch_state: match self.device_switch_state:
case LinkStatus.GREEN | LinkStatus.YELLOW | LinkStatus.ORANGE: case LinkStatus.GREEN | LinkStatus.YELLOW | LinkStatus.ORANGE:
self.p.send(RefreshDeviceMsg()) self.p.send(RefreshDeviceMsg())

View File

@ -6,7 +6,7 @@ import zmq
from flandre.config import C from flandre.config import C
from flandre.nodes.Node import Node from flandre.nodes.Node import Node
from flandre.utils.Msg import KillMsg, SetDeviceSwitchMsg, DeviceSwitchMsg, RefreshDeviceMsg from flandre.utils.Msg import KillMsg, SetDeviceSwitchMsg, DeviceSwitchMsg, RefreshDeviceMsg, InterruptMsg
from flandre.utils.mi import c1_connect, c1_connected, c1_disconnect from flandre.utils.mi import c1_connect, c1_connected, c1_disconnect
from flandre.utils.network import check_port, check_socket from flandre.utils.network import check_port, check_socket
@ -106,7 +106,7 @@ class Mi(Node):
# self.mi_rep_socket.send(b'ok') # self.mi_rep_socket.send(b'ok')
if self.c.sub in r: if self.c.sub in r:
msg = self.recv() msg = self.recv()
logger.info(f'{msg}') # logger.info(f'{msg}')
if isinstance(msg, KillMsg): if isinstance(msg, KillMsg):
if msg.name == '': if msg.name == '':
return return
@ -121,6 +121,7 @@ class Mi(Node):
self.device_py_req_socket.recv() self.device_py_req_socket.recv()
self.send(DeviceSwitchMsg('RED')) self.send(DeviceSwitchMsg('RED'))
elif isinstance(msg, RefreshDeviceMsg): elif isinstance(msg, RefreshDeviceMsg):
self.send(InterruptMsg('device123'))
self.device_py_req_socket.send(b'kill') self.device_py_req_socket.send(b'kill')
self.device_py_req_socket.recv() self.device_py_req_socket.recv()
self.device_py_req_socket.send(b'start') self.device_py_req_socket.send(b'start')

View File

@ -1,11 +1,12 @@
import logging import logging
import sys
import time import time
from abc import abstractmethod from abc import abstractmethod
import zmq import zmq
from flandre.BusClient import BusClient from flandre.BusClient import BusClient
from flandre.utils.Msg import Msg, KillMsg, NodeOnlineMsg, Msg1 from flandre.utils.Msg import Msg, KillMsg, NodeOnlineMsg, Msg1, Msg2, InterruptMsg
class Node: class Node:
@ -13,7 +14,7 @@ class Node:
bp = BusClient.bp bp = BusClient.bp
topics = [] topics = []
def __init__(self, enable_init=True, level=logging.INFO, conflare=False, broker=False, req=False): def __init__(self, enable_init=True, level=logging.INFO, conflare=False, broker=False, req=None):
self.enable_init = enable_init self.enable_init = enable_init
self.isalive = True self.isalive = True
self.level = level self.level = level
@ -24,6 +25,9 @@ class Node:
def recv(self): def recv(self):
return self.c.recv() return self.c.recv()
def poll(self, timeout: int):
return self.c.poll(timeout)
def send(self, msg: Msg): def send(self, msg: Msg):
return self.c.send(msg) return self.c.send(msg)
@ -56,16 +60,20 @@ class Node:
self.context = zmq.Context() self.context = zmq.Context()
if self.enable_init: if self.enable_init:
self.c = BusClient(*([KillMsg, Msg1] + self.topics), self.c = BusClient(*([KillMsg,InterruptMsg, Msg1, Msg2] + self.topics),
poller=True, conflare=self.conflare, req_socket_str=self.req) poller=True, conflare=self.conflare, req_socket_str=self.req)
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
self.setup() self.setup()
if not self.broker: if not self.broker:
time.sleep(2) while True:
self.send(NodeOnlineMsg(self.__class__.__name__)) msg = self.poll(100)
# input('asdasd') if msg is not None:
msg = self.recv() break
# logging.info(f'{self.__class__.__name__},{msg}') while True:
self.send(NodeOnlineMsg(self.__class__.__name__))
msg = self.recv()
if isinstance(msg, Msg1):
break
self.loop() self.loop()
print(self.__class__.__name__, 'exiting') print(self.__class__.__name__, 'exiting')