From 80eb1eea96cfa1888232bb238654cd7006eb586b Mon Sep 17 00:00:00 2001 From: flandre Date: Tue, 13 May 2025 19:23:10 +0800 Subject: [PATCH] add device function --- cmd_example.ipynb | 104 ++++++++++++++++++++++++++++++++++++++++ flandre/BusClient.py | 28 +++++------ flandre/launcher.py | 56 ++++++++++++++++++++++ flandre/nodes/Device.py | 9 ++-- 4 files changed, 179 insertions(+), 18 deletions(-) create mode 100644 cmd_example.ipynb diff --git a/cmd_example.ipynb b/cmd_example.ipynb new file mode 100644 index 0000000..55d223b --- /dev/null +++ b/cmd_example.ipynb @@ -0,0 +1,104 @@ +{ + "cells": [ + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-05-13T11:19:50.850223Z", + "start_time": "2025-05-13T11:19:35.463013Z" + } + }, + "cell_type": "code", + "source": "!flandre device connect", + "id": "b9a1cfa42427ea58", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\"/home/lambda/source/scarlet/flandre/flandre/nodes/Device.py:67\" [2025-05-13 19:19:38.685] WARNING - retry DeviceCmd.SetConnectionOn\r\n", + "\"/home/lambda/source/scarlet/flandre/flandre/nodes/Device.py:67\" [2025-05-13 19:19:41.688] WARNING - retry DeviceCmd.SetConnectionOn\r\n", + "\"/home/lambda/source/scarlet/flandre/flandre/nodes/Device.py:67\" [2025-05-13 19:19:44.691] WARNING - retry DeviceCmd.SetConnectionOn\r\n", + "\"/home/lambda/source/scarlet/flandre/flandre/nodes/Device.py:67\" [2025-05-13 19:19:47.696] WARNING - retry DeviceCmd.SetConnectionOn\r\n", + "\"/home/lambda/source/scarlet/flandre/flandre/nodes/Device.py:67\" [2025-05-13 19:19:50.699] WARNING - retry DeviceCmd.SetConnectionOn\r\n", + "\"/home/lambda/source/scarlet/flandre/flandre/BusClient.py:102\" [2025-05-13 19:19:50.699] WARNING - timeout\r\n", + "\"/home/lambda/source/scarlet/flandre/flandre/nodes/Device.py:83\" [2025-05-13 19:19:50.700] ERROR - Device msg: timeout\r\n" + ] + } + ], + "execution_count": 34 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-05-13T11:19:54.021623Z", + "start_time": "2025-05-13T11:19:51.402588Z" + } + }, + "cell_type": "code", + "source": "!flandre device upload fakename config/device/max-256-120,U=120,M=PWI,S=\\(256\\ 6002\\).txt", + "id": "ac406034e9609c90", + "outputs": [], + "execution_count": 35 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-05-13T11:19:56.434235Z", + "start_time": "2025-05-13T11:19:54.591188Z" + } + }, + "cell_type": "code", + "source": "!flandre device enable", + "id": "ab586d49c1b1ba92", + "outputs": [], + "execution_count": 36 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-05-13T11:20:10.235636Z", + "start_time": "2025-05-13T11:20:08.501316Z" + } + }, + "cell_type": "code", + "source": "!flandre device disable", + "id": "ca701d64ece107ad", + "outputs": [], + "execution_count": 37 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-05-13T11:20:20.518130Z", + "start_time": "2025-05-13T11:20:18.355438Z" + } + }, + "cell_type": "code", + "source": "!flandre device disconnect", + "id": "43b7940521fe2281", + "outputs": [], + "execution_count": 38 + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/flandre/BusClient.py b/flandre/BusClient.py index 23fce3a..5476128 100644 --- a/flandre/BusClient.py +++ b/flandre/BusClient.py @@ -41,14 +41,14 @@ class BusClient: self.pub.connect(f'tcp://127.0.0.1:{self.fp}') self.req_socket = 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.poller_for_interrupt = zmq.Poller() + self.sub_for_interrupt = self.ctx.socket(zmq.SUB) + self.sub_for_interrupt.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 = self.ctx.socket(zmq.REQ) - self.poller2.register(self.req_socket, zmq.POLLIN) - self.poller2.register(self.sub2, zmq.POLLIN) + self.poller_for_interrupt.register(self.req_socket, zmq.POLLIN) + self.poller_for_interrupt.register(self.sub_for_interrupt, zmq.POLLIN) self.req_socket.connect(req_socket_str) # todo fix poller @@ -78,27 +78,27 @@ class BusClient: retry_times=114514, cb_retry=None, ): - self.sub2.connect(f'tcp://127.0.0.1:{self.bp}') + self.sub_for_interrupt.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)) + r = dict(self.poller_for_interrupt.poll(timeout)) if self.req_socket in r: - self.sub2.disconnect(f'tcp://127.0.0.1:{self.bp}') + self.sub_for_interrupt.disconnect(f'tcp://127.0.0.1:{self.bp}') return self.req_socket.recv() if cb_retry is not None: cb_retry() - self.poller2.unregister(self.req_socket) + self.poller_for_interrupt.unregister(self.req_socket) self.req_socket.close() self.req_socket = self.ctx.socket(zmq.REQ) - self.poller2.register(self.req_socket, zmq.POLLIN) + self.poller_for_interrupt.register(self.req_socket, zmq.POLLIN) self.req_socket.connect(self.req_socket_str) - if self.sub2 in r: - msg = Msg.decode_msg(self.sub2.recv()) + if self.sub_for_interrupt in r: + msg = Msg.decode_msg(self.sub_for_interrupt.recv()) if isinstance(msg, InterruptMsg): if msg.value == interrupt_name: - self.sub2.disconnect(f'tcp://127.0.0.1:{self.bp}') + self.sub_for_interrupt.disconnect(f'tcp://127.0.0.1:{self.bp}') return None logging.warning('timeout') - self.sub2.disconnect(f'tcp://127.0.0.1:{self.bp}') + self.sub_for_interrupt.disconnect(f'tcp://127.0.0.1:{self.bp}') return 'timeout' diff --git a/flandre/launcher.py b/flandre/launcher.py index b68d7ee..3215147 100644 --- a/flandre/launcher.py +++ b/flandre/launcher.py @@ -6,16 +6,20 @@ import shutil import subprocess import tomllib from enum import Enum, auto +from io import TextIOWrapper from pathlib import Path import click import platformdirs +import zmq +from zmq import Socket from flandre import C from flandre import P from flandre.BusClient import BusClient from flandre.kde_pyqt6_mainui import kde_pyqt6_mainui from flandre.nodes.Broker import Broker +from flandre.nodes.Device import Device, DeviceCmd from flandre.utils.Msg import KillMsg, NodeOnlineMsg, Msg1, Msg2 from flandre.utils.mi import MiSwitch @@ -171,5 +175,57 @@ def status(name): print(mi.is_on()) +device_req: Socket = None + +dd: Device = None + + +@entrypoint.group() +def device(): + global device_req + ctx = zmq.Context() + device_req = ctx.socket(zmq.REQ) + device_req.connect(C.live_rep_socket) + global dd + dd = Device() + dd.setup() + + +@device.command('connect') +def device_connect(): + dd.connect() + + +@device.command('disconnect') +def device_disconnect(): + dd.disconnect() + + +@device.command('enable') +def device_enable(): + dd.enable() + + +@device.command('disable') +def device_disable(): + dd.disable() + + +@device.command('upload') +@click.argument('name') +@click.argument('file', type=click.File('r')) +def device_upload(name, file: TextIOWrapper): + dd.set_name_and_file_only(name, file.read()) + +@device.command('recvtest') +def device_upload(): + ctx = zmq.Context() + pull = ctx.socket(zmq.PULL) + pull.connect(C.live_push_socket) + while True: + b = pull.recv() + print(b.__len__()) + + if __name__ == '__main__': entrypoint() diff --git a/flandre/nodes/Device.py b/flandre/nodes/Device.py index eb41979..d476c10 100644 --- a/flandre/nodes/Device.py +++ b/flandre/nodes/Device.py @@ -55,15 +55,16 @@ class Device(Node): self.online() time.sleep(1) - def d2b(self, cmd: DeviceCmd, v: bytes = b''): - return struct.pack('i', self.magic) + struct.pack('i', cmd.value) + v + @classmethod + def generate_cmd_bytes(cls, cmd: DeviceCmd, v: bytes = b''): + return struct.pack('i', cls.magic) + struct.pack('i', cmd.value) + v def device_cmd(self, cmd: DeviceCmd, v: bytes = b''): return self.c.req_interrupt( - self.d2b(cmd, v), + self.generate_cmd_bytes(cmd, v), interrupt_name='device123', retry_times=5, - cb_retry=lambda : logger.warning(f'retry {cmd}'), + cb_retry=lambda: logger.warning(f'retry {cmd}'), ) def connect(self):