Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4daff72d39 | |||
| f99719832a | |||
| 58e09bfcda | |||
| 55780514b9 | |||
| 936514871f | |||
| f25d9221c6 | |||
| 2ee9fa6b19 | |||
| e2f7bba961 | |||
| bff75dc49e | |||
| 35912f614e | |||
| cfc4e39c8a | |||
| 8c4916d1e8 | |||
| e3c252f204 | |||
| c2164da48b | |||
| ab2d746afb | |||
| 8a870a860a | |||
| f4c5cf0135 | |||
| 1f01fd3b9b | |||
| d1fe388c27 | |||
| 91d5e73c5e | |||
| d1b6c2892f | |||
| 4243a13536 | |||
| 97188abff8 | |||
| 9d8178d11a |
@@ -1589,6 +1589,9 @@ class ControlAPI(metaclass=Router):
|
|||||||
def set_project(self, project, content) -> bool:
|
def set_project(self, project, content) -> bool:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def set_project_cycle(self, project, index, content) -> bool:
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
def show_device_data(self, device) -> bool:
|
def show_device_data(self, device) -> bool:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|||||||
@@ -1586,12 +1586,7 @@ class EISZeroOneDataDecoder(RecDataDecoder):
|
|||||||
else:
|
else:
|
||||||
impedance = 0
|
impedance = 0
|
||||||
|
|
||||||
if (real > 0):
|
raw_phase = math.atan2(img , real) * 180 / math.pi
|
||||||
raw_phase = math.atan(img / real) * 180 / math.pi
|
|
||||||
elif (real == 0):
|
|
||||||
raw_phase = 90
|
|
||||||
else:
|
|
||||||
raw_phase = math.atan(img / real) * 180 / math.pi + 180
|
|
||||||
|
|
||||||
if (freq >= 1000000): # 10000 Hz
|
if (freq >= 1000000): # 10000 Hz
|
||||||
fre_idx = 0
|
fre_idx = 0
|
||||||
@@ -1602,16 +1597,21 @@ class EISZeroOneDataDecoder(RecDataDecoder):
|
|||||||
elif (freq >= 1): # 0.01 Hz
|
elif (freq >= 1): # 0.01 Hz
|
||||||
fre_idx = 3
|
fre_idx = 3
|
||||||
|
|
||||||
ideal_raw_phase = phase_coeff[fre_idx][gain] /1e10 * freq + phase_offset[fre_idx][gain] / 1e6
|
ideal_raw_phase = phase_coeff[gain][fre_idx] /1e10 * freq + phase_offset[gain][fre_idx] / 1e6
|
||||||
|
|
||||||
phase = raw_phase - ideal_raw_phase
|
phase = raw_phase - ideal_raw_phase
|
||||||
|
phase = phase % 180 if phase % 180<=90 else phase % 180-180
|
||||||
|
|
||||||
if (self._first_phase_flag):
|
# last_phase_to90 = self._last_phase % 180 if self._last_phase % 180<=90 else self._last_phase % 180-180
|
||||||
self._last_phase = phase
|
# diff = phase - last_phase_to90
|
||||||
self._first_phase_flag = 0
|
|
||||||
elif (abs(phase - self._last_phase) >= 90):
|
# if (self._first_phase_flag):
|
||||||
phase -= 360
|
# # self._last_phase = phase
|
||||||
self._last_phase = phase
|
# self._first_phase_flag = 0
|
||||||
|
# elif (abs(diff) >= 90):
|
||||||
|
# phase = self._last_phase + diff + (180 if diff<0 else-180)
|
||||||
|
# else:
|
||||||
|
# phase = self._last_phase + diff
|
||||||
|
# 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)
|
||||||
|
|||||||
@@ -1032,7 +1032,7 @@ class CompletedDevice(Device):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def mac_address_in_str(self) -> str:
|
def mac_address_in_str(self) -> str:
|
||||||
return ':'.join('{:02x}'.format(b) for b in self._device.mac_address)
|
return ':'.join('{:02x}'.format(b) for b in self._device.mac_address).upper()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device(self) -> Device:
|
def device(self) -> Device:
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
|
|||||||
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], ']')
|
# print('mem_req==ram_sel,[', self._pin_mem_req_value[device], ',', self._pin_ram_sel_value[device], ']')
|
||||||
|
|
||||||
rx = []
|
rx = []
|
||||||
|
|
||||||
@@ -312,7 +312,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# print('data=', list(data))
|
# print('data=', list(data))
|
||||||
print('Ram:', data[62])
|
# print('Ram:', data[62])
|
||||||
|
|
||||||
if (length >= 4000):
|
if (length >= 4000):
|
||||||
flag_print = True
|
flag_print = True
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class UARTInterface(LowLevelHardwareInterface):
|
|||||||
self._serial = serial.Serial(self._port,
|
self._serial = serial.Serial(self._port,
|
||||||
baudrate=self._baudrate,
|
baudrate=self._baudrate,
|
||||||
timeout=0,
|
timeout=0,
|
||||||
writeTimeout=0.01)
|
writeTimeout=1)
|
||||||
# deprecate function name which change at version 3.0
|
# deprecate function name which change at version 3.0
|
||||||
self._serial.flushInput()
|
self._serial.flushInput()
|
||||||
self._serial.flushOutput()
|
self._serial.flushOutput()
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ class Condition():
|
|||||||
# print(operator, x, y)
|
# print(operator, x, y)
|
||||||
cases = {
|
cases = {
|
||||||
"equal": lambda a, b: a == b,
|
"equal": lambda a, b: a == b,
|
||||||
"bigger": lambda a, b: a > b,
|
"bigger": lambda a, b: a >= b,
|
||||||
"smaller": lambda a, b: a < b,
|
"smaller": lambda a, b: a <= b,
|
||||||
}
|
}
|
||||||
|
|
||||||
return cases[operator](x, y)
|
return cases[operator](x, y)
|
||||||
@@ -71,14 +71,23 @@ class Condition():
|
|||||||
return self.compareWith(self.comparsion, time_diff, round(int(self._value), 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['task_start_time'],kwargs['delay_time'])
|
||||||
if len(kwargs['task_start_time']) == 0:
|
if len(kwargs['task_start_time']) == 0:
|
||||||
return False
|
return False
|
||||||
|
task = kwargs['self_task']
|
||||||
|
running_task = kwargs['running_task']
|
||||||
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 = round(time() - task_start_time - delay_time, 1)
|
time_diff = round(time() - task_start_time - delay_time, 1)
|
||||||
return self.compareWith(self.comparsion, time_diff, round(int(self._value), 1))
|
# print('real_diff', time() - task_start_time - delay_time)
|
||||||
|
# print(task.name, task.uuid, time_diff, round(int(self._value), 1), running_task.name, running_task.uuid)
|
||||||
|
# if round(int(self._value), 1) == 0 and time_diff == 0.1:
|
||||||
|
# return True
|
||||||
|
if task.uuid != running_task.uuid:
|
||||||
|
return False
|
||||||
|
return self.compareWith('bigger', time_diff, round(int(self._value), 1))
|
||||||
|
# return self.compareWith(self.comparsion, time_diff, round(int(self._value), 1))
|
||||||
|
|
||||||
def device(self, **kwargs):
|
def device(self, **kwargs):
|
||||||
print('device')
|
print('device')
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ key_list = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Project(threading.Thread):
|
class Project(threading.Thread):
|
||||||
def __init__(self, project, device_manager: DeviceManager, mqttThread = None, name="project"):
|
def __init__(self, project, device_manager: DeviceManager, mqttThread = None, log_verbose = None, name="project"):
|
||||||
super(Project, self).__init__(name = name)
|
super(Project, self).__init__(name = name)
|
||||||
self._project = project
|
self._project = project
|
||||||
self._device_manager = device_manager
|
self._device_manager = device_manager
|
||||||
@@ -33,7 +33,7 @@ class Project(threading.Thread):
|
|||||||
self._name = None
|
self._name = None
|
||||||
self._desc = None
|
self._desc = None
|
||||||
self._device = None
|
self._device = None
|
||||||
self._complete_device = []
|
self._complete_device = {}
|
||||||
self._status = 0
|
self._status = 0
|
||||||
|
|
||||||
self._instruction_set = Instruction()
|
self._instruction_set = Instruction()
|
||||||
@@ -41,6 +41,12 @@ class Project(threading.Thread):
|
|||||||
|
|
||||||
self._task_manager = None
|
self._task_manager = None
|
||||||
|
|
||||||
|
self._cycle = []
|
||||||
|
|
||||||
|
self._count = 1 #流水號
|
||||||
|
|
||||||
|
self.log_verbose = log_verbose
|
||||||
|
|
||||||
self.setup_project(project)
|
self.setup_project(project)
|
||||||
self.setup_device(self._device)
|
self.setup_device(self._device)
|
||||||
|
|
||||||
@@ -50,7 +56,7 @@ class Project(threading.Thread):
|
|||||||
key = key_list[key]
|
key = key_list[key]
|
||||||
|
|
||||||
if key == 'task':
|
if key == 'task':
|
||||||
self._task_manager = TaskManager(project['task'])
|
self._task_manager = TaskManager(project['task'], project['cycle'])
|
||||||
elif key == 'uuid':
|
elif key == 'uuid':
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@@ -58,8 +64,9 @@ class Project(threading.Thread):
|
|||||||
|
|
||||||
def setup_device(self, device_list):
|
def setup_device(self, device_list):
|
||||||
for device in device_list:
|
for device in device_list:
|
||||||
complete_device = self._device_manager.get_device(device['connectDevice']['device_address'])
|
mac_address = device_list[device]['pair']
|
||||||
self._complete_device.append(complete_device)
|
complete_device = self._device_manager.get_device(mac_address)
|
||||||
|
self._complete_device[device] = complete_device
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self) -> int:
|
def id(self) -> int:
|
||||||
@@ -84,6 +91,14 @@ class Project(threading.Thread):
|
|||||||
@name.setter
|
@name.setter
|
||||||
def name(self, new_name):
|
def name(self, new_name):
|
||||||
self._name = new_name
|
self._name = new_name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cycle(self) -> list:
|
||||||
|
return self._cycle
|
||||||
|
|
||||||
|
@cycle.setter
|
||||||
|
def cycle(self, new_cycle):
|
||||||
|
self._cycle = new_cycle
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def desc(self) -> str:
|
def desc(self) -> str:
|
||||||
@@ -124,6 +139,7 @@ class Project(threading.Thread):
|
|||||||
def run(self):
|
def run(self):
|
||||||
self._status = 1
|
self._status = 1
|
||||||
self._start_time = time()
|
self._start_time = time()
|
||||||
|
self.log_verbose('Project ' + self.name + ' start')
|
||||||
self.mqtt_thread.broadcast_command('project:' + self._name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
|
self.mqtt_thread.broadcast_command('project:' + self._name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
|
||||||
|
|
||||||
while not self._stop_flag :
|
while not self._stop_flag :
|
||||||
@@ -134,10 +150,6 @@ class Project(threading.Thread):
|
|||||||
for task in check_list:
|
for task in check_list:
|
||||||
if task != None:
|
if task != None:
|
||||||
now = time()
|
now = time()
|
||||||
# print('round task', task.name)
|
|
||||||
# print('running task', self._task_manager.running_task.name, self._task_manager.running_task.status)
|
|
||||||
# if self._task_manager.prev_task != None:
|
|
||||||
# print('previous_task', self._task_manager.prev_task.name, self._task_manager.prev_task.status)
|
|
||||||
|
|
||||||
match_condition_list = task.check_condition(
|
match_condition_list = task.check_condition(
|
||||||
project_start_time = self._start_time,
|
project_start_time = self._start_time,
|
||||||
@@ -146,51 +158,87 @@ class Project(threading.Thread):
|
|||||||
previous_task = self._task_manager.prev_task,
|
previous_task = self._task_manager.prev_task,
|
||||||
self_task = task
|
self_task = task
|
||||||
)
|
)
|
||||||
# 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('action type', action.type)
|
if action.type == 'cycle' and condition.type == 'previous_task_done':
|
||||||
# print('match_action_list len: ', len(match_action_list))
|
|
||||||
if action.type == 'start' and task.status != 1:
|
|
||||||
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)
|
self._task_manager.set_running_task(task)
|
||||||
elif action.type == 'stop' and len(self._task_manager.running_task.parameter_set) == 0:
|
if action.type == 'cycle' and condition.type == 'until_button_trigger':
|
||||||
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()
|
||||||
|
|
||||||
|
if self._task_manager.running_task != None:
|
||||||
|
if self._task_manager.running_task.uuid == task.uuid and action.type == 'cycle' and condition.type == 'after_task_run':
|
||||||
|
self._task_manager.running_task.stop()
|
||||||
|
|
||||||
|
if action.type == 'start':
|
||||||
|
if task.status != 1:
|
||||||
|
self._task_manager.set_running_task(task)
|
||||||
|
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 == 'stop':
|
||||||
|
# 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._count += 1
|
||||||
|
# if self.check_running_task_not_run() == True:
|
||||||
|
# self._task_manager.running_task.stop()
|
||||||
|
|
||||||
elif action.type == 'idle':
|
elif action.type == 'idle':
|
||||||
self._task_manager.running_task.stop()
|
self._task_manager.running_task.stop()
|
||||||
|
|
||||||
device = self._complete_device[action.target]
|
instruction_set = None
|
||||||
task_info = task.get_task_info(action)
|
|
||||||
instruction_set = getattr(self._instruction_set, action.type, None)
|
if action.target is not None:
|
||||||
# print('instruction_set', instruction_set, '\n', action.type)
|
device = self._complete_device[action.target]
|
||||||
# if instruction_set != None and task.cycle == -1:
|
if ((action.type == 'start' and device.status == 0) or (action.type == 'stop' and device.status == 1)):
|
||||||
if instruction_set != None and len(task.parameter_set) > 0:
|
self.log_verbose('Project' + self.name + 'Task ' + task.name + ' match_condition ' + condition.type + ' trigger_action ' + action.type + ' ' + str(action.target))
|
||||||
for instruction in instruction_set:
|
task_info = task.get_task_info(action)
|
||||||
args = list(map(lambda arg: task_info[arg], instruction['arguments']))
|
instruction_set = getattr(self._instruction_set, action.type, None)
|
||||||
threading.Thread(target=getattr(device, instruction['method'])(*args))
|
|
||||||
|
# 檔名修正
|
||||||
|
# device
|
||||||
|
task_info['file_name'] += '#' + device.mac_address_in_str[12:].upper()
|
||||||
|
# 流水號
|
||||||
|
task_info['file_name'] += '#' + str(self._count)
|
||||||
|
|
||||||
|
# 添加cycle資訊
|
||||||
|
if len(self.cycle) > 0:
|
||||||
|
index = self._task_manager.get_index_by_task(task)
|
||||||
|
# get list of cycle determine by index of task
|
||||||
|
filtered = list(filter(lambda info: self._task_manager.get_index_by_uuid(info['range'][0]) < index and self._task_manager.get_index_by_uuid(info['range'][1]) > index, self.cycle))
|
||||||
|
|
||||||
|
if len(filtered) == 0:
|
||||||
|
pass
|
||||||
|
elif len(filtered) == 1:
|
||||||
|
if filtered[0]['useID'] == True:
|
||||||
|
task_info['file_name'] += '#' + str(filtered[0]['id'])
|
||||||
|
else:
|
||||||
|
task_info['file_name'] += '#' + str(filtered[0]['name']) + '-' + str(filtered[0]['count'])
|
||||||
|
else:
|
||||||
|
# if multi cycle, then sort by range from task index to cycle start index, then loop concat filename
|
||||||
|
filtered.sort(key=lambda info: abs(self._task_manager.get_index_by_uuid(info['range'][0]) - index))
|
||||||
|
for cycle_info in filtered:
|
||||||
|
if cycle_info['useID'] == True:
|
||||||
|
task_info['file_name'] += '#' + str(cycle_info['id'])
|
||||||
|
else:
|
||||||
|
task_info['file_name'] += '#' + str(cycle_info['name']) + '-' + str(cycle_info['count'])
|
||||||
|
self.log_verbose('file name ' + task_info['file_name'])
|
||||||
|
|
||||||
|
if instruction_set != None and len(task.parameter_set) > 0:
|
||||||
|
if action.type == 'start':
|
||||||
|
self._count += 1
|
||||||
|
for instruction in instruction_set:
|
||||||
|
print('instruction 1', device, instruction, datetime.now())
|
||||||
|
args = list(map(lambda arg: task_info[arg], instruction['arguments']))
|
||||||
|
target=getattr(device, instruction['method'])(*args)
|
||||||
|
print('instruction 2', device, instruction, datetime.now())
|
||||||
|
|
||||||
delay_time += (time() - now)
|
delay_time += (time() - now)
|
||||||
|
|
||||||
# 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:
|
||||||
if self._task_manager.running_task.cycle == -1:
|
if self._task_manager.running_task.type == '':
|
||||||
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.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:
|
||||||
@@ -228,11 +276,24 @@ class Project(threading.Thread):
|
|||||||
def set_content(self, content):
|
def set_content(self, content):
|
||||||
self.running_task.button_trigger = True
|
self.running_task.button_trigger = True
|
||||||
|
|
||||||
|
def set_cycle(self, index, content):
|
||||||
|
# change cycle name
|
||||||
|
for key in content:
|
||||||
|
self.cycle[index][key] = content[key]
|
||||||
|
|
||||||
|
# change task name
|
||||||
|
# self._task_manager.get_task_by_uuid(self.cycle[index]['range'][0]).name = content['name']
|
||||||
|
# self._task_manager.get_task_by_uuid(self.cycle[index]['range'][1]).name = content['name']
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
# if running is cycle then no need to stop by device
|
||||||
|
if self._task_manager.running_task.type == 'cycle':
|
||||||
|
return False
|
||||||
|
|
||||||
for key in self._task_manager.running_task.action:
|
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])
|
# 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':
|
if len(self._task_manager.running_task.parameter_set) == 0 and self._task_manager.running_task.action[key]['type'] == 'stop':
|
||||||
@@ -257,6 +318,7 @@ class Project(threading.Thread):
|
|||||||
'status': self._status,
|
'status': self._status,
|
||||||
'device': self._device,
|
'device': self._device,
|
||||||
'task': self.task_list,
|
'task': self.task_list,
|
||||||
'running_task': running_task
|
'running_task': running_task,
|
||||||
|
'cycle': self._cycle
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|||||||
@@ -9,13 +9,14 @@ def json_stringify(o: Any) -> str:
|
|||||||
return _json_stringify(o, separators=(',', ':'))
|
return _json_stringify(o, separators=(',', ':'))
|
||||||
|
|
||||||
class ProjectManager():
|
class ProjectManager():
|
||||||
def __init__(self, device_manager: DeviceManager, mqtt_thread=None) :
|
def __init__(self, device_manager: DeviceManager, mqtt_thread=None, log_verbose = None) :
|
||||||
self._project_list = []
|
self._project_list = []
|
||||||
self._mqtt_thread = mqtt_thread
|
self._mqtt_thread = mqtt_thread
|
||||||
self._device_manager = device_manager
|
self._device_manager = device_manager
|
||||||
|
self.log_verbose = log_verbose
|
||||||
|
|
||||||
def create(self, project):
|
def create(self, project):
|
||||||
new_project = Project(project, self._device_manager, self._mqtt_thread)
|
new_project = Project(project, self._device_manager, self._mqtt_thread, self.log_verbose)
|
||||||
self._project_list.append(new_project)
|
self._project_list.append(new_project)
|
||||||
return new_project
|
return new_project
|
||||||
|
|
||||||
@@ -41,3 +42,7 @@ class ProjectManager():
|
|||||||
def set_project(self, project_uuid, content):
|
def set_project(self, project_uuid, content):
|
||||||
_project = self.get(project_uuid)
|
_project = self.get(project_uuid)
|
||||||
_project.set_content(content)
|
_project.set_content(content)
|
||||||
|
|
||||||
|
def set_project_cycle(self, project_uuid, index, content):
|
||||||
|
_project = self.get(project_uuid)
|
||||||
|
_project.set_cycle(index, content)
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ key_list = {
|
|||||||
class Task:
|
class Task:
|
||||||
def __init__(self, task):
|
def __init__(self, task):
|
||||||
self._id = None
|
self._id = None
|
||||||
|
self._uuid = None
|
||||||
|
self._type = None
|
||||||
self._name = None
|
self._name = None
|
||||||
self._parent = None
|
self._parent = None
|
||||||
self._cycle = None
|
self._cycle = None
|
||||||
@@ -82,6 +84,14 @@ class Task:
|
|||||||
@uuid.setter
|
@uuid.setter
|
||||||
def uuid(self, new_uuid):
|
def uuid(self, new_uuid):
|
||||||
self._uuid = new_uuid
|
self._uuid = new_uuid
|
||||||
|
|
||||||
|
@property
|
||||||
|
def type(self):
|
||||||
|
return self._type
|
||||||
|
|
||||||
|
@type.setter
|
||||||
|
def type(self, new_type):
|
||||||
|
self._type = new_type
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
@@ -275,7 +285,7 @@ class Task:
|
|||||||
return {
|
return {
|
||||||
'device': action.target,
|
'device': action.target,
|
||||||
'parameter': self.get_parameter_set_by_device(action.target),
|
'parameter': self.get_parameter_set_by_device(action.target),
|
||||||
'file_name': self._name + '-' + str(action.target),
|
'file_name': self._name,
|
||||||
'parent': self.parent,
|
'parent': self.parent,
|
||||||
'instruction': _type
|
'instruction': _type
|
||||||
}
|
}
|
||||||
@@ -285,6 +295,8 @@ class Task:
|
|||||||
'id': self.id,
|
'id': self.id,
|
||||||
'name': self.name,
|
'name': self.name,
|
||||||
'parent': self.parent,
|
'parent': self.parent,
|
||||||
|
'type': self.type,
|
||||||
|
'uuid': self.uuid,
|
||||||
'cycle': self.cycle,
|
'cycle': self.cycle,
|
||||||
'cycle_count': self.cycle_count,
|
'cycle_count': self.cycle_count,
|
||||||
'cycle_next': self.cycle_next,
|
'cycle_next': self.cycle_next,
|
||||||
|
|||||||
@@ -12,11 +12,12 @@ def json_stringify(o: Any) -> str:
|
|||||||
return _json_stringify(o, separators=(',', ':'))
|
return _json_stringify(o, separators=(',', ':'))
|
||||||
|
|
||||||
class TaskManager():
|
class TaskManager():
|
||||||
def __init__(self, task_list):
|
def __init__(self, task_list, cycle_list):
|
||||||
self._task_list = []
|
self._task_list = []
|
||||||
self._next_task = []
|
self._next_task = []
|
||||||
self._prev_task = None
|
self._prev_task = None
|
||||||
self._running_task = None
|
self._running_task = None
|
||||||
|
self._cycle_list = cycle_list
|
||||||
|
|
||||||
self.load_task_list(task_list)
|
self.load_task_list(task_list)
|
||||||
|
|
||||||
@@ -44,6 +45,23 @@ class TaskManager():
|
|||||||
def next_task(self):
|
def next_task(self):
|
||||||
return self._next_task
|
return self._next_task
|
||||||
|
|
||||||
|
def get_task_by_index(self, index):
|
||||||
|
return self._task_list[index]
|
||||||
|
|
||||||
|
def get_task_by_uuid(self, uuid):
|
||||||
|
return next((x for x in self.task_list if x.uuid == uuid), None)
|
||||||
|
|
||||||
|
def get_index_by_task(self, task):
|
||||||
|
return next((i for i, x in enumerate(self.task_list) if x.uuid == task.uuid), None)
|
||||||
|
|
||||||
|
def get_index_by_uuid(self, uuid):
|
||||||
|
return next((i for i, x in enumerate(self.task_list) if x.uuid == uuid), None)
|
||||||
|
|
||||||
|
def check_task_is_cycle_end(self, task):
|
||||||
|
for index, cycle in enumerate(self._cycle_list):
|
||||||
|
if cycle['range'][1] == task.uuid:
|
||||||
|
return index
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def check_list(self):
|
def check_list(self):
|
||||||
return [self._running_task, *self._next_task]
|
return [self._running_task, *self._next_task]
|
||||||
@@ -83,42 +101,49 @@ class TaskManager():
|
|||||||
self._next_task.append(_task)
|
self._next_task.append(_task)
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
print(e) """
|
print(e) """
|
||||||
|
|
||||||
def set_running_task(self, task):
|
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:
|
||||||
# print('set_running_task return false: ', self._running_task.name)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# save running task
|
# save task
|
||||||
self._prev_task = self._running_task
|
self._prev_task = self._running_task
|
||||||
# clear next task list
|
# clear next task list
|
||||||
self._next_task.clear()
|
self._next_task.clear()
|
||||||
|
# set task to running_task
|
||||||
self._running_task = task
|
self._running_task = task
|
||||||
self._running_task.run()
|
self._running_task.run()
|
||||||
|
|
||||||
|
# if previous task is still running, then need to close
|
||||||
if self._prev_task != None:
|
if self._prev_task != None:
|
||||||
# if previous task is still running, then need to close
|
|
||||||
if self._prev_task.status == 1:
|
if self._prev_task.status == 1:
|
||||||
self._prev_task.stop()
|
self._prev_task.stop()
|
||||||
print('prev', 'run', self._prev_task.name, self._running_task.name)
|
# if reach cycle end, count < max, then go to cycle start
|
||||||
|
cycle_index = self.check_task_is_cycle_end(task)
|
||||||
# print(f'!!@#!set_running_task\n\n\n{task._cycle_count}\n{task._cycle}\n\n\n')
|
if cycle_index is None:
|
||||||
if task._cycle_count < task._cycle - 1:
|
# print('next', self._running_task.name, self._running_task.next)
|
||||||
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:
|
for task_uuid in self._running_task.next:
|
||||||
_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:
|
||||||
_task.reset()
|
_task.reset()
|
||||||
self._next_task.append(_task)
|
self._next_task.append(_task)
|
||||||
|
# print('self._next_task', self._next_task)
|
||||||
|
else:
|
||||||
|
# print('cycle', self._cycle_list[cycle_index])
|
||||||
|
cycle = self._cycle_list[cycle_index]
|
||||||
|
if int(cycle['count']) < int(cycle['max']):
|
||||||
|
self._next_task.append(self.get_task_by_uuid(cycle['range'][0]))
|
||||||
|
cycle['count'] += 1
|
||||||
|
else:
|
||||||
|
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)
|
||||||
|
cycle['count'] = 1
|
||||||
|
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class DataServer(SocketServer, DataAPI):
|
|||||||
"""
|
"""
|
||||||
global _FLAG_DATA_LOST_STATS_
|
global _FLAG_DATA_LOST_STATS_
|
||||||
|
|
||||||
super().__init__(DataAPI, 'DataServer', self.ADDR, socket_listen=3)
|
super().__init__(DataAPI, 'DataServer', self.ADDR, socket_listen=20)
|
||||||
|
|
||||||
data_options = DataServerOptions.get_options(*options)
|
data_options = DataServerOptions.get_options(*options)
|
||||||
|
|
||||||
@@ -656,7 +656,7 @@ class DataServer(SocketServer, DataAPI):
|
|||||||
sync = self.get_spi_obj()
|
sync = self.get_spi_obj()
|
||||||
|
|
||||||
busy = sync.get_pin_busy()
|
busy = sync.get_pin_busy()
|
||||||
print('pin_busy=', busy, device, datetime.now())
|
# 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)
|
||||||
@@ -669,13 +669,15 @@ class DataServer(SocketServer, DataAPI):
|
|||||||
print('data=None, mem_req!=ram_sel, [', sync.get_pin_mem_req(), ', ', sync.get_pin_ram_sel(), ']', device, datetime.now())
|
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.get(device, None) != None:
|
||||||
self._configurations[device].queue_flag = False
|
if self._configurations[device].queue_flag:
|
||||||
print("q size= ", self._configurations[device]._queue_rec.qsize())
|
self._configurations[device].queue_flag = False
|
||||||
|
print("q size= ", self._configurations[device]._queue_rec.qsize())
|
||||||
self._configurations[device].put_rec_queue(data)
|
|
||||||
# self._no_data_total_duration = 0
|
if self._configurations.get(device, None) != None:
|
||||||
ret = True
|
self._configurations[device].put_rec_queue(data)
|
||||||
|
# self._no_data_total_duration = 0
|
||||||
|
ret = True
|
||||||
# else:
|
# else:
|
||||||
# time_diff = time() - self._recv_memory_cost_time
|
# time_diff = time() - self._recv_memory_cost_time
|
||||||
# self._no_data_total_duration += time_diff
|
# self._no_data_total_duration += time_diff
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ class ControlServer(SocketServer, ControlServerAPI):
|
|||||||
# device detect
|
# device detect
|
||||||
self._detect_device_thread = RoutineConnectDeviceThread(self._device_manager, self.mqtt_thread, self.led_thread, 3)
|
self._detect_device_thread = RoutineConnectDeviceThread(self._device_manager, self.mqtt_thread, self.led_thread, 3)
|
||||||
|
|
||||||
self._project_manager = ProjectManager(self.device_manager, self.mqtt_thread)
|
self._project_manager = ProjectManager(self.device_manager, self.mqtt_thread, self.log_verbose)
|
||||||
|
|
||||||
if not c.flag_disable_led_control:
|
if not c.flag_disable_led_control:
|
||||||
self.led_thread.set_state(LED.COLOR_RED)
|
self.led_thread.set_state(LED.COLOR_RED)
|
||||||
@@ -1037,6 +1037,12 @@ class ControlServer(SocketServer, ControlServerAPI):
|
|||||||
if project is not None:
|
if project is not None:
|
||||||
self._project_manager.set_project(project, content)
|
self._project_manager.set_project(project, content)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@logging_info
|
||||||
|
def set_project_cycle(self, project, index, content) -> bool:
|
||||||
|
if project is not None:
|
||||||
|
self._project_manager.set_project_cycle(project, index, content)
|
||||||
|
return True
|
||||||
|
|
||||||
@logging_info
|
@logging_info
|
||||||
def get_running_project(self) -> bool:
|
def get_running_project(self) -> bool:
|
||||||
|
|||||||
@@ -93,13 +93,15 @@ class SocketClient(metaclass=abc.ABCMeta):
|
|||||||
if self._socket is None:
|
if self._socket is None:
|
||||||
try:
|
try:
|
||||||
self._socket = Socket(AF_UNIX, SOCK_STREAM)
|
self._socket = Socket(AF_UNIX, SOCK_STREAM)
|
||||||
self._socket.settimeout(1)
|
self._socket.settimeout(5)
|
||||||
self._socket.connect(self._socket_file)
|
self._socket.connect(self._socket_file)
|
||||||
except FileNotFoundError as e:
|
except Exception as e:
|
||||||
raise RuntimeError('server not available') from e
|
print('open_socket error:', e)
|
||||||
|
# except FileNotFoundError as e:
|
||||||
|
# raise RuntimeError('server not available') from e
|
||||||
|
|
||||||
except ConnectionRefusedError as e:
|
# except ConnectionRefusedError as e:
|
||||||
raise RuntimeError('server crash') from e
|
# raise RuntimeError('server crash') from e
|
||||||
|
|
||||||
def close_socket(self):
|
def close_socket(self):
|
||||||
if self._socket is not None:
|
if self._socket is not None:
|
||||||
|
|||||||
@@ -70,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": {
|
||||||
|
|||||||
@@ -63,6 +63,8 @@
|
|||||||
"EIS CURVE",
|
"EIS CURVE",
|
||||||
"Cyclic Voltammetry",
|
"Cyclic Voltammetry",
|
||||||
"Chronoamperometric",
|
"Chronoamperometric",
|
||||||
|
"V-T Graph",
|
||||||
|
"R-T Graph",
|
||||||
"Dev Mode"
|
"Dev Mode"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -277,6 +279,29 @@
|
|||||||
"expression": "VALUE"
|
"expression": "VALUE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MEASURE_VIN_RANGE": {
|
||||||
|
"description": "measure range of Vin",
|
||||||
|
"record_meta": true,
|
||||||
|
"initial": 0,
|
||||||
|
"value": [
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"auto"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"RT_VOLT_SET": {
|
||||||
|
"description": "DAC output Voltage",
|
||||||
|
"record_meta": true,
|
||||||
|
"initial": 37500,
|
||||||
|
"domain": [
|
||||||
|
65536
|
||||||
|
],
|
||||||
|
"value": {
|
||||||
|
"expression": "VALUE"
|
||||||
|
},
|
||||||
|
"on_change": "set_para_RT_VOLT_SET"
|
||||||
|
},
|
||||||
"BLE_WRITE": {
|
"BLE_WRITE": {
|
||||||
"description": "send msg to elite",
|
"description": "send msg to elite",
|
||||||
"domain": {
|
"domain": {
|
||||||
@@ -308,14 +333,18 @@
|
|||||||
"expression": "MODE",
|
"expression": "MODE",
|
||||||
"when": {
|
"when": {
|
||||||
"1": "set_adc_gain_I",
|
"1": "set_adc_gain_I",
|
||||||
"2": "set_adc_gain_I"
|
"2": "set_adc_gain_I",
|
||||||
|
"3": "set_adc_gain_I",
|
||||||
|
"4": "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"
|
"2": "set_adc_gain_Vin",
|
||||||
|
"3": "set_adc_gain_Vin",
|
||||||
|
"4": "set_adc_gain_Vin"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -323,7 +352,9 @@
|
|||||||
"when": {
|
"when": {
|
||||||
"0": "curve_eis",
|
"0": "curve_eis",
|
||||||
"1": "curve_cv3",
|
"1": "curve_cv3",
|
||||||
"2": "curve_const_vscan"
|
"2": "curve_const_vscan",
|
||||||
|
"3": "curve_vt",
|
||||||
|
"4": "curve_rt"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -456,6 +487,46 @@
|
|||||||
"2B>pe"
|
"2B>pe"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"curve_rt": {
|
||||||
|
"type": "RIS",
|
||||||
|
"parameter": {
|
||||||
|
"va": "RT_VOLT_SET",
|
||||||
|
"pa": "ADC_LEVEL_I_15",
|
||||||
|
"pb": "ADC_LEVEL_V_IN_15",
|
||||||
|
"pd": "CTRL_HIGH_Z_15",
|
||||||
|
"pe": "SAMPLE_RATE"
|
||||||
|
},
|
||||||
|
"data": [
|
||||||
|
"X04;",
|
||||||
|
"2B>va;",
|
||||||
|
"4b>pa;4b>pb;",
|
||||||
|
"4b>0;4b>pd;",
|
||||||
|
"2B>pe"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"curve_vt": {
|
||||||
|
"type": "RIS",
|
||||||
|
"parameter": {
|
||||||
|
"pa": "ADC_LEVEL_I_15",
|
||||||
|
"pb": "ADC_LEVEL_V_IN_15",
|
||||||
|
"pd": "CTRL_HIGH_Z_15",
|
||||||
|
"pe": "SAMPLE_RATE",
|
||||||
|
"va": "MEASURE_VIN_RANGE"
|
||||||
|
},
|
||||||
|
"data": [
|
||||||
|
"X05;",
|
||||||
|
"4b>pa;4b>pb;",
|
||||||
|
"4b>0;4b>pd;",
|
||||||
|
"2B>pe;",
|
||||||
|
"1B>va"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"set_para_RT_VOLT_SET": {
|
||||||
|
"type": "RIS",
|
||||||
|
"data": [
|
||||||
|
"XE2;X01;2B>RT_VOLT_SET"
|
||||||
|
]
|
||||||
|
},
|
||||||
"ble_instru_send": [
|
"ble_instru_send": [
|
||||||
"ble_write",
|
"ble_write",
|
||||||
"_cdr('20X>ADC_VALUE_I')"
|
"_cdr('20X>ADC_VALUE_I')"
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"EIS CURVE",
|
"EIS CURVE",
|
||||||
"Cyclic Voltammetry",
|
"Cyclic Voltammetry",
|
||||||
"Chronoamperometric",
|
"Chronoamperometric",
|
||||||
|
"V-T Graph",
|
||||||
"Dev Mode"
|
"Dev Mode"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -70,7 +71,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": {
|
||||||
@@ -277,6 +278,17 @@
|
|||||||
"expression": "VALUE"
|
"expression": "VALUE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MEASURE_VIN_RANGE": {
|
||||||
|
"description": "measure range of Vin",
|
||||||
|
"record_meta": true,
|
||||||
|
"initial": 0,
|
||||||
|
"value": [
|
||||||
|
"0",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"auto"
|
||||||
|
]
|
||||||
|
},
|
||||||
"BLE_WRITE": {
|
"BLE_WRITE": {
|
||||||
"description": "send msg to elite",
|
"description": "send msg to elite",
|
||||||
"domain": {
|
"domain": {
|
||||||
@@ -308,14 +320,16 @@
|
|||||||
"expression": "MODE",
|
"expression": "MODE",
|
||||||
"when": {
|
"when": {
|
||||||
"1": "set_adc_gain_I",
|
"1": "set_adc_gain_I",
|
||||||
"2": "set_adc_gain_I"
|
"2": "set_adc_gain_I",
|
||||||
|
"3": "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"
|
"2": "set_adc_gain_Vin",
|
||||||
|
"3": "set_adc_gain_Vin"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -323,7 +337,8 @@
|
|||||||
"when": {
|
"when": {
|
||||||
"0": "curve_eis",
|
"0": "curve_eis",
|
||||||
"1": "curve_cv3",
|
"1": "curve_cv3",
|
||||||
"2": "curve_const_vscan"
|
"2": "curve_const_vscan",
|
||||||
|
"3": "curve_vt"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -456,6 +471,23 @@
|
|||||||
"2B>pe"
|
"2B>pe"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"curve_vt": {
|
||||||
|
"type": "RIS",
|
||||||
|
"parameter": {
|
||||||
|
"pa": "ADC_LEVEL_I_15",
|
||||||
|
"pb": "ADC_LEVEL_V_IN_15",
|
||||||
|
"pd": "CTRL_HIGH_Z_15",
|
||||||
|
"pe": "SAMPLE_RATE",
|
||||||
|
"va": "MEASURE_VIN_RANGE"
|
||||||
|
},
|
||||||
|
"data": [
|
||||||
|
"X05;",
|
||||||
|
"4b>pa;4b>pb;",
|
||||||
|
"4b>0;4b>pd;",
|
||||||
|
"2B>pe;",
|
||||||
|
"1B>va"
|
||||||
|
]
|
||||||
|
},
|
||||||
"ble_instru_send": [
|
"ble_instru_send": [
|
||||||
"ble_write",
|
"ble_write",
|
||||||
"_cdr('20X>ADC_VALUE_I')"
|
"_cdr('20X>ADC_VALUE_I')"
|
||||||
|
|||||||
Reference in New Issue
Block a user