Compare commits

..

24 Commits

Author SHA1 Message Date
peterlu14 58bfc86572 - Fixed parameter value string error 2024-10-04 11:59:28 +08:00
peterlu14 febba59c37 - Fix Elite_2.0 ble_write
- Fix Pel_2.0 parameters
2024-10-01 15:09:23 +08:00
peterlu14 b8f39e984b - Add pulse_e_load_2.0 lib 2024-10-01 11:48:25 +08:00
peterlu14 59585507a5 - Fix missing parameter ADC_VALUE_I 2024-09-20 09:45:35 +08:00
peterlu14 f9f15457cf change default parameter 2024-09-11 16:47:34 +08:00
peterlu14 cf62cfbe04 - Add coundown instruction 2024-09-11 10:00:00 +08:00
peterlu14 33697af99c - Add countdown internal instruction for device 2024-09-11 09:59:24 +08:00
peterlu14 985e043ca5 - Complete CPG 1.1 parameters & instructions 2024-09-10 16:04:48 +08:00
peterlu14 8fd119f4f0 support float domain parameter 2024-09-10 16:04:14 +08:00
peterlu14 b5bd64bf6c - BLE_WRITE change instruction type to ALL 2024-08-21 17:42:05 +08:00
peterlu14 241296f36c -Enable TYPE ALL Instruction 2024-08-21 17:40:58 +08:00
peterlu14 f46073a46a -CPG BLE_WRITE extend to 255 bytes 2024-08-21 14:55:28 +08:00
peterlu14 24fd5ca28b -Extension of list parameter parse rule
-Fix the list paratmeter change with changing it's length
2024-08-21 14:42:36 +08:00
peterlu14 288f261abe - Add CPG library 2024-07-31 15:02:29 +08:00
peterlu14 a32267f1fd update pulse_e_load json 2024-07-30 10:27:58 +08:00
Roy c89c6e88d0 update EDC1.5r2 library and new EDC2.0 library 2024-03-05 17:07:52 +08:00
peterlu14 536bc23896 -update stop update battery when device running 2023-11-21 16:28:40 +08:00
Roy 7deb709946 [update] print msg when connection fail 2023-07-17 17:37:14 +08:00
Roy 25267411d8 [update] fix connect & write function 2023-07-10 13:00:06 +08:00
peterlu14 200feead76 - update cycle default 1 2023-07-05 17:45:49 +08:00
Roy f445550b4e [update] update write gatt and fix read value of dev tool 2023-06-29 13:39:17 +08:00
Roy dfbbfe4e07 [update] set ram status register = 0x41 2023-06-26 17:34:45 +08:00
Roy 57e5c1a9e2 [update] fix eis mini calibration 2023-06-20 15:27:50 +08:00
Roy ba192ccce8 [update] print something debug info 2023-06-20 12:28:20 +08:00
19 changed files with 4346 additions and 112 deletions
+70 -29
View File
@@ -163,12 +163,14 @@ def is_headstage_device(info: cc2650.GapEvt_DeviceInformation) -> Optional[Devic
version_info[3], version_info[3],
version_info[4], version_info[4],
version_info[5]) version_info[5])
return DeviceResponseInfo(local_name.decode(), serial_number, info.address, battery=battery_percentage) return DeviceResponseInfo(local_name.decode(), serial_number, info.address, battery=battery_percentage)
elif company_code[:2] == b'HS': elif company_code[:2] == b'HS':
# legacy device # legacy device
serial_number = DeviceSerialNumber(0, 0, 0, 0, 0, 0) serial_number = DeviceSerialNumber(0, 0, 0, 0, 0, 0)
return DeviceResponseInfo(local_name.decode(), serial_number, info.address) return DeviceResponseInfo(local_name.decode(), serial_number, info.address)
else: else:
@@ -198,7 +200,7 @@ def is_headstage_device_central_version(device_mac: ADDRESS = EMPTY_ADDRESS,
version_info[3], version_info[3],
version_info[4], version_info[4],
version_info[5]) version_info[5])
print('***********', version_info, device_mac)
return DeviceResponseInfo(local_name, return DeviceResponseInfo(local_name,
serial_number, serial_number,
device_mac, device_mac,
@@ -427,17 +429,20 @@ class CC2650Device(Device):
self._start_flag = False self._start_flag = False
def _encode_instruction(self, ins_type: int, ins_oper: int, *instruction: int) -> bytes: def _encode_instruction(self, ins_type: int, ins_oper: int, *instruction: int) -> bytes:
# print('_encode_instruction', ins_type, ins_oper, instruction)
length = len(instruction) length = len(instruction)
if length == 1 and instruction[0] < 0: if length == 1 and instruction[0] < 0:
return struct.pack('2B1b', return struct.pack('2B1b',
(ins_type & 0xF0) | (self.device_id & 0x0F), (ins_type & 0xF0) | (self.device_id & 0x0F),
(ins_oper & 0xFF), (ins_oper & 0xFF),
*instruction) *instruction)
if ins_type == None:
return struct.pack('%dB' % (length + 2), return struct.pack('%dB' % length, *instruction)
(ins_type & 0xF0) | (self.device_id & 0x0F), else:
(ins_oper & 0xFF), return struct.pack('%dB' % (length + 2),
*instruction) (ins_type & 0xF0) | (self.device_id & 0x0F),
(ins_oper & 0xFF),
*instruction)
def _decode_data(self, ins_oper: int, data: bytes) -> bytes: def _decode_data(self, ins_oper: int, data: bytes) -> bytes:
"""CIS data decoder. """CIS data decoder.
@@ -481,17 +486,19 @@ class CC2650Device(Device):
day = struct.unpack('<B', data[4:5])[0] day = struct.unpack('<B', data[4:5])[0]
hour = struct.unpack('<B', data[5:6])[0] hour = struct.unpack('<B', data[5:6])[0]
minute = struct.unpack('<B', data[6:7])[0] minute = struct.unpack('<B', data[6:7])[0]
mac1 = struct.unpack('<B', data[7:8])[0] # mac1 = struct.unpack('<B', data[7:8])[0]
mac2 = struct.unpack('<B', data[8:9])[0] # mac2 = struct.unpack('<B', data[8:9])[0]
mac1 = "%02X" % mac1 # mac1 = "%02X" % mac1
mac2 = "%02X" % mac2 # mac2 = "%02X" % mac2
self._device_version = str(year) + '/' + str(month) + '/' + str(day) + " " + str(hour) + ":" + str( self._device_version = str(year) + '/' + str(month) + '/' + str(day) + " " + str(hour) + ":" + str(
minute) + " | " + str(mac1) + ":" + str(mac2) minute)
# + " | " + str(mac1) + ":" + str(mac2)
@property @property
def battery(self) -> int: def battery(self) -> int:
self.update_battery_info() if self._start_flag == False:
self.update_battery_info()
return self._battery return self._battery
@property @property
@@ -2145,6 +2152,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
connected = False connected = False
connect_response = None connect_response = None
ins = bytearray() ins = bytearray()
ins.append(0x05) ins.append(0x05)
ins.append(0x08) #length ins.append(0x08) #length
ins.append(addr_type) ins.append(addr_type)
@@ -2156,6 +2164,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
ins.append(address[5]) ins.append(address[5])
ins.append(0xF1) ins.append(0xF1)
self._interface.flush_input() self._interface.flush_input()
for retry in range(5): for retry in range(5):
try: try:
self.log_verbose('[CC2650]', 'connect att_write', '0x'+str.upper(ins.hex())) self.log_verbose('[CC2650]', 'connect att_write', '0x'+str.upper(ins.hex()))
@@ -2169,7 +2178,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
try: try:
connect_response = self._cc2650.recv_uart(2) connect_response = self._cc2650.recv_uart(2)
except RecvTimeout: except RecvTimeout:
self.log_verbose('[CC2650]', 'connect response timeout') # self.log_verbose('[CC2650]', 'connect response timeout')
if retry < 5: if retry < 5:
self.log_verbose('[CC2650]', 'connect retry') self.log_verbose('[CC2650]', 'connect retry')
continue continue
@@ -2177,15 +2186,23 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
break break
if connect_response is None: if connect_response is None:
self.log_verbose('[CC2650]', 'connect response timeout')
return False return False
pack_len = connect_response[0] pack_len = connect_response[0]
connect_ack = connect_response[1:pack_len+1] connect_ack = connect_response[1:pack_len+1]
if pack_len == 1:
if connect_ack[0] == 3:
connected = True
connect_response_hex = ''.join(format(i, '02X') for i in connect_response)
self.log_verbose('[CC2650]', 'connect success', '0x'+connect_response_hex)
if connect_ack[0] == 46 and connect_ack[1] == 80 and \ elif pack_len == 4:
connect_ack[2] == 48 and connect_ack[3] == 4: if connect_ack[0] == 46 and connect_ack[1] == 80 and \
connected = True connect_ack[2] == 48 and connect_ack[3] == 4:
connect_response_hex = ''.join(format(i, '02X') for i in connect_response) connected = True
self.log_verbose('[CC2650]', 'connect success', '0x'+connect_response_hex) connect_response_hex = ''.join(format(i, '02X') for i in connect_response)
self.log_verbose('[CC2650]', 'connect success', '0x'+connect_response_hex)
if connected == True: if connected == True:
# CC2650Device(device_id, master, scan_response) is a slave device # CC2650Device(device_id, master, scan_response) is a slave device
@@ -2195,7 +2212,8 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
self.log_verbose('[CC2650]', DEVICE_CONNECTED, address_s) self.log_verbose('[CC2650]', DEVICE_CONNECTED, address_s)
return ret return ret
self.log_verbose('[CC2650]', 'connect fail') connect_response_hex = ''.join(format(i, '02X') for i in connect_response)
self.log_verbose('[CC2650]', 'connect fail', '0x'+connect_response_hex)
return False return False
@synchronized @synchronized
@@ -2207,7 +2225,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
ins.append(0xF1) ins.append(0xF1)
self._interface.flush_input() self._interface.flush_input()
for _ in range(5): for retry in range(5):
try: try:
self.log_verbose('[CC2650]', 'disconnect att_write','0x'+str.upper(ins.hex())) self.log_verbose('[CC2650]', 'disconnect att_write','0x'+str.upper(ins.hex()))
self._cc2650.send("bytes", bytes(ins)) self._cc2650.send("bytes", bytes(ins))
@@ -2221,6 +2239,30 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
self.reset_hardware() self.reset_hardware()
self.log_verbose('[CC2650]', 'disconnect success') self.log_verbose('[CC2650]', 'disconnect success')
return True return True
# try:
# disconnect_response = self._cc2650.recv_uart(0.01)
# print(disconnect_response)
# except RecvTimeout:
# self.log_verbose('[CC2650]', 'disconnect response timeout')
# if retry < 5:
# self.log_verbose('[CC2650]', 'connect retry')
# continue
# else:
# break
# if disconnect_response is None:
# return False
# pack_len = disconnect_response[0]
# disconnect_ack = disconnect_response[1:pack_len+1]
# if disconnect_ack == [3]:
# disconnect_response_hex = ''.join(format(i, '02X') for i in disconnect_response)
# self.log_verbose('[CC2650]', 'disconnect success', '0x'+disconnect_response_hex)
# self.reset_internal()
# self.reset_hardware()
# return True
self.log_verbose('[CC2650]', 'disconnect fail') self.log_verbose('[CC2650]', 'disconnect fail')
return False return False
@@ -2231,7 +2273,10 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
ins = bytearray() ins = bytearray()
ins.append(0x06) ins.append(0x06)
ins.append(len(data)+2) #length = handle + C0C0XXXX(data len) + F1 if len(data) + 2 > 255:
ins.append(255)
else:
ins.append(len(data)+2) #length = handle + C0C0XXXX(data len) + F1
ins.append(handle) ins.append(handle)
ins.extend(data) ins.extend(data)
ins.append(0xF1) ins.append(0xF1)
@@ -2253,6 +2298,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
self.log_verbose('[CC2650]', 'write_characteristic response timeout') self.log_verbose('[CC2650]', 'write_characteristic response timeout')
if write_response is None: if write_response is None:
self.log_verbose('[CC2650]', 'write_characteristic fail')
return False return False
pack_len = write_response[0] pack_len = write_response[0]
@@ -2569,15 +2615,15 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
return ret return ret
def connect(self, response: DeviceResponseInfo, direct_connect: bool = True) -> Device: def connect(self, response: DeviceResponseInfo, direct_connect: bool = False) -> Device:
self.log_verbose('connect') self.log_verbose('connect')
master = None master = None
print('self._foreach_empty_master()', self._foreach_empty_master())
for master in self._foreach_empty_master(): for master in self._foreach_empty_master():
m = self._cc2650[master] m = self._cc2650[master]
d = self._device[master] d = self._device[master]
print('master', master, d, m)
if direct_connect is True and d is None: if direct_connect is True and d is None:
break break
@@ -2588,27 +2634,22 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
if master is None: if master is None:
raise RuntimeError('cannot connect any more device') raise RuntimeError('cannot connect any more device')
else: else:
print('456')
raise RuntimeError('rescan please') raise RuntimeError('rescan please')
# #
master = 4
self.log_verbose('use', master) self.log_verbose('use', master)
m = self._cc2650[master] m = self._cc2650[master]
d = self._device[master] d = self._device[master]
print('4')
if d is not None: if d is not None:
raise RuntimeError('cc2650 has connected a device') raise RuntimeError('cc2650 has connected a device')
with self: with self:
print('5')
self._interface.flush() self._interface.flush()
self._selector.select(master) self._selector.select(master)
sleep(0.0001) sleep(0.0001)
d = m.connect(response, direct_connect) d = m.connect(response, direct_connect)
print('6')
if d is None: if d is None:
raise RuntimeError('connect failed, retry please') raise RuntimeError('connect failed, retry please')
+13 -7
View File
@@ -683,12 +683,12 @@ class DeviceManager(MasterDevice, Synchronized):
address = address_str(response.mac_address) address = address_str(response.mac_address)
self.log_info(DEVICE_CONNECTING, address) self.log_info(DEVICE_CONNECTING, address)
# response = self.found_device(response) response = self.found_device(response)
# ''' device not found''' ''' device not found'''
# if response is None: if response is None:
# self.log_warn(DEVICE_CONNECT_FAIL, address, DEVICE_NOT_FOUND) self.log_warn(DEVICE_CONNECT_FAIL, address, DEVICE_NOT_FOUND)
# return None return None
# raise RuntimeError(DEVICE_NOT_FOUND, address) # raise RuntimeError(DEVICE_NOT_FOUND, address)
# get device library # get device library
@@ -718,9 +718,7 @@ class DeviceManager(MasterDevice, Synchronized):
serial_number=response.serial_number) serial_number=response.serial_number)
else: else:
try: try:
print('here!!!!!!!!!!!!!!!!!!!!!!!', response)
device = self._centralMaster.connect(response) device = self._centralMaster.connect(response)
print('connect', device)
device = CompletedDevice(self, library, device.device_id, device) device = CompletedDevice(self, library, device.device_id, device)
except Exception as e: except Exception as e:
@@ -838,6 +836,9 @@ class DeviceManager(MasterDevice, Synchronized):
elif func == InternalInstruction.PREDEFINED_IDLE: elif func == InternalInstruction.PREDEFINED_IDLE:
self._idle(device, *para) self._idle(device, *para)
elif func == InternalInstruction.PREDEFINED_COUNTDOWN:
self._countdown(device, *para)
elif isinstance(device, DebugDevice): elif isinstance(device, DebugDevice):
if func == InternalInstruction.PREDEFINED_NOTIFY: if func == InternalInstruction.PREDEFINED_NOTIFY:
return True return True
@@ -860,6 +861,11 @@ class DeviceManager(MasterDevice, Synchronized):
self._handler.device_internal_command(device.device_id, self._handler.device_internal_command(device.device_id,
InternalInstruction.PREDEFINED_IDLE, InternalInstruction.PREDEFINED_IDLE,
None) None)
def _countdown(self, device: Device, expr: AnyStr):
self._handler.device_internal_command(device.device_id,
InternalInstruction.PREDEFINED_COUNTDOWN,
expr)
def _device_data_format_cali(self, device: Device, expr: str, cali: bytes = None): def _device_data_format_cali(self, device: Device, expr: str, cali: bytes = None):
if cali is None: if cali is None:
+19 -1
View File
@@ -854,7 +854,8 @@ 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', '_show_data') '_mode_stop', '_show_data',
'_last_mem_wrong_information', '_last_mem_cnt', '_last_elite_notify_times')
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@@ -871,6 +872,10 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
self._show_data = False self._show_data = False
self._last_mem_wrong_information = -1
self._last_mem_cnt = -1
self._last_elite_notify_times = -1
@property @property
def name(self) -> str: def name(self) -> str:
return self.NAME return self.NAME
@@ -935,6 +940,19 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
# self._show_data = True # 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
if mem_wrong_information != self._last_mem_wrong_information:
print(datetime.now(), 'device', str(self.device), 'mem_wrong_information[43:47]:', data[43:47], mem_wrong_information, self._last_mem_wrong_information, flush = True)
if mem_cnt != self._last_mem_cnt+1:
if not (mem_cnt == 0 and self._last_mem_cnt == 255):
print(datetime.now(), 'device', str(self.device), 'mem_cnt:', mem_cnt, 'self._last_mem_cnt:', self._last_mem_cnt, flush = True)
if (elite_notify_times != self._last_elite_notify_times+1) and not (elite_notify_times == 0 and self._last_elite_notify_times == 0):
if not (elite_notify_times == 0 and self._last_elite_notify_times == 255):
print(datetime.now(), 'device', str(self.device), 'elite_notify_times:', elite_notify_times, 'self._elite_notify_times:', self._last_elite_notify_times, flush = True)
self._last_mem_wrong_information = mem_wrong_information
self._last_mem_cnt = mem_cnt
self._last_elite_notify_times = elite_notify_times
ram_num = data[47] ram_num = data[47]
broken_flag = data[-1] broken_flag = data[-1]
+5 -1
View File
@@ -689,11 +689,13 @@ class DeviceInstruction:
TYP_IIS = -1 TYP_IIS = -1
"""internal instruction""" """internal instruction"""
TYP_ALL = None
__slots__ = () __slots__ = ()
@classmethod @classmethod
def valid_ins_type(cls, ins_type: int): def valid_ins_type(cls, ins_type: int):
if ins_type not in (cls.TYP_RIS, cls.TYP_VIS, cls.TYP_CIS, cls.TYP_IIS): if ins_type not in (cls.TYP_RIS, cls.TYP_VIS, cls.TYP_CIS, cls.TYP_IIS, cls.TYP_ALL):
raise ValueError('unknown instruction type : ' + str(ins_type)) raise ValueError('unknown instruction type : ' + str(ins_type))
@classmethod @classmethod
@@ -704,6 +706,8 @@ class DeviceInstruction:
return cls.TYP_VIS return cls.TYP_VIS
elif ins_type == 'CIS': elif ins_type == 'CIS':
return cls.TYP_CIS return cls.TYP_CIS
elif ins_type == 'ALL':
return cls.TYP_ALL
else: else:
raise RuntimeError('unknown instruction type : ' + ins_type) raise RuntimeError('unknown instruction type : ' + ins_type)
+29 -3
View File
@@ -120,6 +120,9 @@ class ParameterDomain(JsonSerialize, metaclass=abc.ABCMeta):
elif json == 'int': elif json == 'int':
return ParameterIntDomain return ParameterIntDomain
elif json == 'float':
return ParameterFloatDomain
elif json == 'property': elif json == 'property':
return ParameterPropertyDomain return ParameterPropertyDomain
@@ -291,6 +294,25 @@ class ParameterIntDomainType(ParameterTypeDomain):
ParameterIntDomain = ParameterIntDomainType() ParameterIntDomain = ParameterIntDomainType()
class ParameterFloatDomainType(ParameterTypeDomain):
__slots__ = ()
def init_para(self, initial: Optional[Any] = None) -> float:
print('ParameterFloatDomainType')
if initial is None:
return 0
else:
return float(initial)
def valid_para(self, value: int) -> bool:
return True
def __str__(self):
return "float"
ParameterFloatDomain = ParameterFloatDomainType()
class ParameterValueDomain(ParameterDomain, metaclass=abc.ABCMeta): class ParameterValueDomain(ParameterDomain, metaclass=abc.ABCMeta):
"""limited/ranged P value domain """ """limited/ranged P value domain """
@@ -301,7 +323,7 @@ class ParameterValueDomain(ParameterDomain, metaclass=abc.ABCMeta):
if initial is None: if initial is None:
return self.range[0] return self.range[0]
else: else:
initial = int(initial) initial = initial
f, t = self.range f, t = self.range
if f <= initial < t: if f <= initial < t:
@@ -742,6 +764,7 @@ class ParameterListDomain(ParameterCollectionDomain):
sz = len(target) sz = len(target)
i = oper.index(sz) i = oper.index(sz)
v = oper.value(d) v = oper.value(d)
# print('ParameterListDomain', d, sz, i, v, str(d) == 'float', type(d))
if i is None and v is None: if i is None and v is None:
pass pass
@@ -780,8 +803,11 @@ class ParameterListDomain(ParameterCollectionDomain):
if isinstance(v, int): if isinstance(v, int):
v = [v] v = [v]
target[len(v):] = []
target[i] = v if isinstance(d, ParameterFloatDomainType):
target[i] = [float(i) for i in v]
else:
target[i] = v
def _valid_list_limit(self, target: List[Any], inc: int) -> bool: def _valid_list_limit(self, target: List[Any], inc: int) -> bool:
if self._limit is not None: if self._limit is not None:
+1 -7
View File
@@ -532,7 +532,6 @@ class ComplexExpression(Expression[T]):
@classmethod @classmethod
def parse(cls, json: JSON_OBJECT) -> Union['ComplexExpression', UndeterminedExpression]: def parse(cls, json: JSON_OBJECT) -> Union['ComplexExpression', UndeterminedExpression]:
expression = _get(json, 'expression', str, _truncate(json), nullable=True) expression = _get(json, 'expression', str, _truncate(json), nullable=True)
print('expression parse', expression, json)
if expression is None: if expression is None:
# un-determined expression # un-determined expression
@@ -880,13 +879,8 @@ class WhenExpression(ComplexExpression[T]):
self._when: Dict[str, Expression[T]] = when self._when: Dict[str, Expression[T]] = when
def value(self, context: Scope) -> Union[str, T]: def value(self, context: Scope) -> Union[str, T]:
print('value', context)
value = super().value(context) value = super().value(context)
key = str(int(value))
key = str(value)
print('value1', key,value)
print('when', self._when)
if key in self._when: if key in self._when:
return self._when[key].value(context.child(VALUE=value)) return self._when[key].value(context.child(VALUE=value))
+13
View File
@@ -5,6 +5,13 @@ from .device import *
from .instruction import * from .instruction import *
from .parameter import * from .parameter import *
def convert_to_float(lst):
# Check if the element is a list (for handling nested lists)
if isinstance(lst, list):
return [convert_to_float(x) for x in lst]
else:
# If it's not a list, convert it to float
return float(lst)
class MatchRule(JsonSerialize, metaclass=abc.ABCMeta): class MatchRule(JsonSerialize, metaclass=abc.ABCMeta):
"""Device matching rule. Program use this table to find correct library according to the response information from """Device matching rule. Program use this table to find correct library according to the response information from
@@ -444,6 +451,12 @@ class DefaultLibraryLoader:
elif guard is not None: elif guard is not None:
guard = ListGuardExpression([GuardExpression.parse(guard)]) guard = ListGuardExpression([GuardExpression.parse(guard)])
if "float" in str(domain):
initial = convert_to_float(initial)
# print('!@#$%^&')
# print(name, domain, initial, value, value_set)
return ParameterInfo(name, domain, return ParameterInfo(name, domain,
initial=initial, initial=initial,
+28 -16
View File
@@ -1,4 +1,5 @@
import re import re
import struct
from random import randint from random import randint
from time import sleep from time import sleep
from typing import Sequence, Tuple from typing import Sequence, Tuple
@@ -284,6 +285,7 @@ class InternalInstruction(SingleInstruction):
PREDEFINED_CDR = '_cdr' PREDEFINED_CDR = '_cdr'
PREDEFINED_DISABLE_CACHE = '_disable_cache' PREDEFINED_DISABLE_CACHE = '_disable_cache'
PREDEFINED_IDLE = '_idle' PREDEFINED_IDLE = '_idle'
PREDEFINED_COUNTDOWN = '_countdown'
PREDEFINED = ( PREDEFINED = (
PREDEFINED_SLEEP, PREDEFINED_SLEEP,
@@ -296,6 +298,7 @@ class InternalInstruction(SingleInstruction):
PREDEFINED_CDR, PREDEFINED_CDR,
PREDEFINED_DISABLE_CACHE, PREDEFINED_DISABLE_CACHE,
PREDEFINED_IDLE, PREDEFINED_IDLE,
PREDEFINED_COUNTDOWN
) )
__slots__ = ('_expr', '_para') __slots__ = ('_expr', '_para')
@@ -375,7 +378,7 @@ class InternalInstruction(SingleInstruction):
parser.parse_instruction(context, data) parser.parse_instruction(context, data)
# tag2
class ListInstruction(Instruction, ImmutableListNode[Union[Instruction, Expression[str]]]): class ListInstruction(Instruction, ImmutableListNode[Union[Instruction, Expression[str]]]):
"""Instruction group, allow the name of the instruction or a expression it. """Instruction group, allow the name of the instruction or a expression it.
If instruction name is ``None``, ignore it. If instruction name is ``None``, ignore it.
@@ -404,9 +407,7 @@ class ListInstruction(Instruction, ImmutableListNode[Union[Instruction, Expressi
ImmutableListNode.__init__(self, list(ins)) ImmutableListNode.__init__(self, list(ins))
def eval_instruction(self, context: Scope) -> Iterable['SingleInstruction']: def eval_instruction(self, context: Scope) -> Iterable['SingleInstruction']:
print('eval_instruction', context)
for ins in self: for ins in self:
print(ins)
# foreach instructions # foreach instructions
# ins type could be Union[str, Expression] # ins type could be Union[str, Expression]
@@ -590,7 +591,7 @@ class InstructionContentWidth:
return InstructionContentWidth(z, t, signed_value=s is not None, little_endian=e == '<'), x return InstructionContentWidth(z, t, signed_value=s is not None, little_endian=e == '<'), x
# The start from the json file parse
class InstructionContent(JsonSerialize): class InstructionContent(JsonSerialize):
""" """
**json format** **json format**
@@ -684,7 +685,7 @@ class InstructionContent(JsonSerialize):
return ins_type(width, expr, **ins_argv, comment=comment) return ins_type(width, expr, **ins_argv, comment=comment)
# tag1
class InstructionDataContent(InstructionContent): class InstructionDataContent(InstructionContent):
""" """
**json format** **json format**
@@ -745,6 +746,7 @@ class InstructionDataContent(InstructionContent):
return ret[index] return ret[index]
def build_instruction(self, context: Scope, buffer: List[int], shift: int = 0) -> int: def build_instruction(self, context: Scope, buffer: List[int], shift: int = 0) -> int:
# print('build_instruction', context, buffer, shift, self.value(context))
if self._width.is_array: if self._width.is_array:
raise NotImplementedError() raise NotImplementedError()
@@ -752,24 +754,33 @@ class InstructionDataContent(InstructionContent):
value = 1 value = 1
elif self.value(context) == 'false': elif self.value(context) == 'false':
value = 0 value = 0
elif isinstance(self.value(context), list):
value = self.value(context)
else: else:
value = int(self.value(context)) value = self.value(context)
# print('value', value, type(value))
# print('self._width.bytes_unit', self._width.bytes_unit)
# print('self._width.size', self._width.size)
if self._width.bytes_unit: if self._width.bytes_unit:
if self._width.size == 1: if self._width.size == 1:
buffer.append(value) buffer.append(value)
else: else:
tmp = [] if isinstance(self.value(context), list):
for _ in range(self._width.size): buffer.extend(value)
tmp.append(value & 0xFF) elif isinstance(value, int):
value >>= 8 tmp = []
for _ in range(self._width.size):
if self._width.little_endian: tmp.append(value & 0xFF)
buffer.extend(tmp) value >>= 8
else:
buffer.extend(tmp[::-1])
if self._width.little_endian:
buffer.extend(tmp)
else:
buffer.extend(tmp[::-1])
elif isinstance(value, float):
buffer.extend(struct.pack('>f', value))
return 8 return 8
else: else:
@@ -796,6 +807,7 @@ class InstructionDataContent(InstructionContent):
offset += 1 offset += 1
else: else:
buffer.extend([0]*(self._width.size-len(buffer)))
for i in range(self._width.size): for i in range(self._width.size):
if self._width.little_endian: if self._width.little_endian:
value |= (buffer[offset] << (1 * i)) value |= (buffer[offset] << (1 * i))
@@ -1113,7 +1125,7 @@ class SendInstruction(SingleInstruction):
else: else:
for scope in self._foreach_parameter.for_scope(context): for scope in self._foreach_parameter.for_scope(context):
yield ResolvedSendInstruction(self, self._build_instruction(scope)) yield ResolvedSendInstruction(self, self._build_instruction(scope))
# tag3
def _build_instruction(self, context: Scope) -> List[int]: def _build_instruction(self, context: Scope) -> List[int]:
buffer = [] buffer = []
shift = 0 shift = 0
+11 -1
View File
@@ -359,6 +359,7 @@ class DeviceParameter(JsonSerialize):
# initial parameter table # initial parameter table
for para_info in library.parameter_table.values(): for para_info in library.parameter_table.values():
# print('DeviceParameter', para_info)
try: try:
para_value = para_info.init_para() para_value = para_info.init_para()
@@ -522,6 +523,7 @@ class DeviceParameter(JsonSerialize):
raise RuntimeError('not a collection parameter ' + para) raise RuntimeError('not a collection parameter ' + para)
target = self._parameter[para] target = self._parameter[para]
# print(table, info, domain, target, str(domain) == '[float]', oper)
if isinstance(target, set): if isinstance(target, set):
old = set(target) old = set(target)
@@ -1128,13 +1130,21 @@ class CompletedDevice(Device):
:param value: new parameter P value :param value: new parameter P value
""" """
info = self._library.parameter_table[name] info = self._library.parameter_table[name]
# print('info', info.domain, info.domain == 'float', info.domain == '[float]')
if isinstance(info.domain, ParameterCollectionDomain): if isinstance(info.domain, ParameterCollectionDomain):
self._parameter.oper_parameter(name, value) self._parameter.oper_parameter(name, value)
elif isinstance(info.domain, ParameterFloatDomainType):
self._parameter.set_parameter(name, float(value))
else: else:
try: try:
value = value
# value int # value int
value = int(value) if isinstance(value, str):
if "." in value:
value = float(value)
else:
value = int(value)
except ValueError as e: except ValueError as e:
# value float # value float
self._parameter.set_parameter(name, value) self._parameter.set_parameter(name, value)
+2
View File
@@ -433,6 +433,7 @@ class ParameterInfo(JsonSerialize):
return self._on_change return self._on_change
def init_para(self) -> Any: def init_para(self) -> Any:
# print('initial', self._name, self._initial)
""" """
:return: initial P value :return: initial P value
:raises value: illegal initial value :raises value: illegal initial value
@@ -617,6 +618,7 @@ class ParameterInfo(JsonSerialize):
return [] return []
elif isinstance(self._value, ComplexExpression): elif isinstance(self._value, ComplexExpression):
print('cast_value_dependency', self._value.dependency)
return self._value.dependency return self._value.dependency
else: else:
+34 -19
View File
@@ -13,7 +13,7 @@ MSM_REG_WRITE = 0x01
MEM_INS_WRITE = 0x02 MEM_INS_WRITE = 0x02
MEM_INS_READ = 0x03 MEM_INS_READ = 0x03
MEM_REG_READ = 0x05 MEM_REG_READ = 0x05
DEFAULT_REGISTER_VALUE = 0b0100_0011 # 67 DEFAULT_REGISTER_VALUE = 0b0100_0001 # 0x41
MEM_SIZE = 0x1000 MEM_SIZE = 0x1000
_SLEEP_TIME_ = 0.001 _SLEEP_TIME_ = 0.001
@@ -457,6 +457,16 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
self._spi.send_byte(tx) self._spi.send_byte(tx)
def test_ram(self, channel: int):
spi_MOSI = [MEM_INS_WRITE, 0, 0, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
self._spi.send_byte(spi_MOSI)
print('device:', channel, 'spi_MOSI:',spi_MOSI)
spi_MISO = [0] * len(spi_MOSI)
spi_MISO[0:3] = [MEM_INS_READ, 0, 0]
spi_MISO = self._spi.send_byte(spi_MISO)
print('device:', channel, 'spi_MISO:', spi_MISO)
class ExtMemManager: class ExtMemManager:
def __init__(self, ext_mem: MultiExtMemSpiInterface): def __init__(self, ext_mem: MultiExtMemSpiInterface):
self._ext_mem = ext_mem self._ext_mem = ext_mem
@@ -493,28 +503,31 @@ class ExtMemManager:
ret[channel] = tuple(r) ret[channel] = tuple(r)
print('ret=', ret)
return ret return ret
@staticmethod @staticmethod
def is_no_device(result: Tuple[Optional[int], Optional[int]]) -> bool: def is_memory_test_fail(result: Tuple[Optional[int], Optional[int]], channel: int) -> int:
r1, r2 = result r1, r2 = result
return (r1 is None or r2 is None) and (r1 is None or r1 == 0) and (r2 is None or r2 == 0) r1_check = False
r2_check = False
@staticmethod if r1 is not None and r1 != 0:
def is_memory_test_fail(result: Tuple[Optional[int], Optional[int]]) -> int: if (r1 & 0b11000001 == DEFAULT_REGISTER_VALUE & 0b11000001):
r1, r2 = result r1_check = True
print('device:', channel, 'ram0 ready')
if r2 is not None and r2 != 0:
if (r2 & 0b11000001 == DEFAULT_REGISTER_VALUE & 0b11000001):
r2_check = True
print('device:', channel, 'ram1 ready')
print('--------------------')
if r1 is None or r2 is None: if r1_check and r2_check:
return 0
else:
return 1 return 1
if r1 is not None and r1 > 0 and r1 != DEFAULT_REGISTER_VALUE:
return 2
if r2 is not None and r2 > 0 and r2 != DEFAULT_REGISTER_VALUE:
return 3
return 0
def get_available_channel(self, result: List[Tuple[Optional[int], Optional[int]]] = None) -> List[int]: def get_available_channel(self, result: List[Tuple[Optional[int], Optional[int]]] = None) -> List[int]:
if result is None: if result is None:
result = self.get_ext_mem_register() result = self.get_ext_mem_register()
@@ -522,12 +535,14 @@ class ExtMemManager:
ret = [] ret = []
for channel, result in enumerate(result): for channel, result in enumerate(result):
if self.is_no_device(result): if self.is_memory_test_fail(result, channel) != 0:
continue
if self.is_memory_test_fail(result) != 0:
continue continue
ret.append(channel) ret.append(channel)
# test ram
# for channel in self._ext_mem.foreach():
# if channel == 4 or channel == 5:
# self._ext_mem.test_ram(channel)
return ret return ret
+33 -25
View File
@@ -2,6 +2,8 @@ from time import sleep
from typing import Iterable from typing import Iterable
from datetime import datetime from datetime import datetime
import json import json
import threading
from time import time
import biopro.impl.vcgencmd as vcg import biopro.impl.vcgencmd as vcg
from biopro.data import DataServerOptions, DataAPI from biopro.data import DataServerOptions, DataAPI
@@ -329,30 +331,6 @@ class ControlServer(SocketServer, ControlServerAPI):
finally: finally:
self.led_thread.set_state(LED.AVAILABLE) self.led_thread.set_state(LED.AVAILABLE)
# version_info = [0, 2, 1, 7, 23, 2]
# serial_number = DeviceSerialNumber(version_info[0],
# version_info[1],
# version_info[2],
# version_info[3],
# version_info[4],
# version_info[5])
# response = DeviceResponseInfo('Elite-EDC', serial_number, (164, 218, 50, 212, 231, 12), addr_type=0)
# print('setup done', response)
# ret = self.device_manager.connect(response)
# print('ret', ret)
version_info = [0, 5, 1, 0, 23, 5]
serial_number = DeviceSerialNumber(version_info[0],
version_info[1],
version_info[2],
version_info[3],
version_info[4],
version_info[5])
response = DeviceResponseInfo('Elite-EDC', serial_number, (164, 218, 50, 212, 238, 89), addr_type=0)
print('setup done', response)
ret = self.device_manager.connect(response)
print('ret', ret)
def _setup_get_available_channel(self) -> Optional[List[int]]: def _setup_get_available_channel(self) -> Optional[List[int]]:
client = self.data_server.client() client = self.data_server.client()
@@ -582,6 +560,7 @@ class ControlServer(SocketServer, ControlServerAPI):
response = content response = content
else: else:
response = to_device_info(content) response = to_device_info(content)
try: try:
ret = self.device_manager.connect(response) ret = self.device_manager.connect(response)
except DeviceInstructionError as e: except DeviceInstructionError as e:
@@ -891,7 +870,7 @@ class ControlServer(SocketServer, ControlServerAPI):
mac_address = address_str(connect_device.mac_address) mac_address = address_str(connect_device.mac_address)
device = Device.get_device({"mac_address": mac_address}) device = Device.get_device({"mac_address": mac_address})
try: try:
if connect_device.library.name.startswith('Elite_EIS_1.1'): if connect_device.library.name.startswith('Elite_EIS'):
# update calibration version # update calibration version
connect_device._device.update_cali_version() connect_device._device.update_cali_version()
# check if is first time or calibration version is different # check if is first time or calibration version is different
@@ -1116,6 +1095,34 @@ class ControlServer(SocketServer, ControlServerAPI):
device.status = 1 device.status = 1
return True return True
elif oper == InternalInstruction.PREDEFINED_COUNTDOWN:
if value == 'PULSE_OUTPUT':
continue_mode = device.get_parameter('CONTINUE_MODE')
if continue_mode == 0:
stop_time = device.get_parameter('STOP_TIME')
# Function to send the instruction
def send_instruction():
device.call_instruction('deactive_electrode')
# Function to wait for 30 seconds and then execute the instruction
def delayed_execution(stop_time):
sleep(stop_time)
send_instruction()
device.set_parameter('ACTIVATE_ELECTRODE', 0)
self.mqtt_thread.broadcast_command('device_refresh')
# Create a thread for the delayed execution
thread = threading.Thread(target=delayed_execution, args=(stop_time,))
# Start the thread
thread.start()
# Main program continues without waiting for the thread
# print("Main program continues...")
# print('COUNTDOWN!!!', device, oper, value)
# print(device.get_parameter(value), device.get_parameter_value(value))
return True
else: else:
return False return False
@@ -1421,6 +1428,7 @@ class ControlServer(SocketServer, ControlServerAPI):
if client is not None: if client is not None:
with client: with client:
client.show_data(device) client.show_data(device)
class _RandomCrashThread(ServerThread): class _RandomCrashThread(ServerThread):
def __init__(self): def __init__(self):
super().__init__('Crash') super().__init__('Crash')
File diff suppressed because it is too large Load Diff
+343
View File
@@ -0,0 +1,343 @@
{
"name": "CPG",
"version": "1.2.30",
"match_rule": {
"local_name_pattern": "Elite-CPG.*",
"major_product_number": 0,
"minor_product_number": 8,
"major_version_number": 0,
"minor_version_number": 1
},
"constant": {
"TIME_MAX": 100000,
"VOLT_MAX": 65536,
"Const_Current_Range": 1500001,
"BLE_WRITE_MAX": 255
},
"parameters": {
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"FREQUENCY": {
"description": "FREQUENCY",
"record_meta": true,
"initial": [80, 0],
"domain": {
"list": [1000000]
}
},
"AMPLITUDE": {
"description": "AMPLITUDE",
"record_meta": true,
"initial": [1, 1],
"domain": {
"list": "float"
}
},
"PULSE_WIDTH": {
"description": "PULSE_WIDTH",
"record_meta": true,
"initial": [250, 250],
"domain": {
"list": [1000000]
}
},
"PATTERN_MODE": {
"description": "SELECT_ELECTRODE",
"record_meta": true,
"initial": [1, 0],
"domain": {
"list": "float"
}
},
"CONTINUE_MODE": {
"description": "CONTINUE_MODE",
"record_meta": true,
"initial": 1,
"domain": [2],
"value": {
"expression": "VALUE"
}
},
"STOP_TIME": {
"description": "STOP_TIME",
"record_meta": true,
"initial": 30,
"domain": [1000000],
"value": {
"expression": "VALUE"
}
},
"ELECTRODE_SELECTOR": {
"description": "ELECTRODE_SELECTOR",
"record_meta": true,
"initial": [true,false,true,false],
"domain": {
"list": [2]
}
},
"WORKING_ELECTRODE": {
"description": "WORKING_ELECTRODE",
"record_meta": true,
"initial": [0, 0, 0, 0],
"domain": {
"list": "float"
}
},
"PATTERN_SELECTOR": {
"description": "PATTERN_SELECTOR",
"record_meta": true,
"initial": [0, 0, 1, 1],
"domain": {
"list": "float"
}
},
"ACTIVATE_ELECTRODE": {
"description": "PATTERN_SELECTOR",
"record_meta": true,
"initial": 0,
"domain": "float"
},
"CHANNEL": {
"description": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"CHANNEL_LABEL": {
"description": "channel label",
"record_meta": true,
"domain": "property",
"value": "['current', 'voltage', 'impedance']"
},
"SAMPLE_RATE": {
"description": "data sampling rate",
"record_meta": true,
"initial": 1000,
"domain": [
1001
],
"value": {
"expression": "VALUE"
},
"on_change": "set_sample_rate"
},
"AMP_GAIN": {
"description": "amp gain",
"record_meta": true,
"domain": "constant",
"value": 1
},
"MODE": {
"description": "working mode",
"record_meta": true,
"initial": 0,
"value": [
"Electrical stimulation",
"Dev Mode"
]
},
"BLE_WRITE": {
"description": "send msg to elite",
"domain": {
"list": [
"BLE_WRITE_MAX"
]
},
"initial": "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]",
"value": "VALUE"
},
"BLE_READ": {
"description": "receive msg from elite",
"domain": "int"
},
"TIME_UNIT": {
"description": "Duration unit",
"initial": 2,
"value": [
"h",
"m",
"s",
"ms"
]
},
"TIME_DURATION": {
"description": "Run duration",
"record_meta": true,
"initial": 0,
"domain": [
"TIME_MAX"
],
"value": {
"expression": "VALUE"
}
}
},
"instruction": {
"output": [
"active_electrode",
"_countdown('PULSE_OUTPUT')"
],
"active_electrode": {
"type": "RIS",
"parameter": {
"ch0": "ELECTRODE_SELECTOR[0]",
"ch1": "ELECTRODE_SELECTOR[1]",
"ch2": "ELECTRODE_SELECTOR[2]",
"ch3": "ELECTRODE_SELECTOR[3]",
"Amp1": {
"expression": "PATTERN_SELECTOR[0]",
"when": {
"0": "AMPLITUDE[0]",
"1": "AMPLITUDE[1]"
}
},
"Freq1": {
"expression": "PATTERN_SELECTOR[0]",
"when": {
"0": "FREQUENCY[0]",
"1": "FREQUENCY[1]"
}
},
"Pulse1": {
"expression": "PATTERN_SELECTOR[0]",
"when": {
"0": "PULSE_WIDTH[0]",
"1": "PULSE_WIDTH[1]"
}
},
"Amp2": {
"expression": "PATTERN_SELECTOR[2]",
"when": {
"0": "AMPLITUDE[0]",
"1": "AMPLITUDE[1]"
}
},
"Freq2": {
"expression": "PATTERN_SELECTOR[2]",
"when": {
"0": "FREQUENCY[0]",
"1": "FREQUENCY[1]"
}
},
"Pulse2": {
"expression": "PATTERN_SELECTOR[2]",
"when": {
"0": "PULSE_WIDTH[0]",
"1": "PULSE_WIDTH[1]"
}
}
},
"data": [
"1XFF;1X02;1XA0;",
"1bch0;1bch1;6b000000;",
"4BAmp1;4BPulse1;4BFreq1;",
"2b00;1bch2;1bch3;4b0000;",
"4BAmp2;4BPulse2;4BFreq2;",
"4BSTOP_TIME;",
"1bch0;1bch1;1bch2;1bch3;4b0000;"
]
},
"deactive_electrode": {
"type": "RIS",
"parameter": {
"ch0": "ELECTRODE_SELECTOR[0]",
"ch1": "ELECTRODE_SELECTOR[1]",
"ch2": "ELECTRODE_SELECTOR[2]",
"ch3": "ELECTRODE_SELECTOR[3]"
},
"data": [
"1XFF;1X02;1XA1;",
"1bch0;1bch1;1bch2;1bch3;4b0000;"
]
},
"resume_electrode_0": {
"type": "RIS",
"data": [
"1XFF;1X02;1X06;4b1000;4b0000;"
]
},
"resume_electrode_1": {
"type": "RIS",
"data": [
"1XFF;1X02;1X06;4b0100;4b0000;"
]
},
"resume_electrode_2": {
"type": "RIS",
"data": [
"1XFF;1X02;1X06;4b0010;4b0000;"
]
},
"resume_electrode_3": {
"type": "RIS",
"data": [
"1XFF;1X02;1X06;4b0001;4b0000;"
]
},
"suspend_electrode_0": {
"type": "RIS",
"data": [
"1XFF;1X02;1X05;4b1000;4b0000;"
]
},
"suspend_electrode_1": {
"type": "RIS",
"data": [
"1XFF;1X02;1X05;4b0100;4b0000;"
]
},
"suspend_electrode_2": {
"type": "RIS",
"data": [
"1XFF;1X02;1X05;4b0010;4b0000;"
]
},
"suspend_electrode_3": {
"type": "RIS",
"data": [
"1XFF;1X02;1X05;4b0001;4b0000;"
]
},
"idle": [
"_idle()"
],
"data_format": [
"_data_format('I4V4Z4T4')",
{
"expression": "MODE",
"when": {
"0": "_disable_cache(True)",
"1": "_disable_cache(True)",
"*": "_disable_cache(False)"
}
}
],
"ble_instru_send": [
"ble_write",
"_cdr('20X>ADC_VALUE_I')"
],
"ble_write": {
"type": "ALL",
"data": [
"255X>BLE_WRITE;"
]
},
"dev_version": [
"CIS_VERSION",
"_cdr('20X>ADC_VALUE_I')"
],
"dev_battery": [
"CIS_VOLT",
"_cdr('20X>ADC_VALUE_I')"
],
"set_para_DAC_VOLT": {
"type": "RIS",
"data": [
"XE2;X01;2B>DAC_VOLT"
]
}
}
}
@@ -1,12 +1,12 @@
{ {
"name": "Elite_EDC_1.5re", "name": "Elite_EDC_1.5r2",
"version": "1.2.30", "version": "1.2.30",
"match_rule": { "match_rule": {
"local_name_pattern": "Elite.*", "local_name_pattern": "Elite.*",
"major_product_number": 0, "major_product_number": 0,
"minor_product_number": 2, "minor_product_number": 2,
"major_version_number": 1, "major_version_number": 1,
"minor_version_number": 7 "minor_version_number": 8
}, },
"constant": { "constant": {
"TIME_MAX": 100000, "TIME_MAX": 100000,
File diff suppressed because it is too large Load Diff
@@ -58,7 +58,7 @@
"value": "VALUE" "value": "VALUE"
}, },
"CYCLE": { "CYCLE": {
"initial": [0, 0, 0, 0, 0, 0, 0, 0], "initial": [1, 1, 1, 1, 1, 1, 1, 1],
"domain": { "domain": {
"list": [ "list": [
0, 65535 0, 65535
@@ -332,6 +332,7 @@
"MODE": { "MODE": {
"description": "working mode", "description": "working mode",
"record_meta": true, "record_meta": true,
"initial": 3,
"value": [ "value": [
"Analog Current Control (ACC)", "Analog Current Control (ACC)",
"Idle", "Idle",
+122
View File
@@ -0,0 +1,122 @@
{
"name": "PEL_1.0",
"version": "1.2.30",
"match_rule": {
"local_name_pattern": "Elite-PEL.*",
"major_product_number": 0,
"minor_product_number": 7,
"major_version_number": 0,
"minor_version_number": 0
},
"constant": {
"TIME_MAX": 100000,
"VOLT_MAX": 65536,
"Const_Current_Range": 1500001,
"BLE_WRITE_MAX": 255
},
"parameters": {
"CHANNEL": {
"description": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"SAMPLE_RATE": {
"description": "data sampling rate",
"record_meta": true,
"initial": 1000,
"domain": [
1001
],
"value": {
"expression": "VALUE"
},
"on_change": "set_sample_rate"
},
"AMP_GAIN": {
"description": "amp gain",
"record_meta": true,
"domain": "constant",
"value": 1
},
"PATTERN_SWITCH": {
"description": "switch of pattern",
"initial": 1,
"domain": [
2
],
"value": {
"expression": "VALUE"
}
},
"PULSE": {
"description": "Pulse Mode Segment Duration 2",
"record_meta": true,
"initial": [
0,
0,
0
],
"domain": {
"list": [
66536
]
},
"value": {
"expression": "VALUE"
}
},
"PATTERN": {
"description": "Pulse Mode Segment Duration 2",
"record_meta": true,
"initial": 1,
"domain": [
44
],
"value": {
"expression": "VALUE"
}
}
},
"instruction": {
"start": [
"pulse_e_load"
],
"pulse_e_load": [
{
"expression": "PATTERN_SWITCH",
"when": {
"0": "pattern",
"1": "manual"
}
}
],
"manual": {
"type": "RIS",
"parameter": {
"pa": "PULSE[0]",
"pb": "PULSE[1]",
"pc": "PULSE[2]"
},
"data": [
"XFF;",
"X62;",
"4b1;4b>pa;4b>pb;4b>pc;"
]
},
"pattern": {
"type": "RIS",
"parameter": {
"pa": "PATTERN"
},
"data": [
"XFF;X62;",
"4b>0;12b>pa;"
]
},
"ble_instru_send": [
"ble_write",
"_cdr('20X>ADC_VALUE_I')"
]
}
}
+155
View File
@@ -0,0 +1,155 @@
{
"name": "PEL_2.0",
"version": "1.2.30",
"match_rule": {
"local_name_pattern": "Elite-PEL.*",
"major_product_number": 0,
"minor_product_number": 7,
"major_version_number": 0,
"minor_version_number": 1
},
"constant": {
"TIME_MAX": 100000,
"VOLT_MAX": 65536,
"Const_Current_Range": 1500001,
"BLE_WRITE_MAX": 255
},
"parameters": {
"CHANNEL": {
"description": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"SAMPLE_RATE": {
"description": "data sampling rate",
"record_meta": true,
"initial": 1000,
"domain": [
1001
],
"value": {
"expression": "VALUE"
},
"on_change": "set_sample_rate"
},
"AMP_GAIN": {
"description": "amp gain",
"record_meta": true,
"domain": "constant",
"value": 1
},
"MODE": {
"description": "working mode",
"record_meta": true,
"initial": 0,
"value": [
"Select Resistor Mode",
"Dev Mode"
]
},
"BLE_WRITE": {
"description": "send msg to elite",
"domain": {
"list": [
"BLE_WRITE_MAX"
]
},
"initial": "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]",
"value": "VALUE"
},
"BLE_READ": {
"description": "receive msg from elite",
"domain": "int"
},
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"PATTERN_SWITCH": {
"description": "switch of pattern",
"initial": 1,
"domain": [
2
],
"value": {
"expression": "VALUE"
}
},
"PULSE": {
"description": "Pulse Mode Segment Duration 2",
"record_meta": true,
"initial": [
0,
0,
0
],
"domain": {
"list": [
66536
]
},
"value": {
"expression": "VALUE"
}
},
"PATTERN": {
"description": "Pulse Mode Segment Duration 2",
"record_meta": true,
"initial": 1,
"domain": [
44
],
"value": {
"expression": "VALUE"
}
}
},
"instruction": {
"start": [
"pulse_e_load"
],
"pulse_e_load": [
{
"expression": "PATTERN_SWITCH",
"when": {
"0": "pattern",
"1": "manual"
}
}
],
"manual": {
"type": "RIS",
"parameter": {
"pa": "PULSE[0]",
"pb": "PULSE[1]",
"pc": "PULSE[2]"
},
"data": [
"XFF;",
"X62;",
"4b1;4b>pa;4b>pb;4b>pc;"
]
},
"pattern": {
"type": "RIS",
"parameter": {
"pa": "PATTERN"
},
"data": [
"XFF;X62;",
"4b>0;12b>pa;"
]
},
"ble_instru_send": [
"ble_write",
"_cdr('20X>ADC_VALUE_I')"
],
"ble_write": {
"type": "ALL",
"data": [
"255X>BLE_WRITE;"
]
}
}
}