qlsdk2 0.4.0a3__py3-none-any.whl → 0.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qlsdk/ar4/__init__.py +9 -5
- qlsdk/core/device.py +10 -1
- qlsdk/core/message/command.py +56 -35
- qlsdk/persist/edf.py +21 -2
- qlsdk/persist/rsc_edf.py +187 -128
- qlsdk/rsc/__init__.py +4 -2
- qlsdk/rsc/command/__init__.py +183 -61
- qlsdk/rsc/command/message.py +171 -74
- qlsdk/rsc/device/__init__.py +2 -0
- qlsdk/rsc/device/base.py +388 -0
- qlsdk/rsc/device/c64_rs.py +364 -0
- qlsdk/rsc/device/device_factory.py +29 -0
- qlsdk/rsc/entity.py +63 -24
- qlsdk/rsc/interface/__init__.py +3 -0
- qlsdk/rsc/interface/command.py +10 -0
- qlsdk/rsc/interface/device.py +107 -0
- qlsdk/rsc/interface/handler.py +9 -0
- qlsdk/rsc/interface/parser.py +9 -0
- qlsdk/rsc/manager/__init__.py +2 -0
- qlsdk/rsc/manager/container.py +121 -0
- qlsdk/rsc/manager/search.py +0 -0
- qlsdk/rsc/network/__init__.py +1 -0
- qlsdk/rsc/network/discover.py +87 -0
- qlsdk/rsc/paradigm.py +1 -1
- qlsdk/rsc/parser/__init__.py +1 -0
- qlsdk/rsc/parser/base.py +66 -0
- qlsdk/sdk/ar4sdk.py +13 -4
- qlsdk/x8/__init__.py +4 -0
- {qlsdk2-0.4.0a3.dist-info → qlsdk2-0.4.1.dist-info}/METADATA +1 -1
- qlsdk2-0.4.1.dist-info/RECORD +58 -0
- qlsdk2-0.4.0a3.dist-info/RECORD +0 -42
- {qlsdk2-0.4.0a3.dist-info → qlsdk2-0.4.1.dist-info}/WHEEL +0 -0
- {qlsdk2-0.4.0a3.dist-info → qlsdk2-0.4.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
import abc
|
|
3
|
+
|
|
4
|
+
class IDevice(ABC):
|
|
5
|
+
|
|
6
|
+
@property
|
|
7
|
+
@abc.abstractmethod
|
|
8
|
+
def device_type(self) -> int:
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
def set_device_type(self, value: int):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def device_no(self) -> str:
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
def set_device_no(self, value: str):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
def from_parent(cls, parent) :
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
def start_implementation(self) -> None:
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
def stop_implementation(self) -> None:
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
def start_acquisition(self) -> None:
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
def stop_acquisition(self) -> None:
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
def subscribe(self, type="signal") -> None:
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
def unsubscribe(self, topic) -> None:
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
def start_stimulation(self, type="signal", duration=0) -> None:
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
def stop_stimulation(self) -> None:
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
def __eq__(self, other):
|
|
49
|
+
return self.device_id == other.device_id
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class RscDevice(IDevice):
|
|
53
|
+
def __init__(self, socket):
|
|
54
|
+
super().__init__(socket)
|
|
55
|
+
|
|
56
|
+
def start_implementation(self):
|
|
57
|
+
"""
|
|
58
|
+
Start the device implementation
|
|
59
|
+
"""
|
|
60
|
+
raise NotImplementedError("This method should be overridden by subclasses")
|
|
61
|
+
|
|
62
|
+
def stop_implementation(self):
|
|
63
|
+
"""
|
|
64
|
+
Stop the device implementation
|
|
65
|
+
"""
|
|
66
|
+
raise NotImplementedError("This method should be overridden by subclasses")
|
|
67
|
+
|
|
68
|
+
def start_acquisition(self):
|
|
69
|
+
"""
|
|
70
|
+
Start data acquisition
|
|
71
|
+
"""
|
|
72
|
+
raise NotImplementedError("This method should be overridden by subclasses")
|
|
73
|
+
|
|
74
|
+
def stop_acquisition(self):
|
|
75
|
+
"""
|
|
76
|
+
Stop data acquisition
|
|
77
|
+
"""
|
|
78
|
+
raise NotImplementedError("This method should be overridden by subclasses")
|
|
79
|
+
|
|
80
|
+
def subscribe(self, type="signal"):
|
|
81
|
+
"""
|
|
82
|
+
Subscribe to data of a specific type (default is "signal")
|
|
83
|
+
"""
|
|
84
|
+
raise NotImplementedError("This method should be overridden by subclasses")
|
|
85
|
+
|
|
86
|
+
def unsubscribe(self, topic):
|
|
87
|
+
"""
|
|
88
|
+
Unsubscribe from a specific topic
|
|
89
|
+
"""
|
|
90
|
+
raise NotImplementedError("This method should be overridden by subclasses")
|
|
91
|
+
|
|
92
|
+
def start_stimulation(self, type="signal", duration=0):
|
|
93
|
+
"""
|
|
94
|
+
Start stimulation of a specific type (default is "signal") for a given duration
|
|
95
|
+
"""
|
|
96
|
+
raise NotImplementedError("This method should be overridden by subclasses")
|
|
97
|
+
|
|
98
|
+
def stop_stimulation(self):
|
|
99
|
+
"""
|
|
100
|
+
Stop stimulation
|
|
101
|
+
"""
|
|
102
|
+
raise NotImplementedError("This method should be overridden by subclasses")
|
|
103
|
+
|
|
104
|
+
class ProxyDevice(IDevice):
|
|
105
|
+
def __init__(self, socket, proxy_socket):
|
|
106
|
+
super().__init__(socket)
|
|
107
|
+
self.proxy_socket = proxy_socket
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from loguru import logger
|
|
4
|
+
from qlsdk.rsc.network.discover import UdpBroadcaster
|
|
5
|
+
from threading import Thread
|
|
6
|
+
from qlsdk.core import *
|
|
7
|
+
from qlsdk.rsc.device import QLBaseDevice, DeviceFactory
|
|
8
|
+
from qlsdk.rsc.interface import IDevice
|
|
9
|
+
from qlsdk.rsc.proxy import DeviceProxy
|
|
10
|
+
import time
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DeviceContainer(object):
|
|
14
|
+
def __init__(self, proxy_enabled=False, tcp_port = 19216):
|
|
15
|
+
self._devices = {}
|
|
16
|
+
self._tcp_port = tcp_port
|
|
17
|
+
self._proxy_enabled = proxy_enabled
|
|
18
|
+
|
|
19
|
+
# 设备搜索广播器
|
|
20
|
+
self._broadcaster = UdpBroadcaster()
|
|
21
|
+
self._broadcaster.start()
|
|
22
|
+
|
|
23
|
+
# 监听设备连接
|
|
24
|
+
self._listening_thread = Thread(target=self._listening)
|
|
25
|
+
self._listening_thread.daemon = True
|
|
26
|
+
self._listening_thread.start()
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def devices(self)-> IDevice:
|
|
30
|
+
return self._devices
|
|
31
|
+
|
|
32
|
+
'''
|
|
33
|
+
等待设备连接
|
|
34
|
+
'''
|
|
35
|
+
def connect(self, device_id: str, timeout:int=30) -> Optional[IDevice]:
|
|
36
|
+
logger.info(f"Searching for device: {device_id}")
|
|
37
|
+
self.add_search(device_id)
|
|
38
|
+
for _ in range(timeout):
|
|
39
|
+
device = self.get_device(device_id)
|
|
40
|
+
if device:
|
|
41
|
+
logger.success(f"Device {device_id} connected")
|
|
42
|
+
return device
|
|
43
|
+
time.sleep(1)
|
|
44
|
+
logger.error(f"Device {device_id} not found")
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
def _listening(self):
|
|
48
|
+
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
49
|
+
tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
50
|
+
try:
|
|
51
|
+
# 绑定到所有接口的19216端口
|
|
52
|
+
tcp_socket.bind(('0.0.0.0', self._tcp_port))
|
|
53
|
+
tcp_socket.listen(5)
|
|
54
|
+
logger.info(f"端口[{self._tcp_port}]监听服务已启动")
|
|
55
|
+
|
|
56
|
+
while True:
|
|
57
|
+
client_socket, addr = tcp_socket.accept()
|
|
58
|
+
logger.info(f"接收到来自 {addr[0]}:{addr[1]} 的连接")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# 为每个新连接创建线程处理
|
|
62
|
+
client_handler = Thread(
|
|
63
|
+
target=self.client_handler,
|
|
64
|
+
args=(client_socket,)
|
|
65
|
+
)
|
|
66
|
+
client_handler.daemon = True
|
|
67
|
+
client_handler.start()
|
|
68
|
+
|
|
69
|
+
except KeyboardInterrupt:
|
|
70
|
+
logger.error(f"端口[{self._tcp_port}]监听服务异常关闭")
|
|
71
|
+
finally:
|
|
72
|
+
logger.error(f"端口[{self._tcp_port}]监听服务关闭")
|
|
73
|
+
tcp_socket.close()
|
|
74
|
+
|
|
75
|
+
def client_handler(self, client_socket):
|
|
76
|
+
|
|
77
|
+
if self._proxy_enabled:
|
|
78
|
+
# 启动代理 TODO: 代理的同时支持接口控制和数据转发
|
|
79
|
+
proxy = DeviceProxy(client_socket)
|
|
80
|
+
proxy.start()
|
|
81
|
+
else:
|
|
82
|
+
# 数据监听
|
|
83
|
+
device = QLBaseDevice(client_socket)
|
|
84
|
+
# GET_DEVICE_INFO
|
|
85
|
+
msg = GetDeviceInfoCommand.build(device).pack()
|
|
86
|
+
logger.info(f"发送获取设备信息命令: {msg.hex()}")
|
|
87
|
+
device.send(msg)
|
|
88
|
+
# 添加设备
|
|
89
|
+
while True:
|
|
90
|
+
if device.device_name:
|
|
91
|
+
logger.info(f"设备 {device.device_name} 已连接")
|
|
92
|
+
real_device = DeviceFactory.create_device(device)
|
|
93
|
+
self.add_device(real_device)
|
|
94
|
+
break
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# 搜寻设备
|
|
98
|
+
def add_search(self, device_id):
|
|
99
|
+
self._broadcaster.add_device(device_id)
|
|
100
|
+
|
|
101
|
+
def add_device(self, device: IDevice):
|
|
102
|
+
if device is None or device.device_no is None:
|
|
103
|
+
logger.warning("无效的设备")
|
|
104
|
+
|
|
105
|
+
self._devices.update({device.device_no: device})
|
|
106
|
+
logger.debug(f"add_device {device.device_no} then has devices {self._devices}")
|
|
107
|
+
|
|
108
|
+
self._broadcaster.remove_device(device.device_no)
|
|
109
|
+
logger.debug(f"add_device {device.device_no} then has broadcaster {self._broadcaster}")
|
|
110
|
+
|
|
111
|
+
def get_device(self, device_id=None)->IDevice:
|
|
112
|
+
logger.trace(f"已连接设备数量:{len(self._devices)}")
|
|
113
|
+
if len(self._devices) == 0:
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
# 未指定device_id,返回第一个设备
|
|
117
|
+
if device_id is None:
|
|
118
|
+
return list(self._devices.values())[0]
|
|
119
|
+
|
|
120
|
+
return self._devices.get(device_id)
|
|
121
|
+
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .discover import *
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import time
|
|
3
|
+
from threading import Thread, Lock
|
|
4
|
+
from loguru import logger
|
|
5
|
+
|
|
6
|
+
from qlsdk.core.message import UDPMessage
|
|
7
|
+
|
|
8
|
+
class UdpBroadcaster:
|
|
9
|
+
# 广播端口需要和ar4sdk做区分, 使用54366时不能和x8同时使用
|
|
10
|
+
def __init__(self, port=54366):
|
|
11
|
+
self.broadcast_port = port
|
|
12
|
+
self.devices_to_broadcast = [] # 待广播的设备序列号列表
|
|
13
|
+
self.connected_devices = set() # 已连接的设备序列号集合
|
|
14
|
+
self.lock = Lock() # 用于线程安全的锁
|
|
15
|
+
self.running = True
|
|
16
|
+
|
|
17
|
+
# 创建UDP socket
|
|
18
|
+
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
19
|
+
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
|
20
|
+
|
|
21
|
+
def add_device(self, device_id):
|
|
22
|
+
"""添加设备序列号到待广播列表"""
|
|
23
|
+
with self.lock:
|
|
24
|
+
if device_id not in self.devices_to_broadcast:
|
|
25
|
+
self.devices_to_broadcast.append(device_id)
|
|
26
|
+
logger.info(f"Added device {device_id} to broadcast list.")
|
|
27
|
+
|
|
28
|
+
def remove_device(self, device_id):
|
|
29
|
+
"""从待广播列表中移除设备序列号"""
|
|
30
|
+
with self.lock:
|
|
31
|
+
if device_id in self.devices_to_broadcast:
|
|
32
|
+
self.devices_to_broadcast.remove(device_id)
|
|
33
|
+
logger.info(f"Removed device {device_id} from broadcast list.")
|
|
34
|
+
|
|
35
|
+
def mark_device_as_connected(self, device_id):
|
|
36
|
+
"""将设备标记为已连接,并从未广播列表中移除"""
|
|
37
|
+
with self.lock:
|
|
38
|
+
if device_id in self.devices_to_broadcast:
|
|
39
|
+
self.devices_to_broadcast.remove(device_id)
|
|
40
|
+
self.connected_devices.add(device_id)
|
|
41
|
+
logger.info(f"Device {device_id} is now connected.")
|
|
42
|
+
|
|
43
|
+
def broadcast_devices(self):
|
|
44
|
+
"""轮询发送广播"""
|
|
45
|
+
while self.running:
|
|
46
|
+
with self.lock:
|
|
47
|
+
for device_id in self.devices_to_broadcast:
|
|
48
|
+
message = UDPMessage.search(device_id)
|
|
49
|
+
self.sock.sendto(message, ('<broadcast>', self.broadcast_port))
|
|
50
|
+
logger.info(f"Broadcasting device ID: {device_id}")
|
|
51
|
+
time.sleep(1) # 每隔1秒发送一次广播
|
|
52
|
+
|
|
53
|
+
def start(self):
|
|
54
|
+
"""启动广播线程"""
|
|
55
|
+
self.broadcast_thread = Thread(target=self.broadcast_devices)
|
|
56
|
+
self.broadcast_thread.setDaemon(True)
|
|
57
|
+
self.broadcast_thread.start()
|
|
58
|
+
|
|
59
|
+
def stop(self):
|
|
60
|
+
"""停止广播"""
|
|
61
|
+
self.running = False
|
|
62
|
+
self.broadcast_thread.join()
|
|
63
|
+
self.sock.close()
|
|
64
|
+
|
|
65
|
+
# 示例使用
|
|
66
|
+
if __name__ == "__main__":
|
|
67
|
+
broadcaster = UdpBroadcaster()
|
|
68
|
+
|
|
69
|
+
# 添加设备序列号到待广播列表
|
|
70
|
+
broadcaster.add_device_to_broadcast("390024130032")
|
|
71
|
+
|
|
72
|
+
# 启动广播
|
|
73
|
+
broadcaster.start()
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
# 模拟运行一段时间
|
|
77
|
+
time.sleep(10)
|
|
78
|
+
|
|
79
|
+
# 标记设备为已连接
|
|
80
|
+
broadcaster.mark_device_as_connected("390024130032")
|
|
81
|
+
|
|
82
|
+
# 继续运行一段时间
|
|
83
|
+
time.sleep(10)
|
|
84
|
+
|
|
85
|
+
finally:
|
|
86
|
+
# 停止广播
|
|
87
|
+
broadcaster.stop()
|
qlsdk/rsc/paradigm.py
CHANGED
|
@@ -195,7 +195,7 @@ class PulseStimulation(StimulationChannel):
|
|
|
195
195
|
delay_time: float, 延迟启动时间,单位为秒(暂未启用)
|
|
196
196
|
'''
|
|
197
197
|
def __init__(self, channel_id: int, current: float, duration: float, frequency: float, pulse_width: int,
|
|
198
|
-
pulse_width_ratio: float = 1, pulse_interval = 0, ramp_up: float = 0, ramp_down: float = 0, delay_time = 0):
|
|
198
|
+
pulse_width_ratio: float = 1, pulse_interval: int = 0, ramp_up: float = 0, ramp_down: float = 0, delay_time = 0):
|
|
199
199
|
super().__init__(channel_id, WaveForm.PULSE.value, current, duration, ramp_up, ramp_down)
|
|
200
200
|
self.frequency = frequency
|
|
201
201
|
self.delay_time = delay_time
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .base import TcpMessageParser
|
qlsdk/rsc/parser/base.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from qlsdk.rsc.interface import IDevice, IParser
|
|
2
|
+
|
|
3
|
+
from loguru import logger
|
|
4
|
+
from threading import Thread
|
|
5
|
+
from time import time_ns
|
|
6
|
+
from qlsdk.rsc.command import CommandFactory
|
|
7
|
+
|
|
8
|
+
class TcpMessageParser(IParser):
|
|
9
|
+
def __init__(self, device : IDevice):
|
|
10
|
+
# 待解析的数据来源于该设备
|
|
11
|
+
self.device = device
|
|
12
|
+
self.running = False
|
|
13
|
+
|
|
14
|
+
self.cache = b''
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def header(self):
|
|
18
|
+
return b'\x5A\xA5'
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def header_len(self):
|
|
22
|
+
return 14
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def cmd_pos(self):
|
|
26
|
+
return 12
|
|
27
|
+
|
|
28
|
+
def append(self, buffer):
|
|
29
|
+
self.cache += buffer
|
|
30
|
+
logger.debug(f"已缓存的数据长度: {len(self.cache)}")
|
|
31
|
+
|
|
32
|
+
def __parser__(self):
|
|
33
|
+
logger.info("数据解析开始")
|
|
34
|
+
while self.running:
|
|
35
|
+
if len(self.cache) < 14:
|
|
36
|
+
continue
|
|
37
|
+
if self.cache[0] != 0x5A or self.cache[1] != 0xA5:
|
|
38
|
+
self.cache = self.cache[1:]
|
|
39
|
+
continue
|
|
40
|
+
pkg_len = int.from_bytes(self.cache[8:12], 'little')
|
|
41
|
+
logger.trace(f" cache len: {len(self.cache)}, pkg_len len: {len(self.cache)}")
|
|
42
|
+
# 一次取整包数据
|
|
43
|
+
if len(self.cache) < pkg_len:
|
|
44
|
+
continue
|
|
45
|
+
pkg = self.cache[:pkg_len]
|
|
46
|
+
self.cache = self.cache[pkg_len:]
|
|
47
|
+
self.unpack(pkg)
|
|
48
|
+
|
|
49
|
+
def unpack(self, packet):
|
|
50
|
+
# 提取指令码
|
|
51
|
+
cmd_code = int.from_bytes(packet[self.cmd_pos : self.cmd_pos + 2], 'little')
|
|
52
|
+
cmd_class = CommandFactory.create_command(cmd_code)
|
|
53
|
+
logger.debug(f"收到指令:{cmd_class.cmd_desc}[{hex(cmd_code)}]")
|
|
54
|
+
instance = cmd_class(self.device)
|
|
55
|
+
start = time_ns()
|
|
56
|
+
logger.debug(f"开始解析: {start}")
|
|
57
|
+
instance.parse_body(packet[self.header_len:-2])
|
|
58
|
+
logger.debug(f"解析完成:{time_ns()}, 解析耗时:{time_ns() - start}ns")
|
|
59
|
+
return instance
|
|
60
|
+
|
|
61
|
+
def start(self):
|
|
62
|
+
self.running = True
|
|
63
|
+
parser = Thread(target=self.__parser__,)
|
|
64
|
+
parser.daemon = True
|
|
65
|
+
parser.start()
|
|
66
|
+
|
qlsdk/sdk/ar4sdk.py
CHANGED
|
@@ -584,9 +584,16 @@ class LMDevice(object):
|
|
|
584
584
|
|
|
585
585
|
def start_record(self):
|
|
586
586
|
pass
|
|
587
|
+
|
|
587
588
|
def stop_record(self):
|
|
588
589
|
pass
|
|
590
|
+
|
|
591
|
+
def trigger(self, trigger_type: int):
|
|
592
|
+
pass
|
|
589
593
|
|
|
594
|
+
def set_storage_path(self, storage_path):
|
|
595
|
+
pass
|
|
596
|
+
|
|
590
597
|
def disconnect(self):
|
|
591
598
|
"""断开连接"""
|
|
592
599
|
if self._handle:
|
|
@@ -623,12 +630,14 @@ class LMDevice(object):
|
|
|
623
630
|
|
|
624
631
|
def eeg_accept(self, packet: LMPacket):
|
|
625
632
|
pass
|
|
626
|
-
|
|
633
|
+
|
|
634
|
+
def eeg2phy(self, digital:int):
|
|
627
635
|
# 向量化计算(自动支持广播)
|
|
628
|
-
return ((
|
|
636
|
+
return ((digital - self._eeg_dig_min) / self._eeg_dig_range) * self._eeg_phy_range + self._eeg_phy_min
|
|
637
|
+
|
|
638
|
+
def acc2phy(self, digital:int):
|
|
639
|
+
return ((digital - self._acc_dig_min) / self._acc_dig_range) * self._acc_phy_range + self._acc_phy_min
|
|
629
640
|
|
|
630
|
-
def acc2phy(self, digtal):
|
|
631
|
-
return ((digtal - self._acc_dig_min) / self._acc_dig_range) * self._acc_phy_range + self._acc_phy_min
|
|
632
641
|
def _wrap_trigger_accept(self):
|
|
633
642
|
|
|
634
643
|
@FuncAr4DataNotify
|
qlsdk/x8/__init__.py
CHANGED
|
@@ -75,6 +75,10 @@ class X8(LMDevice):
|
|
|
75
75
|
self._recording = False
|
|
76
76
|
logger.info(f"停止记录数据: {self.box_mac}")
|
|
77
77
|
|
|
78
|
+
def trigger(self, desc):
|
|
79
|
+
if self._edf_handler:
|
|
80
|
+
self._edf_handler.trigger(desc)
|
|
81
|
+
|
|
78
82
|
# 订阅推送消息
|
|
79
83
|
def subscribe(self, topic: str = None, q: Queue = Queue(), value_type: Literal['phy', 'dig'] = 'phy') -> tuple[str, Queue]:
|
|
80
84
|
if topic is None:
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
qlsdk/__init__.py,sha256=mjjFQ8LEHgwMmud5ie2Tgl2aOafnz53gkcAju0q7T0c,446
|
|
2
|
+
qlsdk/ar4/__init__.py,sha256=103jCUHcDrOpxYKhK2tIlyvbTkoLsW_IU0LBrHhM6A0,4888
|
|
3
|
+
qlsdk/ar4m/__init__.py,sha256=Z13X53WKmKp6MW_fA1FUPdQgJxhxxuyzemJWPS_CEHA,639
|
|
4
|
+
qlsdk/core/__init__.py,sha256=WMjvdiSD3BWAsebktWJU3dt71wOML44xe_EAZ5WJZQY,159
|
|
5
|
+
qlsdk/core/device.py,sha256=p0XQ2otFaFnJW7ZQ9VtHeVF1EQGB73cKjWDkORZHesM,798
|
|
6
|
+
qlsdk/core/exception.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
qlsdk/core/local.py,sha256=vbison4XZtS4SNYLJ9CqBhetEcukdviTWmvtdA1efkQ,811
|
|
8
|
+
qlsdk/core/utils.py,sha256=Dcpor6CGjkIhaZbUzVGFQMdCY54PDJ_etdZ68WD1q8g,4071
|
|
9
|
+
qlsdk/core/crc/__init__.py,sha256=kaYSr6KN5g4U49xlxAvT2lnEeGtwX4Dz1ArwKDvUIIY,143
|
|
10
|
+
qlsdk/core/crc/crctools.py,sha256=sDeE6CMccQX2cRAyMQK0SZUk1fa50XMuwqXau5UX5C8,4242
|
|
11
|
+
qlsdk/core/entity/__init__.py,sha256=THJpYIO-rDfK_UMU6qgraIKft7KfRZ_1dcBQliLT6AM,3291
|
|
12
|
+
qlsdk/core/filter/__init__.py,sha256=YIWIzDUKN30mq2JTr53ZGblggZfC_rLUp2FSRrsQFgU,36
|
|
13
|
+
qlsdk/core/filter/norch.py,sha256=5RdIBX5eqs5w5nmVAnCB3ESSuAT_vVBZ2g-dg6HMZdY,1858
|
|
14
|
+
qlsdk/core/message/__init__.py,sha256=sHuavOyHf4bhH6VdDpTA1EsCh7Q-XsPHcFiItpVz3Rs,51
|
|
15
|
+
qlsdk/core/message/command.py,sha256=94AyM6qmgVHQ8qzNLczdL8iY6N-2uEP5oBU6kD6pOG8,12102
|
|
16
|
+
qlsdk/core/message/tcp.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
qlsdk/core/message/udp.py,sha256=KS_pKZcCEFhNGABCOZTOHiVFkfPNZl_0K5RXppwMIvA,3085
|
|
18
|
+
qlsdk/core/network/__init__.py,sha256=9Ww0cGgBEU_TVrwmgiDz20zA2fMFgepI_kOF4ggHcS0,1111
|
|
19
|
+
qlsdk/core/network/monitor.py,sha256=QqjjPwSr1kgqDTTySp5bpalZmsBQTaAWSxrfPLdROZo,1810
|
|
20
|
+
qlsdk/persist/__init__.py,sha256=OR8mnPTsktxw67G-z0VsPWJXInkKircMTHQdibmmz3M,63
|
|
21
|
+
qlsdk/persist/edf.py,sha256=ETngb86CfkIUJYWmw86QR445MvTFC7Edk_CH9nyNgtY,7857
|
|
22
|
+
qlsdk/persist/rsc_edf.py,sha256=s1zQBml8o0vdOrzMRrApxelWscmYpbisXanB4z-gvcQ,11675
|
|
23
|
+
qlsdk/rsc/__init__.py,sha256=hOMiN0eYn4jYo7O4_0IPlQT0hD15SqqCQUihOVlTZvs,269
|
|
24
|
+
qlsdk/rsc/device_manager.py,sha256=1ucd-lzHkNeQPKPzXV6OBkAMqPp_vOcsLyS-9TJ7wRc,4448
|
|
25
|
+
qlsdk/rsc/discover.py,sha256=ONXN6YWY-OMU0sBoLqqKUyb-8drtAp1g_MvnpzaFvHQ,3124
|
|
26
|
+
qlsdk/rsc/eegion.py,sha256=lxrktO-3Z_MYdFIwc4NxvgLM5AL5kU3UItjH6tsKmHY,11670
|
|
27
|
+
qlsdk/rsc/entity.py,sha256=-fRWFkVWp9d8Y1uh6GiacXC5scdeEKNiNFf3aziGdCE,17751
|
|
28
|
+
qlsdk/rsc/paradigm.py,sha256=DGfwY36sMdPIMRjbGo661GvUTEwsRRi3jrmG405mSTk,12840
|
|
29
|
+
qlsdk/rsc/proxy.py,sha256=9CPdGNGWremwBUh4GvlXAykYB-x_BEPPLqsNvwuwIDE,2736
|
|
30
|
+
qlsdk/rsc/command/__init__.py,sha256=j_yAg61dgyP3FHR21bVSpObiwPYf23MVGzj_0Mbyx6c,12248
|
|
31
|
+
qlsdk/rsc/command/message.py,sha256=nTdG-Vp4MBnltyrgedAWiKD6kzOaPrg58Z_hq6yjhys,12220
|
|
32
|
+
qlsdk/rsc/device/__init__.py,sha256=5tNSYmpl_jfaHZcOMyB2IcO-tzL-Pj5f3V8CRC8uLHc,73
|
|
33
|
+
qlsdk/rsc/device/base.py,sha256=c9jhDH89BNPWVSitPmtLdMRN5dCZUyQjH3jAKYNxMLo,14823
|
|
34
|
+
qlsdk/rsc/device/c64_rs.py,sha256=iZDXMjYHOPmlrx3gkxEx18dihXqj81DfkUmtniHljck,13920
|
|
35
|
+
qlsdk/rsc/device/device_factory.py,sha256=h4kfSLngu10ME60JOHjkxWbCVMEqBdPRo4_3g2yZZbw,1137
|
|
36
|
+
qlsdk/rsc/interface/__init__.py,sha256=xeRzIlQSB7ZSf4r5kLfH5cDQLzCyWeJAReG8Xq5nOE0,70
|
|
37
|
+
qlsdk/rsc/interface/command.py,sha256=1s5Lxb_ejsd-JNvKMqU2aFSnOoW-_cx01VSD3czxmQI,199
|
|
38
|
+
qlsdk/rsc/interface/device.py,sha256=mn3YvOgpymWvfBr8Lqj0WZm74DIhWi9A7v1P27erC-0,2940
|
|
39
|
+
qlsdk/rsc/interface/handler.py,sha256=ADDe_a2RAxGMuooLyivH0JBPTGBcFP2JaTVX41R1A4w,198
|
|
40
|
+
qlsdk/rsc/interface/parser.py,sha256=uNl0E-T4TIq2iHFjV1oeRDUKN4GX0q2GXUxzrio1240,196
|
|
41
|
+
qlsdk/rsc/manager/__init__.py,sha256=4ljT3mR8YPBDQur46B5xPqK5tjLKlsWfgCJVuA0gs-8,40
|
|
42
|
+
qlsdk/rsc/manager/container.py,sha256=Bx7W0p3oCEjxVOjHgW42wsWHeRt-O9gs7-Bq4PiTQ-M,4582
|
|
43
|
+
qlsdk/rsc/manager/search.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
|
+
qlsdk/rsc/network/__init__.py,sha256=PfYiqXS2pZV__uegQ1TjaeYhY1pefZ_shwE_X5HNVbs,23
|
|
45
|
+
qlsdk/rsc/network/discover.py,sha256=ONXN6YWY-OMU0sBoLqqKUyb-8drtAp1g_MvnpzaFvHQ,3124
|
|
46
|
+
qlsdk/rsc/parser/__init__.py,sha256=8RgwbKCINu3eTsxVLF9cMoBXJnVrDocOEFP6NGP_atk,34
|
|
47
|
+
qlsdk/rsc/parser/base.py,sha256=6t0StSsx87s7bQq_av9a7ieROZ0LEDhtUHixKoiwcto,2209
|
|
48
|
+
qlsdk/sdk/__init__.py,sha256=v9LKP-5qXCqnAsCkiRE9LDb5Tagvl_Qd_fqrw7y9yd4,68
|
|
49
|
+
qlsdk/sdk/ar4sdk.py,sha256=tugH3UUeNebdka78AzLyrtAXbYQQE3iFJ227zUit6tY,27261
|
|
50
|
+
qlsdk/sdk/hub.py,sha256=uEOGZBZtMDCWlV8G2TZe6FAo6eTPcwHAW8zdqr1eq_0,1571
|
|
51
|
+
qlsdk/sdk/libs/libAr4SDK.dll,sha256=kZp9_DRwPdAJ5OgTFQSqS8tEETxUs7YmmETuBP2g60U,15402132
|
|
52
|
+
qlsdk/sdk/libs/libwinpthread-1.dll,sha256=W77ySaDQDi0yxpnQu-ifcU6-uHKzmQpcvsyx2J9j5eg,52224
|
|
53
|
+
qlsdk/x8/__init__.py,sha256=FDpDK7GAYL-g3vzfU9U_V03QzoYoxH9YLm93PjMlANg,4870
|
|
54
|
+
qlsdk/x8m/__init__.py,sha256=cLeUqEEj65qXw4Qa4REyxoLh6T24anSqPaKe9_lR340,634
|
|
55
|
+
qlsdk2-0.4.1.dist-info/METADATA,sha256=yrxJIVqc4nl2o1iAa0DPaHnQKFtMuOC_1MK6uq8bR7E,7063
|
|
56
|
+
qlsdk2-0.4.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
57
|
+
qlsdk2-0.4.1.dist-info/top_level.txt,sha256=2CHzn0SY-NIBVyBl07Suh-Eo8oBAQfyNPtqQ_aDatBg,6
|
|
58
|
+
qlsdk2-0.4.1.dist-info/RECORD,,
|
qlsdk2-0.4.0a3.dist-info/RECORD
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
qlsdk/__init__.py,sha256=mjjFQ8LEHgwMmud5ie2Tgl2aOafnz53gkcAju0q7T0c,446
|
|
2
|
-
qlsdk/ar4/__init__.py,sha256=iR0bFanDwqSxSEM1nCcge1l-GSIWjwnMeRQa47wGrds,4752
|
|
3
|
-
qlsdk/ar4m/__init__.py,sha256=Z13X53WKmKp6MW_fA1FUPdQgJxhxxuyzemJWPS_CEHA,639
|
|
4
|
-
qlsdk/core/__init__.py,sha256=WMjvdiSD3BWAsebktWJU3dt71wOML44xe_EAZ5WJZQY,159
|
|
5
|
-
qlsdk/core/device.py,sha256=dPoQUwd78-Ieef6ZcBI7isVm0W8aYarqBy6UHP7Yjoc,587
|
|
6
|
-
qlsdk/core/exception.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
qlsdk/core/local.py,sha256=vbison4XZtS4SNYLJ9CqBhetEcukdviTWmvtdA1efkQ,811
|
|
8
|
-
qlsdk/core/utils.py,sha256=Dcpor6CGjkIhaZbUzVGFQMdCY54PDJ_etdZ68WD1q8g,4071
|
|
9
|
-
qlsdk/core/crc/__init__.py,sha256=kaYSr6KN5g4U49xlxAvT2lnEeGtwX4Dz1ArwKDvUIIY,143
|
|
10
|
-
qlsdk/core/crc/crctools.py,sha256=sDeE6CMccQX2cRAyMQK0SZUk1fa50XMuwqXau5UX5C8,4242
|
|
11
|
-
qlsdk/core/entity/__init__.py,sha256=THJpYIO-rDfK_UMU6qgraIKft7KfRZ_1dcBQliLT6AM,3291
|
|
12
|
-
qlsdk/core/filter/__init__.py,sha256=YIWIzDUKN30mq2JTr53ZGblggZfC_rLUp2FSRrsQFgU,36
|
|
13
|
-
qlsdk/core/filter/norch.py,sha256=5RdIBX5eqs5w5nmVAnCB3ESSuAT_vVBZ2g-dg6HMZdY,1858
|
|
14
|
-
qlsdk/core/message/__init__.py,sha256=sHuavOyHf4bhH6VdDpTA1EsCh7Q-XsPHcFiItpVz3Rs,51
|
|
15
|
-
qlsdk/core/message/command.py,sha256=47FKxW9-h-ws6933_EPeShsAxg45CKDuUaWOE8FoGz0,11547
|
|
16
|
-
qlsdk/core/message/tcp.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
qlsdk/core/message/udp.py,sha256=KS_pKZcCEFhNGABCOZTOHiVFkfPNZl_0K5RXppwMIvA,3085
|
|
18
|
-
qlsdk/core/network/__init__.py,sha256=9Ww0cGgBEU_TVrwmgiDz20zA2fMFgepI_kOF4ggHcS0,1111
|
|
19
|
-
qlsdk/core/network/monitor.py,sha256=QqjjPwSr1kgqDTTySp5bpalZmsBQTaAWSxrfPLdROZo,1810
|
|
20
|
-
qlsdk/persist/__init__.py,sha256=OR8mnPTsktxw67G-z0VsPWJXInkKircMTHQdibmmz3M,63
|
|
21
|
-
qlsdk/persist/edf.py,sha256=usgFjZJVcfAUwSy6cJtRdgjdqMgOS4viLCDGcwAGMZE,7106
|
|
22
|
-
qlsdk/persist/rsc_edf.py,sha256=zr0hXtOwt7_mm4DanZf9QsYPx5raSppYcHQcNfcZ1Io,9249
|
|
23
|
-
qlsdk/rsc/__init__.py,sha256=bR678DilIIK7tFP65tscPUI7Bp4VN0ndVQWt6bnQKGg,197
|
|
24
|
-
qlsdk/rsc/device_manager.py,sha256=1ucd-lzHkNeQPKPzXV6OBkAMqPp_vOcsLyS-9TJ7wRc,4448
|
|
25
|
-
qlsdk/rsc/discover.py,sha256=ONXN6YWY-OMU0sBoLqqKUyb-8drtAp1g_MvnpzaFvHQ,3124
|
|
26
|
-
qlsdk/rsc/eegion.py,sha256=lxrktO-3Z_MYdFIwc4NxvgLM5AL5kU3UItjH6tsKmHY,11670
|
|
27
|
-
qlsdk/rsc/entity.py,sha256=bOBS1sqnpAiBfK6yFGkGE5ZMqI1rUbygi3MuRldz4s4,16260
|
|
28
|
-
qlsdk/rsc/paradigm.py,sha256=qwBkTRglEGMeLYBhE7AQmZoxXfHiDyATqBARF4IjPA8,12835
|
|
29
|
-
qlsdk/rsc/proxy.py,sha256=9CPdGNGWremwBUh4GvlXAykYB-x_BEPPLqsNvwuwIDE,2736
|
|
30
|
-
qlsdk/rsc/command/__init__.py,sha256=D5pBE2leqFG-IPU2pDAGuLsqHmc0wRPrBOXR0-K8d6k,8117
|
|
31
|
-
qlsdk/rsc/command/message.py,sha256=bcuUDJj0CMekcZMNhKrzIpkHtDC-QBCs3dJG6Bx_PHc,8723
|
|
32
|
-
qlsdk/sdk/__init__.py,sha256=v9LKP-5qXCqnAsCkiRE9LDb5Tagvl_Qd_fqrw7y9yd4,68
|
|
33
|
-
qlsdk/sdk/ar4sdk.py,sha256=ZILuUVgUZN7-LNQm4xdItxmZWGwvFt4oWUKGez1BCLI,27101
|
|
34
|
-
qlsdk/sdk/hub.py,sha256=uEOGZBZtMDCWlV8G2TZe6FAo6eTPcwHAW8zdqr1eq_0,1571
|
|
35
|
-
qlsdk/sdk/libs/libAr4SDK.dll,sha256=kZp9_DRwPdAJ5OgTFQSqS8tEETxUs7YmmETuBP2g60U,15402132
|
|
36
|
-
qlsdk/sdk/libs/libwinpthread-1.dll,sha256=W77ySaDQDi0yxpnQu-ifcU6-uHKzmQpcvsyx2J9j5eg,52224
|
|
37
|
-
qlsdk/x8/__init__.py,sha256=XlQn3Af_HA7bGrxhv3RZKWMob_SnmissXiso7OH1UgI,4750
|
|
38
|
-
qlsdk/x8m/__init__.py,sha256=cLeUqEEj65qXw4Qa4REyxoLh6T24anSqPaKe9_lR340,634
|
|
39
|
-
qlsdk2-0.4.0a3.dist-info/METADATA,sha256=TRYBQylaQUXnbe55xziq5gvKKbeRRlIP_-gJftcGg0U,7065
|
|
40
|
-
qlsdk2-0.4.0a3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
41
|
-
qlsdk2-0.4.0a3.dist-info/top_level.txt,sha256=2CHzn0SY-NIBVyBl07Suh-Eo8oBAQfyNPtqQ_aDatBg,6
|
|
42
|
-
qlsdk2-0.4.0a3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|