Compare commits

...

32 Commits

Author SHA1 Message Date
Roy bbde653a8e [update] update cali value 2022-09-28 14:50:22 +08:00
Roy 6c0cef7925 [update] test function: print mem board info 2022-09-27 14:38:00 +08:00
Roy 3bbf0c912a [update] test function: print mem board info 2022-09-27 13:41:32 +08:00
Roy 4333958ebe [update] fix eis's FREQ default value 2022-09-16 17:49:28 +08:00
Roy 3239a691e3 [update] test function: print ram info 2022-09-16 13:12:40 +08:00
Roy 30183788d8 [update] test function: print ram info 2022-09-14 18:12:53 +08:00
Roy 13df921b1c [update] test function: print ram info 2022-09-14 17:14:47 +08:00
Roy d182a04ed3 [update] add channel data 2022-09-14 15:36:01 +08:00
Roy 35a09ff9a0 [update] switch mode set default highz & time_duration in Elite_EDC 2022-09-06 18:51:32 +08:00
Roy e134b9780c [update] add new api set_project & add new condition until_button_trigger & add new action idle 2022-09-06 16:28:38 +08:00
peterlu14 df39f241b3 [update] add battery 2022-08-22 19:57:02 +08:00
peterlu14 0b72ac0c9d Merge branch 'dev/scheduler_cycle' into release/v1.6.6/merge_scheduler 2022-08-22 17:42:57 +08:00
JayC319 0afbe66229 [update] edc 1.5 library 2022-08-22 13:58:39 +08:00
108000207 9846cfd708 [update] set _time_interval as 0.1 to avoid delay 2022-08-19 15:44:51 +08:00
108000207 b4ad2a7fba [update] remove useless comments 2022-08-18 17:51:51 +08:00
108000207 675fdc2226 [update] cycle_next use uuid version 2022-08-18 17:39:59 +08:00
108000207 a847b1222d [debug] fix the bug of first task can't idle 2022-08-17 15:51:29 +08:00
108000207 bd0c36923a [update] scheduler cycle version 1 2022-08-17 11:50:22 +08:00
peterlu14 612785f51a [update] EIS show data 2022-08-16 19:40:27 +08:00
peterlu14 7dbf09e9a5 [update] EIS show data 2022-08-16 19:39:06 +08:00
peterlu14 ee64d43de1 [update] ca instruction b0 -> D3 2022-08-16 19:31:33 +08:00
peterlu14 60b91f0c1e [update] EIS add show data 2022-08-16 19:15:04 +08:00
Roy 8ac01bdf54 [update] update eis library 2022-08-16 19:10:18 +08:00
JayC319 0f90b16b6e [update] library product number 2022-08-16 17:35:06 +08:00
peterlu14 cd98a14e84 [debug] fix idle send instruction & remove deepcopy & close task by device 2022-08-16 14:25:37 +08:00
peterlu14 2e97ad23eb [debug] fix parameter empty 2022-08-16 12:11:35 +08:00
108000207 e0dd5a6972 [update] add schdeuler cycle attribute 2022-08-16 11:34:47 +08:00
Roy 76e0a150d1 Merge remote-tracking branch 'origin/dev/Cali_mode' into dev/cc_cp_separate 2022-08-15 18:11:20 +08:00
JayC319 ecd4b9325d [update] 2022-08-15 18:09:40 +08:00
peterlu14 978b1254f0 Merge branch 'dev/debug' into dev/cc_cp_separate 2022-08-11 13:53:13 +08:00
peterlu14 26e02f2d40 [update] add data_show function print device data 2022-08-11 00:58:30 +08:00
Roy 257958768f [update] new ca mode instruvtion 2022-08-05 18:34:33 +08:00
23 changed files with 730 additions and 128 deletions
+6
View File
@@ -1585,6 +1585,12 @@ class ControlAPI(metaclass=Router):
def stop_project(self, project) -> bool: def stop_project(self, project) -> bool:
raise NotImplementedError() raise NotImplementedError()
def set_project(self, project, content) -> bool:
raise NotImplementedError()
def show_device_data(self, device) -> bool:
raise NotImplementedError()
# noinspection PyAbstractClass # noinspection PyAbstractClass
class ControlClient(SocketClient, ControlAPI, metaclass=SocketClientMacro(ControlAPI)): class ControlClient(SocketClient, ControlAPI, metaclass=SocketClientMacro(ControlAPI)):
+11
View File
@@ -130,6 +130,14 @@ class DataAPI(metaclass=abc.ABCMeta):
def hardware_test(self) -> JSON_OBJECT: def hardware_test(self) -> JSON_OBJECT:
"""""" """"""
pass pass
@abc.abstractmethod
def show_data(self, device: Union[int, Device]):
"""show device data
:param device: device ID
"""
pass
# noinspection PyAbstractClass # noinspection PyAbstractClass
@@ -191,6 +199,9 @@ class DataClient(SocketClient, DataAPI, metaclass=SocketClientMacro(DataAPI)):
def stop_sync(self, *device: Union[int, Device]): def stop_sync(self, *device: Union[int, Device]):
self.send_command('stop_sync', *self._to_device_id(*device)) self.send_command('stop_sync', *self._to_device_id(*device))
def show_data(self, device: int):
self.send_command('show_data', device)
@staticmethod @staticmethod
def _to_device_id(*device: Union[int, Device]) -> Tuple[int, ...]: def _to_device_id(*device: Union[int, Device]) -> Tuple[int, ...]:
+1 -1
View File
@@ -662,7 +662,7 @@ class CC2650Device(Device):
elif device_type == 'EISZeroOne': elif device_type == 'EISZeroOne':
i = 0 i = 0
request_times = 0 request_times = 0
while i < 7: while i < 13:
try: try:
# send # send
code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, i) code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, i)
+131 -58
View File
@@ -1,6 +1,7 @@
import abc import abc
import struct import struct
import math import math
import numpy
from typing import Optional, TypeVar, Generic, Tuple, Dict, List, AnyStr from typing import Optional, TypeVar, Generic, Tuple, Dict, List, AnyStr
from datetime import datetime from datetime import datetime
@@ -853,7 +854,7 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
__slots__ = ('_message', '_cycle_number', '_start_return_data', '_time_stamp', __slots__ = ('_message', '_cycle_number', '_start_return_data', '_time_stamp',
'_total_time_stamp', '_mode', '_cycle_start_time', '_total_time_stamp', '_mode', '_cycle_start_time',
'_mode_stop') '_mode_stop', '_show_data')
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@@ -868,6 +869,8 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
self._mode = 0 self._mode = 0
self._cycle_start_time = [] self._cycle_start_time = []
self._show_data = False
@property @property
def name(self) -> str: def name(self) -> str:
return self.NAME return self.NAME
@@ -892,6 +895,10 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
finish_mode_falg = data[22] finish_mode_falg = data[22]
battery = struct.unpack('<i', data[23:27])[0] battery = struct.unpack('<i', data[23:27])[0]
elite_notify_times = data[27] elite_notify_times = data[27]
notify_one = struct.unpack('<i', data[28:32])[0]
notify_two = struct.unpack('<i', data[32:36])[0]
notify_three = struct.unpack('<i', data[36:40])[0]
# self._show_data = True
mem_wrong_information = struct.unpack('<i', data[43:47])[0] # mem_wrong_information = green retry, green wrong, red retry, red wrong mem_wrong_information = struct.unpack('<i', data[43:47])[0] # mem_wrong_information = green retry, green wrong, red retry, red wrong
ram_num = data[47] ram_num = data[47]
@@ -915,9 +922,11 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
print("error timeStamp full data:", list(data), datetime.now(), '\n') print("error timeStamp full data:", list(data), datetime.now(), '\n')
return None return None
else: else:
# print('|', time_stamp, '|', delta, '|', int(time_stamp * 1000 / 2), if self._show_data:
# '|', current, '|', voltage, '|', impedance, print('|', time_stamp, '|', delta, '|', int(time_stamp * 1000 / 2),
# '|', cycle_number, '|', finishMode, '@', str(self.device)) '|', current, '|', voltage, '|', impedance, '|', cycle_number,
'|', notify_one, '|', notify_two, '|', notify_three,
'|', finishMode, '@', str(self.device))
# print('|', '{:10}'.format(time_stamp), # print('|', '{:10}'.format(time_stamp),
# '|', '{:4}'.format(delta), # '|', '{:4}'.format(delta),
@@ -946,6 +955,9 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
ret.append_data(1, voltage) ret.append_data(1, voltage)
ret.append_data(2, impedance) ret.append_data(2, impedance)
ret.append_data(3, cycle_number) ret.append_data(3, cycle_number)
ret.append_data(4, notify_one)
ret.append_data(5, notify_two)
ret.append_data(6, notify_three)
# ret.append_data(4, battery) # ret.append_data(4, battery)
# ret.append_data(5, elite_notify_times) # ret.append_data(5, elite_notify_times)
# ret.append_data(6, mem_cnt) # ret.append_data(6, mem_cnt)
@@ -1335,7 +1347,7 @@ class EISZeroOneDataDecoder(RecDataDecoder):
'_total_time_stamp', '_mode', '_cycle_start_time', '_total_time_stamp', '_mode', '_cycle_start_time',
'_mode_stop', '_last_time_stamp', '_last_delta', '_cali_coeff', '_mode_stop', '_last_time_stamp', '_last_delta', '_cali_coeff',
'cali_coeff', '_ac_amp', '_mode', '_freq_start', '_freq_stop', 'cali_coeff', '_ac_amp', '_mode', '_freq_start', '_freq_stop',
'_freq_direction', '_last_phase', '_first_phase_flag') '_freq_direction', '_last_phase', '_first_phase_flag', '_show_data')
def __init__(self, cali_coeff: bytes = None): def __init__(self, cali_coeff: bytes = None):
super().__init__() super().__init__()
@@ -1359,6 +1371,8 @@ class EISZeroOneDataDecoder(RecDataDecoder):
self._cali_coeff: Optional[bytes] = None self._cali_coeff: Optional[bytes] = None
self.cali_coeff: Optional[List[Tuple[int, int]]] = None self.cali_coeff: Optional[List[Tuple[int, int]]] = None
self._show_data = False
if cali_coeff is not None: if cali_coeff is not None:
self._cali_coeff = cali_coeff self._cali_coeff = cali_coeff
self.cali_coeff = self._decode_cali_coeff(cali_coeff) self.cali_coeff = self._decode_cali_coeff(cali_coeff)
@@ -1367,12 +1381,27 @@ class EISZeroOneDataDecoder(RecDataDecoder):
def _decode_cali_coeff(cali_coeff: bytes) -> Optional[List[Tuple[int, int]]]: def _decode_cali_coeff(cali_coeff: bytes) -> Optional[List[Tuple[int, int]]]:
if cali_coeff != b'': if cali_coeff != b'':
cali_table = [] cali_table = []
phase_para_a = []
phase_para_b = []
hsrtia_a = [] hsrtia_a = []
hsrtia_b = [] hsrtia_b = []
hsrtia_c = [] hsrtia_c = []
hsrtia_d = [] hsrtia_d = []
phase_coeff = []
phase_offset = []
# phase_coeff = [[0]*4 for i in range(4)]
# phase_offset = [[0]*4 for i in range(4)]
phase_coeff = numpy.zeros([4, 4], dtype = int)
phase_offset = numpy.zeros([4, 4], dtype = int)
########################################
# phase_coeff
# [[gain0, g1, g2, g3] ----->最高頻
# [gain0, g1, g2, g3] ----->中頻
# [gain0, g1, g2, g3] ----->低頻
# [gain0, g1, g2, g3] ----->最低頻
# ]
#######################################
# print('cali_coeff', cali_coeff) # print('cali_coeff', cali_coeff)
cutoff_freq = struct.unpack('>I', cali_coeff[1:5])[0] * 100 #4 cutoff_freq = struct.unpack('>I', cali_coeff[1:5])[0] * 100 #4
@@ -1383,15 +1412,19 @@ class EISZeroOneDataDecoder(RecDataDecoder):
# hsrtia_160k = struct.unpack('>I', cali_coeff[8:12])[0] #4 # hsrtia_160k = struct.unpack('>I', cali_coeff[8:12])[0] #4
index = 20 index = 20
for i in range(index, index+16, 8): g = 0
phase_para_a.append(struct.unpack('>i', cali_coeff[i+1:i+5])[0]) phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_para_b.append(struct.unpack('>i', cali_coeff[i+5:i+9])[0]) phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 40 index = 40
for i in range(index, index+16, 8): g = 0
phase_para_a.append(struct.unpack('>i', cali_coeff[i+1:i+5])[0]) phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_para_b.append(struct.unpack('>i', cali_coeff[i+5:i+9])[0]) phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
#Lv[0] 160k #Lv[0] 160k
index = 60 index = 60
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8) hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8)
@@ -1416,18 +1449,58 @@ class EISZeroOneDataDecoder(RecDataDecoder):
hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8) hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8)
hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]/1e4) hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]/1e4)
# hsrtia_a.append(struct.unpack('>I', cali_coeff[index+1:index+5])[0]) index = 140
# hsrtia_b.append(struct.unpack('>I', cali_coeff[index+5:index+9])[0]/1e6) g = 1
# hsrtia_c.append(struct.unpack('>I', cali_coeff[index+9:index+13])[0]/1e5) phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 160
g = 1
phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 180
g = 2
phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 200
g = 2
phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 220
g = 3
phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 240
g = 3
phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
# print('cutoff_freq', cutoff_freq) # print('cutoff_freq', cutoff_freq)
# print('hsrtia_a', hsrtia_a) # print('hsrtia_a', hsrtia_a)
# print('hsrtia_b', hsrtia_b) # print('hsrtia_b', hsrtia_b)
# print('hsrtia_c', hsrtia_c) # print('hsrtia_c', hsrtia_c)
# print('phase_para_a', phase_para_a) # print('phase_coeff')
# print('phase_para_b', phase_para_b) # print(phase_coeff)
# print('phase_offset')
# print(phase_offset)
cali_table.append((cutoff_freq, phase_para_a, phase_para_b, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d)) cali_table.append((cutoff_freq, phase_coeff, phase_offset, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d))
return cali_table return cali_table
else: else:
@@ -1477,13 +1550,12 @@ class EISZeroOneDataDecoder(RecDataDecoder):
return None return None
else: else:
if self.cali_coeff is not None and self._mode == 0: if self.cali_coeff is not None and self._mode == 0:
phase_para_a = []
phase_para_b = []
hsrtia_a = [] hsrtia_a = []
hsrtia_b = [] hsrtia_b = []
hsrtia_c = [] hsrtia_c = []
hsrtia_d = [] hsrtia_d = []
cutoff_freq, phase_para_a, phase_para_b, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d = self.cali_coeff[0] cutoff_freq, phase_coeff, phase_offset, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d = self.cali_coeff[0]
voltage_amp = round(self._ac_amp * 800 / 2047) # use UI value voltage_amp = round(self._ac_amp * 800 / 2047) # use UI value
if (self._freq_start > self._freq_stop): if (self._freq_start > self._freq_stop):
self._freq_direction = 0 self._freq_direction = 0
@@ -1494,6 +1566,7 @@ class EISZeroOneDataDecoder(RecDataDecoder):
img = ch1 img = ch1
real = ch2 real = ch2
freq = ch3 freq = ch3
fre_idx = 0
voltage_mag = math.sqrt(img ** 2 + real ** 2) * (1 + freq ** 2 / cutoff_freq ** 2) voltage_mag = math.sqrt(img ** 2 + real ** 2) * (1 + freq ** 2 / cutoff_freq ** 2)
@@ -1521,56 +1594,56 @@ class EISZeroOneDataDecoder(RecDataDecoder):
raw_phase = math.atan(img / real) * 180 / math.pi + 180 raw_phase = math.atan(img / real) * 180 / math.pi + 180
if (freq >= 1000000): # 10000 Hz if (freq >= 1000000): # 10000 Hz
i = 0 fre_idx = 0
elif (freq >= 10000): # 100 Hz elif (freq >= 10000): # 100 Hz
i = 1 fre_idx = 1
elif (freq >= 1000): # 10 Hz elif (freq >= 1000): # 10 Hz
i = 2 fre_idx = 2
elif (freq >= 1): # 0.01 Hz elif (freq >= 1): # 0.01 Hz
i = 3 fre_idx = 3
ideal_raw_phase = phase_para_a[i] /1e10 * freq + phase_para_b[i] / 1e6 ideal_raw_phase = phase_coeff[fre_idx][gain] /1e10 * freq + phase_offset[fre_idx][gain] / 1e6
phase = raw_phase - ideal_raw_phase phase = raw_phase - ideal_raw_phase
if (self._first_phase_flag): if (self._first_phase_flag):
self._last_phase = phase self._last_phase = phase
self._first_phase_flag = 0 self._first_phase_flag = 0
elif (abs(phase - self._last_phase) >= 200): elif (abs(phase - self._last_phase) >= 90):
phase -= 360 phase -= 360
self._last_phase = phase self._last_phase = phase
imag_after_cal = impedance * math.sin(round(phase) * math.pi / 180) imag_after_cal = impedance * math.sin(round(phase) * math.pi / 180)
real_after_cal = impedance * math.cos(round(phase) * math.pi / 180) real_after_cal = impedance * math.cos(round(phase) * math.pi / 180)
if self._show_data:
if (self._mode == 0): if (self._mode == 0):
# print('|', '{:10}'.format(time_stamp), print('|', '{:10}'.format(time_stamp),
# '|', '{:5}'.format(delta), '|', '{:5}'.format(delta),
# '|', '{:6}'.format(ch1), '|', '{:6}'.format(ch1),
# '|', '{:6}'.format(ch2), '|', '{:6}'.format(ch2),
# '|', '{:8}'.format(ch3 / 100), '|', '{:8}'.format(ch3 / 100),
# '|', '{:6}'.format(round(voltage_mag)), '|', '{:6}'.format(round(voltage_mag)),
# '|', '{:5}'.format(int(imag_after_cal)), '|', '{:5}'.format(int(imag_after_cal)),
# '|', '{:5}'.format(int(real_after_cal)), '|', '{:5}'.format(int(real_after_cal)),
# '|', '{:5}'.format(round(impedance)), '|', '{:5}'.format(round(impedance)),
# '|', '{:5}'.format(round(phase, 1)), '|', '{:5}'.format(round(phase, 1)),
# '|', '{:5}'.format(round(current, 3)), '|', '{:5}'.format(round(current, 3)),
# '|', '{:1}'.format(gain), '|', '{:1}'.format(gain),
# '|', '{:1}'.format(finishMode), '|', '{:1}'.format(finishMode),
# '@', str(self.device), '|') '@', str(self.device), '|')
pass pass
else: else:
# print('|', '{:10}'.format(time_stamp), print('|', '{:10}'.format(time_stamp),
# '|', '{:5}'.format(delta), '|', '{:5}'.format(delta),
# '|', '{:5}'.format(ch1), '|', '{:5}'.format(ch1),
# '|', '{:5}'.format(ch2), '|', '{:5}'.format(ch2),
# '|', '{:5}'.format(ch3), '|', '{:5}'.format(ch3),
# '|', '{:5}'.format(cycle_number), '|', '{:5}'.format(cycle_number),
# '|', '{:1}'.format(gain), '|', '{:1}'.format(gain),
# '|', '{:1}'.format(finishMode), '|', '{:1}'.format(finishMode),
# '@', str(self.device), '|') '@', str(self.device), '|')
pass pass
if finishMode == True: if finishMode == True:
print("finishMode full data:", list(data), datetime.now()) print("finishMode full data:", list(data), datetime.now())
+7
View File
@@ -1105,6 +1105,8 @@ class CompletedDevice(Device):
return self._configuration.get_parameter(name, False) return self._configuration.get_parameter(name, False)
def set_multi_parameters(self, parameter): def set_multi_parameters(self, parameter):
if len(parameter) == 0:
return
for (name, value) in parameter[0].items(): for (name, value) in parameter[0].items():
if name != 'target': if name != 'target':
self.set_parameter(name, value) self.set_parameter(name, value)
@@ -1128,6 +1130,11 @@ class CompletedDevice(Device):
self._parameter.set_parameter(name, value) self._parameter.set_parameter(name, value)
# raise RuntimeError('illegal parameter value : ' + value) from e # raise RuntimeError('illegal parameter value : ' + value) from e
else: else:
if name == 'MODE':
if self.library_name.startswith('Elite_EDC'):
self.set_parameter('CTRL_HIGH_Z_15', self.get_parameter('HIGHZ_TABLE')[value])
self.set_parameter('TIME_DURATION', 0)
self._parameter.set_parameter(name, value) self._parameter.set_parameter(name, value)
on_change = info.on_change on_change = info.on_change
+21 -7
View File
@@ -35,7 +35,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
'_pin_ram_sel_value', '_pin_mem_sel_value', '_pin_mem_req_value', '_pin_ram_sel_value', '_pin_mem_sel_value', '_pin_mem_req_value',
'_read_green_times','_read_red_times', '_read_green_times','_read_red_times',
'_elite_data_len', '_mem_header_len', '_mem_tailer_len', '_single_data_len', '_elite_data_len', '_mem_header_len', '_mem_tailer_len', '_single_data_len',
'_head_wrong_cnt') '_head_wrong_cnt', '_pin_busy_value')
def __init__(self, def __init__(self,
select: Selector, select: Selector,
@@ -50,11 +50,11 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
self._single_data_len = self._elite_data_len + self._mem_header_len + self._mem_tailer_len self._single_data_len = self._elite_data_len + self._mem_header_len + self._mem_tailer_len
# buffer # buffer
self._tx_buffer_header = [0] * 19 self._tx_buffer_header = [0] * 64
self._tx_buffer_data = [0] * (self._single_data_len * 10 + 3) self._tx_buffer_data = [0] * (self._single_data_len * 10 + 3)
# memory control pin # memory control pin
self.pin_busy = OutputPin.get_used(P3Pin.MEM_BZY, True) self.pin_busy: Optional[InputPin] = InputPin.get_used(P3Pin.MEM_BZY)
self.pin_mem_req = OutputPin.get_used(P3Pin.MEM_REQ, False) self.pin_mem_req = OutputPin.get_used(P3Pin.MEM_REQ, False)
self.pin_mem_sel = OutputPin.get_used(P3Pin.MEM_RST, True) # MEM_RST -> actually which memory board is assign self.pin_mem_sel = OutputPin.get_used(P3Pin.MEM_RST, True) # MEM_RST -> actually which memory board is assign
self.pin_ram_sel: Optional[InputPin] = InputPin.get_used(P3Pin.MEM_SEL) # MEM_SEL -> actually is RAM_SEL, which RAM is assign self.pin_ram_sel: Optional[InputPin] = InputPin.get_used(P3Pin.MEM_SEL) # MEM_SEL -> actually is RAM_SEL, which RAM is assign
@@ -62,6 +62,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
self._pin_ram_sel_value = [bool(self.pin_ram_sel) for _ in range(Selector.SIZE)] self._pin_ram_sel_value = [bool(self.pin_ram_sel) for _ in range(Selector.SIZE)]
self._pin_mem_sel_value = [bool(self.pin_mem_sel) for _ in range(Selector.SIZE)] self._pin_mem_sel_value = [bool(self.pin_mem_sel) for _ in range(Selector.SIZE)]
self._pin_mem_req_value = [bool(self.pin_mem_req) for _ in range(Selector.SIZE)] self._pin_mem_req_value = [bool(self.pin_mem_req) for _ in range(Selector.SIZE)]
self._pin_busy_value = [bool(self.pin_busy) for _ in range(Selector.SIZE)]
self._read_green_times = 0 self._read_green_times = 0
self._read_red_times = 0 self._read_red_times = 0
@@ -98,6 +99,14 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
self._pin_ram_sel_value[channel] = True self._pin_ram_sel_value[channel] = True
return self._pin_ram_sel_value[channel] return self._pin_ram_sel_value[channel]
def get_pin_busy(self):
channel = self.select
if self.pin_busy.input() == 0:
self._pin_busy_value[channel] = False
else:
self._pin_busy_value[channel] = True
return self._pin_busy_value[channel]
@property @property
def select(self) -> int: def select(self) -> int:
return self._selector.channel return self._selector.channel
@@ -216,7 +225,9 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
return return
def recv_memory(self, device: int) -> Optional[bytes]: def recv_memory(self, device: int) -> Optional[bytes]:
self.pin_busy.output(False) # self.pin_busy.output(False)
print('mem_req==ram_sel,[', self._pin_mem_req_value[device], ',', self._pin_ram_sel_value[device], ']')
rx = [] rx = []
@@ -300,6 +311,9 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
print("green data print:", data, device, datetime.now()) print("green data print:", data, device, datetime.now())
return None return None
# print('data=', list(data))
print('Ram:', data[62])
if (length >= 4000): if (length >= 4000):
flag_print = True flag_print = True
print("green data: big length:", length) print("green data: big length:", length)
@@ -415,9 +429,9 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
except BaseException as e: except BaseException as e:
print(e) print(e)
finally: # finally:
# print("\n") # # print("\n")
self.pin_busy.output(True) # self.pin_busy.output(True)
return bytes(rx) return bytes(rx)
+8
View File
@@ -24,3 +24,11 @@ class Action():
@property @property
def condition(self): def condition(self):
return self._condition return self._condition
def as_json(self):
return {
'id': self._id,
'type': self._type,
'target': self._target,
'condition': self._condition
}
+48 -8
View File
@@ -56,7 +56,8 @@ class Condition():
return getattr(self, self.type)(**kwargs) return getattr(self, self.type)(**kwargs)
def absolute_time(self, **kwargs): def absolute_time(self, **kwargs):
now = int(time()) # now = int(time())
now = round(time(), 1)
time_condition = round(self.datetime_to_timestamp(self.str_to_datetime(self._value))) time_condition = round(self.datetime_to_timestamp(self.str_to_datetime(self._value)))
return self.compareWith(self.comparsion, now, time_condition) return self.compareWith(self.comparsion, now, time_condition)
@@ -65,8 +66,9 @@ class Condition():
project_start_time = kwargs['project_start_time'] project_start_time = kwargs['project_start_time']
delay_time = kwargs['delay_time'] delay_time = kwargs['delay_time']
time_diff = int(time() - project_start_time - delay_time) # time_diff = int(time() - project_start_time - delay_time)
return self.compareWith(self.comparsion, time_diff, int(self._value)) time_diff = round(time() - project_start_time - delay_time, 1)
return self.compareWith(self.comparsion, time_diff, round(int(self._value), 1))
def after_task_run(self, **kwargs): def after_task_run(self, **kwargs):
# print('relative_time_from_task', kwargs,kwargs['task_start_time'],kwargs['delay_time']) # print('relative_time_from_task', kwargs,kwargs['task_start_time'],kwargs['delay_time'])
@@ -75,22 +77,60 @@ class Condition():
task_start_time = kwargs['task_start_time'][-1] task_start_time = kwargs['task_start_time'][-1]
delay_time = kwargs['delay_time'] delay_time = kwargs['delay_time']
time_diff = int(time() - task_start_time - delay_time) time_diff = round(time() - task_start_time - delay_time, 1)
# print('time_diff', time_diff) return self.compareWith(self.comparsion, time_diff, round(int(self._value), 1))
return self.compareWith(self.comparsion, time_diff, int(self._value))
def device(self, **kwargs): def device(self, **kwargs):
print('device') print('device')
def previous_task_done(self, **kwargs): """ def previous_task_done(self, **kwargs):
running_task = kwargs['running_task'] running_task = kwargs['running_task']
if running_task.status == 2 and self._active == False: if running_task.status == 2 and self._active == False:
self._active = True self._active = True
return True return True
return False """
def previous_task_done(self, **kwargs):
running_task = kwargs['running_task']
self_task = kwargs['self_task']
# if running_task != None and self_task != None:
# print('\nprevious_task_done: ', running_task.status, ' ', self._active)
if running_task != self_task:
if running_task == None:
return True
if running_task.status == 2 and self._active == False:
# self._active = True
return True
return False return False
def until_button_trigger(self, **kwargs):
running_task = kwargs['running_task']
if running_task != None:
if running_task.button_trigger == True:
running_task.button_trigger = False
return True
return False
""" def cycle(self, **kwargs):
running_task = kwargs['running_task']
self_task = kwargs['self_task']
if running_task != self_task:
if running_task.status == 2 and self._active == False:
# self._active = True
return True
return False """
def str_to_datetime(self, time_str): def str_to_datetime(self, time_str):
return datetime.strptime(time_str,'%Y-%m-%dT%H:%M') return datetime.strptime(time_str,'%Y-%m-%dT%H:%M')
def datetime_to_timestamp(self, date): def datetime_to_timestamp(self, date):
return datetime.timestamp(date) return datetime.timestamp(date)
def as_json(self):
return {
'id': self._id,
'type': self._type,
'comparsion': self._comparsion,
'value': self._value,
'active': self._active
}
+6 -1
View File
@@ -22,6 +22,7 @@ class Instruction():
self._start_instruction = list(map(lambda ins: self._instruction_set[ins] ,['set_file_name', 'set_parent', 'set_parameter', 'call_instruction'])) self._start_instruction = list(map(lambda ins: self._instruction_set[ins] ,['set_file_name', 'set_parent', 'set_parameter', 'call_instruction']))
self._stop_instruction = list(map(lambda ins: self._instruction_set[ins] ,['call_instruction'])) self._stop_instruction = list(map(lambda ins: self._instruction_set[ins] ,['call_instruction']))
self._idle_instruction = []
@property @property
def start(self) -> list: def start(self) -> list:
@@ -29,4 +30,8 @@ class Instruction():
@property @property
def stop(self) -> list: def stop(self) -> list:
return self._stop_instruction return self._stop_instruction
@property
def idle(self) -> list:
return self.idle_instruction
+43 -8
View File
@@ -24,7 +24,7 @@ class Project(threading.Thread):
self._project = project self._project = project
self._device_manager = device_manager self._device_manager = device_manager
self._mqtt_thread = mqttThread self._mqtt_thread = mqttThread
self._time_interval = 1 self._time_interval = 0.1
self._start_time = None self._start_time = None
self._end_time = None self._end_time = None
@@ -117,6 +117,10 @@ class Project(threading.Thread):
def mqtt_thread(self): def mqtt_thread(self):
return self._mqtt_thread return self._mqtt_thread
@property
def running_task(self):
return self._task_manager.running_task
def run(self): def run(self):
self._status = 1 self._status = 1
self._start_time = time() self._start_time = time()
@@ -139,23 +143,42 @@ class Project(threading.Thread):
project_start_time = self._start_time, project_start_time = self._start_time,
delay_time = delay_time, delay_time = delay_time,
running_task= self._task_manager.running_task, running_task= self._task_manager.running_task,
previous_task = self._task_manager.prev_task previous_task = self._task_manager.prev_task,
self_task = task
) )
# print('match_condition_list', match_condition_list) # print('match_condition_list', match_condition_list)
for condition in match_condition_list: for condition in match_condition_list:
# print('\ncondition.type: ', condition.type)
match_action_list = task.get_match_action(condition.id) match_action_list = task.get_match_action(condition.id)
# print('match_action_list', match_action_list)
for action in match_action_list: for action in match_action_list:
# print('match_action', action.type, action.target) # print('action type', action.type)
# print('match_action_list len: ', len(match_action_list))
if action.type == 'start' and task.status != 1: if action.type == 'start' and task.status != 1:
self._task_manager.set_running_task(task) self._task_manager.set_running_task(task)
# Trace
self.mqtt_thread.broadcast_command('project:task ' + task.name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]) self.mqtt_thread.broadcast_command('project:task ' + task.name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
elif action.type == 'cycle' and task.status != 1:
# TODO: directly goto next without swich cycle as running task
""" if task._cycle_count < task._cycle - 1:
task._cycle_count += 1
cycle_target = self._task_manager.task_list[task._cycle_next - 1] # TODO: not sure deep or shallow
cycle_target.reset()
task = cycle_target """
self._task_manager.set_running_task(task)
elif action.type == 'stop' and len(self._task_manager.running_task.parameter_set) == 0:
self.mqtt_thread.broadcast_command('project:task ' + str(self._task_manager.running_task.name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
self._task_manager.running_task.stop()
elif action.type == 'idle':
self._task_manager.running_task.stop()
device = self._complete_device[action.target] device = self._complete_device[action.target]
task_info = task.get_task_info(action) task_info = task.get_task_info(action)
instruction_set = getattr(self._instruction_set, action.type, None) instruction_set = getattr(self._instruction_set, action.type, None)
# print('instruction_set',instruction_set) # print('instruction_set', instruction_set, '\n', action.type)
# if instruction_set != None and task.cycle == -1:
if instruction_set != None: if instruction_set != None and len(task.parameter_set) > 0:
for instruction in instruction_set: for instruction in instruction_set:
args = list(map(lambda arg: task_info[arg], instruction['arguments'])) args = list(map(lambda arg: task_info[arg], instruction['arguments']))
threading.Thread(target=getattr(device, instruction['method'])(*args)) threading.Thread(target=getattr(device, instruction['method'])(*args))
@@ -164,8 +187,10 @@ class Project(threading.Thread):
# check task not running then stop # check task not running then stop
if self.check_running_task_not_run() == True: if self.check_running_task_not_run() == True:
self.mqtt_thread.broadcast_command('project:task ' + str(self._task_manager.running_task.name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]) if self._task_manager.running_task.cycle == -1:
self.mqtt_thread.broadcast_command('project:task ' + str(self._task_manager.running_task.name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
self._task_manager.running_task.stop() self._task_manager.running_task.stop()
# self._task_manager.set_running_task(task)
# check project done then close project # check project done then close project
if self.check_project_done() == True: if self.check_project_done() == True:
@@ -200,11 +225,21 @@ class Project(threading.Thread):
return False return False
return True return True
def set_content(self, content):
self.running_task.button_trigger = True
def check_running_task_not_run(self): def check_running_task_not_run(self):
# if no running task # if no running task
if self._task_manager.running_task == None: if self._task_manager.running_task == None:
return False return False
for key in self._task_manager.running_task.action:
# print('action key', key, self._task_manager.running_task, self._task_manager.running_task.action[key])
if len(self._task_manager.running_task.parameter_set) == 0 and self._task_manager.running_task.action[key]['type'] == 'stop':
return False
if len(self._task_manager.running_task.parameter_set) == 0 and self._task_manager.running_task.action[key]['type'] == 'idle':
return False
for device in self._task_manager.running_task.device: for device in self._task_manager.running_task.device:
if self._complete_device[device].status == 1: if self._complete_device[device].status == 1:
return False return False
+4
View File
@@ -37,3 +37,7 @@ class ProjectManager():
def stop_project(self, project): def stop_project(self, project):
_project = self.get(project) _project = self.get(project)
_project.stop() _project.stop()
def set_project(self, project_uuid, content):
_project = self.get(project_uuid)
_project.set_content(content)
+49 -1
View File
@@ -15,26 +15,34 @@ class Task:
self._name = None self._name = None
self._parent = None self._parent = None
self._cycle = None self._cycle = None
self._cycle_count = 0
self._cycle_next = None
self._cycle_next_uuid = None
self._device = None self._device = None
self._event = None self._event = None
self._trigger = None self._trigger = None
self._parameter_set = None self._parameter_set = None
self._condition = None self._condition = None
self._action = None self._action = None
# -1: initial 0: start(idle), 1: running, 2: close(idle) # -1: init 0: start(idle), 1: run, 2: close(idle)
self._status = 0 self._status = 0
self._next = None self._next = None
# action & condition info
self._condition_list: List[Condition] = [] self._condition_list: List[Condition] = []
self._action_list: List[Action] = [] self._action_list: List[Action] = []
self._instruction_list = [] self._instruction_list = []
self._record_list = [] self._record_list = []
# time info
self._start_time = [] self._start_time = []
self._idle_time = [] self._idle_time = []
self._end_time = [] self._end_time = []
self._period = None self._period = None
# trigger info
self._button_trigger = False
self.load_task(task) self.load_task(task)
def load_task(self, task) -> None: def load_task(self, task) -> None:
@@ -100,6 +108,31 @@ class Task:
@cycle.setter @cycle.setter
def cycle(self, new_cycle): def cycle(self, new_cycle):
self._cycle = new_cycle self._cycle = new_cycle
# TODO: not sure needed?
@property
def cycle_count(self) -> int:
return self._cycle_count
@cycle_count.setter
def cycle_count(self, new_cycle_count):
self._cycle_count = new_cycle_count
@property
def cycle_next(self) -> str:
return self._cycle_next
@cycle_next.setter
def cycle_next(self, new_cycle_next):
self._cycle_next = new_cycle_next
@property
def cycle_next_uuid(self) -> str:
return self._cycle_next_uuid
@cycle_next_uuid.setter
def cycle_next_uuid(self, new_cycle_next_uuid):
self._cycle_next_uuid = new_cycle_next_uuid
@property @property
def device(self) -> dict: def device(self) -> dict:
@@ -177,6 +210,14 @@ class Task:
def end_time(self) -> List: def end_time(self) -> List:
return self._end_time return self._end_time
@property
def button_trigger(self) -> List:
return self._button_trigger
@button_trigger.setter
def button_trigger(self, button_trigger):
self._button_trigger = button_trigger
def new_start_time(self): def new_start_time(self):
self._start_time.append(time()) self._start_time.append(time())
@@ -207,6 +248,10 @@ class Task:
def stop(self): def stop(self):
self.status = 2 self.status = 2
def reset(self):
self.status = -1
# self.status = 0
def get_match_action_list(self, match_condition_list): def get_match_action_list(self, match_condition_list):
return map(lambda condition: [x for x in self._action_list if condition.id in x.get_condition_list()], match_condition_list) return map(lambda condition: [x for x in self._action_list if condition.id in x.get_condition_list()], match_condition_list)
@@ -241,6 +286,9 @@ class Task:
'name': self.name, 'name': self.name,
'parent': self.parent, 'parent': self.parent,
'cycle': self.cycle, 'cycle': self.cycle,
'cycle_count': self.cycle_count,
'cycle_next': self.cycle_next,
'cycle_next_uuid': self.cycle_next_uuid,
'device': self.device, 'device': self.device,
'event': self.event, 'event': self.event,
'trigger': self.trigger, 'trigger': self.trigger,
+40 -1
View File
@@ -57,7 +57,8 @@ class TaskManager():
task = Task(task) task = Task(task)
self._task_list.append(task) self._task_list.append(task)
def set_running_task(self, task): # original version
""" def set_running_task(self, task):
try: try:
# if there is task running & same task active ,then reject # if there is task running & same task active ,then reject
if self._running_task != None and self._running_task.uuid == task.uuid: if self._running_task != None and self._running_task.uuid == task.uuid:
@@ -80,6 +81,44 @@ class TaskManager():
_task = next((task for task in self._task_list if task.uuid == task_uuid), None) _task = next((task for task in self._task_list if task.uuid == task_uuid), None)
if _task != None: if _task != None:
self._next_task.append(_task) self._next_task.append(_task)
except RuntimeError as e:
print(e) """
def set_running_task(self, task):
try:
# if there is task running & same task active ,then reject
if self._running_task != None and self._running_task.uuid == task.uuid:
# print('set_running_task return false: ', self._running_task.name)
return False
# save running task
self._prev_task = self._running_task
# clear next task list
self._next_task.clear()
self._running_task = task
self._running_task.run()
if self._prev_task != None:
# if previous task is still running, then need to close
if self._prev_task.status == 1:
self._prev_task.stop()
print('prev', 'run', self._prev_task.name, self._running_task.name)
# print(f'!!@#!set_running_task\n\n\n{task._cycle_count}\n{task._cycle}\n\n\n')
if task._cycle_count < task._cycle - 1:
task._cycle_count += 1
# use uuid to get the cycle next task
cycle_target = [_task_next for _task_next in self._task_list if _task_next.uuid == task._cycle_next_uuid]
# cycle_target = self._task_list[task._cycle_next - 1] # original use index version
cycle_target[0].reset()
self._next_task.append(cycle_target[0])
else:
task._cycle_count = 0
for task_uuid in self._running_task.next:
_task = next((task for task in self._task_list if task.uuid == task_uuid), None)
if _task != None:
_task.reset()
self._next_task.append(_task)
except RuntimeError as e: except RuntimeError as e:
print(e) print(e)
+8
View File
@@ -646,6 +646,7 @@ class DataServer(SocketServer, DataAPI):
def whether_to_record(self, device): def whether_to_record(self, device):
# if user click "start", return True; if user click "stop", return False; # if user click "start", return True; if user click "stop", return False;
if device in self._configurations.keys() and self._configurations[device] is not None: if device in self._configurations.keys() and self._configurations[device] is not None:
# print(self._configurations.keys(), ',', device, datetime.now())
return True return True
else: else:
return False return False
@@ -654,6 +655,9 @@ class DataServer(SocketServer, DataAPI):
ret = False ret = False
sync = self.get_spi_obj() sync = self.get_spi_obj()
busy = sync.get_pin_busy()
print('pin_busy=', busy, device, datetime.now())
if sync.get_pin_mem_req() == sync.get_pin_ram_sel(): if sync.get_pin_mem_req() == sync.get_pin_ram_sel():
spi_data = sync.recv_memory(device) spi_data = sync.recv_memory(device)
signal = sync.get_pin_mem_req() signal = sync.get_pin_mem_req()
@@ -662,6 +666,7 @@ class DataServer(SocketServer, DataAPI):
else: else:
data = None data = None
print('data=None, mem_req!=ram_sel, [', sync.get_pin_mem_req(), ', ', sync.get_pin_ram_sel(), ']', device, datetime.now())
if data is not None: if data is not None:
if self._configurations[device].queue_flag: if self._configurations[device].queue_flag:
@@ -699,6 +704,9 @@ class DataServer(SocketServer, DataAPI):
self.mqtt_thread.publish('device_instruction', json_stringify(content), inter = True) self.mqtt_thread.publish('device_instruction', json_stringify(content), inter = True)
return True return True
def show_data(self, device):
self._configurations[device].put_rec_queue('show_data')
class DataRuntime(metaclass=abc.ABCMeta): class DataRuntime(metaclass=abc.ABCMeta):
__slots__ = ('_server', '_device', '_meta_file', '_data_format', __slots__ = ('_server', '_device', '_meta_file', '_data_format',
+26 -6
View File
@@ -819,12 +819,18 @@ class ControlServer(SocketServer, ControlServerAPI):
return True return True
@logging_info @logging_info
def device_battery(self) -> List[int]: def device_battery(self, device:int) -> List[int]:
device_list = self.device_manager.list_device() battery = {}
if len(device_list) > 0: if device == 'all':
battery_list = list(map(lambda x: self.device_manager.get_device(x).battery, device_list)) device_list = self.device_manager.list_device()
if len(device_list) > 0:
return battery_list battery = list(map(lambda x: {"device": x.memory_board, "battery":self.device_manager.get_device(x).battery}, device_list))
else:
battery = {
"device": device,
"battery": self.device_manager.get_device(device).battery
}
return battery
@logging_info @logging_info
def device_parent(self, device: int, content: Optional[str] = None) -> List[int]: def device_parent(self, device: int, content: Optional[str] = None) -> List[int]:
@@ -1015,6 +1021,7 @@ class ControlServer(SocketServer, ControlServerAPI):
@logging_info @logging_info
def run_project(self, project) -> bool: def run_project(self, project) -> bool:
if project is not None: if project is not None:
# print(project)
project = self._project_manager.create(project) project = self._project_manager.create(project)
self._project_manager.run_project(project) self._project_manager.run_project(project)
return project.as_json() return project.as_json()
@@ -1024,6 +1031,12 @@ class ControlServer(SocketServer, ControlServerAPI):
if project is not None: if project is not None:
self._project_manager.stop_project(project) self._project_manager.stop_project(project)
return True return True
@logging_info
def set_project(self, project, content) -> bool:
if project is not None:
self._project_manager.set_project(project, content)
return True
@logging_info @logging_info
def get_running_project(self) -> bool: def get_running_project(self) -> bool:
@@ -1339,6 +1352,13 @@ class ControlServer(SocketServer, ControlServerAPI):
def _hardware_send_test_set(self, options: Dict[str, str]) -> bool: def _hardware_send_test_set(self, options: Dict[str, str]) -> bool:
# TODO write options files # TODO write options files
return False return False
@logging_info
def show_device_data(self, device: int):
client = self.data_server.client()
if client is not None:
with client:
client.show_data(device)
class _RandomCrashThread(ServerThread): class _RandomCrashThread(ServerThread):
def __init__(self): def __init__(self):
+2
View File
@@ -185,6 +185,8 @@ class RecordingProcess(Process):
self.final_write() self.final_write()
self.is_closed = True self.is_closed = True
return False return False
elif q == 'show_data':
self._decoder._show_data = not self._decoder._show_data
else: else:
self.rec_update() self.rec_update()
self.sync_data(q) self.sync_data(q)
@@ -1203,7 +1203,7 @@
"pe": "SAMPLE_RATE" "pe": "SAMPLE_RATE"
}, },
"data": [ "data": [
"X07;", "X0C;",
"B>va;4B>vb;2B>vc;2B>vd;", "B>va;4B>vb;2B>vc;2B>vd;",
"4b>pa;4b>pb;", "4b>pa;4b>pb;",
"4b>pc;4b>pd;", "4b>pc;4b>pd;",
@@ -15,6 +15,33 @@
"BLE_WRITE_MAX": 255 "BLE_WRITE_MAX": 255
}, },
"parameters": { "parameters": {
"HIGHZ_TABLE": {
"initial": [
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
1,
1,
1,
0,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"DPV_e_init": { "DPV_e_init": {
"description": "DPV initial voltage ", "description": "DPV initial voltage ",
"record_meta": true, "record_meta": true,
@@ -671,6 +698,17 @@
}, },
"on_change": "set_para_DAC_VOLT" "on_change": "set_para_DAC_VOLT"
}, },
"DAC_VOLT_SCROLL": {
"description": "DAC scroll output Voltage",
"record_meta": true,
"initial": 25000,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
},
"ADC_VALUE_I": { "ADC_VALUE_I": {
"description": "ADC value current value", "description": "ADC value current value",
"domain": "int" "domain": "int"
@@ -836,6 +874,18 @@
], ],
"on_change": "set_dac_gain_Vout" "on_change": "set_dac_gain_Vout"
}, },
"DAC_VOLT_BUTTON": {
"description": "DAC volt",
"record_meta": true,
"initial": 1,
"value": [
"10000",
"25000",
"50000",
"60000"
],
"on_change": "cali_Vout"
},
"CTRL_HIGH_Z_15": { "CTRL_HIGH_Z_15": {
"description": "ctrl highZ level", "description": "ctrl highZ level",
"record_meta": true, "record_meta": true,
@@ -851,7 +901,8 @@
"initial": 0, "initial": 0,
"value": [ "value": [
"Iin", "Iin",
"Vin" "Vin",
"Vout"
] ]
}, },
"BLE_WRITE": { "BLE_WRITE": {
@@ -912,11 +963,13 @@
"_notify(True)", "_notify(True)",
"set_adc_gain_I", "set_adc_gain_I",
"set_adc_gain_Vin", "set_adc_gain_Vin",
"set_dac_gain_Vout",
{ {
"expression": "ADC_DAC_CHANNEL_15", "expression": "ADC_DAC_CHANNEL_15",
"when": { "when": {
"0": "cali_Iin", "0": "cali_Iin",
"1": "cali_Vin" "1": "cali_Vin",
"2": "cali_Vout"
} }
}, },
"_sync(True)", "_sync(True)",
@@ -1007,12 +1060,6 @@
"XE0;2B>va" "XE0;2B>va"
] ]
}, },
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_adc_gain_I": { "set_adc_gain_I": {
"type": "RIS", "type": "RIS",
"data": [ "data": [
@@ -1025,6 +1072,12 @@
"XE1;X01;B>ADC_LEVEL_V_IN_15" "XE1;X01;B>ADC_LEVEL_V_IN_15"
] ]
}, },
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_ctrl_highZ": { "set_ctrl_highZ": {
"type": "RIS", "type": "RIS",
"data": [ "data": [
@@ -1052,6 +1105,15 @@
"XF1;B>ADC_DAC_CHANNEL_15;B>ADC_LEVEL_V_IN_15" "XF1;B>ADC_DAC_CHANNEL_15;B>ADC_LEVEL_V_IN_15"
] ]
}, },
"cali_Vout": {
"type": "RIS",
"parameter": {
"v": "DAC_VOLT_BUTTON"
},
"data": [
"XF1;B>ADC_DAC_CHANNEL_15;B>v"
]
},
"curve_iv": { "curve_iv": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
@@ -1203,7 +1265,7 @@
"pe": "SAMPLE_RATE" "pe": "SAMPLE_RATE"
}, },
"data": [ "data": [
"X07;", "X0C;",
"B>va;4B>vb;2B>vc;2B>vd;", "B>va;4B>vb;2B>vc;2B>vd;",
"4b>pa;4b>pb;", "4b>pa;4b>pb;",
"4b>pc;4b>pd;", "4b>pc;4b>pd;",
@@ -15,6 +15,33 @@
"BLE_WRITE_MAX": 255 "BLE_WRITE_MAX": 255
}, },
"parameters": { "parameters": {
"HIGHZ_TABLE": {
"initial": [
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
1,
1,
1,
0,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"DPV_e_init": { "DPV_e_init": {
"description": "DPV initial voltage ", "description": "DPV initial voltage ",
"record_meta": true, "record_meta": true,
@@ -671,6 +698,17 @@
}, },
"on_change": "set_para_DAC_VOLT" "on_change": "set_para_DAC_VOLT"
}, },
"DAC_VOLT_SCROLL": {
"description": "DAC scroll output Voltage",
"record_meta": true,
"initial": 25000,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
},
"ADC_VALUE_I": { "ADC_VALUE_I": {
"description": "ADC value current value", "description": "ADC value current value",
"domain": "int" "domain": "int"
@@ -836,6 +874,18 @@
], ],
"on_change": "set_dac_gain_Vout" "on_change": "set_dac_gain_Vout"
}, },
"DAC_VOLT_BUTTON": {
"description": "DAC volt",
"record_meta": true,
"initial": 1,
"value": [
"10000",
"25000",
"50000",
"60000"
],
"on_change": "cali_Vout"
},
"CTRL_HIGH_Z_15": { "CTRL_HIGH_Z_15": {
"description": "ctrl highZ level", "description": "ctrl highZ level",
"record_meta": true, "record_meta": true,
@@ -851,7 +901,8 @@
"initial": 0, "initial": 0,
"value": [ "value": [
"Iin", "Iin",
"Vin" "Vin",
"Vout"
] ]
}, },
"BLE_WRITE": { "BLE_WRITE": {
@@ -912,11 +963,13 @@
"_notify(True)", "_notify(True)",
"set_adc_gain_I", "set_adc_gain_I",
"set_adc_gain_Vin", "set_adc_gain_Vin",
"set_dac_gain_Vout",
{ {
"expression": "ADC_DAC_CHANNEL_15", "expression": "ADC_DAC_CHANNEL_15",
"when": { "when": {
"0": "cali_Iin", "0": "cali_Iin",
"1": "cali_Vin" "1": "cali_Vin",
"2": "cali_Vout"
} }
}, },
"_sync(True)", "_sync(True)",
@@ -1007,12 +1060,6 @@
"XE0;2B>va" "XE0;2B>va"
] ]
}, },
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_adc_gain_I": { "set_adc_gain_I": {
"type": "RIS", "type": "RIS",
"data": [ "data": [
@@ -1025,6 +1072,12 @@
"XE1;X01;B>ADC_LEVEL_V_IN_15" "XE1;X01;B>ADC_LEVEL_V_IN_15"
] ]
}, },
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_ctrl_highZ": { "set_ctrl_highZ": {
"type": "RIS", "type": "RIS",
"data": [ "data": [
@@ -1052,6 +1105,15 @@
"XF1;B>ADC_DAC_CHANNEL_15;B>ADC_LEVEL_V_IN_15" "XF1;B>ADC_DAC_CHANNEL_15;B>ADC_LEVEL_V_IN_15"
] ]
}, },
"cali_Vout": {
"type": "RIS",
"parameter": {
"v": "DAC_VOLT_BUTTON"
},
"data": [
"XF1;B>ADC_DAC_CHANNEL_15;B>v"
]
},
"curve_iv": { "curve_iv": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
@@ -1203,7 +1265,7 @@
"pe": "SAMPLE_RATE" "pe": "SAMPLE_RATE"
}, },
"data": [ "data": [
"X07;", "X0C;",
"B>va;4B>vb;2B>vc;2B>vd;", "B>va;4B>vb;2B>vc;2B>vd;",
"4b>pa;4b>pb;", "4b>pa;4b>pb;",
"4b>pc;4b>pd;", "4b>pc;4b>pd;",
@@ -15,6 +15,33 @@
"BLE_WRITE_MAX": 255 "BLE_WRITE_MAX": 255
}, },
"parameters": { "parameters": {
"HIGHZ_TABLE": {
"initial": [
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
1,
1,
1,
0,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"DPV_e_init": { "DPV_e_init": {
"description": "DPV initial voltage ", "description": "DPV initial voltage ",
"record_meta": true, "record_meta": true,
@@ -671,6 +698,17 @@
}, },
"on_change": "set_para_DAC_VOLT" "on_change": "set_para_DAC_VOLT"
}, },
"DAC_VOLT_SCROLL": {
"description": "DAC scroll output Voltage",
"record_meta": true,
"initial": 25000,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
},
"ADC_VALUE_I": { "ADC_VALUE_I": {
"description": "ADC value current value", "description": "ADC value current value",
"domain": "int" "domain": "int"
@@ -836,6 +874,18 @@
], ],
"on_change": "set_dac_gain_Vout" "on_change": "set_dac_gain_Vout"
}, },
"DAC_VOLT_BUTTON": {
"description": "DAC volt",
"record_meta": true,
"initial": 1,
"value": [
"10000",
"25000",
"50000",
"60000"
],
"on_change": "cali_Vout"
},
"CTRL_HIGH_Z_15": { "CTRL_HIGH_Z_15": {
"description": "ctrl highZ level", "description": "ctrl highZ level",
"record_meta": true, "record_meta": true,
@@ -851,7 +901,8 @@
"initial": 0, "initial": 0,
"value": [ "value": [
"Iin", "Iin",
"Vin" "Vin",
"Vout"
] ]
}, },
"BLE_WRITE": { "BLE_WRITE": {
@@ -912,11 +963,13 @@
"_notify(True)", "_notify(True)",
"set_adc_gain_I", "set_adc_gain_I",
"set_adc_gain_Vin", "set_adc_gain_Vin",
"set_dac_gain_Vout",
{ {
"expression": "ADC_DAC_CHANNEL_15", "expression": "ADC_DAC_CHANNEL_15",
"when": { "when": {
"0": "cali_Iin", "0": "cali_Iin",
"1": "cali_Vin" "1": "cali_Vin",
"2": "cali_Vout"
} }
}, },
"_sync(True)", "_sync(True)",
@@ -1007,12 +1060,6 @@
"XE0;2B>va" "XE0;2B>va"
] ]
}, },
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_adc_gain_I": { "set_adc_gain_I": {
"type": "RIS", "type": "RIS",
"data": [ "data": [
@@ -1025,6 +1072,12 @@
"XE1;X01;B>ADC_LEVEL_V_IN_15" "XE1;X01;B>ADC_LEVEL_V_IN_15"
] ]
}, },
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_ctrl_highZ": { "set_ctrl_highZ": {
"type": "RIS", "type": "RIS",
"data": [ "data": [
@@ -1052,6 +1105,15 @@
"XF1;B>ADC_DAC_CHANNEL_15;B>ADC_LEVEL_V_IN_15" "XF1;B>ADC_DAC_CHANNEL_15;B>ADC_LEVEL_V_IN_15"
] ]
}, },
"cali_Vout": {
"type": "RIS",
"parameter": {
"v": "DAC_VOLT_BUTTON"
},
"data": [
"XF1;B>ADC_DAC_CHANNEL_15;B>v"
]
},
"curve_iv": { "curve_iv": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
@@ -62,6 +62,7 @@
"value": [ "value": [
"EIS CURVE", "EIS CURVE",
"Cyclic Voltammetry", "Cyclic Voltammetry",
"Chronoamperometric",
"Dev Mode" "Dev Mode"
] ]
}, },
@@ -265,6 +266,17 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_VSCAN": {
"description": "Voltage of VScan",
"record_meta": true,
"initial": 25000,
"domain": [
"VOLT_MAX"
],
"value": {
"expression": "VALUE"
}
},
"BLE_WRITE": { "BLE_WRITE": {
"description": "send msg to elite", "description": "send msg to elite",
"domain": { "domain": {
@@ -295,20 +307,23 @@
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"1": "set_adc_gain_I" "1": "set_adc_gain_I",
"2": "set_adc_gain_I"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"1": "set_adc_gain_Vin" "1": "set_adc_gain_Vin",
"2": "set_adc_gain_Vin"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "curve_eis", "0": "curve_eis",
"1": "curve_cv3" "1": "curve_cv3",
"2": "curve_const_vscan"
} }
}, },
{ {
@@ -424,6 +439,23 @@
"1XD2;1X02;4B>ve;2B>vf;2B>cn" "1XD2;1X02;4B>ve;2B>vf;2B>cn"
] ]
}, },
"curve_const_vscan": {
"type": "RIS",
"parameter": {
"va": "VOLT_VSCAN",
"pa": "ADC_LEVEL_I_15",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE"
},
"data": [
"1XD3;",
"2B>va;",
"4b>pa;4b>pb;",
"4b>0;4b>pd;",
"2B>pe"
]
},
"ble_instru_send": [ "ble_instru_send": [
"ble_write", "ble_write",
"_cdr('20X>ADC_VALUE_I')" "_cdr('20X>ADC_VALUE_I')"
@@ -62,6 +62,7 @@
"value": [ "value": [
"EIS CURVE", "EIS CURVE",
"Cyclic Voltammetry", "Cyclic Voltammetry",
"Chronoamperometric",
"Dev Mode" "Dev Mode"
] ]
}, },
@@ -69,7 +70,7 @@
"description": "DPV current recording period start", "description": "DPV current recording period start",
"record_meta": true, "record_meta": true,
"initial": [ "initial": [
13422819, 13333333,
7 7
], ],
"domain": { "domain": {
@@ -265,6 +266,17 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_VSCAN": {
"description": "Voltage of VScan",
"record_meta": true,
"initial": 25000,
"domain": [
"VOLT_MAX"
],
"value": {
"expression": "VALUE"
}
},
"BLE_WRITE": { "BLE_WRITE": {
"description": "send msg to elite", "description": "send msg to elite",
"domain": { "domain": {
@@ -295,20 +307,23 @@
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"1": "set_adc_gain_I" "1": "set_adc_gain_I",
"2": "set_adc_gain_I"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"1": "set_adc_gain_Vin" "1": "set_adc_gain_Vin",
"2": "set_adc_gain_Vin"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "curve_eis", "0": "curve_eis",
"1": "curve_cv3" "1": "curve_cv3",
"2": "curve_const_vscan"
} }
}, },
{ {
@@ -424,6 +439,23 @@
"1XD2;1X02;4B>ve;2B>vf;2B>cn" "1XD2;1X02;4B>ve;2B>vf;2B>cn"
] ]
}, },
"curve_const_vscan": {
"type": "RIS",
"parameter": {
"va": "VOLT_VSCAN",
"pa": "ADC_LEVEL_I_15",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE"
},
"data": [
"1XD3;",
"2B>va;",
"4b>pa;4b>pb;",
"4b>0;4b>pd;",
"2B>pe"
]
},
"ble_instru_send": [ "ble_instru_send": [
"ble_write", "ble_write",
"_cdr('20X>ADC_VALUE_I')" "_cdr('20X>ADC_VALUE_I')"
@@ -62,6 +62,7 @@
"value": [ "value": [
"EIS CURVE", "EIS CURVE",
"Cyclic Voltammetry", "Cyclic Voltammetry",
"Chronoamperometric",
"Dev Mode" "Dev Mode"
] ]
}, },
@@ -265,6 +266,17 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_VSCAN": {
"description": "Voltage of VScan",
"record_meta": true,
"initial": 25000,
"domain": [
"VOLT_MAX"
],
"value": {
"expression": "VALUE"
}
},
"BLE_WRITE": { "BLE_WRITE": {
"description": "send msg to elite", "description": "send msg to elite",
"domain": { "domain": {
@@ -295,20 +307,23 @@
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"1": "set_adc_gain_I" "1": "set_adc_gain_I",
"2": "set_adc_gain_I"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"1": "set_adc_gain_Vin" "1": "set_adc_gain_Vin",
"2": "set_adc_gain_Vin"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "curve_eis", "0": "curve_eis",
"1": "curve_cv3" "1": "curve_cv3",
"2": "curve_const_vscan"
} }
}, },
{ {
@@ -424,6 +439,23 @@
"1XD2;1X02;4B>ve;2B>vf;2B>cn" "1XD2;1X02;4B>ve;2B>vf;2B>cn"
] ]
}, },
"curve_const_vscan": {
"type": "RIS",
"parameter": {
"va": "VOLT_VSCAN",
"pa": "ADC_LEVEL_I_15",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE"
},
"data": [
"1XD3;",
"2B>va;",
"4b>pa;4b>pb;",
"4b>0;4b>pd;",
"2B>pe"
]
},
"ble_instru_send": [ "ble_instru_send": [
"ble_write", "ble_write",
"_cdr('20X>ADC_VALUE_I')" "_cdr('20X>ADC_VALUE_I')"