Compare commits

..

57 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
peterlu14 aae1ab7a33 -update send instruction when trigger channel used 2023-06-14 12:02:35 +08:00
Roy 59148cff6d Feat(#6): new instruction of all output mode
https://www.notion.so/6-TRIG-s-All-output-mode-c382a9f88a444185873dbb62a7deee1a
2023-06-14 11:01:15 +08:00
Roy c9b10fc6aa [update] TRIG json 2023-06-13 13:23:58 +08:00
peterlu14 f82c3ab033 - add new mode 2023-06-13 09:51:43 +08:00
peterlu14 3884fad006 -update trigger 2023-06-13 09:33:31 +08:00
peterlu14 75ca525f36 -add trigger dev mode 2023-05-15 11:30:04 +08:00
Roy 9bb947f8e0 Refactor(#4): optimize scan function
https://www.notion.so/4-Controller-Uart-451f896953eb4e15bd70eeadb17eb94e
2023-04-26 22:50:15 +08:00
Roy fc4f931f9d Refactor(#4): fix battery and elite version info
https://www.notion.so/4-Controller-Uart-451f896953eb4e15bd70eeadb17eb94e
2023-04-21 17:50:06 +08:00
Roy 57ba7ed94f Refactor(#4): fix uart fun, and connect 5 times
https://www.notion.so/4-Controller-Uart-451f896953eb4e15bd70eeadb17eb94e
2023-04-21 16:15:44 +08:00
Roy cf8433c7ee Refactor(#3): fix cali version byte
https://www.notion.so/3-EIS-Controller-EIS-Controller-check-sum-5426fe5ccb024a9da73770bed559df65
2023-04-21 15:16:33 +08:00
Roy 4d1eee6893 Refactor(#4): fix instruction
https://www.notion.so/4-Controller-Uart-451f896953eb4e15bd70eeadb17eb94e
2023-04-21 14:55:48 +08:00
Roy 7a77c4d413 Refactor(#3): calibration data use CRC and cali version
https://www.notion.so/3-EIS-Controller-EIS-Controller-check-sum-5426fe5ccb024a9da73770bed559df65
2023-04-20 23:42:36 +08:00
Roy 6f8d68f476 Style: uart formatting 2023-04-20 23:37:42 +08:00
Roy 8ae45d3b50 Style: uart formatting 2023-04-20 23:28:32 +08:00
Roy 5e4980a1d5 Refactor(#4): optimize write/read function
https://www.notion.so/4-Controller-Uart-451f896953eb4e15bd70eeadb17eb94e
2023-04-20 22:56:07 +08:00
Roy 7716908a3b Refactor(#4): optimize disconnect function
https://www.notion.so/4-Controller-Uart-451f896953eb4e15bd70eeadb17eb94e
2023-04-20 22:41:52 +08:00
Roy 813ff7bc7d Refactor(#4): optimize connect function
https://www.notion.so/4-Controller-Uart-451f896953eb4e15bd70eeadb17eb94e
2023-04-20 20:22:32 +08:00
Roy c2224ed624 Refactor(#4): optimize scan function
https://www.notion.so/4-Controller-Uart-451f896953eb4e15bd70eeadb17eb94e
2023-04-20 20:20:40 +08:00
Roy 72943c3b6f Style: uart formatting 2023-04-20 18:20:52 +08:00
Roy 4d47d07996 Refactor(4): uart data reserve len, optimize chk memboard
https://www.notion.so/4-Controller-Uart-451f896953eb4e15bd70eeadb17eb94e
2023-04-20 18:00:22 +08:00
peterlu14 2fdcef998f - change calibration column type bytea 2023-04-19 10:37:15 +08:00
peterlu14 2b6381fa46 - devices table add new column calibration version
- save calibration info into db compare with cali version
2023-04-18 16:12:34 +08:00
Roy c29d9729ba [update] controller receive cali data when mem connect device 2023-04-17 10:32:17 +08:00
Roy 001905ec96 [update] fix scan error 2023-04-17 10:27:28 +08:00
Roy 5033381e64 [update] receive 21 cali package 2023-04-11 12:16:48 +08:00
Roy aa88201a93 [update] up to 8 hstia 2023-04-11 12:16:01 +08:00
Roy c02c59345b [update] update cali package 2023-04-10 18:07:53 +08:00
peterlu14 0386cf1847 Merge remote-tracking branch 'origin/release/update_eis_cali_fomula' into dev/scheduler_folder 2023-04-06 10:52:17 +08:00
peterlu14 62d8610191 - fix UnboundLocalError : 'project_meta_id' 2023-04-06 10:51:43 +08:00
Roy 991f5d06ea [update] use 4hstia calibration down 2023-04-06 09:06:05 +08:00
peterlu14 55711285e6 - update create meta project info change from data-server to control-server 2023-03-31 13:14:33 +08:00
peterlu14 3ec5fee43b - update create collection table
- init project then create folder
2023-03-31 13:14:29 +08:00
Roy 614a9c0b0f [update] hstia pA->nA & hsrtia_b is 8bytes 2023-03-31 10:16:50 +08:00
33 changed files with 5976 additions and 675 deletions
+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 Collection(Base):
__tablename__ = "collections"
id = Column(Integer, primary_key=True)
name = Column(String(255))
parent = Column(JSONB)
controller_id = Column(Integer)
type = Column(String(255))
description = 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_collection(cls, collection_name, parent):
with Session() as session:
name = cls.check_name_duplicate(collection_name, parent, 0)
collection = Collection(
name = name,
parent = parent,
type= "folder",
)
session.add(collection)
session.commit()
print('a', collection.id)
return collection
@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
+51
View File
@@ -0,0 +1,51 @@
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, Float, BINARY, LargeBinary
from sqlalchemy.dialects.postgresql import JSONB
from .base import Base, Session
class Device(Base):
__tablename__ = "devices"
id = Column(Integer, primary_key=True)
name = Column(String(255))
mac_address = Column(String(255))
serial_number = Column(String(255))
configuration = Column(JSONB)
library = Column(String(255))
library_version = Column(String(255))
device_version = Column(String(255))
type = Column(String(255))
battery = Column(Integer)
temperature = Column(Float)
auto_connect = Column(Boolean)
connect_priority = Column(Integer)
connect_time = Column(BigInteger)
parameter_set = Column(JSONB)
running = Column(Boolean)
calibration = Column(LargeBinary)
calibration_version = Column(Integer, default=-1)
user_auth = Column(JSONB)
deleted = Column(Boolean)
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
@classmethod
def update_device(cls, device, options):
with Session() as session:
result = session.query(Device).filter(Device.mac_address == device['mac_address']).first()
for key, value in options.items():
setattr(result, key, value)
session.commit()
@classmethod
def get_device(cls, device):
with Session() as session:
result = session.query(Device).filter(Device.mac_address == device['mac_address']).first()
return result
# def __repr__(self):
# return f"User(id={self.id!r}, name={self.name!r}, fullname={self.task!r})"
+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
class Project(Base):
__tablename__ = "project"
id = Column(Integer, primary_key=True)
name = Column(String)
desc = Column(String)
task = Column(JSONB)
cycle = Column(JSONB)
device = Column(JSONB)
uuid = Column(String(36))
user_auth = Column(JSONB)
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})"
+9 -1
View File
@@ -3,7 +3,7 @@ from sqlalchemy.sql import select, func
from sqlalchemy.types import Integer, BigInteger, String, Boolean, TIMESTAMP, Numeric from sqlalchemy.types import Integer, BigInteger, String, Boolean, TIMESTAMP, Numeric
from sqlalchemy.dialects.postgresql import JSONB from sqlalchemy.dialects.postgresql import JSONB
from .base import Base from .base import Base, Session
class MetaProjectInfo(Base): class MetaProjectInfo(Base):
__tablename__ = "project_metas" __tablename__ = "project_metas"
@@ -17,5 +17,13 @@ class MetaProjectInfo(Base):
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now()) created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now()) updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
@classmethod
def create_project_meta(cls, project):
with Session() as session:
project_meta = MetaProjectInfo(project = project['project'], cycle= project['cycle'], task=project['task'], serial_number=int(project['serial_number']))
session.add(project_meta)
session.commit()
return project_meta.id
# def __repr__(self): # def __repr__(self):
# return f"User(id={self.id!r}, name={self.name!r}, fullname={self.task!r})" # return f"User(id={self.id!r}, name={self.name!r}, fullname={self.task!r})"
+378 -375
View File
@@ -350,6 +350,7 @@ class CC2650Device(Device):
self._recording_file_name: str = 'recording_data' self._recording_file_name: str = 'recording_data'
self._coeff: bytes = b'' self._coeff: bytes = b''
self._device_version = "" self._device_version = ""
self._cali_version = -1
@property @property
def device_id(self) -> int: def device_id(self) -> int:
@@ -428,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 & 0xF0) | (length & 0x0F), (ins_oper & 0xFF),
*instruction)
return struct.pack('%dB' % (length + 2),
(ins_type & 0xF0) | (self.device_id & 0x0F),
(ins_oper & 0xF0) | (length & 0x0F),
*instruction) *instruction)
if ins_type == None:
return struct.pack('%dB' % length, *instruction)
else:
return struct.pack('%dB' % (length + 2),
(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.
@@ -477,22 +481,24 @@ class CC2650Device(Device):
else: else:
if data is not None and len(data) > 0: if data is not None and len(data) > 0:
year = struct.unpack('<B', data[0:1])[0] year = struct.unpack('<B', data[2:3])[0]
month = struct.unpack('<B', data[1:2])[0] month = struct.unpack('<B', data[3:4])[0]
day = struct.unpack('<B', data[2:3])[0] day = struct.unpack('<B', data[4:5])[0]
hour = struct.unpack('<B', data[3:4])[0] hour = struct.unpack('<B', data[5:6])[0]
minute = struct.unpack('<B', data[4:5])[0] minute = struct.unpack('<B', data[6:7])[0]
mac1 = struct.unpack('<B', data[5:6])[0] # mac1 = struct.unpack('<B', data[7:8])[0]
mac2 = struct.unpack('<B', data[6:7])[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
@@ -537,7 +543,7 @@ class CC2650Device(Device):
else: else:
if data is not None and len(data) > 2 : if data is not None and len(data) > 2 :
battery = struct.unpack('<H', data[1:3])[0] battery = struct.unpack('<H', data[2:4])[0]
if battery is not None: if battery is not None:
self._battery = battery self._battery = battery
@@ -549,6 +555,39 @@ class CC2650Device(Device):
self.update_calibration_info(device_type) self.update_calibration_info(device_type)
return self._coeff return self._coeff
def _check_crc(self, data):
data_chk_sum = data[-1]
# print('data:', list(data), 'data_chk_sum:', data_chk_sum)
# print('data[0:-1]:', list(data[0:-1]), 'check_sum:', sum(data[0:-1]) & 0b11111111)
if data_chk_sum == sum(data[0:-1]) & 0b11111111:
return True
return False
def update_cali_version(self) -> bool:
for _ in range(5):
try:
code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, 0)
self._master.write_characteristic(self.device_id, CC2650MasterDevice.COMMAND_HANDLE, code)
except SendInstructionTimeoutError:
self._master.log_warn('device', self.device_id, 'update cali version error')
return False
except RuntimeError:
self._master.log_warn('device', self.device_id, 'update cali version error')
return False
else:
version = self._master.read_characteristic(self.device_id,CC2650MasterDevice.RETURN_HANDLE)
if self._check_crc(version):
self._cali_version = struct.unpack('<H', version[2:4])[0]
print('self._cali_version=', self._cali_version)
return True
self._master.log_warn('device', self.device_id, 'update cali version error')
return False
def update_calibration_info(self, device_type: str): def update_calibration_info(self, device_type: str):
""" get device calibration info """ """ get device calibration info """
@@ -571,20 +610,6 @@ class CC2650Device(Device):
elif device_type == 'TDC4VC': elif device_type == 'TDC4VC':
i = 0 i = 0
request_times = 0 request_times = 0
# neulive 2.1 (only support ch1~ch8)
# try:
# # send
# code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, 0)
# self._master.write_characteristic(self.device_id, CC2650MasterDevice.COMMAND_HANDLE, code)
# # receive
# data = self._master.read_characteristic(self.device_id, CC2650MasterDevice.RETURN_HANDLE)
#
# coeff.append(self._decode_data(DeviceInstruction.CIS_CALI, data))
# except SendInstructionTimeoutError:
# self._master.log_warn('device', self.device_id, 'update_calibration_info no response')
# except RuntimeError:
# self._master.log_warn('device', self.device_id, 'update_calibration_info no response')
while i < 4: while i < 4:
try: try:
# print('i', i) # print('i', i)
@@ -661,42 +686,33 @@ class CC2650Device(Device):
elif device_type == 'EISZeroOne': elif device_type == 'EISZeroOne':
i = 1 i = 1
request_times = 0
while i <= 24: while i <= 24:
try: for _ in range(5):
# send try:
code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, i) # send
self._master.write_characteristic(self.device_id, CC2650MasterDevice.COMMAND_HANDLE, code) code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, i)
self._master.write_characteristic(self.device_id, CC2650MasterDevice.COMMAND_HANDLE, code)
sleep(0.1) except SerialTimeoutException:
self._master.log_warn('device', self.device_id, 'send update_calibration_info instruction fail')
# receive continue
data = self._master.read_characteristic(self.device_id,
CC2650MasterDevice.RETURN_HANDLE)
coeff.append(self._decode_data(DeviceInstruction.CIS_CALI, data))
except SendInstructionTimeoutError as e:
print(e)
self._master.log_warn('device', self.device_id, 'update_calibration_info no response')
raise BaseException
except RuntimeError as e:
print(e)
self._master.log_warn('device', self.device_id, 'update_calibration_info no response - 2')
request_times += 1
if request_times > 3:
self._master.reset(self.device_id)
break
else:
# print('data success')
if len(data) > 0:
i += 1
else: else:
request_times += 1 try:
if request_times > 3: # receive
self._master.reset(self.device_id) data = self._master.read_characteristic(self.device_id,
break CC2650MasterDevice.RETURN_HANDLE)
except RecvTimeout:
self._master.log_warn('device', self.device_id, 'update_calibration_info no response')
else:
if self._check_crc(data) and data is not None:
coeff.append(self._decode_data(DeviceInstruction.CIS_CALI, data))
i += 1
else:
self._master.log_warn('device', self.device_id, 'update_calibration_info crc wrong')
continue
else: else:
# default: neulive 2.1 # default: neulive 2.1
for i in range(1): for i in range(1):
@@ -1950,120 +1966,6 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
"""initialize cc2650 (master)""" """initialize cc2650 (master)"""
pass pass
def scan_send_ins(self):
# send scan command
try:
print(':: scan_send_ins ::', self.CC2650_COMMAND_LEN, 3, 0, 0)
self._cc2650.send(self.CC2650_COMMAND_LEN, 3, 0, 0)
except SerialTimeoutException as e:
raise RecvTimeout('send scan fail') from e
else:
# wait scanning
# sleep(2)
clean_buf = self._cc2650.receive_timeout("20B", timeout=3)
print("clean_buf = ", clean_buf)
# def cc2650_uart_irq(self):
# uart_irq = self.get_uart_irq_pin()
# uart_irq.output(False)
# sleep(0.001)
# uart_irq.output(True)
@synchronized
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
self._found = found = []
self._found_with_id = []
hdr_BPHS = [66, 80, 72, 83]
scan_response: Union[Optional[tuple], Any] = None
# build scan instruction
scan_ins = bytearray()
scan_ins.append(3) #scan instruction
scan_ins.append(1) #length
scan_ins.append(0xF1)
# print('send_scan', bytes(scan_ins))
self._cc2650.send("bytes", bytes(scan_ins))
try:
scan_response = self._cc2650.recv_uart(timeout)
except RecvTimeout:
# self.reset_internal()
# self.reset_hardware()
# self._interface.flush()
return False
# instruction format:
# ins[0]: get_scan_response = 0x04
# ins[1]: number of scanned device=0; a certain device = device_id (could be 1~8)
# ins[2]: addr=MAC=1, localName=2, company_code=3, version_info=4, battery_info=5, all_info=6;
# attr_length=0, e.g. len(addr)=6, len(company_code)=4
local_mac = None
local_cc = None
local_ver = None
local_bat = None
local_name = None
local_addr_type = None
# get device attribute length
attr_length = [6, 4, 6, 5, 20]
index = 0
local_mac = get_device_mac_in_address_format(scan_response[index:index + 6])
index = index + 6
# print("local_mac = ", hex(local_mac[0]), hex(local_mac[1]),
# hex(local_mac[2]), hex(local_mac[3]),
# hex(local_mac[4]), hex(local_mac[5]))
local_cc = get_device_company_code(scan_response[index:index + 4])
index = index + 4
# print("local_cc = ", local_cc)
local_ver = scan_response[index:index + 6]
index = index + 6
# print("local_ver = ", local_ver)
local_bat = get_device_battery_info(scan_response[index:index + 5])
index = index + 5
# print("local_bat = ", local_bat)
local_name = get_device_name_in_string_format(list(scan_response[index:index + 20]))
index = index + 20
# print("local_name = ", local_name)
# addr type is don't care in BMD380
print('scan_response:', list(scan_response))
local_addr_type = int(scan_response[index:index + 1][0])
# local_addr_type = 0xFF
index = index + 1
# print("local_addr_type = ", local_addr_type)
response = is_headstage_device_central_version(local_mac,
local_addr_type,
local_name,
local_cc,
local_ver,
local_bat)
if response is not None:
self.log_info('found', address_str(response.mac_address), response.serial_number)
self._interface.flush_input()
# apppend into db
devicesList = DeviceAPI.getByMac(address_str(response.mac_address))
if devicesList is not None:
if len(devicesList) == 0:
DeviceAPI.create(response.device_name, local_ver, address_str(response.mac_address))
found.append(response)
# print('scan_done_found', found)
self._found_with_id.append((response, 0 + 1))
callback(response)
return True
def decode_uart_preamble(self, raw_uart: tuple, expect_ret_len: int = 0) -> Optional[list]: def decode_uart_preamble(self, raw_uart: tuple, expect_ret_len: int = 0) -> Optional[list]:
# print("decode_uart_preamble: raw_uart = ", raw_uart) # print("decode_uart_preamble: raw_uart = ", raw_uart)
if raw_uart is None: if raw_uart is None:
@@ -2090,34 +1992,154 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
return self._found return self._found
def check_mem_survive(self) -> Optional[CC2650Device]: def check_mem_survive(self) -> Optional[CC2650Device]:
ack = [] chk_mem_response = None
ins = bytearray() ins = bytearray()
ins.append(10)
ins.append(1) #length ins.append(0x0A)
ins.append(0x01) #length
ins.append(0xF1) ins.append(0xF1)
# print('ins', list(ins)) self._interface.flush_input()
try: try:
self.log_verbose('[CC2650]', 'check_mem_survive att_write','0x'+str.upper(ins.hex()))
self._cc2650.send("bytes", bytes(ins)) self._cc2650.send("bytes", bytes(ins))
except SerialTimeoutException as e: except SerialTimeoutException:
raise RecvTimeout('device CC2650 check_mem_survive timeout') from e self.log_verbose('[CC2650]', 'check_mem_survive send fail')
else: else:
try: try:
ack = self._cc2650.recv_uart(0.001) chk_mem_response = self._cc2650.recv_uart(0.001)
except RecvTimeout: except RecvTimeout:
self.log_info("no memory board") self.log_verbose('[CC2650]', 'check_mem_survive response timeout, no memory board')
# else: if chk_mem_response is None:
# print('ack=', ack) return False
if ack == [3]: pack_len = chk_mem_response[0]
mem_ack = chk_mem_response[1:pack_len+1]
if mem_ack == [3]:
chk_mem_response_hex = ''.join(format(i, '02X') for i in chk_mem_response)
self.log_verbose('[CC2650]', 'check_mem_survive success', '0x'+chk_mem_response_hex)
return True return True
return False return False
@synchronized
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
self._found = found = []
self._found_with_id = []
scan_response = None
ins = bytearray()
ins.append(0x03)
ins.append(0x01) #length
ins.append(0xF1)
self._interface.flush_input()
for _ in range(5):
try:
self.log_verbose('[CC2650]', 'scan_callback att_write','0x'+str.upper(ins.hex()))
self._cc2650.send("bytes", bytes(ins))
except SerialTimeoutException:
self.log_verbose('[CC2650]', 'scan_callback send fail, rescan')
continue
else:
try:
scan_response = self._cc2650.recv_uart(0.01)
except RecvTimeout:
self.log_verbose('[CC2650]', 'scan_callback response timeout, no device, rescan')
continue
else:
if scan_response is None:
self.log_verbose('[CC2650]', 'scan_callback response is None, rescan')
continue
else:
break
if scan_response is None:
self.log_verbose('[CC2650]', 'scan_callback response is None--2')
return False
scan_response_hex = ''.join(format(i, '02X') for i in scan_response)
self.log_verbose('[CC2650]', 'scan_callback success', '0x'+scan_response_hex)
if len(scan_response) <= 2:
print('******************************************************************')
print('******************************************************************')
print('******************************************************************')
print('******************************************************************')
print('****need to fix, len(scan) <= 2')
print()
return False
pack_len = scan_response[0]
device_info_pkg = scan_response[1:pack_len+1]
# instruction format:
# ins[0]: get_scan_response = 0x04
# ins[1]: number of scanned device=0; a certain device = device_id (could be 1~8)
# ins[2]: addr=MAC=1, localName=2, company_code=3, version_info=4, battery_info=5, all_info=6;
# attr_length=0, e.g. len(addr)=6, len(company_code)=4
local_mac = None
local_cc = None
local_ver = None
local_bat = None
local_name = None
local_addr_type = None
# get device attribute length
attr_length = [6, 4, 6, 5, 20]
index = 0
local_mac = get_device_mac_in_address_format(device_info_pkg[index:index + 6])
index = index + 6
local_cc = get_device_company_code(device_info_pkg[index:index + 4])
index = index + 4
local_ver = device_info_pkg[index:index + 6]
index = index + 6
local_bat = get_device_battery_info(device_info_pkg[index:index + 5])
index = index + 5
local_name = get_device_name_in_string_format(list(device_info_pkg[index:index + 20]))
index = index + 20
local_addr_type = int(device_info_pkg[index:index + 1][0])
index = index + 1
response = is_headstage_device_central_version(local_mac,
local_addr_type,
local_name,
local_cc,
local_ver,
local_bat)
if response is not None:
self.log_info('found', address_str(response.mac_address), response.serial_number)
self._interface.flush_input()
# apppend into db
devicesList = DeviceAPI.getByMac(address_str(response.mac_address))
if devicesList is not None:
if len(devicesList) == 0:
DeviceAPI.create(response.device_name, local_ver, address_str(response.mac_address))
found.append(response)
# print('scan_done_found', found)
self._found_with_id.append((response, 0 + 1))
callback(response)
return True
@synchronized @synchronized
def connect(self, response: DeviceResponseInfo, direct_connect: bool = False) -> Optional[CC2650Device]: def connect(self, response: DeviceResponseInfo, direct_connect: bool = False) -> Optional[CC2650Device]:
if self._handle is not None: if self._handle is not None:
@@ -2127,215 +2149,202 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
addr_type = response.addr_type addr_type = response.addr_type
address_s = cc2650.address_str(address) address_s = cc2650.address_str(address)
self.log_info(DEVICE_CONNECTING, address_s)
connect_ins = bytearray()
connect_ins.append(5)
connect_ins.append(8) #length
connect_ins.append(addr_type)
connect_ins.append(address[0])
connect_ins.append(address[1])
connect_ins.append(address[2])
connect_ins.append(address[3])
connect_ins.append(address[4])
connect_ins.append(address[5])
connect_ins.append(0xF1)
connected = False connected = False
connect_response = None
ins = bytearray()
# send connect command ins.append(0x05)
if direct_connect is True: ins.append(0x08) #length
ins.append(addr_type)
# send device mac and addrType ins.append(address[0])
try: ins.append(address[1])
self._cc2650.send("bytes", bytes(connect_ins)) ins.append(address[2])
ins.append(address[3])
except SerialTimeoutException as e: ins.append(address[4])
raise RecvTimeout('device CC2650 connect fail') from e ins.append(address[5])
return None ins.append(0xF1)
# connection establish done?
for retry_recv_ack in range(10):
try:
con_done = self._cc2650.recv_uart(timeout = 0.5)
# print("con_done = ", con_done)
except RecvTimeout:
self.log_info("recv connection timeout, retry... ")
continue
# is the ack valid?
if con_done is None:
continue
elif con_done[0] is 46 and \
con_done[1] is 80 and \
con_done[2] is 48 and \
con_done[3] is 4:
connected = True
break
else:
for dev in self._found:
if dev.mac_address == address:
# connection establish done?
for retry_recv_ack in range(5):
try:
# send device mac and addrType
self._cc2650.send("bytes", bytes(connect_ins))
sleep(1.5)
con_done = self._cc2650.recv_uart(timeout = 0.1)
except RecvTimeout:
self.log_info("recv connection timeout, retry... ")
continue
# is the ack valid?
if con_done is None:
self.log_info("recv connection timeout, retry... ")
continue
elif con_done[0] is 46 and \
con_done[1] is 80 and \
con_done[2] is 48 and \
con_done[3] is 4:
connected = True
# print('con_done=', con_done)
break
else:
continue
# if select device is invalid or connect failed
self._interface.flush_input() self._interface.flush_input()
if connected is False:
if direct_connect is True:
self.reset_internal()
self.reset_hardware()
self._interface.flush()
return None
# CC2650Device(device_id, master, scan_response) is a slave device for retry in range(5):
# device_id is don't care, because it will be overwrite later try:
dont_care = 0 self.log_verbose('[CC2650]', 'connect att_write', '0x'+str.upper(ins.hex()))
self._device = ret = CC2650Device(device_id=dont_care, master=self, response_info=response) self._cc2650.send("bytes", bytes(ins))
self.log_info(DEVICE_CONNECTED, address_s)
sleep(0.5)
print('ret',ret)
return ret except RecvTimeout:
self.log_verbose('[CC2650]', 'connect send fail')
continue
else:
try:
connect_response = self._cc2650.recv_uart(2)
except RecvTimeout:
# self.log_verbose('[CC2650]', 'connect response timeout')
if retry < 5:
self.log_verbose('[CC2650]', 'connect retry')
continue
else:
break
if connect_response is None:
self.log_verbose('[CC2650]', 'connect response timeout')
return False
pack_len = connect_response[0]
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 \
connect_ack[2] == 48 and connect_ack[3] == 4:
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 connected == True:
# CC2650Device(device_id, master, scan_response) is a slave device
# device_id is don't care, because it will be overwrite later
dont_care = 0
self._device = ret = CC2650Device(device_id=dont_care, master=self, response_info=response)
self.log_verbose('[CC2650]', DEVICE_CONNECTED, address_s)
return ret
connect_response_hex = ''.join(format(i, '02X') for i in connect_response)
self.log_verbose('[CC2650]', 'connect fail', '0x'+connect_response_hex)
return False
@synchronized @synchronized
def disconnect(self, device: int, force=False) -> bool: def disconnect(self, device: int, force=False) -> bool:
self.log_info(DEVICE_DISCONNECTING, device)
ins = bytearray() ins = bytearray()
ins.append(8)
ins.append(1) #length ins.append(0x08)
ins.append(0x01) #length
ins.append(0xF1) ins.append(0xF1)
self._interface.flush_input()
for retry in range(5):
try:
self.log_verbose('[CC2650]', 'disconnect att_write','0x'+str.upper(ins.hex()))
self._cc2650.send("bytes", bytes(ins))
except SerialTimeoutException:
self.log_verbose('[CC2650]', 'disconnect send fail')
continue
else:
self.reset_internal()
self.reset_hardware()
self.log_verbose('[CC2650]', 'disconnect success')
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')
return False
@synchronized
def write_characteristic(self, device: int, handle: int, data: bytes) -> bool:
write_response = None
ins = bytearray()
ins.append(0x06)
if len(data) + 2 > 255:
ins.append(255)
else:
ins.append(len(data)+2) #length = handle + C0C0XXXX(data len) + F1
ins.append(handle)
ins.extend(data)
ins.append(0xF1)
self._interface.flush_input()
try: try:
# print('send_disconnect',bytes(ins)) self.log_verbose('[CC2650]', 'write_characteristic', device, str(hex(handle).upper()))
self.log_verbose('[CC2650]', 'write_characteristic att_write','0x'+str.upper(ins.hex()))
self._cc2650.send("bytes", bytes(ins)) self._cc2650.send("bytes", bytes(ins))
except RecvTimeout: except SerialTimeoutException:
self.log_warn('disconnect time out') self.log_verbose('[CC2650]', 'write_characteristic send fail')
return False
except RuntimeError as e:
self.log_warn('suppressed error', str(e))
return False
else: else:
sleep(0.01) try:
write_response = self._cc2650.recv_uart(0.5)
except RecvTimeout:
self.log_verbose('[CC2650]', 'write_characteristic response timeout')
if write_response is None:
self.log_verbose('[CC2650]', 'write_characteristic fail')
return False
pack_len = write_response[0]
write_ack = write_response[1:pack_len+1]
if write_ack == [3]:
write_response_hex = ''.join(format(i, '02X') for i in write_response)
self.log_verbose('[CC2650]', 'write_characteristic success', '0x'+write_response_hex)
return True return True
finally: self.log_verbose('[CC2650]', 'write_characteristic fail')
self.log_info(DEVICE_DISCONNECTED, device) return False
# reset single 2650 after disconnected
self.reset_internal()
self.reset_hardware()
self._interface.flush()
@synchronized @synchronized
def read_characteristic(self, device: int, handle: int) -> Optional[bytes]: def read_characteristic(self, device: int, handle: int) -> Optional[bytes]:
read_response = None
# print("read_characteristic, expect_data_length = ", expect_data_length)
ret = None
ins = bytearray() ins = bytearray()
ins.append(7)
ins.append(2) #length ins.append(0x07)
ins.append(0x02) #length
ins.append(handle) ins.append(handle)
ins.append(0xF1) ins.append(0xF1)
self._interface.flush_input()
for _ in range(2):
try:
# print('send_read',bytes(ins))
self._cc2650.send("bytes", bytes(ins))
except SerialTimeoutException:
raise RecvTimeout('device CC2650 send read_characteristic fail')
try:
ret = self._cc2650.recv_uart(timeout = 2)
except Exception as e2:
raise RecvTimeout()
else:
# print("======== read ret = ", ret)
self._interface.flush_input()
# try:
# ret = self._cc2650.recv_uart(timeout = 1)
# except Exception as e2:
# raise RecvTimeout()
# else:
# # print("read_characteristic ret = ", ret)
# pass
if ret is None:
return None
return bytes(ret)
@synchronized
def write_characteristic(self, device: int, handle: int, data: bytes):
# print("device", device)
# print("handle", handle)
# print("data", data.hex())
# self.log_info('reset')
self.log_verbose('write_characteristic', device, handle)
self.log_verbose('[CC2650]', 'att_write', str.upper(data.hex()))
ack = None
ret = None
data_array = bytearray()
data_array.append(6)
data_array.append(len(data)+2) #length
data_array.append(handle)
data_array.extend(data)
data_array.append(0xF1)
try: try:
self._cc2650.send("bytes", bytes(data_array)) self.log_verbose('[CC2650]', 'read_characteristic', device, str(hex(handle).upper()))
# print('send_write',bytes(data_array)) self.log_verbose('[CC2650]', 'read_characteristic att_write','0x'+str.upper(ins.hex()))
self._cc2650.send("bytes", bytes(ins))
except SerialTimeoutException as e: except SerialTimeoutException:
raise RecvTimeout('device CC2650 send instruction fail') from e self.log_verbose('[CC2650]', 'read_characteristic send fail')
# read error code
try:
ret = self._cc2650.recv_uart()
# print("_______ write ack = ", ret)
except Exception as e2:
pass
else: else:
pass try:
read_response = self._cc2650.recv_uart(1)
self._interface.flush_input() except RecvTimeout:
self._interface.flush_output() self.log_verbose('[CC2650]', 'read_characteristic response timeout')
if read_response is None:
return None
read_response_hex = ''.join(format(i, '02X') for i in read_response)
self.log_verbose('[CC2650]', 'read_characteristic success', '0x'+read_response_hex)
return bytes(read_response)
def set_notify(self, device: Union[int, Device], enable: bool): def set_notify(self, device: Union[int, Device], enable: bool):
if isinstance(device, CompletedDevice): if isinstance(device, CompletedDevice):
@@ -2436,7 +2445,6 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
self._cc2650_log_level = self.log_level self._cc2650_log_level = self.log_level
def read_characteristic(self, device: int, handle: int) -> Optional[bytes]: def read_characteristic(self, device: int, handle: int) -> Optional[bytes]:
self.log_verbose('read_characteristic', device, '0x%02X' % handle)
master = self._cc2650[device] master = self._cc2650[device]
@@ -2494,11 +2502,6 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
self._interface.flush() self._interface.flush()
self._selector.select(device_id) self._selector.select(device_id)
# self._mem_selector.select(device_id)
# print("multiMaster selector = ", device_id)
# print("\n")
# device._notify_flag = enable
try: try:
master.write_characteristic(device_id, self.NOTIFY_HANDLE, value) master.write_characteristic(device_id, self.NOTIFY_HANDLE, value)
except SendInstructionTimeoutError: except SendInstructionTimeoutError:
+8
View File
@@ -836,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
@@ -858,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:
+218 -185
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]
@@ -1383,8 +1401,8 @@ class EISZeroOneDataDecoder(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', '_last_time_stamp', '_last_delta', '_cali_coeff', '_mode_stop', '_last_time_stamp', '_last_delta',
'cali_coeff', '_ac_amp', '_mode', '_cali_package', 'cali_coeff', '_ac_amp', '_mode',
'_last_phase', '_first_phase_flag', '_show_data') '_last_phase', '_first_phase_flag', '_show_data')
def __init__(self, cali_coeff: bytes = None): def __init__(self, cali_coeff: bytes = None):
@@ -1402,209 +1420,224 @@ class EISZeroOneDataDecoder(RecDataDecoder):
self._last_phase = 0 self._last_phase = 0
self._first_phase_flag = 1 self._first_phase_flag = 1
self._cali_coeff: Optional[bytes] = None self._cali_package: Optional[bytes] = None
self.cali_coeff: Optional[List[Tuple[int, int]]] = None self.cali_coeff: Optional[List[Tuple[int, int]]] = None
self._show_data = False self._show_data = False
if cali_coeff is not None: if self._cali_package is None:
self._cali_coeff = cali_coeff self._cali_package = cali_coeff
self.cali_coeff = self._decode_cali_coeff(cali_coeff) self.cali_coeff = self._decode_cali_coeff(self._cali_package)
@staticmethod @staticmethod
def _decode_cali_coeff(cali_coeff: bytes) -> Optional[List[Tuple[int, int]]]: def _decode_cali_coeff(cali_coeff: bytes) -> Optional[List[Tuple[int, int]]]:
#####################################################
# phase_coeff/phase_offset/hsrtia_a/hsrtia_b/rolloff
# [[gain0, g1, g2, g3] ----->最高頻
# [gain0, g1, g2, g3] ----->中頻
# [gain0, g1, g2, g3] ----->低頻
# [gain0, g1, g2, g3] ----->最低頻
# ]
#####################################################
print('cali_coeff=', cali_coeff)
if cali_coeff != b'': if cali_coeff != b'':
cali_table = []
hsrtia_a = numpy.zeros([4, 8], dtype = int) #hsrtia_a[freq][gain]
hsrtia_b = numpy.zeros([4, 8], dtype = numpy.int64) #hsrtia_b[freq][gain]
rolloff = numpy.zeros([4, 8], dtype = int) #rolloff[freq][gain]
phase_coeff = numpy.zeros([4, 8], dtype = int) #phase_coeff[freq][gain]
phase_offset = numpy.zeros([4, 8], dtype = int) #phase_offset[freq][gain]
cis_data_len = 20 cis_data_len = 20
cali_table = []
hsrtia_a = []
hsrtia_b = []
rolloff = []
phase_coeff = []
phase_offset = []
#gain=0 phase_coeff = numpy.zeros([8, 4], dtype = int)
phase_offset = numpy.zeros([8, 4], dtype = int)
########################################
# phase_coeff
# [[freq0, freq1, freq2, freq3] ----->gain0
# [freq0, freq1, freq2, freq3] ----->gain1
# [freq0, freq1, freq2, freq3] ----->gain2
# [freq0, freq1, freq2, freq3] ----->gain3
# ]
#######################################
#hstia=0
cis_cali_packet = 1 cis_cali_packet = 1
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][0] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
hsrtia_b[0][0] = struct.unpack('>q', cali_coeff[index+5:index+13])[0] hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
rolloff[0][0] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
cis_cali_packet = 2 cis_cali_packet = 2
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][0] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 0
phase_offset[0][0] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[1][0] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[1][0] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
cis_cali_packet = 3 cis_cali_packet = 3
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][0] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 0
phase_offset[2][0] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[3][0] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[3][0] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
#gain=1
#hstia=1
cis_cali_packet = 4 cis_cali_packet = 4
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][1] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
hsrtia_b[0][1] = struct.unpack('>q', cali_coeff[index+5:index+13])[0] hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
rolloff[0][1] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
cis_cali_packet = 5 cis_cali_packet = 5
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][1] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 1
phase_offset[0][1] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[1][1] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[1][1] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
cis_cali_packet = 6 cis_cali_packet = 6
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][1] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 1
phase_offset[2][1] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[3][1] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[3][1] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
#gain=2 #hstia=2
cis_cali_packet = 7 cis_cali_packet = 7
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][2] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
hsrtia_b[0][2] = struct.unpack('>q', cali_coeff[index+5:index+13])[0] hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
rolloff[0][2] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
cis_cali_packet = 8 cis_cali_packet = 8
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][2] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 2
phase_offset[0][2] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[1][2] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[1][2] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
cis_cali_packet = 9 cis_cali_packet = 9
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][2] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 2
phase_offset[2][2] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[3][2] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[3][2] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
#gain=3 #hstia=3
cis_cali_packet = 10 cis_cali_packet = 10
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][3] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
hsrtia_b[0][3] = struct.unpack('>q', cali_coeff[index+5:index+13])[0] hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
rolloff[0][3] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
cis_cali_packet = 11 cis_cali_packet = 11
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][3] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 3
phase_offset[0][3] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[1][3] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[1][3] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
cis_cali_packet = 12 cis_cali_packet = 12
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][3] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 3
phase_offset[2][3] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[3][3] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[3][3] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
#gain=4 #hstia=4
cis_cali_packet = 13 cis_cali_packet = 13
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][4] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
hsrtia_b[0][4] = struct.unpack('>q', cali_coeff[index+5:index+13])[0] hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
rolloff[0][4] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
cis_cali_packet = 14 cis_cali_packet = 14
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][4] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 4
phase_offset[0][4] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[1][4] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[1][4] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
cis_cali_packet = 15 cis_cali_packet = 15
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][4] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 4
phase_offset[2][4] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[3][4] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[3][4] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
#gain=5 #hstia=5
cis_cali_packet = 16 cis_cali_packet = 16
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][5] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
hsrtia_b[0][5] = struct.unpack('>q', cali_coeff[index+5:index+13])[0] hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
rolloff[0][5] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
cis_cali_packet = 17 cis_cali_packet = 17
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][5] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 5
phase_offset[0][5] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[1][5] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[1][5] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
cis_cali_packet = 18 cis_cali_packet = 18
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][5] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 5
phase_offset[2][5] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[3][5] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[3][5] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
#gain=6 #hstia=6
cis_cali_packet = 19 cis_cali_packet = 19
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][6] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
hsrtia_b[0][6] = struct.unpack('>q', cali_coeff[index+5:index+13])[0] hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
rolloff[0][6] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
cis_cali_packet = 20 cis_cali_packet = 20
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][6] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 6
phase_offset[0][6] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[1][6] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[1][6] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
cis_cali_packet = 21 cis_cali_packet = 21
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][6] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 6
phase_offset[2][6] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[3][6] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[3][6] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
#gain=7 #hstia=7
cis_cali_packet = 22 cis_cali_packet = 22
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][7] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
hsrtia_b[0][7] = struct.unpack('>q', cali_coeff[index+5:index+13])[0] hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
rolloff[0][7] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
cis_cali_packet = 23 cis_cali_packet = 23
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][7] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 7
phase_offset[0][7] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[1][7] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[1][7] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
cis_cali_packet = 24 cis_cali_packet = 24
index = (cis_cali_packet - 1) * cis_data_len index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][7] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] g = 7
phase_offset[2][7] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
phase_coeff[3][7] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
phase_offset[3][7] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
print('hsrtia_a') print('hsrtia_a', hsrtia_a)
print(hsrtia_a) print('hsrtia_b', hsrtia_b)
print('hsrtia_b') print('rolloff', rolloff)
print(hsrtia_b)
print('rolloff')
print(rolloff)
print('phase_coeff') print('phase_coeff')
print(phase_coeff) print(phase_coeff)
print('phase_offset') print('phase_offset')
@@ -1619,10 +1652,10 @@ class EISZeroOneDataDecoder(RecDataDecoder):
@property @property
def name(self) -> AnyStr: def name(self) -> AnyStr:
if self._cali_coeff is None: if self._cali_package is None:
return self.NAME return self.NAME
else: else:
return self.NAME.encode() + b':' + self._cali_coeff return self.NAME.encode() + b':' + self._cali_package
def message(self) -> Optional[str]: def message(self) -> Optional[str]:
ret = self._message ret = self._message
@@ -1634,16 +1667,16 @@ class EISZeroOneDataDecoder(RecDataDecoder):
if len(data) < 18: if len(data) < 18:
return None return None
ch1 = struct.unpack('>i', data[1+3:5+3])[0] ch1 = struct.unpack('>i', data[1+3:5+3])[0] # unit: 1/1000 nA
ch2 = struct.unpack('>i', data[5+3:9+3])[0] ch2 = struct.unpack('>i', data[5+3:9+3])[0] # unit: mV
ch3 = struct.unpack('>i', data[9+3:13+3])[0] ch3 = struct.unpack('>i', data[9+3:13+3])[0] # unit: kOm
time_stamp: float = struct.unpack('<I', data[13+3:17+3])[0] # unit: ms time_stamp: float = struct.unpack('<I', data[13+3:17+3])[0] # unit: ms
cycle_number = struct.unpack('>H', data[17+3:19+3])[0] cycle_number = struct.unpack('>H', data[17+3:19+3])[0]
d19 = data[19+3] d19 = data[19+3]
gain = data[20+3] gain = data[20+3]
finishMode = (d19 & 0x80) >> 7 finishMode = (d19 & 0x80) >> 7
ch4 = struct.unpack('<i', data[21+3:25+3])[0] ch4 = struct.unpack('<i', data[21+3:25+3])[0] # Amp[uV]
notify_one = struct.unpack('<i', data[25+3:29+3])[0] notify_one = struct.unpack('<i', data[25+3:29+3])[0]
notify_two = struct.unpack('<i', data[29+3:33+3])[0] notify_two = struct.unpack('<i', data[29+3:33+3])[0]
notify_three = struct.unpack('<i', data[33+3:37+3])[0] notify_three = struct.unpack('<i', data[33+3:37+3])[0]
@@ -1665,59 +1698,61 @@ class EISZeroOneDataDecoder(RecDataDecoder):
return None return None
else: else:
if self.cali_coeff is not None and (self._mode == 0 or self._mode == 5): if self.cali_coeff is not None and (self._mode == 0 or self._mode == 5):
hsrtia_a = []
hsrtia_b = []
rolloff = []
phase_coeff, phase_offset, hsrtia_a, hsrtia_b, rolloff = self.cali_coeff[0] phase_coeff, phase_offset, hsrtia_a, hsrtia_b, rolloff = self.cali_coeff[0]
if (self._mode == 0 or self._mode == 5): if (self._mode == 0 or self._mode == 5):
img = ch1
img = ch1 #img[ohm] real = ch2
real = ch2 #real[ohm] freq = ch3
freq = ch3 #freq[10mHz]
fre_idx = 0 fre_idx = 0
voltage_amp = round(ch4 / 1000) #ch4=Amp[uV] #voltage_amp[mV] voltage_amp = round(ch4 / 1000) # Amp[mV]
rolloff_cali = rolloff[0][gain] rolloff_cali = rolloff[gain]
voltage_mag = math.sqrt(img ** 2 + real ** 2) * (1 + freq ** 2 / rolloff_cali ** 2 / 1e4) voltage_mag = math.sqrt(img ** 2 + real ** 2) * (1 + freq ** 2 / rolloff_cali ** 2 / 1e4)
current = (voltage_mag ** 2 * hsrtia_a[0][gain] + voltage_mag * hsrtia_b[0][gain]) / 1e8 #current[nA] current = (voltage_mag ** 2 * hsrtia_a[gain] + voltage_mag * hsrtia_b[gain]) / 1e8 #[nA]
if (current != 0): if (current != 0):
# impedance[mOhm] = voltage_amp[mV] * 1000000 / 1.414213 / current[nA] #RMS=amp*SQRT(2), SQRT(2)=1.414213 # impedance[mOhm] = voltage_amp[mv] * 1000000 / 1.414213 / current[nA] #RMS=amp*SQRT(2), SQRT(2)=1.414213
impedance = voltage_amp * 707106.78 / current impedance = voltage_amp * 707106.78 / current
else: else:
impedance = 0 impedance = 0
raw_phase = math.atan2(img , real) * 180 / math.pi raw_phase = math.atan2(img , real) * 180 / math.pi
if (freq >= 1000000): #10000Hz if (freq >= 1000000): # 10000 Hz
fre_idx = 0 fre_idx = 0
elif (freq >= 10000): #100Hz elif (freq >= 10000): # 100 Hz
fre_idx = 1 fre_idx = 1
elif (freq >= 1000): #10Hz elif (freq >= 1000): # 10 Hz
fre_idx = 2 fre_idx = 2
elif (freq >= 1): #0.01Hz elif (freq >= 1): # 0.01 Hz
fre_idx = 3 fre_idx = 3
ideal_raw_phase = phase_coeff[gain][fre_idx] /1e10 * freq + phase_offset[gain][fre_idx] / 1e6 ideal_raw_phase = phase_coeff[gain][fre_idx] /1e10 * freq + phase_offset[gain][fre_idx] / 1e6
phase = raw_phase - ideal_raw_phase phase = raw_phase - ideal_raw_phase
phase = phase % 180 if phase % 180<=90 else phase % 180-180 phase = phase % 180 if phase % 180<=90 else phase % 180-180
imag_after_cal = impedance * math.sin(phase * math.pi / 180) imag_after_cal = round(impedance * math.sin(phase * math.pi / 180))
real_after_cal = impedance * math.cos(phase * math.pi / 180) real_after_cal = round(impedance * math.cos(phase * math.pi / 180))
if self._show_data: if self._show_data:
if (self._mode == 0 or self._mode == 5): if (self._mode == 0 or self._mode == 5):
print('|', '{:10}'.format(time_stamp), print('|', '{:10}'.format(time_stamp),
'|', '{:5}'.format(delta), '|', '{:5}'.format(delta),
'|', '{:5}'.format(img), '|', '{:5}'.format(ch1), #raw_img
'|', '{:5}'.format(real), '|', '{:5}'.format(ch2), #raw_real
'|', '{:9}'.format(freq*10), '[mHz]', '|', '{:8}'.format(ch3 * 10), '[mHz]', #Frequency [mHz]
'|', '{:5}'.format(cycle_number), '|', '{:5}'.format(cycle_number), #cycle
'|', '{:5}'.format(round(imag_after_cal)), '[Ohm]', #Z_imag[Ohm] '|', '{:5}'.format(round(imag_after_cal)), '[Ohm]', #Z_imag [Ohm]
'|', '{:5}'.format(round(real_after_cal)), '[Ohm]', #Z_real[Ohm] '|', '{:5}'.format(round(real_after_cal)), '[Ohm]', #Z_real [Ohm]
'|', '{:5}'.format(round(impedance)), '[mOhm]', '|', '{:5}'.format(round(impedance)), '[Ohm]', #Impedance [Ohm]
'|', '{:5}'.format(round(phase*1000)), '[mdegree]', '|', '{:5}'.format(round(phase*1000)), '[mdegree]', #Phase [millidegree]
'|', '{:10}'.format(round(current)), '[nA]', '|', '{:5}'.format(round(current)), '[nA]', #Current [nA]
'|', '{:1}'.format(gain), '|', '{:1}'.format(gain), #gain
'|', '{:1}'.format(finishMode), '|', '{:1}'.format(finishMode), #finishMode
'@', str(self.device), '|', flush = True) '@', str(self.device), '|', flush = True)
print('|', '{:10}'.format(time_stamp), print('|', '{:10}'.format(time_stamp),
@@ -1725,7 +1760,7 @@ class EISZeroOneDataDecoder(RecDataDecoder):
'|', '{:5}'.format(notify_one), '|', '{:5}'.format(notify_one),
'|', '{:5}'.format(notify_two), '|', '{:5}'.format(notify_two),
'|', '{:5}'.format(notify_three), '|', '{:5}'.format(notify_three),
'|', '{:5}'.format(voltage_amp), '[mV]', '|', '{:5}'.format(voltage_amp), #amp[mV]
'|', flush = True) '|', flush = True)
pass pass
else: else:
@@ -1747,30 +1782,28 @@ class EISZeroOneDataDecoder(RecDataDecoder):
self._mode_stop = 0 self._mode_stop = 0
ret = RecordingData(self.device, int(time_stamp * 1000 / 2), 0) ret = RecordingData(self.device, int(time_stamp * 1000 / 2), 0)
if self._mode == 0 or self._mode == 5: #EIS/CF Mode if self._mode == 0 or self._mode == 5:
ret.append_data(0, img) ret.append_data(0, ch1) #raw_img
ret.append_data(1, real) ret.append_data(1, ch2) #raw_real
ret.append_data(2, freq * 10) #[mHz] ret.append_data(2, ch3 * 10) #Frequency [mHz]
ret.append_data(3, cycle_number) ret.append_data(3, cycle_number) #cycle
ret.append_data(4, round(imag_after_cal)) #Z_imag [Ohm] ret.append_data(4, imag_after_cal) #Z_imag [Ohm]
ret.append_data(5, round(real_after_cal)) #Z_real [Ohm] ret.append_data(5, real_after_cal) #Z_real [Ohm]
ret.append_data(6, round(impedance)) #[mOhm] ret.append_data(6, round(impedance)) #Impedance [Ohm]
ret.append_data(7, round(phase*1000)) #[millidegree] ret.append_data(7, round(phase*1000)) #Phase [millidegree]
ret.append_data(8, round(current)) #[nA] ret.append_data(8, round(current)) #Current [nA]
ret.append_data(9, gain) ret.append_data(9, gain) #gain
#debug data #debug data
ret.append_data(10, notify_one) ret.append_data(10, notify_one)
ret.append_data(11, notify_two) ret.append_data(11, notify_two)
ret.append_data(12, notify_three) ret.append_data(12, notify_three)
ret.append_data(13, voltage_amp) #mV ret.append_data(13, voltage_amp) #amp[mV]
else: #CV Mode else: #CV Mode
ret.append_data(0, ch1) #Iin [nA]? ret.append_data(0, ch1) #Iin [nA]
ret.append_data(1, ch2) #Vset [nV]? ret.append_data(1, ch2) #Vset [nV]
ret.append_data(2, ch3) #Vout [nV]? ret.append_data(2, ch3) #Vout [nV]
ret.append_data(3, cycle_number) ret.append_data(3, cycle_number)
if cycle_number != self._cycle_number: if cycle_number != self._cycle_number:
+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 -2
View File
@@ -880,8 +880,7 @@ 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,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 -14
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.
@@ -588,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**
@@ -682,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**
@@ -743,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()
@@ -750,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:
@@ -794,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))
@@ -1111,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 -15
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)
@@ -1403,20 +1413,6 @@ class DebugDevice(CompletedDevice):
def read_command_return_data(self) -> Optional[bytes]: def read_command_return_data(self) -> Optional[bytes]:
return None return None
def send_command(self, ins_type: int, ins_oper: int, *instruction: int):
length = len(instruction)
print('instruction send :',
'%02X' % ((ins_type & 0xF0) | (self.device_id & 0x0F)),
'%02X' % ((ins_oper & 0xF0) | (length & 0x0F)),
' '.join(map(lambda v: '%02X' % v, instruction)))
def send_instruction(self, ins_type: int, ins_oper: int, *instruction: int):
length = len(instruction)
print('instruction send :',
'%02X' % ((ins_type & 0xF0) | (self.device_id & 0x0F)),
'%02X' % ((ins_oper & 0xF0) | (length & 0x0F)),
' '.join(map(lambda v: '%02X' % v, instruction)))
@property @property
def battery(self) -> int: def battery(self) -> int:
return 100 return 100
+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:
+16 -12
View File
@@ -3697,7 +3697,6 @@ class CC2650Central(LoggerFlag):
def recv(self, timeout: Optional[float] = None) -> Optional[list]: def recv(self, timeout: Optional[float] = None) -> Optional[list]:
packet = self._recv_byte() packet = self._recv_byte()
# print("packet = ", packet)
if packet is None: if packet is None:
return None return None
@@ -3709,6 +3708,8 @@ class CC2650Central(LoggerFlag):
def _recv_byte(self) -> Optional[int]: def _recv_byte(self) -> Optional[int]:
ret = self._recv_bytes(1) ret = self._recv_bytes(1)
# if ret is not None:
# print('packet = {0}'.format(hex(ret[0]).upper()))
return ret[0] if ret is not None else None return ret[0] if ret is not None else None
def _recv_bytes(self, size: int = 1) -> Union[None, bytes]: def _recv_bytes(self, size: int = 1) -> Union[None, bytes]:
@@ -3724,27 +3725,28 @@ class CC2650Central(LoggerFlag):
return None return None
def _recv_event(self, timeout: Optional[float] = 1) -> Optional[list]: def _recv_event(self, timeout: Optional[float] = 1) -> Optional[list]:
code = self._recv_byte() packet = self._recv_byte()
# print("code = ", code)
if code is None: if packet is None:
return None return None
length = self._recv_byte() length = self._recv_byte()
# print('code::',code,'length::',length) len_b = _struct.pack("B", length)
_start = _time()
data = b'' data = b''
while len(data) < length: _start = _time()
ret = self._recv_bytes(length - len(data))
# print("ret = ", ret)
if ret is not None: while len(data) < length:
data += ret packets = self._recv_bytes(length - len(data))
# hex_packets = ''.join(format(i, '02x') for i in packets)
# print("packets = ", hex_packets.upper())
if packets is not None:
data += packets
elif timeout is not None and _time() - _start > timeout: elif timeout is not None and _time() - _start > timeout:
raise RecvTimeout() raise RecvTimeout()
data = len_b + data
self._interface.flush() self._interface.flush()
return list(data) return list(data)
@@ -3760,5 +3762,7 @@ class CC2650Central(LoggerFlag):
raise RecvTimeout() raise RecvTimeout()
else: else:
uart_data_hex = ''.join(format(i, '02X') for i in uart_data)
# print('uart_data: 0x{0}'.format(uart_data_hex.upper()))
return uart_data return uart_data
+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
+2
View File
@@ -53,6 +53,8 @@ class UARTInterface(LowLevelHardwareInterface):
:param data: raw byte instruction :param data: raw byte instruction
:raises SerialTimeoutException: :raises SerialTimeoutException:
""" """
data_hex = ''.join(format(i, '02X') for i in data)
# print('send_byte: 0x{0}'.format(data_hex.upper()))
self._serial.write(data) self._serial.write(data)
def recv_byte(self, size: int) -> Optional[bytes]: def recv_byte(self, size: int) -> Optional[bytes]:
+14
View File
@@ -15,6 +15,9 @@ from .instruction import Instruction
from biopro.device.manager import DeviceManager from biopro.device.manager import DeviceManager
from biopro.text import * from biopro.text import *
from biopro.db.base import Session
from biopro.db.collection import Collection
key_list = { key_list = {
'deviceList': 'device', 'deviceList': 'device',
} }
@@ -60,6 +63,14 @@ class Project(threading.Thread):
fh = logging.FileHandler(f'/home/pi/logger/project/{self.uuid}.log', mode="w") fh = logging.FileHandler(f'/home/pi/logger/project/{self.uuid}.log', mode="w")
fh.setFormatter(self._formatter) fh.setFormatter(self._formatter)
self._logger.addHandler(fh) self._logger.addHandler(fh)
default_name = 'admin'
default_parent = {"folder": [1]}
collection = Collection.find_collection(default_name, default_parent)
parent = {"folder": [collection.id]}
# create project folder
collection = Collection.create_collection(self.name, parent)
self.setup_collection(collection)
def setup_project(self, project): def setup_project(self, project):
for (key, value) in project.items(): for (key, value) in project.items():
@@ -79,6 +90,9 @@ class Project(threading.Thread):
complete_device = self._device_manager.get_device(mac_address) complete_device = self._device_manager.get_device(mac_address)
complete_device.occupied_by_project = self._uuid complete_device.occupied_by_project = self._uuid
self._complete_device[device] = complete_device self._complete_device[device] = complete_device
def setup_collection(self, collection):
self._task_manager.create_collection(collection)
@property @property
def id(self) -> int: def id(self) -> int:
+17 -1
View File
@@ -5,6 +5,7 @@ from xml.dom.expatbuilder import parseString
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
from biopro.text import * from biopro.text import *
from .task import Task from .task import Task
from biopro.db.collection import Collection
_RUNTIME_COMPILE = False _RUNTIME_COMPILE = False
@@ -67,6 +68,13 @@ class TaskManager():
if cycle['range'][1] == task.uuid: if cycle['range'][1] == task.uuid:
return index return index
def check_task_in_cycle(self, task_index):
for index, cycle in enumerate(self._cycle_list):
if self.get_index_by_uuid(cycle['range'][0]) <= task_index:
if self.get_index_by_uuid(cycle['range'][1]) >= task_index:
return True
return False
@property @property
def check_list(self): def check_list(self):
return [self._running_task, *self._next_task] return [self._running_task, *self._next_task]
@@ -162,4 +170,12 @@ class TaskManager():
def get_task(self, task_id): def get_task(self, task_id):
return self._task_list[task_id] return self._task_list[task_id]
def create_collection(self, parent):
for index, task in enumerate(self._task_list):
if self.check_task_in_cycle(index) == True:
if task.type == '':
collection = Collection.create_collection(task.name, {"folder": [parent.id]})
task.parent = {"folder": [collection.id]}
else:
task.parent = {"folder": [parent.id]}
+8 -8
View File
@@ -362,14 +362,14 @@ class DataServer(SocketServer, DataAPI):
self.log_verbose('device ID', device_id) self.log_verbose('device ID', device_id)
# project binding meta file # project binding meta file
project_id = None # project_id = None
_project = None # _project = None
if project_info != None: # if project_info != None:
_project = json.loads(project_info) # _project = json.loads(project_info)
self.database_process.put_queue(['project_insert', device_id, _project]) # self.database_process.put_queue(['project_insert', device_id, _project])
result = self._queue_ds_dict[int(device_id)].get() # result = self._queue_ds_dict[int(device_id)].get()
if result[0] == 'project_id': # if result[0] == 'project_id':
project_id = result[1] project_id = project_info
# while len(self._configurations) <= device_id: # while len(self._configurations) <= device_id:
# self._configurationsappend(None) # self._configurationsappend(None)
+4 -2
View File
@@ -222,7 +222,8 @@ class DataBaseProcess(Process):
try: try:
sql_cursor.execute(sql_str, sql_set) sql_cursor.execute(sql_str, sql_set)
except: except BaseException as e:
print('meta create error', e)
self._psql_conn.commit() self._psql_conn.commit()
sql_cursor.close() sql_cursor.close()
self._queue_error.put(device_id) self._queue_error.put(device_id)
@@ -249,7 +250,8 @@ class DataBaseProcess(Process):
try: try:
sql_cursor.execute(sql_str, sql_set) sql_cursor.execute(sql_str, sql_set)
except: except BaseException as e:
print('meta update error', e)
self._psql_conn.commit() self._psql_conn.commit()
sql_cursor.close() sql_cursor.close()
self._queue_error.put(device_id) self._queue_error.put(device_id)
+58 -21
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
@@ -35,6 +37,7 @@ 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
_RUNTIME_COMPILE = False _RUNTIME_COMPILE = False
@@ -862,20 +865,32 @@ class ControlServer(SocketServer, ControlServerAPI):
@logging_info @logging_info
def device_update_calibration(self, device: int) -> Union[bool, str]: def device_update_calibration(self, device: int) -> Union[bool, str]:
connect_device = self.device_manager.get_device(device) connect_device = self.device_manager.get_device(device)
mac_address = connect_device.mac_address if connect_device == None:
return
mac_address = address_str(connect_device.mac_address)
device = Device.get_device({"mac_address": mac_address})
try: try:
if connect_device.library.name.startswith('Neulive3.'): if connect_device.library.name.startswith('Elite_EIS'):
connect_device.calibration_info('NeuliveThreeOne') # update calibration version
elif connect_device.library.name.startswith('Neulive'): connect_device._device.update_cali_version()
connect_device.calibration_info('TDC4VC') # check if is first time or calibration version is different
elif connect_device.library.name.startswith('EliteEIS'): if connect_device._device._cali_version == -1 or (device.calibration_version != connect_device._device._cali_version):
connect_device.calibration_info('EISZeroOne') # get calibration info from device
connect_device.calibration_info('EISZeroOne')
# update_calibration_info
Device.update_device(
{ "mac_address": mac_address },
{
'calibration': connect_device.calibration ,
'calibration_version': connect_device._device._cali_version
}
)
else:
connect_device._device._coeff = device.calibration
except BaseException as e: except BaseException as e:
# reset device info in db # reset device info in db
DeviceAPI.updateByMac( DeviceAPI.updateByMac(
address_str(mac_address), mac_address,
{ {
'connect_id': -1, 'connect_id': -1,
'connect_status': 'idle', 'connect_status': 'idle',
@@ -887,14 +902,6 @@ class ControlServer(SocketServer, ControlServerAPI):
print(e) print(e)
return False return False
else: else:
# update_calibration_info
DeviceAPI.updateByMac(
address_str(mac_address),
{
'calibration': str(connect_device.calibration)
}
)
# DeviceAPI.updateByAttrs('connect_status', 'update', {"connect_status": 'connect'})
return True return True
@logging_info @logging_info
@@ -1088,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
@@ -1102,6 +1137,7 @@ class ControlServer(SocketServer, ControlServerAPI):
client = self.data_server.client() client = self.data_server.client()
project = None project = 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)
@@ -1114,10 +1150,11 @@ class ControlServer(SocketServer, ControlServerAPI):
info = self.file_manager.save(device, filename) info = self.file_manager.save(device, filename)
if device.occupied_by_project != None: if device.occupied_by_project != None:
project = json.dumps(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)
with client: with client:
client.update_device_configuration(device, info.meta_file, value, project) 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:
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
@@ -106,13 +106,17 @@
"GENERAL_HS_RTIA": { "GENERAL_HS_RTIA": {
"description": "High speed rtia gain", "description": "High speed rtia gain",
"record_meta": true, "record_meta": true,
"initial": 4, "initial": 8,
"value": [ "value": [
0, 0,
1, 1,
2, 2,
3, 3,
4 4,
5,
6,
7,
8
], ],
"on_change": "set_general_hs_rtia" "on_change": "set_general_hs_rtia"
}, },
@@ -106,13 +106,17 @@
"GENERAL_HS_RTIA": { "GENERAL_HS_RTIA": {
"description": "High speed rtia gain", "description": "High speed rtia gain",
"record_meta": true, "record_meta": true,
"initial": 4, "initial": 8,
"value": [ "value": [
0, 0,
1, 1,
2, 2,
3, 3,
4 4,
5,
6,
7,
8
], ],
"on_change": "set_general_hs_rtia" "on_change": "set_general_hs_rtia"
}, },
@@ -106,13 +106,17 @@
"GENERAL_HS_RTIA": { "GENERAL_HS_RTIA": {
"description": "High speed rtia gain", "description": "High speed rtia gain",
"record_meta": true, "record_meta": true,
"initial": 4, "initial": 8,
"value": [ "value": [
0, 0,
1, 1,
2, 2,
3, 3,
4 4,
5,
6,
7,
8
], ],
"on_change": "set_general_hs_rtia" "on_change": "set_general_hs_rtia"
}, },
@@ -9,9 +9,189 @@
"minor_version_number": 0 "minor_version_number": 0
}, },
"constant": { "constant": {
"TIME_MAX": 100000 "TIME_MAX": 100000,
"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": {
"description": "ADC value current value",
"domain": "int"
},
"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_DURATION": { "TIME_DURATION": {
"description": "timer", "description": "timer",
"record_meta": true, "record_meta": true,
@@ -152,16 +332,14 @@
"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",
"Trigger"
] ]
}, },
"CHANNEL": { "CHANNEL": {
"description": "delete it", "description": "delete it",
"record_meta": true, "record_meta": true,
@@ -220,7 +398,8 @@
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "curve_acc" "0": "curve_acc",
"3": "trig_timer_mode"
} }
}, },
"_sync(True)", "_sync(True)",
@@ -245,6 +424,21 @@
"CIS_VOLT", "CIS_VOLT",
"_cdr('20X>ADC_VALUE_I')" "_cdr('20X>ADC_VALUE_I')"
], ],
"ble_instru_send": [
"ble_write",
"_cdr('20X>ADC_VALUE_I')"
],
"ble_write": {
"type": "RIS",
"data": [
"XFF;",
"1B>BLE_WRITE[0];1B>BLE_WRITE[1];1B>BLE_WRITE[2];1B>BLE_WRITE[3];",
"1B>BLE_WRITE[4];1B>BLE_WRITE[5];1B>BLE_WRITE[6];1B>BLE_WRITE[7];",
"1B>BLE_WRITE[8];1B>BLE_WRITE[9];1B>BLE_WRITE[10];1B>BLE_WRITE[11];",
"1B>BLE_WRITE[12];1B>BLE_WRITE[13];1B>BLE_WRITE[14];1B>BLE_WRITE[15];",
"1B>BLE_WRITE[16];"
]
},
"curve_acc": { "curve_acc": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
@@ -307,6 +501,677 @@
"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
@@ -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;"
]
}
}
}
+9
View File
@@ -27,3 +27,12 @@ sudo su -c "psql -d postgres -c \"ALTER TABLE IF EXISTS project_report RENAME TO
# change table project_meta column cycle to type jsonb # change table project_meta column cycle to type jsonb
sudo su -c "psql -d postgres -c \"ALTER TABLE project_metas ALTER COLUMN cycle type jsonb USING (cycle::jsonb);\"" postgres sudo su -c "psql -d postgres -c \"ALTER TABLE project_metas ALTER COLUMN cycle type jsonb USING (cycle::jsonb);\"" postgres
# drop column calibration default
sudo su -c "psql -d postgres -c \"ALTER TABLE devices ALTER COLUMN calibration DROP DEFAULT;\"" postgres
# drop column calibration default
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
sudo su -c "psql -d postgres -c \"ALTER TABLE devices ADD COLUMN IF NOT EXISTS calibration_version Int4 DEFAULT -1;\"" postgres