Compare commits

..

5 Commits

Author SHA1 Message Date
peterlu14 aa9d270039 -fix DetachedInstanceError 2023-06-08 10:17:06 +08:00
peterlu14 32bc481a91 -update add subject write in same folder 2023-06-08 10:17:04 +08:00
peterlu14 0e30bd1263 -update db_update_script 2023-06-08 10:16:50 +08:00
peterlu14 dda51889dc -fix import error 2023-06-08 10:15:46 +08:00
peterlu14 0c811f529b -update subject 2023-06-05 11:55:36 +08:00
27 changed files with 387 additions and 5192 deletions
+30 -15
View File
@@ -20,29 +20,44 @@ class Collection(Base):
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now()) updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
@classmethod @classmethod
def create_collection(cls, collection_name, parent): def create_collection(cls, collection_name, parent, duplicate=False):
with Session() as session: with Session() as session:
name = cls.check_name_duplicate(collection_name, parent, 0) name = cls.check_name_duplicate(collection_name, parent, 0, duplicate=duplicate)
collection = Collection( if name == None:
name = name, return session.query(Collection).filter(Collection.name == collection_name, Collection.parent == parent).first()
parent = parent, else:
type= "folder", collection = Collection(
) name = name,
session.add(collection) parent = parent,
session.commit() type= "folder",
print('a', collection.id) )
return collection session.add(collection)
session.commit()
session.refresh(collection)
return collection
@classmethod @classmethod
def check_name_duplicate(cls, collection_name, parent, n): def check_name_duplicate(cls, collection_name, parent, n, _session = None, duplicate=False):
with Session() as session: if _session == None:
result = session.query(Collection).filter(Collection.name == cls.generate_name(collection_name, n), Collection.parent == parent).first() with Session() as session:
result = session.query(Collection).filter(Collection.name == cls.generate_name(collection_name, n), Collection.parent == parent).first()
if result is None:
return cls.generate_name(collection_name, n)
else:
if duplicate == True:
return None
else:
new_num = n + 1
# new_name = f"{collection_name}({new_num})"
return cls.check_name_duplicate(collection_name, parent, new_num, session)
else:
result = _session.query(Collection).filter(Collection.name == cls.generate_name(collection_name, n), Collection.parent == parent).first()
if result is None: if result is None:
return cls.generate_name(collection_name, n) return cls.generate_name(collection_name, n)
else: else:
new_num = n + 1 new_num = n + 1
# new_name = f"{collection_name}({new_num})" # new_name = f"{collection_name}({new_num})"
return cls.check_name_duplicate(collection_name, parent, new_num) return cls.check_name_duplicate(collection_name, parent, new_num, _session)
@classmethod @classmethod
def generate_name(cls, collection_name, n): def generate_name(cls, collection_name, n):
+24
View File
@@ -0,0 +1,24 @@
from sqlalchemy import Table, Column, String, MetaData, ForeignKey, JSON
from sqlalchemy.sql import select, func
from sqlalchemy.types import Integer, BigInteger, String, Boolean, TIMESTAMP, Numeric
from sqlalchemy.dialects.postgresql import JSONB
from .base import Base, Session
class RecordingDataMeta(Base):
__tablename__ = "recording_data_metas"
id = Column(Integer, primary_key=True)
path = Column(String(255))
name = Column(String(255))
parent = Column(JSONB)
size = Column(String(255))
time_duration = (String(255))
raw_data = Column(JSONB)
project = Column(Integer)
deleted = Column(Boolean, default = False)
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
# def __repr__(self):
# return f"User(id={self.id!r}, name={self.name!r}, fullname={self.task!r})"
+88
View File
@@ -0,0 +1,88 @@
from sqlalchemy import Table, Column, String, MetaData, ForeignKey, JSON
from sqlalchemy.sql import select, func
from sqlalchemy.types import Integer, BigInteger, String, Boolean, TIMESTAMP, Numeric, Text
from sqlalchemy.dialects.postgresql import JSONB
from biopro.db.base import Session
from .base import Base
# build a model class with a specific table name
def get_raw_model(channel):
tablename = str(channel) + '_recording_data_raws' # dynamic table name
class_name = 'RECORDING_DATA_RAWS' # dynamic class name
print('get_raw_model', tablename)
for mapper in Base.registry.mappers:
cls = mapper.class_
classname = cls.__name__
tblname = cls.__tablename__
print(cls, classname, tblname)
if (classname == class_name):
if tblname == tablename:
return cls
Model = type(class_name, (RECORDING_DATA_RAWS,), {
'__tablename__': tablename
})
return Model
class RECORDING_DATA_RAWS(Base):
__abstract__ = True
id = Column(Integer, primary_key=True)
name = Column(String(255))
parent = Column(Integer)
size = Column(String(255))
path = Column(JSONB)
uuid = Column(String(255))
serial_number = Column(String(255))
data_format = Column(String(255))
channel = Column(Integer)
start_time = Column(String(255))
end_time = Column(String(255))
data = Column(Text)
compressed = Column(Boolean)
deleted = Column(Boolean)
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
# @classmethod
# def create_subject_data(cls, subject_id, project, meta, data):
# with Session() as session:
# subject = Subject(
# subject_id = subject_id,
# project = project,
# meta= meta,
# data = data
# )
# session.add(subject)
# session.commit()
# return subject
# @classmethod
# def check_name_duplicate(cls, collection_name, parent, n):
# with Session() as session:
# result = session.query(Collection).filter(Collection.name == cls.generate_name(collection_name, n), Collection.parent == parent).first()
# if result is None:
# return cls.generate_name(collection_name, n)
# else:
# new_num = n + 1
# # new_name = f"{collection_name}({new_num})"
# return cls.check_name_duplicate(collection_name, parent, new_num)
# @classmethod
# def generate_name(cls, collection_name, n):
# if n==0:
# return collection_name
# else:
# return f"{collection_name}({n})"
# @classmethod
# def find_data(cls, id):
# with Session() as session:
# result = session.query(RECORDING_DATA_RAWS).first()
# return result
+60
View File
@@ -0,0 +1,60 @@
from sqlalchemy import Table, Column, String, MetaData, ForeignKey, JSON
from sqlalchemy.sql import select, func
from sqlalchemy.types import Integer, BigInteger, String, Boolean, TIMESTAMP, Numeric
from sqlalchemy.dialects.postgresql import JSONB
from biopro.db.base import Session
from .base import Base
class SubjectData(Base):
__tablename__ = "subject_datas"
id = Column(Integer, primary_key=True)
subject_id = Column(Integer)
mode = Column(JSONB)
data = Column(JSONB)
user_auth = Column(JSONB)
meta = Column(String(255))
project = Column(String(255))
deleted = Column(Boolean)
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
@classmethod
def create_subject_data(cls, subject_id, project, meta, data):
with Session() as session:
subject = SubjectData(
subject_id = subject_id,
project = project,
meta= meta,
data = data
)
session.add(subject)
session.commit()
return subject
# @classmethod
# def check_name_duplicate(cls, collection_name, parent, n):
# with Session() as session:
# result = session.query(Collection).filter(Collection.name == cls.generate_name(collection_name, n), Collection.parent == parent).first()
# if result is None:
# return cls.generate_name(collection_name, n)
# else:
# new_num = n + 1
# # new_name = f"{collection_name}({new_num})"
# return cls.check_name_duplicate(collection_name, parent, new_num)
# @classmethod
# def generate_name(cls, collection_name, n):
# if n==0:
# return collection_name
# else:
# return f"{collection_name}({n})"
# @classmethod
# def find_collection(cls, collection_name, parent):
# with Session() as session:
# result = session.query(Collection).filter(Collection.name == collection_name, Collection.parent == parent).first()
# return result
+20 -61
View File
@@ -429,20 +429,17 @@ 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, *instruction) return struct.pack('%dB' % (length + 2),
else: (ins_type & 0xF0) | (self.device_id & 0x0F),
return struct.pack('%dB' % (length + 2), (ins_oper & 0xFF),
(ins_type & 0xF0) | (self.device_id & 0x0F), *instruction)
(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.
@@ -486,19 +483,17 @@ 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) minute) + " | " + str(mac1) + ":" + str(mac2)
# + " | " + str(mac1) + ":" + str(mac2)
@property @property
def battery(self) -> int: def battery(self) -> int:
if self._start_flag == False: self.update_battery_info()
self.update_battery_info()
return self._battery return self._battery
@property @property
@@ -2178,7 +2173,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
@@ -2186,23 +2181,16 @@ 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)
elif pack_len == 4: if connect_ack[0] == 46 and connect_ack[1] == 80 and \
if connect_ack[0] == 46 and connect_ack[1] == 80 and \ connect_ack[2] == 48 and connect_ack[3] == 4:
connect_ack[2] == 48 and connect_ack[3] == 4: connected = True
connected = True connect_response_hex = ''.join(format(i, '02X') for i in connect_response)
connect_response_hex = ''.join(format(i, '02X') for i in connect_response) self.log_verbose('[CC2650]', 'connect success', '0x'+connect_response_hex)
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
@@ -2212,8 +2200,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
self.log_verbose('[CC2650]', DEVICE_CONNECTED, address_s) self.log_verbose('[CC2650]', DEVICE_CONNECTED, address_s)
return ret return ret
connect_response_hex = ''.join(format(i, '02X') for i in connect_response) self.log_verbose('[CC2650]', 'connect fail')
self.log_verbose('[CC2650]', 'connect fail', '0x'+connect_response_hex)
return False return False
@synchronized @synchronized
@@ -2225,7 +2212,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
ins.append(0xF1) ins.append(0xF1)
self._interface.flush_input() self._interface.flush_input()
for retry in range(5): for _ 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))
@@ -2239,30 +2226,6 @@ 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
@@ -2273,10 +2236,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
ins = bytearray() ins = bytearray()
ins.append(0x06) ins.append(0x06)
if len(data) + 2 > 255: ins.append(len(data)+2) #length = handle + C0C0XXXX(data len) + F1
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)
@@ -2298,7 +2258,6 @@ 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]
-8
View File
@@ -836,9 +836,6 @@ 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
@@ -861,11 +858,6 @@ 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:
+1 -19
View File
@@ -854,8 +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', '_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__()
@@ -872,10 +871,6 @@ 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
@@ -940,19 +935,6 @@ 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]
+1 -5
View File
@@ -689,13 +689,11 @@ 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, cls.TYP_ALL): if ins_type not in (cls.TYP_RIS, cls.TYP_VIS, cls.TYP_CIS, cls.TYP_IIS):
raise ValueError('unknown instruction type : ' + str(ins_type)) raise ValueError('unknown instruction type : ' + str(ins_type))
@classmethod @classmethod
@@ -706,8 +704,6 @@ 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)
+3 -29
View File
@@ -120,9 +120,6 @@ 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
@@ -294,25 +291,6 @@ 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 """
@@ -323,7 +301,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 = initial initial = int(initial)
f, t = self.range f, t = self.range
if f <= initial < t: if f <= initial < t:
@@ -764,7 +742,6 @@ 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
@@ -803,11 +780,8 @@ class ParameterListDomain(ParameterCollectionDomain):
if isinstance(v, int): if isinstance(v, int):
v = [v] v = [v]
target[len(v):] = []
if isinstance(d, ParameterFloatDomainType): target[i] = v
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:
+2 -1
View File
@@ -880,7 +880,8 @@ class WhenExpression(ComplexExpression[T]):
def value(self, context: Scope) -> Union[str, T]: def value(self, context: Scope) -> Union[str, T]:
value = super().value(context) value = super().value(context)
key = str(int(value))
key = str(value)
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,13 +5,6 @@ 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
@@ -451,12 +444,6 @@ 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,
+14 -28
View File
@@ -1,5 +1,4 @@
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
@@ -285,7 +284,6 @@ 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,
@@ -298,7 +296,6 @@ 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')
@@ -378,7 +375,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.
@@ -591,7 +588,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**
@@ -685,7 +682,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**
@@ -746,7 +743,6 @@ 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()
@@ -754,33 +750,24 @@ 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 = self.value(context) value = int(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:
if isinstance(self.value(context), list): tmp = []
buffer.extend(value) for _ in range(self._width.size):
elif isinstance(value, int): tmp.append(value & 0xFF)
tmp = [] value >>= 8
for _ in range(self._width.size):
tmp.append(value & 0xFF) if self._width.little_endian:
value >>= 8 buffer.extend(tmp)
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:
@@ -807,7 +794,6 @@ 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))
@@ -1125,7 +1111,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
+4 -11
View File
@@ -359,7 +359,6 @@ 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()
@@ -523,7 +522,6 @@ 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)
@@ -1130,21 +1128,13 @@ 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
if isinstance(value, str): value = int(value)
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)
@@ -1302,6 +1292,9 @@ class CompletedDevice(Device):
def central_version_get(self) -> Optional[list]: def central_version_get(self) -> Optional[list]:
return self._device.central_version_get() return self._device.central_version_get()
def save_data_to_subject(self, project, meta, device, subject_id):
self._master._handler.save_data_to_subject(project, meta, device, subject_id)
# utility method # utility method
-2
View File
@@ -433,7 +433,6 @@ 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
@@ -618,7 +617,6 @@ 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:
+19 -34
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_0001 # 0x41 DEFAULT_REGISTER_VALUE = 0b0100_0011 # 67
MEM_SIZE = 0x1000 MEM_SIZE = 0x1000
_SLEEP_TIME_ = 0.001 _SLEEP_TIME_ = 0.001
@@ -457,16 +457,6 @@ 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
@@ -503,31 +493,28 @@ class ExtMemManager:
ret[channel] = tuple(r) ret[channel] = tuple(r)
print('ret=', ret)
return ret return ret
@staticmethod @staticmethod
def is_memory_test_fail(result: Tuple[Optional[int], Optional[int]], channel: int) -> int: def is_no_device(result: Tuple[Optional[int], Optional[int]]) -> bool:
r1, r2 = result r1, r2 = result
r1_check = False return (r1 is None or r2 is None) and (r1 is None or r1 == 0) and (r2 is None or r2 == 0)
r2_check = False
if r1 is not None and r1 != 0: @staticmethod
if (r1 & 0b11000001 == DEFAULT_REGISTER_VALUE & 0b11000001): def is_memory_test_fail(result: Tuple[Optional[int], Optional[int]]) -> int:
r1_check = True r1, r2 = result
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_check and r2_check: if r1 is None or r2 is None:
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()
@@ -535,14 +522,12 @@ class ExtMemManager:
ret = [] ret = []
for channel, result in enumerate(result): for channel, result in enumerate(result):
if self.is_memory_test_fail(result, channel) != 0: if self.is_no_device(result):
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
+26 -1
View File
@@ -49,6 +49,9 @@ class Project(threading.Thread):
self._count = 1 #流水號 self._count = 1 #流水號
self._project_meta_id = -1
self._subject = []
self.log_verbose = log_verbose self.log_verbose = log_verbose
self._logger = logging.getLogger('project') self._logger = logging.getLogger('project')
self._logger.setLevel('DEBUG') self._logger.setLevel('DEBUG')
@@ -69,7 +72,10 @@ class Project(threading.Thread):
collection = Collection.find_collection(default_name, default_parent) collection = Collection.find_collection(default_name, default_parent)
parent = {"folder": [collection.id]} parent = {"folder": [collection.id]}
# create project folder # create project folder
collection = Collection.create_collection(self.name, parent) folder_name_duplicate = False
if len(self._subject) > 0:
folder_name_duplicate = True
collection = Collection.create_collection(self.name, parent, folder_name_duplicate)
self.setup_collection(collection) self.setup_collection(collection)
def setup_project(self, project): def setup_project(self, project):
@@ -101,6 +107,22 @@ class Project(threading.Thread):
@id.setter @id.setter
def id(self, new_id): def id(self, new_id):
self._id = new_id self._id = new_id
@property
def project_meta_id(self) -> int:
return self._project_meta_id
@project_meta_id.setter
def project_meta_id(self, new_project_meta_id):
self._project_meta_id = new_project_meta_id
@property
def subject(self) -> object:
return self._subject
@subject.setter
def subject(self, new_subject):
self._subject = new_subject
@property @property
def uuid(self) -> str: def uuid(self) -> str:
@@ -278,6 +300,9 @@ class Project(threading.Thread):
args = list(map(lambda arg: task_info[arg], instruction['arguments'])) args = list(map(lambda arg: task_info[arg], instruction['arguments']))
target=getattr(device, instruction['method'])(*args) target=getattr(device, instruction['method'])(*args)
print('instruction 2', device, instruction, datetime.now()) print('instruction 2', device, instruction, datetime.now())
if (action.type == 'stop'):
if (len(self._subject) > 0):
target=getattr(device, "save_data_to_subject")(self.id, self.project_meta_id, device, self._subject[0])
if action.type == 'start': if action.type == 'start':
self._count += 1 self._count += 1
+1 -1
View File
@@ -175,7 +175,7 @@ class TaskManager():
for index, task in enumerate(self._task_list): for index, task in enumerate(self._task_list):
if self.check_task_in_cycle(index) == True: if self.check_task_in_cycle(index) == True:
if task.type == '': if task.type == '':
collection = Collection.create_collection(task.name, {"folder": [parent.id]}) collection = Collection.create_collection(task.name, {"folder": [parent.id]}, False)
task.parent = {"folder": [collection.id]} task.parent = {"folder": [collection.id]}
else: else:
task.parent = {"folder": [parent.id]} task.parent = {"folder": [parent.id]}
+82 -38
View File
@@ -2,8 +2,6 @@ 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
@@ -37,8 +35,11 @@ from biopro.project.project_manager import ProjectManager
from biopro.db.base import Base, Session, engine from biopro.db.base import Base, Session, engine
from biopro.db.project_report import ProjectReport from biopro.db.project_report import ProjectReport
from biopro.db.project_meta import MetaProjectInfo from biopro.db.project_meta import MetaProjectInfo
from biopro.db.device import Device # from biopro.db.device import Device
from biopro.db.recording_data import get_raw_model
from biopro.db.subject_data import SubjectData
from biopro.db.meta import RecordingDataMeta
import random
_RUNTIME_COMPILE = False _RUNTIME_COMPILE = False
@@ -331,6 +332,18 @@ 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)
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()
@@ -560,8 +573,15 @@ class ControlServer(SocketServer, ControlServerAPI):
response = content response = content
else: else:
response = to_device_info(content) response = to_device_info(content)
try: try:
# 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))
ret = self.device_manager.connect(response) ret = self.device_manager.connect(response)
except DeviceInstructionError as e: except DeviceInstructionError as e:
'''when device reset fail error''' '''when device reset fail error'''
@@ -870,7 +890,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'): if connect_device.library.name.startswith('Elite_EIS_1.1'):
# 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
@@ -1095,34 +1115,6 @@ 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
@@ -1137,7 +1129,7 @@ class ControlServer(SocketServer, ControlServerAPI):
client = self.data_server.client() client = self.data_server.client()
project = None project = None
project_meta_id = None _project_meta_id = None
if client is not None: if client is not None:
info = self.file_manager.use(device) info = self.file_manager.use(device)
@@ -1151,10 +1143,12 @@ class ControlServer(SocketServer, ControlServerAPI):
if device.occupied_by_project != None: if device.occupied_by_project != None:
project = self.project_manager.get(device.occupied_by_project).info_pass_data_server() project = self.project_manager.get(device.occupied_by_project).info_pass_data_server()
project_meta_id = MetaProjectInfo.create_project_meta(project) _project_meta_id = MetaProjectInfo.create_project_meta(project)
new_project = self.project_manager.get(device.occupied_by_project)
new_project.project_meta_id = _project_meta_id
with client: with client:
client.update_device_configuration(device, info.meta_file, value, project_meta_id) client.update_device_configuration(device, info.meta_file, value, _project_meta_id)
def _device_set_disable_cache(self, device: CompletedDevice, disable): def _device_set_disable_cache(self, device: CompletedDevice, disable):
if disable: if disable:
@@ -1384,6 +1378,57 @@ class ControlServer(SocketServer, ControlServerAPI):
} for pkg in PipPackage.list()] } for pkg in PipPackage.list()]
return ret return ret
def save_data_to_subject(self, project, meta, device, subject):
mode = device.get_parameter('MODE')
library = device.library_name
device = {
"library": library,
"mode": mode
}
# "pattern": {
# "id": number,
# "name": string,
# "parameter": object,
# },
# "data": {
# "id": list[int],
# "channel: list[int]
# }
with Session() as session:
meta_result = session.query(RecordingDataMeta).filter(RecordingDataMeta.project == meta).first()
self.mqtt_thread.publish('', json.dumps({
"pattern": {
"id": 4,
},
"data": {
"id": [meta_result.id],
"channel": ['Time', 6]
},
"others": {
"subject": subject,
"device": device,
"project": project,
"project_meta": meta,
}
}), analysis= True)
# result = session.query(recording_raws).order_by(recording_raws.id.desc()).first()
# value = result.data.split(' ')[1:-1:2]
# _value = list(map(int, value))
# sum_value = sum(_value)
# average_value = sum_value / len(_value)
# subject_data = SubjectData(
# subject_id= subject['id'],
# project = project,
# meta = meta,
# mode= device,
# data= average_value
# )
# # Execute the update query
# session.add(subject_data)
# session.commit()
def _hardware_send_test_hardware(self, section: Optional[str] = None) -> Dict[str, Any]: def _hardware_send_test_hardware(self, section: Optional[str] = None) -> Dict[str, Any]:
if section is not None: if section is not None:
@@ -1428,7 +1473,6 @@ 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')
+3 -1
View File
@@ -170,9 +170,11 @@ class MqttThread(threading.Thread):
self.sleep(3) self.sleep(3)
self._mqtt_client_local.reconnect() self._mqtt_client_local.reconnect()
def publish(self, topic: str, payload: str, inter = False, qos = 2): def publish(self, topic: str, payload: str, inter = False, analysis=False, qos = 2):
if inter: if inter:
_topic = self.__controller_ID + '_user' _topic = self.__controller_ID + '_user'
elif analysis:
_topic = self.__controller_ID + '_data_analysis/get_analysis_data'
else: else:
_topic = self.__controller_ID + '/' + topic _topic = self.__controller_ID + '/' + topic
if self._mqtt_client_local is not None: if self._mqtt_client_local is not None:
File diff suppressed because it is too large Load Diff
-343
View File
@@ -1,343 +0,0 @@
{
"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.5r2", "name": "Elite_EDC_1.5re",
"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": 8 "minor_version_number": 7
}, },
"constant": { "constant": {
"TIME_MAX": 100000, "TIME_MAX": 100000,
File diff suppressed because it is too large Load Diff
@@ -10,170 +10,9 @@
}, },
"constant": { "constant": {
"TIME_MAX": 100000, "TIME_MAX": 100000,
"BLE_WRITE_MAX": 255, "BLE_WRITE_MAX": 255
"MODE_ALL_OUTPUT": 15,
"ELITE_CH_PR0": 0,
"ELITE_CH_D0": 1,
"ELITE_CH_A0": 2,
"ELITE_CH_A2": 3,
"ELITE_CH_A3": 4,
"ELITE_CH_A1": 5,
"ELITE_CH_D1": 6,
"ELITE_CH_PR1": 7,
"PR0": 0,
"PR1": 1,
"D0": 2,
"D1": 3,
"A0": 4,
"A1": 5,
"A2": 6,
"A3": 7
}, },
"parameters": { "parameters": {
"USED": {
"initial": [false, false, false, false, false, false, false, false],
"domain": {
"list": [
0, 2
]
},
"value": "VALUE"
},
"T_EARLY": {
"initial": [0, 0, 0, 0, 0, 0, 0, 0],
"domain": {
"list": [
0, 86400000
]
},
"value": "VALUE"
},
"V_EARLY": {
"initial": [false, false, false, false, false, false, false, false],
"domain": {
"list": [
0, 2
]
},
"value": "VALUE"
},
"CYCLE": {
"initial": [1, 1, 1, 1, 1, 1, 1, 1],
"domain": {
"list": [
0, 65535
]
},
"value": "VALUE"
},
"T_MID0": {
"initial": [0, 0, 0, 0, 0, 0, 0, 0],
"domain": {
"list": [
0, 86400000
]
},
"value": "VALUE"
},
"T_MID1": {
"initial": [0, 0, 0, 0, 0, 0, 0, 0],
"domain": {
"list": [
0, 86400000
]
},
"value": "VALUE"
},
"T_MID2": {
"initial": [0, 0, 0, 0, 0, 0, 0, 0],
"domain": {
"list": [
0, 86400000
]
},
"value": "VALUE"
},
"T_MID3": {
"initial": [0, 0, 0, 0, 0, 0, 0, 0],
"domain": {
"list": [
0, 86400000
]
},
"value": "VALUE"
},
"V_MID0": {
"initial": [false, false, false, false, false, false, false, false],
"domain": {
"list": [
0, 2
]
},
"value": "VALUE"
},
"V_MID1": {
"initial": [false, false, false, false, false, false, false, false],
"domain": {
"list": [
0, 2
]
},
"value": "VALUE"
},
"V_MID2": {
"initial": [false, false, false, false, false, false, false, false],
"domain": {
"list": [
0, 2
]
},
"value": "VALUE"
},
"V_MID3": {
"initial": [false, false, false, false, false, false, false, false],
"domain": {
"list": [
0, 2
]
},
"value": "VALUE"
},
"T_LATE": {
"initial": [0, 0, 0, 0, 0, 0, 0, 0],
"domain": {
"list": [
0, 86400000
]
},
"value": "VALUE"
},
"V_LATE": {
"initial": [false, false, false, false, false, false, false, false],
"domain": {
"list": [
0, 2
]
},
"value": "VALUE"
},
"CURRENT": {
"initial": [0, 0, 0, 0, 0, 0, 0, 0],
"domain": {
"list": [
0, 50000
]
},
"value": "VALUE"
},
"OUTPUT_5V": {
"initial": [false, false, false, false, false, false, false, false],
"domain": {
"list": [
0, 2
]
},
"value": "VALUE"
},
"ADC_VALUE_I": { "ADC_VALUE_I": {
"description": "ADC value current value", "description": "ADC value current value",
"domain": "int" "domain": "int"
@@ -332,12 +171,10 @@
"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",
"Dev Mode", "Dev Mode"
"Trigger"
] ]
}, },
"CHANNEL": { "CHANNEL": {
@@ -398,8 +235,7 @@
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "curve_acc", "0": "curve_acc"
"3": "trig_timer_mode"
} }
}, },
"_sync(True)", "_sync(True)",
@@ -501,677 +337,6 @@
"data": [ "data": [
"XE2;X02;X03;2B>ACC_a_out3_current;1B>ACC_a_out3" "XE2;X02;X03;2B>ACC_a_out3_current;1B>ACC_a_out3"
] ]
},
"trig_timer_mode": [
"trig_timer_mode_set_mode",
{
"expression": "USED[PR0]",
"when": {
"True": "trig_timer_mode_set_PR0"
}
},
{
"expression": "USED[PR1]",
"when": {
"True": "trig_timer_mode_set_PR1"
}
},
{
"expression": "USED[D0]",
"when": {
"True": "trig_timer_mode_set_D0"
}
},
{
"expression": "USED[D1]",
"when": {
"True": "trig_timer_mode_set_D1"
}
},
{
"expression": "USED[A0]",
"when": {
"True": "trig_timer_mode_set_A0"
}
},
{
"expression": "USED[A1]",
"when": {
"True": "trig_timer_mode_set_A1"
}
},
{
"expression": "USED[A2]",
"when": {
"True": "trig_timer_mode_set_A2"
}
},
{
"expression": "USED[A3]",
"when": {
"True": "trig_timer_mode_set_A3"
}
}
],
"trig_timer_mode_set_mode": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT"
},
"data": [
"1B>mode;",
"1XFF;"
]
},
"trig_timer_mode_set_PR0": [
"trig_timer_mode_set_PR0_para1",
"trig_timer_mode_set_PR0_para2",
"trig_timer_mode_set_PR0_para3"
],
"trig_timer_mode_set_PR0_para1": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_PR0",
"para_sequence": 1,
"used": "USED[PR0]",
"v_early": "V_EARLY[PR0]",
"v_late": "V_LATE[PR0]",
"v_mid0": "V_MID0[PR0]",
"v_mid1": "V_MID1[PR0]",
"v_mid2": "V_MID2[PR0]",
"v_mid3": "V_MID3[PR0]",
"cycle": "CYCLE[PR0]",
"t_early": "T_EARLY[PR0]",
"t_late": "T_LATE[PR0]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"5b>0;1b>v_late;1b>v_early;1b>used;",
"4b>0;1b>v_mid3;1b>v_mid2;1b>v_mid1;1b>v_mid0;",
"2B>cycle;4B>t_early;4B>t_late;"
]
},
"trig_timer_mode_set_PR0_para2": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_PR0",
"para_sequence": 2,
"t_mid0": "T_MID0[PR0]",
"t_mid1": "T_MID1[PR0]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid0;4B>t_mid1;"
]
},
"trig_timer_mode_set_PR0_para3": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_PR0",
"para_sequence": 3,
"t_mid2": "T_MID2[PR0]",
"t_mid3": "T_MID3[PR0]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid2;4B>t_mid3;"
]
},
"trig_timer_mode_set_PR1": [
"trig_timer_mode_set_PR1_para1",
"trig_timer_mode_set_PR1_para2",
"trig_timer_mode_set_PR1_para3"
],
"trig_timer_mode_set_PR1_para1": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_PR1",
"para_sequence": 1,
"used": "USED[PR1]",
"v_early": "V_EARLY[PR1]",
"v_late": "V_LATE[PR1]",
"v_mid0": "V_MID0[PR1]",
"v_mid1": "V_MID1[PR1]",
"v_mid2": "V_MID2[PR1]",
"v_mid3": "V_MID3[PR1]",
"cycle": "CYCLE[PR1]",
"t_early": "T_EARLY[PR1]",
"t_late": "T_LATE[PR1]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"5b>0;1b>v_late;1b>v_early;1b>used;",
"4b>0;1b>v_mid3;1b>v_mid2;1b>v_mid1;1b>v_mid0;",
"2B>cycle;4B>t_early;4B>t_late;"
]
},
"trig_timer_mode_set_PR1_para2": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_PR1",
"para_sequence": 2,
"t_mid0": "T_MID0[PR1]",
"t_mid1": "T_MID1[PR1]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid0;4B>t_mid1;"
]
},
"trig_timer_mode_set_PR1_para3": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_PR1",
"para_sequence": 3,
"t_mid2": "T_MID2[PR1]",
"t_mid3": "T_MID3[PR1]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid2;4B>t_mid3;"
]
},
"trig_timer_mode_set_D0": [
"trig_timer_mode_set_D0_para1",
"trig_timer_mode_set_D0_para2",
"trig_timer_mode_set_D0_para3",
"trig_timer_mode_set_D0_para4"
],
"trig_timer_mode_set_D0_para1": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_D0",
"para_sequence": 1,
"used": "USED[D0]",
"v_early": "V_EARLY[D0]",
"v_late": "V_LATE[D0]",
"v_mid0": "V_MID0[D0]",
"v_mid1": "V_MID1[D0]",
"v_mid2": "V_MID2[D0]",
"v_mid3": "V_MID3[D0]",
"cycle": "CYCLE[D0]",
"t_early": "T_EARLY[D0]",
"t_late": "T_LATE[D0]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"5b>0;1b>v_late;1b>v_early;1b>used;",
"4b>0;1b>v_mid3;1b>v_mid2;1b>v_mid1;1b>v_mid0;",
"2B>cycle;4B>t_early;4B>t_late;"
]
},
"trig_timer_mode_set_D0_para2": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_D0",
"para_sequence": 2,
"t_mid0": "T_MID0[D0]",
"t_mid1": "T_MID1[D0]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid0;4B>t_mid1;"
]
},
"trig_timer_mode_set_D0_para3": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_D0",
"para_sequence": 3,
"t_mid2": "T_MID2[D0]",
"t_mid3": "T_MID3[D0]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid2;4B>t_mid3;"
]
},
"trig_timer_mode_set_D0_para4": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_D0",
"para_sequence": 4,
"d0_as_5v_en": "OUTPUT_5V[D0]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"1B>d0_as_5v_en;"
]
},
"trig_timer_mode_set_D1": [
"trig_timer_mode_set_D1_para1",
"trig_timer_mode_set_D1_para2",
"trig_timer_mode_set_D1_para3",
"trig_timer_mode_set_D1_para4"
],
"trig_timer_mode_set_D1_para1": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_D1",
"para_sequence": 1,
"used": "USED[D1]",
"v_early": "V_EARLY[D1]",
"v_late": "V_LATE[D1]",
"v_mid0": "V_MID0[D1]",
"v_mid1": "V_MID1[D1]",
"v_mid2": "V_MID2[D1]",
"v_mid3": "V_MID3[D1]",
"cycle": "CYCLE[D1]",
"t_early": "T_EARLY[D1]",
"t_late": "T_LATE[D1]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"5b>0;1b>v_late;1b>v_early;1b>used;",
"4b>0;1b>v_mid3;1b>v_mid2;1b>v_mid1;1b>v_mid0;",
"2B>cycle;4B>t_early;4B>t_late;"
]
},
"trig_timer_mode_set_D1_para2": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_D1",
"para_sequence": 2,
"t_mid0": "T_MID0[D1]",
"t_mid1": "T_MID1[D1]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid0;4B>t_mid1;"
]
},
"trig_timer_mode_set_D1_para3": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_D1",
"para_sequence": 3,
"t_mid2": "T_MID2[D1]",
"t_mid3": "T_MID3[D1]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid2;4B>t_mid3;"
]
},
"trig_timer_mode_set_D1_para4": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_D1",
"para_sequence": 4,
"d0_as_5v_en": "OUTPUT_5V[D1]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"1B>d0_as_5v_en;"
]
},
"trig_timer_mode_set_A0": [
"trig_timer_mode_set_A0_para1",
"trig_timer_mode_set_A0_para2",
"trig_timer_mode_set_A0_para3",
"trig_timer_mode_set_A0_para4"
],
"trig_timer_mode_set_A0_para1": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A0",
"para_sequence": 1,
"used": "USED[A0]",
"v_early": "V_EARLY[A0]",
"v_late": "V_LATE[A0]",
"v_mid0": "V_MID0[A0]",
"v_mid1": "V_MID1[A0]",
"v_mid2": "V_MID2[A0]",
"v_mid3": "V_MID3[A0]",
"cycle": "CYCLE[A0]",
"t_early": "T_EARLY[A0]",
"t_late": "T_LATE[A0]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"5b>0;1b>v_late;1b>v_early;1b>used;",
"4b>0;1b>v_mid3;1b>v_mid2;1b>v_mid1;1b>v_mid0;",
"2B>cycle;4B>t_early;4B>t_late;"
]
},
"trig_timer_mode_set_A0_para2": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A0",
"para_sequence": 2,
"t_mid0": "T_MID0[A0]",
"t_mid1": "T_MID1[A0]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid0;4B>t_mid1;"
]
},
"trig_timer_mode_set_A0_para3": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A0",
"para_sequence": 3,
"t_mid2": "T_MID2[A0]",
"t_mid3": "T_MID3[A0]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid2;4B>t_mid3;"
]
},
"trig_timer_mode_set_A0_para4": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A0",
"para_sequence": 4,
"current": "CURRENT[A0]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"2B>current;"
]
},
"trig_timer_mode_set_A1": [
"trig_timer_mode_set_A1_para1",
"trig_timer_mode_set_A1_para2",
"trig_timer_mode_set_A1_para3",
"trig_timer_mode_set_A1_para4"
],
"trig_timer_mode_set_A1_para1": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A1",
"para_sequence": 1,
"used": "USED[A1]",
"v_early": "V_EARLY[A1]",
"v_late": "V_LATE[A1]",
"v_mid0": "V_MID0[A1]",
"v_mid1": "V_MID1[A1]",
"v_mid2": "V_MID2[A1]",
"v_mid3": "V_MID3[A1]",
"cycle": "CYCLE[A1]",
"t_early": "T_EARLY[A1]",
"t_late": "T_LATE[A1]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"5b>0;1b>v_late;1b>v_early;1b>used;",
"4b>0;1b>v_mid3;1b>v_mid2;1b>v_mid1;1b>v_mid0;",
"2B>cycle;4B>t_early;4B>t_late;"
]
},
"trig_timer_mode_set_A1_para2": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A1",
"para_sequence": 2,
"t_mid0": "T_MID0[A1]",
"t_mid1": "T_MID1[A1]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid0;4B>t_mid1;"
]
},
"trig_timer_mode_set_A1_para3": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A1",
"para_sequence": 3,
"t_mid2": "T_MID2[A1]",
"t_mid3": "T_MID3[A1]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid2;4B>t_mid3;"
]
},
"trig_timer_mode_set_A1_para4": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A1",
"para_sequence": 4,
"current": "CURRENT[A1]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"2B>current;"
]
},
"trig_timer_mode_set_A2": [
"trig_timer_mode_set_A2_para1",
"trig_timer_mode_set_A2_para2",
"trig_timer_mode_set_A2_para3",
"trig_timer_mode_set_A2_para4"
],
"trig_timer_mode_set_A2_para1": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A2",
"para_sequence": 1,
"used": "USED[A2]",
"v_early": "V_EARLY[A2]",
"v_late": "V_LATE[A2]",
"v_mid0": "V_MID0[A2]",
"v_mid1": "V_MID1[A2]",
"v_mid2": "V_MID2[A2]",
"v_mid3": "V_MID3[A2]",
"cycle": "CYCLE[A2]",
"t_early": "T_EARLY[A2]",
"t_late": "T_LATE[A2]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"5b>0;1b>v_late;1b>v_early;1b>used;",
"4b>0;1b>v_mid3;1b>v_mid2;1b>v_mid1;1b>v_mid0;",
"2B>cycle;4B>t_early;4B>t_late;"
]
},
"trig_timer_mode_set_A2_para2": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A2",
"para_sequence": 2,
"t_mid0": "T_MID0[A2]",
"t_mid1": "T_MID1[A2]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid0;4B>t_mid1;"
]
},
"trig_timer_mode_set_A2_para3": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A2",
"para_sequence": 3,
"t_mid2": "T_MID2[A2]",
"t_mid3": "T_MID3[A2]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid2;4B>t_mid3;"
]
},
"trig_timer_mode_set_A2_para4": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A2",
"para_sequence": 4,
"current": "CURRENT[A2]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"2B>current;"
]
},
"trig_timer_mode_set_A3": [
"trig_timer_mode_set_A3_para1",
"trig_timer_mode_set_A3_para2",
"trig_timer_mode_set_A3_para3",
"trig_timer_mode_set_A3_para4"
],
"trig_timer_mode_set_A3_para1": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A3",
"para_sequence": 1,
"used": "USED[A3]",
"v_early": "V_EARLY[A3]",
"v_late": "V_LATE[A3]",
"v_mid0": "V_MID0[A3]",
"v_mid1": "V_MID1[A3]",
"v_mid2": "V_MID2[A3]",
"v_mid3": "V_MID3[A3]",
"cycle": "CYCLE[A3]",
"t_early": "T_EARLY[A3]",
"t_late": "T_LATE[A3]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"5b>0;1b>v_late;1b>v_early;1b>used;",
"4b>0;1b>v_mid3;1b>v_mid2;1b>v_mid1;1b>v_mid0;",
"2B>cycle;4B>t_early;4B>t_late;"
]
},
"trig_timer_mode_set_A3_para2": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A3",
"para_sequence": 2,
"t_mid0": "T_MID0[A3]",
"t_mid1": "T_MID1[A3]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid0;4B>t_mid1;"
]
},
"trig_timer_mode_set_A3_para3": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A3",
"para_sequence": 3,
"t_mid2": "T_MID2[A3]",
"t_mid3": "T_MID3[A3]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"4B>t_mid2;4B>t_mid3;"
]
},
"trig_timer_mode_set_A3_para4": {
"type": "RIS",
"parameter": {
"mode": "MODE_ALL_OUTPUT",
"elite_ch": "ELITE_CH_A3",
"para_sequence": 4,
"current": "CURRENT[A3]"
},
"data": [
"1B>mode;",
"1B>elite_ch;",
"1B>para_sequence;",
"2B>current;"
]
} }
} }
} }
-122
View File
@@ -1,122 +0,0 @@
{
"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
@@ -1,155 +0,0 @@
{
"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;"
]
}
}
}
+4 -1
View File
@@ -35,4 +35,7 @@ sudo su -c "psql -d postgres -c \"ALTER TABLE devices ALTER COLUMN calibration D
sudo su -c "psql -d postgres -c \"ALTER TABLE devices ALTER COLUMN calibration TYPE bytea USING calibration::bytea;\"" postgres sudo su -c "psql -d postgres -c \"ALTER TABLE devices ALTER COLUMN calibration TYPE bytea USING calibration::bytea;\"" postgres
# add column project in recording_data_metas # add column project in recording_data_metas
sudo su -c "psql -d postgres -c \"ALTER TABLE devices ADD COLUMN IF NOT EXISTS calibration_version Int4 DEFAULT -1;\"" postgres sudo su -c "psql -d postgres -c \"ALTER TABLE devices ADD COLUMN IF NOT EXISTS calibration_version Int4 DEFAULT -1;\"" postgres
# add column subject in project
sudo su -c "psql -d postgres -c \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS subject JSONB;\"" postgres