flandre/src/nodes/Device.py
2025-02-26 16:22:09 +08:00

156 lines
4.9 KiB
Python

import logging
import subprocess
import time
import zmq
from config import LIVE_REP_SOCKET, CONFIG, DEVICE_CONFIG
from nodes.Node import Node
from utils.Msg import ImageArgMsg, KillMsg, SetDeviceConnectedMsg, SetDeviceEnabledMsg, DeviceEnabledMsg, \
DeviceConnectedMsg, SetDeviceConfigMsg, DeviceOnlineMsg, DeviceConfigListMsg
logger = logging.getLogger(__name__)
class Device(Node):
topics = [SetDeviceConnectedMsg, SetDeviceEnabledMsg, SetDeviceConfigMsg]
def __init__(self, level=logging.INFO):
super(Device, self).__init__(level=level)
self.arg = ImageArgMsg('', t_start=0, t_end=1499)
self.seq_meta = None
self.device_rep_socket = None
self.ok = b'ok\x00'
def connect(self):
self.device_rep_socket.send(b'connect')
rb = self.device_rep_socket.recv()
if rb == self.ok:
self.send(DeviceConnectedMsg(True))
else:
logger.error(f"Device msg: {rb}")
def disconnect(self):
self.device_rep_socket.send(b'disconnect')
rb = self.device_rep_socket.recv()
if rb == self.ok:
self.send(DeviceConnectedMsg(False))
else:
logger.error(f"Device msg: {rb}")
def enable(self):
self.device_rep_socket.send(b'enable')
rb = self.device_rep_socket.recv()
if rb == self.ok:
self.send(DeviceEnabledMsg(True))
return True
else:
logger.error(f"Device msg: {rb}")
return False
def disable(self):
self.device_rep_socket.send(b'disable')
rb = self.device_rep_socket.recv()
if rb == self.ok:
self.send(DeviceEnabledMsg(False))
return True
else:
logger.error(f"Device msg: {rb}")
return False
def online(self):
code = subprocess.run(['curl', '-m', '1', f'http://{LIVE_REP_SOCKET}'], stderr=subprocess.DEVNULL,
stdout=subprocess.DEVNULL).returncode
logger.info(f'detect curl code: {code}')
match code:
case 28 | 7:
self.send(DeviceOnlineMsg(False))
return False
case _:
self.send(DeviceOnlineMsg(True))
return True
def enabled(self):
self.device_rep_socket.send(b'enabled')
rb = self.device_rep_socket.recv()
match rb:
case b'true':
self.send(DeviceEnabledMsg(True))
return True
case b'false':
self.send(DeviceEnabledMsg(False))
return False
case _:
logger.error(f"Device msg: {rb}")
def connected(self):
self.device_rep_socket.send(b'connected')
rb = self.device_rep_socket.recv()
match rb:
case b'true':
self.send(DeviceConnectedMsg(True))
return True
case b'false':
self.send(DeviceConnectedMsg(False))
return False
case _:
logger.error(f"Device msg: {rb}")
def setfile(self, config_str: str):
if self.enabled():
self.disable()
self.setfileonly(config_str)
self.enable()
elif self.connected():
self.setfileonly(config_str)
else:
logger.warning(f"Device not connect, cannot set config")
def setfileonly(self, s: str):
self.device_rep_socket.send(b'fileonly' + s.encode())
rb = self.device_rep_socket.recv()
if rb == self.ok:
return True
else:
logger.error(f"Device msg: {rb}")
return False
def data(self):
self.device_rep_socket.send(b'data')
return self.device_rep_socket.recv()
def custom_setup(self):
self.device_rep_socket = self.context.socket(zmq.REQ)
self.device_rep_socket.connect(f"tcp://{LIVE_REP_SOCKET}")
def loop(self):
arr = []
time.sleep(1)
if self.online():
self.connected()
self.enabled()
for f in DEVICE_CONFIG.glob('*.txt'):
arr.append((f.stem, f.read_text()))
self.send(DeviceConfigListMsg(arr))
# if arr.__len__() > 0:
# self.setfile(arr[0][1])
logger.debug(f'device start loop')
while True:
msg = self.recv()
logger.debug(f'{msg}')
if isinstance(msg, KillMsg):
if msg.name == '':
return
elif isinstance(msg, SetDeviceEnabledMsg):
if msg.value:
self.enable()
else:
self.disable()
elif isinstance(msg, SetDeviceConnectedMsg):
if msg.value:
self.connect()
else:
self.disconnect()
elif isinstance(msg, SetDeviceConfigMsg):
self.setfile(msg.value)