Compare commits

..

3 Commits

Author SHA1 Message Date
Roy 5e7c0710b9 flow of power on controller 2022-01-07 16:14:06 +08:00
Roy 5131535bda merge Spi & mitiSpi class 2022-01-03 11:08:33 +08:00
Roy ac5a6ef77a [update] data length: 120 bytes 2021-12-22 14:39:28 +08:00
150 changed files with 954 additions and 1177 deletions
-7
View File
@@ -1,7 +0,0 @@
.DS_Store
*.cpython-37.opt-2.pyc
*.pyc
*/__pycache__
/.vscode
/media
python/biopro/sever/_identify.py
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3 -4
View File
@@ -18,10 +18,9 @@ class ControllerAPI():
@staticmethod
def getByMac(mac_address):
try:
if mac_address != None:
ret = requests.get(API_URL + 'api/controller/get_by_mac/' + mac_address, headers= AuthAPI.get_key())
if ret.status_code == 200:
return ret.json()
ret = requests.get(API_URL + 'api/controller/get_by_mac/' + mac_address, headers= AuthAPI.get_key())
if ret.status_code == 200:
return ret.json()
except (requests.exceptions.ConnectionError, json.decoder.JSONDecodeError) as e:
print('get controller fail', e)
return []
-5
View File
@@ -1576,11 +1576,6 @@ class ControlAPI(metaclass=Router):
should handle this exit code and re-run server process.
"""
raise NotImplementedError()
def run_project(self, project) -> bool:
print('create_project', project)
self._project_manager.create(project)
return False
# noinspection PyAbstractClass
+248 -118
View File
@@ -315,6 +315,14 @@ class CC2650MasterDevice(MasterDevice, metaclass=abc.ABCMeta):
return cls.CC2650_RESET_PIN
@classmethod
def get_uart_irq_pin(cls) -> OutputPin:
if cls.CC2650_UART_IRQ is None:
cls.CC2650_UART_IRQ = OutputPin.get_used(P3Pin.MEM_RST, initial=True)
return cls.CC2650_UART_IRQ
class CC2650Device(Device):
def __init__(self,
@@ -536,7 +544,7 @@ class CC2650Device(Device):
self._master.log_warn('device', self.device_id, 'update_battery_info no response')
else:
if data is not None and len(data) > 2 :
if data is not None and len(data) == 4 :
battery = struct.unpack('<H', data[1:3])[0]
if battery is not None:
self._battery = battery
@@ -947,6 +955,9 @@ class CC2650SingleMasterDevice(CC2650MasterDevice, Synchronized):
self._cc2650.recv_util(..., when=self._cond, timeout=timeout)
def available_device(self) -> List[int]:
return [0]
@synchronized
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
if self._scan_max_time != timeout:
@@ -1431,6 +1442,11 @@ class CC2650MultiMasterDevice(CC2650MasterDevice, Synchronized):
super().shutdown()
self._selector.close()
def available_device(self) -> List[int]:
return list(map(lambda it: it[0],
filter(lambda it: it[1] is not None,
enumerate(self._cc2650))))
def get_device(self, device: int) -> Optional[Device]:
return self._device[device]
@@ -1926,34 +1942,44 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
self.log_verbose('reset (hardware)')
pin.output(False)
# sleep(0.001)
sleep(0.1)
pin.output(True)
sleep(0.1)
@synchronized
def reset_software(self):
"""software reset cc2650 (master)"""
# print('resettt---------14')
# print()
# self.log_verbose('reset (software)')
self.log_verbose('reset (software)')
# try:
# #self._cc2650.send("3B", 1, 0, 0)
# pass
try:
#self._cc2650.send("3B", 1, 0, 0)
pass
# except SerialTimeoutException as e:
# raise RecvTimeout('device CC2650 reset fail') from e
except SerialTimeoutException as e:
raise RecvTimeout('device CC2650 reset fail') from e
finally:
sleep(0.1)
# finally:
# sleep(0.1)
print("pass")
print()
@synchronized
def init_hardware(self, timeout=1):
"""initialize cc2650 (master)"""
pass
def available_device(self) -> List[int]:
return [0]
def scan_send_ins(self):
# send scan command
try:
print(':: scan_send_ins ::', self.CC2650_COMMAND_LEN, 3, 0, 0)
print()
self._cc2650.send(self.CC2650_COMMAND_LEN, 3, 0, 0)
except SerialTimeoutException as e:
@@ -1965,16 +1991,21 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
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)
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:
# if self._scan_max_time != timeout:
# self.log_info('set max scan limit time', timeout)
# self._scan_max_time = timeout
self._found = found = []
self._found_with_id = []
number_of_device = 0
hdr_BPHS = [66, 80, 72, 83]
scan_response: Union[Optional[tuple], Any] = None
@@ -1984,16 +2015,42 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
scan_ins.append(1) #length
scan_ins.append(0xF1)
# print('send_scan', bytes(scan_ins))
print('send_scan', list(scan_ins))
self._cc2650.send("bytes", bytes(scan_ins))
# for wait_scan_response in range(5):
# try:
# scan_response = self._cc2650.recv_uart(0.2)
# except RecvTimeout:
# if wait_scan_response == 4:
# self.reset_internal()
# self.reset_hardware()
# self._interface.flush()
# return True
# else:
# self.log_info("wait for scan response")
# continue
# # check if response is valid
# if scan_response is None:
# if wait_scan_response == 4:
# self.reset_internal()
# self.reset_hardware()
# self._interface.flush()
# else:
# self.log_info("wait for scan response")
# continue
# else:
# break
try:
scan_response = self._cc2650.recv_uart(timeout)
scan_response = self._cc2650.recv_uart(0.2)
except RecvTimeout:
# self.reset_internal()
# self.reset_hardware()
# self._interface.flush()
return False
self.reset_internal()
self.reset_hardware()
self._interface.flush()
return True
# instruction format:
# ins[0]: get_scan_response = 0x04
@@ -2088,35 +2145,6 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
def found(self) -> List[DeviceResponseInfo]:
return self._found
def check_mem_survive(self) -> Optional[CC2650Device]:
ack = []
ins = bytearray()
ins.append(10)
ins.append(1) #length
ins.append(0xF1)
# print('ins', list(ins))
try:
self._cc2650.send("bytes", bytes(ins))
except SerialTimeoutException as e:
raise RecvTimeout('device CC2650 check_mem_survive timeout') from e
else:
try:
ack = self._cc2650.recv_uart(0.001)
except RecvTimeout:
self.log_info("no memory board")
# else:
# print('ack=', ack)
if ack == [3]:
return True
return False
@synchronized
def connect(self, response: DeviceResponseInfo, direct_connect: bool = False) -> Optional[CC2650Device]:
if self._handle is not None:
@@ -2147,6 +2175,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
# send device mac and addrType
try:
print('send_connect..',list(connect_ins))
self._cc2650.send("bytes", bytes(connect_ins))
except SerialTimeoutException as e:
@@ -2179,39 +2208,26 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
# send device mac and addrType
try:
# print('send_connect',bytes(connect_ins))
print('send_connect',list(connect_ins))
self._cc2650.send("bytes", bytes(connect_ins))
except SerialTimeoutException as e:
raise RecvTimeout('device CC2650 connect fail') from e
else:
sleep(2)
# connection establish done?
for retry_recv_ack in range(5):
self._cc2650.send("bytes", bytes((0, 0, 0, 0)))
sleep(1)
try:
con_done = self._cc2650.recv_uart(timeout = 0.1)
except RecvTimeout:
self.log_info("recv connection timeout, retry... ")
continue
self.log_info("recv connection timeout, fail... ")
# is the ack valid?
if con_done is None:
continue
elif con_done[0] is 46 and \
if 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
print('con_done=', con_done)
# if select device is invalid or connect failed
self._interface.flush_input()
@@ -2232,6 +2248,36 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
return ret
def check_mem_survive(self) -> Optional[CC2650Device]:
ack = []
ins = bytearray()
ins.append(10)
ins.append(1) #length
ins.append(0xF1)
try:
self._cc2650.send("bytes", bytes(ins))
except SerialTimeoutException as e:
raise RecvTimeout('device CC2650 check_mem_survive timeout') from e
else:
# sleep(1)
try:
ack = self._cc2650.recv_uart(timeout = 0.1)
except RecvTimeout:
self.log_info("no survive device")
else:
print('ack=', ack)
if ack == [3]:
return True
return False
@synchronized
def disconnect(self, device: int, force=False) -> bool:
self.log_info(DEVICE_DISCONNECTING, device)
@@ -2242,7 +2288,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
ins.append(0xF1)
try:
# print('send_disconnect',bytes(ins))
print('send_disconnect',list(ins))
self._cc2650.send("bytes", bytes(ins))
except RecvTimeout:
@@ -2277,28 +2323,20 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
ins.append(handle)
ins.append(0xF1)
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:
print('read_characteristic',list(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
try:
ret = self._cc2650.recv_uart(timeout = 2)
except Exception as e2:
raise RecvTimeout()
else:
# print("======== read ret = ", ret)
self._interface.flush_input()
if ret is None:
return None
@@ -2326,23 +2364,21 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
try:
self._cc2650.send("bytes", bytes(data_array))
# print('send_write',bytes(data_array))
self._cc2650.send("bytes", list(data_array))
print('send_write',list(data_array))
except SerialTimeoutException as e:
raise RecvTimeout('device CC2650 send instruction fail') from e
# read error code
try:
ret = self._cc2650.recv_uart()
ret = self._cc2650.recv_uart(timeout = 0.1)
print('ret=', ret)
# print("_______ write ack = ", ret)
except Exception as e2:
pass
else:
pass
self._interface.flush_input()
self._interface.flush_output()
@@ -2519,44 +2555,143 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
else:
self.log_warn('cannot %s notify for device : %s' % (message, device.__class__.__name__))
# def reset(self, device: Optional[List[int]] = None, software_reset=True):
# print('resettt---------15')
# print()
# # self.log_verbose('reset')
# # reset hardware
# # print("reset device = ", device)
# print('device:', device, software_reset)
# print('self._device', list(self._device))
# print('self._cc2650_once:', list(self._cc2650))
# print('|')
# print('|')
# for i in range(len(self._cc2650)):
# print('i', i)
# if device is None or i in device:
# self._device[i] = None
# m = self._cc2650[i]
# if m is None:
# m = CC2650SingleMasterCentralDevice(self._master, self._interface, self._options)
# self._interface.flush()
# self._selector.select(i)
# try:
# self.log_info('reset device', i)
# with m:
# m.reset_internal()
# m.reset_hardware()
# if software_reset:
# check_mem_survive_flag = m.check_mem_survive()
# if check_mem_survive_flag:
# self._cc2650[i] = m
# except RecvTimeout:
# self.log_warn('reset device', i, 'fail')
# self._cc2650[i] = None
# print('self._cc2650::', list(self._cc2650))
# return
def reset(self, device: Optional[List[int]] = None, software_reset=True):
print('resettt---------15')
print()
# self.log_verbose('reset')
# reset hardware
# print("reset device = ", device)
print('device:', device, software_reset)
print('self._device', list(self._device))
print('self._cc2650_once:', list(self._cc2650))
print('|')
print('|')
for i in range(len(self._cc2650)):
if device is None or i in device:
if device is None:
self._device[i] = None
m = self._cc2650[i]
if m is None:
m = CC2650SingleMasterCentralDevice(self._master, self._interface, self._options)
self._cc2650[i] = m
self._interface.flush()
self._selector.select(i)
try:
self.log_info('reset device', i)
with m:
m.reset_internal()
m.reset_hardware()
m.reset_software()
if not software_reset:
check_mem_survive_flag = m.check_mem_survive()
if check_mem_survive_flag:
self._cc2650[i] = m
except RecvTimeout:
self.log_warn('reset device', i, 'fail')
self._cc2650[i] = None
if not software_reset:
return
print('self._cc2650::', list(self._cc2650))
def _foreach_empty_master(self) -> Iterable[int]:
for i in range(len(self._device)):
return
def reset_empty_master(self, device: Optional[List[int]] = None, software_reset=True):
self.log_verbose('reset')
# reset hardware
# print("reset device = ", device)
for i in range(len(self._cc2650)):
# print(i)
m = self._cc2650[i]
d = self._device[i]
if d is None:
# print(m, d)
if m is not None and d is None:
m = CC2650SingleMasterCentralDevice(self._master, self._interface, self._options)
# m.set_log_level(self._cc2650_log_level)
self._interface.flush()
self._selector.select(i)
self._mem_selector.select(i)
try:
self.log_info('reset device', i)
with m:
m.reset_internal()
m.reset_hardware()
except RecvTimeout:
self.log_warn('reset device', i, 'fail')
self._cc2650[i] = None
def available_device(self) -> List[int]:
return list(map(lambda it: it[0],
filter(lambda it: it[1] is not None,
enumerate(self._cc2650))))
def _foreach_empty_master(self) -> Iterable[int]:
for i in range(len(self._cc2650)):
m = self._cc2650[i]
d = self._device[i]
if m is not None and d is None:
yield i
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
@@ -2564,35 +2699,28 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
all_result = False
for device in range(len(self._cc2650)):
for device in self._foreach_empty_master():
self.log_verbose('use', device)
m = self._cc2650[device]
d = self._device[device]
if d is None:
if m is not None and d is None:
error = None
with self:
self._interface.flush()
self._selector.select(device)
# self._mem_selector.select(device)
try:
if m.check_mem_survive() == False:
continue
result = m.scan_callback(callback, timeout=0.001)
sleep(0.0001)
result = m.scan_callback(callback, timeout=timeout)
except RuntimeError as e:
error = e
else:
if result == False:
result = True
all_result = all_result or result
continue
all_result = all_result or result
if result and not all_device:
@@ -2600,7 +2728,8 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
if error is not None:
self.log_warn('suppressed error : ' + str(error))
# self.reset(device)
sleep(1)
return all_result
def found(self) -> List[DeviceResponseInfo]:
@@ -2653,6 +2782,7 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
with self:
self._interface.flush()
self._selector.select(master)
# self._mem_selector.select(device)
sleep(0.0001)
d = m.connect(response, direct_connect)
+10 -7
View File
@@ -261,7 +261,8 @@ class DeviceManager(MasterDevice, Synchronized):
__slots__ = ('_handler', '_options',
'_library_path', '_library',
'_interface', '_master', '_found_history', '_found', '_device', '_master_log_level')
'_interface', '_master', '_found_history', '_found', '_device', '_master_log_level',
'_mem_survive_channel')
def __init__(self,
options: DeviceManagerOptions,
@@ -381,8 +382,16 @@ class DeviceManager(MasterDevice, Synchronized):
"""reset master device"""
self._device.clear()
self._demo.clear()
print('resettt---------21')
print()
self._centralMaster.reset(device, software_reset)
def get_mem_survive_channel(self):
return self._mem_survive_channel
def available_device(self) -> List[int]:
return self._centralMaster.available_device()
@logging_info
def shutdown(self, release_resource=True):
# shutdown reset memeryboard
@@ -562,7 +571,6 @@ class DeviceManager(MasterDevice, Synchronized):
@logging_verbose
def get_device(self, device: Union[int, DeviceInfo]) -> Optional[CompletedDevice]:
print('get_device', device)
"""get connected device
:param device: device ID or response info
@@ -573,11 +581,6 @@ class DeviceManager(MasterDevice, Synchronized):
if slave.device_id == device:
return slave
elif isinstance(device, str):
for slave in self._device:
if ':'.join('{:02x}'.format(b) for b in slave.mac_address) == device.lower():
return slave
elif isinstance(device, DeviceInfo):
for slave in self._device:
if device.match(slave):
+42 -58
View File
@@ -882,18 +882,19 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
if len(data) < 18:
return None
mem_cnt = data[1]
time_stamp: float = struct.unpack('<I', data[4:8])[0] # unit: ms 0x18030000
current = struct.unpack('<i', data[8:12])[0] # unit: nA
voltage = struct.unpack('<i', data[12:16])[0] # unit: uV
impedance = struct.unpack('<i', data[16:20])[0] # unit: mOm
cycle_number = struct.unpack('<H', data[20:22])[0]
finish_mode_falg = data[22]
battery = struct.unpack('>i', data[23:27])[0]
elite_notify_times = data[27]
current = struct.unpack('>i', data[1:5])[0] # unit: 1/1000 nA
voltage = struct.unpack('>i', data[5:9])[0] # unit: mV
impedance = struct.unpack('>i', data[9:13])[0] # unit: kOm
time_stamp: float = struct.unpack('<I', data[13:17])[0] # unit: ms
cycle_number = struct.unpack('>H', data[17:19])[0]
finish_mode_falg = data[19]
mem_wrong_information = struct.unpack('<i', data[43:47])[0] # mem_wrong_information = green retry, green wrong, red retry, red wrong
ram_num = data[47]
# print('decode', list(data[20:]))
mem_wrong = data[120]
mem_retry_cnt = data[121]
mem_green_wrong = data[122]
mem_green_retry_cnt = data[123]
ram_num = data[124]
broken_flag = data[-1]
if (finish_mode_falg & 0b11110000 == 0b10100000):
@@ -914,13 +915,10 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
print("error timeStamp full data:", list(data), datetime.now(), '\n')
return None
else:
# print('|', time_stamp, '|', delta, '|', int(time_stamp * 1000 / 2),
# '|', current, '|', voltage, '|', impedance,
# print('|', time_stamp, '|', delta, '|', current, '|', voltage, '|', impedance,
# '|', cycle_number, '|', finishMode, '@', str(self.device))
# print('|', '{:10}'.format(time_stamp),
# '|', '{:4}'.format(delta),
# '|', '{:10}'.format(int(time_stamp * 1000 / 2)),
# '|', '{:10}'.format(delta),
# '|', '{:10}'.format(current),
# '|', '{:10}'.format(voltage),
# '|', '{:10}'.format(impedance),
@@ -928,9 +926,12 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
# '|', '{:1}'.format(finishMode),
# '@', str(self.device), '|')
# print('|', '{:5}'.format(mem_wrong_information),
# '|', '{:2}'.format(ram_num),
# '|', '{:2}'.format(broken_flag),
# print('|', '{:5}'.format(mem_wrong),
# '|', '{:5}'.format(mem_retry_cnt),
# '|', '{:5}'.format(mem_green_wrong),
# '|', '{:5}'.format(mem_green_retry_cnt),
# '|', '{:5}'.format(ram_num),
# '|', '{:5}'.format(broken_flag),
# '@', str(self.device), '|')
pass
@@ -945,20 +946,14 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
ret.append_data(1, voltage)
ret.append_data(2, impedance)
ret.append_data(3, cycle_number)
ret.append_data(4, battery)
ret.append_data(5, elite_notify_times)
ret.append_data(6, mem_cnt)
# memoryboard information
ret.append_data(7, ram_num)
ret.append_data(8, broken_flag)
try:
ret.append_data(9, mem_wrong_information)
# print('append_data success, mem_wrong_information:', mem_wrong_information, hex(mem_wrong_information))
except:
print('append_data fail, mem_wrong_information:', mem_wrong_information, hex(mem_wrong_information))
ret.append_data(4, mem_wrong)
ret.append_data(5, mem_retry_cnt)
ret.append_data(6, mem_green_wrong)
ret.append_data(7, mem_green_retry_cnt)
ret.append_data(8, ram_num)
ret.append_data(9, broken_flag)
if cycle_number != self._cycle_number:
# notify cycle_number change
@@ -1383,46 +1378,41 @@ class EISZeroOneDataDecoder(RecDataDecoder):
index = 20
for i in range(index, index+16, 8):
phase_para_a.append(struct.unpack('>i', cali_coeff[i+1:i+5])[0])
phase_para_a.append(struct.unpack('>I', cali_coeff[i+1:i+5])[0])
phase_para_b.append(struct.unpack('>i', cali_coeff[i+5:i+9])[0])
index = 40
for i in range(index, index+16, 8):
phase_para_a.append(struct.unpack('>i', cali_coeff[i+1:i+5])[0])
phase_para_a.append(struct.unpack('>I', cali_coeff[i+1:i+5])[0])
phase_para_b.append(struct.unpack('>i', cali_coeff[i+5:i+9])[0])
#Lv[0] 160k
index = 60
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8)
hsrtia_a.append(struct.unpack('>I', cali_coeff[index+1:index+5])[0]/1e8)
hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8)
hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]/1e4)
hsrtia_d.append(struct.unpack('>B', cali_coeff[index+13:index+14])[0])
#Lv[1] 20k
index = 80
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8)
hsrtia_a.append(struct.unpack('>I', cali_coeff[index+1:index+5])[0]/1e8)
hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8)
hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]/1e4)
hsrtia_c.append(struct.unpack('>I', cali_coeff[index+9:index+13])[0]/1e4)
hsrtia_d.append(struct.unpack('>B', cali_coeff[index+13:index+14])[0])
#Lv[2] 5k
index = 100
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8)
hsrtia_a.append(struct.unpack('>I', cali_coeff[index+1:index+5])[0]/1e8)
hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8)
hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]/1e4)
hsrtia_c.append(struct.unpack('>I', cali_coeff[index+9:index+13])[0]/1e4)
hsrtia_d.append(struct.unpack('>B', cali_coeff[index+13:index+14])[0])
#Lv[3] 200R
index = 120
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8)
hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8)
hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]/1e4)
hsrtia_d.append(struct.unpack('>B', cali_coeff[index+13:index+14])[0])
# hsrtia_a.append(struct.unpack('>I', cali_coeff[index+1:index+5])[0])
# hsrtia_b.append(struct.unpack('>I', cali_coeff[index+5:index+9])[0]/1e6)
# hsrtia_c.append(struct.unpack('>I', cali_coeff[index+9:index+13])[0]/1e5)
# hsrtia_d.append(struct.unpack('>I', cali_coeff[index+13:index+17])[0]/1e6)
hsrtia_a.append(struct.unpack('>I', cali_coeff[index+1:index+5])[0])
hsrtia_b.append(struct.unpack('>I', cali_coeff[index+5:index+9])[0]/1e6)
hsrtia_c.append(struct.unpack('>I', cali_coeff[index+9:index+13])[0]/1e5)
hsrtia_d.append(struct.unpack('>I', cali_coeff[index+13:index+17])[0]/1e6)
# print('cutoff_freq', cutoff_freq)
# print('hsrtia_a', hsrtia_a)
@@ -1502,19 +1492,13 @@ class EISZeroOneDataDecoder(RecDataDecoder):
voltage_mag = math.sqrt(img ** 2 + real ** 2) * (1 + freq ** 2 / cutoff_freq ** 2)
# if (gain == 3):
# current = hsrtia_a[gain] * math.exp(hsrtia_b[gain] * voltage_mag) + hsrtia_c[gain] * math.exp(hsrtia_d[gain] * voltage_mag)
# else:
current = voltage_mag ** 2 * hsrtia_a[gain] + voltage_mag * hsrtia_b[gain] + hsrtia_c[gain]
# print(current)
# print(voltage_mag)
# print(hsrtia_a[gain])
# print(hsrtia_b[gain])
# print(hsrtia_c[gain])
if (gain == 3):
current = hsrtia_a[gain] * math.exp(hsrtia_b[gain] * voltage_mag) + hsrtia_c[gain] * math.exp(hsrtia_d[gain] * voltage_mag)
else:
current = voltage_mag ** 2 * hsrtia_a[gain] + voltage_mag * hsrtia_b[gain] + hsrtia_c[gain]
if (current != 0):
# impedance = voltage_amp * 1000_000 / 1.414213 / current
impedance = voltage_amp * 707106.78 / current
impedance = voltage_amp * 1000000 / current
else:
impedance = 0
+7
View File
@@ -963,6 +963,10 @@ class MasterDevice(LoggerFlag, metaclass=abc.ABCMeta):
"""
pass
@abc.abstractmethod
def available_device(self) -> List[int]:
pass
def scan(self, timeout=5, all_device=False) -> List[DeviceResponseInfo]:
"""scan the nearby device.
@@ -1097,6 +1101,9 @@ class NullMasterDevice(MasterDevice):
def shutdown(self, release_resource=True):
pass
def available_device(self) -> List[int]:
return []
def scan(self, timeout=5, all_device=False) -> List[DeviceResponseInfo]:
return []
-5
View File
@@ -1082,11 +1082,6 @@ class CompletedDevice(Device):
:return: parameter V value
"""
return self._configuration.get_parameter(name, False)
def set_multi_parameters(self, parameter):
for (name, value) in parameter[0].items():
if name != 'target':
self.set_parameter(name, value)
def set_parameter(self, name: str, value: Union[int, str]):
"""replace parameter value with *value*
+4 -1
View File
@@ -3720,9 +3720,12 @@ class CC2650Central(LoggerFlag):
if ret is not None and len(ret) > 0:
return ret
elif _time() - start > 0.01: # read timeout
elif _time() - start > 1:
return None
else:
sleep(0.01)
def _recv_event(self, timeout: Optional[float] = 1) -> Optional[list]:
code = self._recv_byte()
# print("code = ", code)
+120 -175
View File
@@ -16,6 +16,8 @@ MEM_REG_READ = 0x05
DEFAULT_REGISTER_VALUE = 0b0100_0011 # 67
MEM_SIZE = 0x1000
_RUNTIME_COMPILE = False
_SLEEP_TIME_ = 0.001
@@ -24,15 +26,12 @@ def zero_buffer(size: int) -> List[int]:
return [0] * size
class MultiExtMemSpiInterface(LowLevelHardwareInterface):
MEM_INS_MARKED1 = [MEM_INS_WRITE, 0, 2, 0x5A, 0xA5]
MEM_INS_MARKED2 = [MEM_INS_WRITE, 0, 6, 0x5A, 0xA5]
MEM_INS_MARKED3 = [MEM_INS_WRITE, 0, 10, 0x5A, 0xA5]
# MEM_INS_RESET = [MEM_INS_WRITE, 0, 2, 1, 1, 0, 0xFF]
MEM_INS_MARKED = [MEM_INS_WRITE, 0, 2, 1, 1]
MEM_INS_RESET = [MEM_INS_WRITE, 0, 2, 1, 1, 0, 0xFF]
__slots__ = ('_selector', '_wait_for_first_data', '_spi', '_tx_buffer_header', '_tx_buffer_data',
'pin_busy', 'pin_mem_req', 'pin_mem_sel', 'pin_ram_sel',
__slots__ = ('_selector', '_wait_for_first_data', '_spi', '_tx_buffer', '_tx_buffer_header', '_tx_buffer_data',
'pin_busy', 'pin_request', 'pin_reset', 'pin_sel',
'_pin_sel_val',
'_pin_ram_sel_value', '_pin_mem_sel_value', '_pin_mem_req_value',
'_read_green_times','_read_red_times',
'_elite_data_len', '_mem_header_len', '_mem_tailer_len', '_single_data_len',
'_head_wrong_cnt')
@@ -42,26 +41,24 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
device: Tuple[int, int] = None):
self._spi = HardwareImplSpiInterface(device,
spi_speed=12_000_000)
spi_speed=12_000_000 # XXX temp parameter
)
self._elite_data_len = 40
self._elite_data_len = 120
self._mem_header_len = 3
self._mem_tailer_len = 6
self._mem_tailer_len = 8
self._single_data_len = self._elite_data_len + self._mem_header_len + self._mem_tailer_len
# buffer
self._tx_buffer_header = [0] * 19
self._tx_buffer = [0] * 512
self._tx_buffer_header = [0] * 11
self._tx_buffer_data = [0] * (self._single_data_len * 10 + 3)
# memory control pin
self.pin_busy = OutputPin.get_used(P3Pin.MEM_BZY, True)
self.pin_mem_req = OutputPin.get_used(P3Pin.MEM_REQ, False)
self.pin_mem_sel = OutputPin.get_used(P3Pin.MEM_RST, True) # MEM_RST -> actually which memory board is assign
self.pin_ram_sel: Optional[InputPin] = InputPin.get_used(P3Pin.MEM_SEL) # MEM_SEL -> actually is RAM_SEL, which RAM is assign
self._pin_ram_sel_value = [bool(self.pin_ram_sel) for _ in range(Selector.SIZE)]
self._pin_mem_sel_value = [bool(self.pin_mem_sel) for _ in range(Selector.SIZE)]
self._pin_mem_req_value = [bool(self.pin_mem_req) for _ in range(Selector.SIZE)]
self.pin_request = OutputPin.get_used(P3Pin.MEM_REQ, True)
self.pin_reset = OutputPin.get_used(P3Pin.MEM_RST, True)
self.pin_sel: Optional[InputPin] = InputPin.get_used(P3Pin.MEM_SEL)
self._read_green_times = 0
self._read_red_times = 0
@@ -74,28 +71,6 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
self._pin_sel_val = [False for _ in range(Selector.SIZE)]
self._wait_for_first_data = [True for _ in range(Selector.SIZE)]
def set_pin_mem_req(self, value: bool):
channel = self.select
self.pin_mem_req.output(value)
self._pin_mem_req_value[channel] = value
def set_pin_mem_sel(self, value: bool):
channel = self.select
self.pin_mem_sel.output(value)
self._pin_mem_sel_value[channel] = value
def get_pin_mem_req(self):
channel = self.select
return self._pin_mem_req_value[channel]
def get_pin_ram_sel(self):
channel = self.select
if self.pin_ram_sel.input() == 0:
self._pin_ram_sel_value[channel] = False
else:
self._pin_ram_sel_value[channel] = True
return self._pin_ram_sel_value[channel]
@property
def select(self) -> int:
return self._selector.channel
@@ -104,35 +79,71 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
def select(self, value: int):
self._selector.select(value)
def changed(self, flip=False) -> bool:
channel = self._selector.channel
old = self._pin_sel_val[channel]
value = bool(self.pin_sel)
if flip:
self._pin_sel_val[channel] = value
return value != old
def reset(self):
self._spi.reset()
def flush(self):
pass
def close(self):
self._selector.close()
self._spi.close()
def flush(self):
self.pin_reset.output(False)
self.pin_reset.output(True)
def send_byte(self, data: bytes):
raise RuntimeError()
def recv_byte(self, size: int) -> Optional[bytes]:
raise RuntimeError()
# def flush_all(self):
# for _ in self._selector.foreach():
# self.pin_reset.output(False)
# self.pin_reset.output(True)
def foreach(self) -> Iterable[int]:
for channel in self._selector.foreach():
yield channel
def set_wait_flag(self, spi_idx:int = None, value:bool = None):
self._wait_for_first_data[spi_idx] = value
def get_wait_flag(self, spi_idx:int = None) -> Optional[bool]:
if spi_idx < Selector.SIZE:
return self._wait_for_first_data[spi_idx]
else:
return None
def request_data(self):
self.pin_request.output(False)
sleep(0.001)
# count = 0
# for i in range(300):
# count = count + 1
self.pin_request.output(True)
# sleep(0.001) -> 1.2ms
# no sleep -> 5us ~ 12us (central can't receive)
# for i in range
# (1000) -> 500us ~ 1ms
# (500) -> 200us ~ 500us
# (300) -> 120us ~ 270us (seldom)
# (200) -> 70us ~ 160us (skip req about every 64 time) x
# (100) -> 40us ~ 100us (skip req sometimes) x
def compare_green_data(self, data_first: Union[bytes, List[int]], data_second: Union[bytes, List[int]], data_third: Union[bytes, List[int]], length: int):
data = []
data.append(255)
@@ -167,52 +178,6 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
print("read red data times", self._read_red_times)
return data
def _compare_green_data_addr_and_flag(self, data: Union[bytes, List[int]], device: int):
green_data_section1 = data[3:7]
green_data_section2 = data[7:11]
green_data_section3 = data[11:15]
green_data_section = []
if green_data_section1 == green_data_section2:
green_data_section = green_data_section1
elif(green_data_section2 == green_data_section3 or green_data_section1 == green_data_section3):
print("green data not equal: = ", data[3:15])
print("green data print:", data, device, datetime.now())
green_data_section = green_data_section3
else:
print("green data not equal: = ", data[3:15])
print("green data print:", data, device, datetime.now())
green_data_section = green_data_section3 # use last data
return green_data_section
def _print_ram_all_data(self):
addr = 0
red_length = int(7000 / 2)
tx_temp = [0] * (red_length + 3)
while True:
tx_temp[0] = MEM_INS_READ
tx_temp[1] = ((addr >> 8) & 0xFF)
tx_temp[2] = (addr & 0xFF)
ram_data = []
ram_data = self._spi.send_byte(tx_temp)
ram_data[0:3] = [255, 255, 255]
print(list(ram_data), len(ram_data), addr)
addr += len(ram_data) - 3
if (7000 < addr + len(ram_data)):
del ram_data
break
print()
return
def recv_memory(self, device: int) -> Optional[bytes]:
self.pin_busy.output(False)
@@ -237,9 +202,9 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
if (data[0] != 255 or data[1] != 255 or data[2] != 255):
self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
if (self._head_wrong_cnt[device] <= 5): # print 5 times
print('data_first[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times')
print(list(data))
if (self._head_wrong_cnt[device] < 6):
print('data_first[0:3] != [255, 255, 255]', device)
print(list(data[0:7]))
data[0:3] = [255, 255, 255]
# ----------------------------------------------------------------------------------------------
@@ -257,14 +222,14 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
# if (data_first[0] != 255 or data_first[1] != 255 or data_first[2] != 255):
# self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
# if (self._head_wrong_cnt[device] < 10):
# print('data_first[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times')
# print(list(data_first))
# print('data_first[0:3] != [255, 255, 255]', device)
# print(list(data_first[0:7]))
# if (data_second[0] != 255 or data_second[1] != 255 or data_second[2] != 255):
# self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
# if (self._head_wrong_cnt[device] < 10):
# print('data_second[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times')
# print(list(data_second))
# print('data_second[0:3] != [255, 255, 255]', device)
# print(list(data_second[0:7]))
# if (data_first[3:] == data_second[3:]):
# data = data_first
@@ -276,47 +241,59 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
# data = self.compare_green_data(data_first, data_second, data_third, len(tx_h))
# ----------------------------------------------------------------------------------------------
green_data_section = self._compare_green_data_addr_and_flag(data, device)
# debug use
# green_data = []
# green_data = data
# print("_[Debug] @ spi green data = ", green_data)
length = (green_data_section[0] << 8) | green_data_section[1]
header = data[15]
elite_data_len = data[17]
if length <= 12:
if length < 12:
print("length < 12")
print("green data print:", data, device, datetime.now())
if length == 0:
self._print_ram_all_data()
length = (data[3] << 8) | data[4]
header = data[7]
elite_data_len = data[9]
if length <= 4:
# print("length <= 4")
# print("green data print:", data, device, datetime.now())
return None
if green_data_section[2] != 0xA5 or green_data_section[3] != 0x5A:
if data[5] != 0 or data[6] != 0:
# give a default length if the data header did not update
print("green data: is not [0xA5, 0x5A], = ", data[5:7])
length = 7000
print("green data: is not [0,0], = ", data[5:7])
print("green data print:", data, device, datetime.now())
return None
if (length >= 4000):
if (length >= 7000):
flag_print = True
print("green data: big length:", length)
if (header != 255):
flag_print = True
print("green data: header is not 255: ", header)
self._print_ram_all_data()
if (elite_data_len != self._elite_data_len):
flag_print = True
print("green data: length is not", self._elite_data_len, ": ", elite_data_len)
if (flag_print):
print("green data print:", data, device, datetime.now(), '\n')
print("green data print:", data, device, datetime.now())
address = 12
# neulive
# address += len(data) - 11
# tx_d = self._tx_buffer_data
# red_length = len(tx_d)
# elite read all data of ram
# address = 4
# red_length = length - 1
# tx_d = [0] * red_length
address = 4
red_length = int(length / 2)
tx_d = [0] * (red_length + 3)
tx_d = [0] * red_length
# elite read len(_tx_buffer_data) byte
# address = 4
# tx_d = self._tx_buffer_data
while True:
tx_d[0] = MEM_INS_READ
@@ -355,60 +332,22 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
address += len(data) - 3
del data
# last_index = 0
# print("_[Debug] @ spi recv data rx, ram_select:", self._pin_ram_sel_value[device], ",", datetime.now())
# print("_[Debug] @ spi recv data rx = ")
# for i in range(0, len(rx), self._single_data_len):
# last_index = i
# # print(rx[i:i+self._single_data_len])
# if i == 0:
# print(rx[0:8], 'ram:', rx[47])
# if last_index != 0:
# print(rx[last_index:last_index+8], 'ram:', rx[last_index+47])
# print(rx[i:i+self._single_data_len])
# print()
# /*
# * red data formate:
# * ramHdr, ramHdr, ramHdr, (3B)
# * 255, #, data_length, (3B)
# * data, (40B)
# * data, (20B)
# * red_wrong, red_retry_cnt, green_wrong, green_retry_cnt, (4B)
# * check_num, (1B)
# * 255, #, data_length, (3B)
# * */
# read again if check num is wrong
index = 0
check_number_print = False
for i in range(0, len(rx), self._single_data_len):
check_sum = sum(rx[i : i + self._single_data_len - 1]) & 0b11111111
# print(check_sum, rx[i + self._single_data_len - 1])
if (check_sum != rx[i + self._single_data_len - 1]):
print('check_sum wrong, origin value:', 'check_sum =', check_sum, rx[i : i + self._single_data_len])
tx_d = [0] * (self._single_data_len + 3)
address = 12 + self._single_data_len * index
tx_d[0] = MEM_INS_READ
tx_d[1] = ((address >> 8) & 0xFF)
tx_d[2] = (address & 0xFF)
data = []
data = self._spi.send_byte(tx_d)
data[0:3] = [255, 255, 255]
rx[i : i + self._single_data_len] = data[3:]
print('check_sum wrong, read again:', 'check_sum =', check_sum, rx[i : i + self._single_data_len])
check_number_print = True
index = index + 1
if check_number_print:
print('check_sum wrong:', device, datetime.now())
for i in range(0, len(rx), self._single_data_len):
print(rx[i:i+self._single_data_len])
print()
# mark read
self._spi.send_byte(self.MEM_INS_MARKED1)
self._spi.send_byte(self.MEM_INS_MARKED2)
self._spi.send_byte(self.MEM_INS_MARKED3)
self._spi.send_byte(self.MEM_INS_MARKED)
except BaseException as e:
print(e)
@@ -443,37 +382,39 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
class ExtMemManager:
def __init__(self, ext_mem: MultiExtMemSpiInterface):
self._mem_sel = InputPin.get_used(P3Pin.MEM_SEL, pull_up_down=True)
self._mem_req = OutputPin.get_used(P3Pin.MEM_REQ, initial=True)
self._ext_mem = ext_mem
print('ExtMemManager.....')
print()
def mem_request(self):
self._mem_req.pulse()
sleep(_SLEEP_TIME_)
def get_ext_mem_register(self) -> List[Tuple[Optional[int], Optional[int]]]:
print('get_ext_mem_register......')
print()
ret = [(None, None) for _ in range(Selector.SIZE)]
for channel in self._ext_mem.foreach():
r = [None, None]
self._ext_mem.set_pin_mem_sel(False)
pin_value = self._ext_mem.get_pin_mem_req()
self._ext_mem.set_pin_mem_req(not pin_value)
m1 = int(self._ext_mem.get_pin_ram_sel())
self.mem_request()
sleep(0.01)
m1 = int(self._mem_sel)
# print("m1 = ", m1)
self._ext_mem.write_register(DEFAULT_REGISTER_VALUE)
r[m1] = self._ext_mem.read_register()
sleep(0.040)
self._ext_mem.set_pin_mem_sel(True)
sleep(0.200)
self._ext_mem.set_pin_mem_sel(False)
pin_value = self._ext_mem.get_pin_mem_req()
self._ext_mem.set_pin_mem_req(not pin_value)
m2 = int(self._ext_mem.get_pin_ram_sel())
self.mem_request()
sleep(0.01)
m2 = int(self._mem_sel)
# print("m2 = ", m2)
self._ext_mem.write_register(DEFAULT_REGISTER_VALUE)
r[m2] = self._ext_mem.read_register()
sleep(0.040)
self._ext_mem.set_pin_mem_sel(True)
sleep(0.200)
ret[channel] = tuple(r)
@@ -500,9 +441,12 @@ class ExtMemManager:
return 0
def get_available_channel(self, result: List[Tuple[Optional[int], Optional[int]]] = None) -> List[int]:
print('get_available_channel......')
print()
if result is None:
result = self.get_ext_mem_register()
ret = []
for channel, result in enumerate(result):
@@ -515,3 +459,4 @@ class ExtMemManager:
ret.append(channel)
return ret
+1 -1
View File
@@ -53,7 +53,7 @@ class HardwareImplSpiInterface(LowLevelHardwareInterface):
*MISO*, *SCLK*, *GE0_N*
"""
__slots__ = ('_device', '_spi', '_spi_mode', '_spi_speed')
__slots__ = ('_device', '_spi', '_spi_mode', 'pin_request', '_spi_speed')
def __init__(self,
device: Tuple[int, int] = None,
+1 -1
View File
@@ -28,7 +28,7 @@ class UARTInterface(LowLevelHardwareInterface):
self._serial = serial.Serial(self._port,
baudrate=self._baudrate,
timeout=0,
writeTimeout=0.01)
writeTimeout=1)
# deprecate function name which change at version 3.0
self._serial.flushInput()
self._serial.flushOutput()
+8 -8
View File
@@ -117,14 +117,14 @@ class Selector:
self._p1.output(p[1])
self._p2.output(p[2])
# if (value == 4 and self._last_sel != 6):
# print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
# elif (value == 5 and self._last_sel != 4):
# print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
# elif (value == 7 and self._last_sel != 5):
# print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
# elif (value == 6 and self._last_sel != 7):
# print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
if (value == 4 and self._last_sel != 6):
print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
elif (value == 5 and self._last_sel != 4):
print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
elif (value == 7 and self._last_sel != 5):
print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
elif (value == 6 and self._last_sel != 7):
print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
self._last_sel = value
+17 -6
View File
@@ -280,11 +280,14 @@ class Main(CliMain):
@cli_command('controller')
def _controller_server(self, command: str, argv: List[str]):
"""controller server"""
print(self, command, argv)
print('##_controller_server')
return _ControlServer
@cli_command('data')
def _data_server(self, command: str, argv: List[str]):
"""data server"""
print('##_data_server')
return _DataServer
@cli_command('export')
@@ -302,6 +305,7 @@ class Main(CliMain):
return LEDControlMain(command)
def run(self):
print('RUN!!!!!!!!!!!!!!!!!!!')
self.print_help()
@@ -335,15 +339,16 @@ class _ServerMain(CliSubCommandMain, metaclass=abc.ABCMeta):
def run(self):
exit_code = 1
server = self.create_server()
print('create_server')
if _RUNTIME_COMPILE:
exit_code = server.main()
else:
with self.profiling_options.generate_profile_context():
exit_code = server.main()
server = self.create_server()
exit_code = server.main()
print('....after create_server')
print('.. ..')
print()
sys.exit(exit_code)
# noinspection PyUnusedLocal
@@ -355,6 +360,7 @@ class _ControlServer(_ServerMain):
from biopro.device.manager import DeviceManagerOptions
from biopro.server.data import DataServerOptions
from biopro.exp_pro.manager import ExpManagerOption
print('command', command)
super().__init__(command)
@@ -456,6 +462,8 @@ class _ControlServer(_ServerMain):
def create_server(self) -> SocketServer:
from biopro.server.main import ControlServer
print('..create_server')
return ControlServer(self.server_device_options,
self.server_data_options,
self.server_controller_options,
@@ -477,8 +485,11 @@ class _DataServer(_ServerMain):
def create_server(self) -> SocketServer:
from biopro.server.data import DataServer
print('.1.create_server')
return DataServer(self.server_data_options)
if __name__ == '__main__':
print('START!!!!!!!!!!!!!!!!!!!!!!!!')
Main().main()
View File
-65
View File
@@ -1,65 +0,0 @@
class Action():
def __init__(self, task, action_id, action):
self._task = task
self._id:str = action_id
self._type:str = action['type']
self._target:str = action['target']
self._condition_list:list[str] = action['condition']
self._duration = action.get('duration', None)
self._goto = action.get('goto', None)
self._cycle = action.get('cycle', None)
self._instruction = None
self.update_instruction()
@property
def type(self):
return self._type
def update_instruction(self):
self._instruction = {
"device_instruction": {
"header": "call_instruction",
"device": self._target,
"arguments": {
"instruction": self._type,
}
},
"device_parameter": {
"header": "set_multi_parameters",
"device": self._target,
"arguments": {
"parameter": self._task.get_parameter_set_by_device(self._target),
}
},
"device_recording_file_name": {
"header": "update_recording_file_name_info",
"device": self._target,
"arguments": {
"content": self._task.file_name,
}
},
"device_parent": {
"header": "update_parent_info",
"device": self._target,
"arguments": {
"content": self._task.parent
}
}
}
def get_condition_list(self):
return self._condition_list
def get_instruction(self, value):
return self._instruction[value]
def get_instruction_list(self):
instruction_set = {
'start': ['device_parent', 'device_recording_file_name', 'device_parameter', 'device_instruction'],
'stop': ['device_instruction'],
}
return map(self.get_instruction, instruction_set[self._type])
-75
View File
@@ -1,75 +0,0 @@
from datetime import datetime
from time import time
class Condition():
def __init__(self, id, condition):
print('condition', id, condition)
self._id = id
self._type = condition['type']
self._comparsion = condition['comparsion']
self._value = condition['value']
@property
def id(self):
return self._id
@property
def type(self):
return self._type
@property
def comparsion(self):
return self._comparsion
@property
def value(self):
return self._value
def set_comparsion(self, comparsion):
self._comparsion = comparsion
def set_type(self, type):
self._type = type
def set_value(self, value):
self._value = value
def compareWith(self, operator:str, x, y) -> bool:
cases = {
"equal": lambda a, b: a == b,
"bigger": lambda a, b: a > b,
"smaller": lambda a, b: a < b,
}
# print('x','y',x, y,type(x),type(y))
return cases[operator](x, y)
def match_or_not(self, **kwargs):
return self.method_mapping(self.type)()
def absolute_time(self, **kwargs):
now = time()
time_condition = self.datetime_to_timestamp(self.str_to_datetime(self._value))
return self.compareWith(self.comparsion, int(now), int(time_condition))
def relative_time(self, **kwargs):
now = time()
def device(self, **kwargs):
print('device')
def task_status(self, **kwargs):
print('task_status')
def method_mapping(self, method_name):
methods = {
"relative_time": self.relative_time,
"absolute_time": self.absolute_time,
"device": self.device,
"task_status": self.task_status,
}
return methods[method_name]
def str_to_datetime(self, time_str):
return datetime.strptime(time_str,'%Y-%m-%dT%H:%M')
def datetime_to_timestamp(self, date):
return datetime.timestamp(date)
-78
View File
@@ -1,78 +0,0 @@
from .task import Task
from .task_manager import TaskManager
import sys
import json
import threading
import time
from datetime import datetime
from collections import deque
from biopro.device.manager import DeviceManager
from biopro.text import *
class Project(threading.Thread):
def __init__(self, project, device_manager: DeviceManager, mqttThread = None, name="project"):
super(Project, self).__init__(name = name)
self._project = project
self._device_manager = device_manager
self._mqtt_thread = mqttThread
self._time_interval = 1
self._start_time = None
self._task_manager = TaskManager(self._project['taskList'])
self._start_time = None
@property
def desc(self) -> str:
return self._project['desc']
@property
def status(self) -> str:
return self._project['status']
@property
def device(self) -> list:
return self._project['deviceList']
@property
def task(self) -> list:
return self._task_manager.get()
@property
def get_current_task(self) -> str:
return self._task_manager.get_current_task()
def run(self):
self._start_time = time.time()
while True:
# current task
for task in self._task_manager.get_check_task_list():
# [<match_condition>, ...]
match_condition_list = task.check_condition('time')
# [[<match_action>, ...], ...]
match_action_list = task.get_match_action_list(match_condition_list)
for action_list in match_action_list:
for action in action_list:
if action.type == 'start':
self._task_manager.set_current_task(task)
task.do_action(action)
while len(task.instruction_list) > 0:
instruction = task.instruction_list.pop(0)
if instruction.get('device', None) != None:
device = self._device_manager.get_device(self.device[instruction['device']]['connectDevice']['device_address'])
if device is None:
raise RuntimeError(DEVICE_NOT_FOUND, device)
# print(instruction['header'], *instruction['arguments'].values())
getattr(device, instruction['header'])(*instruction['arguments'].values())
time.sleep(self._time_interval)
def stop(self):
return
def close(self):
return
-33
View File
@@ -1,33 +0,0 @@
from io import StringIO
from json import loads as json_parse, dumps as _json_stringify
from typing import Dict, Optional, Any
import paho.mqtt.client as mqtt
from .project import Project
from biopro.device.manager import DeviceManager
def json_stringify(o: Any) -> str:
return _json_stringify(o, separators=(',', ':'))
class ProjectManager():
def __init__(self, device_manager: DeviceManager, mqtt_thread=None) :
self._project_list = []
self._mqtt_thread = mqtt_thread
self._device_manager = device_manager
def create(self, project):
new_project = Project(project, self._device_manager, self._mqtt_thread)
self._project_list.append(new_project)
return new_project
def remove(self, index):
self._project_list[index].stop()
del self._project_list[index]
def get(self):
return self._project_list
def run(self, project):
project.start()
def stop(self, project):
project.stop()
-168
View File
@@ -1,168 +0,0 @@
from .condition import Condition
from .action import Action
from time import time
class Task:
def __init__(self, task):
self._task = task
self._condition_list = []
self._action_list = []
self._start_time = time()
self._idle_time = []
self._period = None
self._next_time = None
self._last_time = None
self._instruction_list = []
self.setup()
def setup(self) -> None:
# add condition
for key, condition in self._task['condition'].items():
new_condition = Condition(key, condition)
self._condition_list.append(new_condition)
# add action
for key, action in self._task['action'].items():
new_action = Action(self, key, action)
self._action_list.append(new_action)
@property
def id(self) -> str:
return self._task['id']
@property
def file_name(self):
return self._task['name']
@property
def parent(self):
return self._task.get('parent', {"folder": [2]})
@property
def instruction_list(self):
return self._instruction_list
@property
def cycle(self) -> int:
return self._task['cycle']
@property
def order(self) -> int:
return self._task['order']
@property
def max_cycle(self) -> int:
return self._task['max_cycle']
@property
def devices(self) -> dict:
return self._task['devices']
@property
def devices_id(self) -> list:
return [device_id for device_id in self.devices]
@property
def events(self) -> list:
return self._task['events']
@property
def triggers(self) -> list:
return self._task['triggers']
@property
def parameter_set(self) -> list:
return self._task['parameterSet']
@property
def instructions(self) -> list:
return self._task['instructions']
@property
def conditions(self) -> list:
return self._task['conditions']
@property
def actions(self) -> list:
return self._task['actions']
@property
def condition_list(self) -> list:
return self._condition_list
@property
def status(self) -> str:
return self._task['status']
@property
def uuid(self) -> str:
return self._task['uuid']
@property
def next(self) -> str:
return self._task['next']
def get_parameter_set_by_device(self, device):
return [parameter_set for parameter_set in self.parameter_set.values() if device == parameter_set['target']]
def get_parameter(self, name_or_value, device):
name_list = []
value_list = []
for parameter in self.get_parameter_set_by_device(device):
for key, value in parameter.items():
if key != 'target':
name_list.append(key)
value_list.append(str(value))
return '|'.join(name_list) if name_or_value == 'name' else '|'.join(value_list)
def run(self):
self._status = 'running'
self._start_time = time()
def pause(self):
self._status = 'pause'
def set_cycle(self, cycle):
self._cycle = cycle
def set_status(self, status):
self._status = status
def start(self):
self.set_status('running')
def stop(self):
if self.status == 'running':
self.do_action('stop')
self.set_status('idle')
def done(self):
self.set_status('done')
def end(self):
self.set_status('end')
def get_match_action_list(self, match_condition_list):
return map(lambda condition: [x for x in self._action_list if condition.id in x.get_condition_list()], match_condition_list)
def do_action(self, action):
# # match_action = [x for x in self._action_list if condition_id in x.get_condition_list()]
# for action in match_action:
for instruction in action.get_instruction_list():
self._instruction_list.append(instruction)
def status_mapping(self, status):
statuses = {
"start": self.task_start,
"done": self.task_done,
}
return statuses[status]
def check_condition(self, type):
return [condition for condition in self._condition_list if condition.match_or_not()]
-56
View File
@@ -1,56 +0,0 @@
from json import loads as json_parse, dumps as _json_stringify
from typing import Dict, Optional, Any
from xml.dom.expatbuilder import parseString
import paho.mqtt.client as mqtt
from biopro.text import *
from .task import Task
_RUNTIME_COMPILE = False
def json_stringify(o: Any) -> str:
return _json_stringify(o, separators=(',', ':'))
class TaskManager():
def __init__(self, task_list):
self._current_task = None
self._task_list = []
self._need_to_check_task_list = []
for task in task_list:
task = Task(task)
self._task_list.append(task)
self.set_current_task(self._task_list[0])
self._current_task.run()
def remove(self, index):
pass
def get_task(self, task_id):
return self._task_list[task_id]
def get_check_task_list(self):
return self._need_to_check_task_list
def get_current_task(self) -> Task:
return self._current_task
def get_next_task(self):
return self._current_task.next
def set_current_task(self, task):
try:
if self._current_task != None and self._current_task.id != task.id:
self._current_task.stop()
self._current_task = task
self._need_to_check_task_list = []
# append current task
self._need_to_check_task_list.append(self._current_task)
# append next task
for task_uuid in self._current_task.next:
task = next((task for task in self._task_list if task.uuid == task_uuid), None)
self._need_to_check_task_list.append(task)
except Exception as e:
print(e)
+75 -28
View File
@@ -19,8 +19,6 @@ from statistics import mean
import random
# from numba import jit
from copy import copy
def json_stringify(o) -> str:
return _json_stringify(o, separators=(',', ':'))
@@ -115,8 +113,8 @@ class RecordingMetaFile(JsonSerialize):
__slots__ = ('_filename', '_filepath', '_id_db', '_create_time', '_file_version', '_file_uuid', '_data_format', '_last_time',
'_device', '_configuration', '_channel_mask', '_database',
'_dirty', '_last_modify_time', '_file_size_cache',
'_recording_file_ch', '_size',
'_parameter', '_parent', '_recording_file_name', '_recording_mini_ch',
'_recording_file_ch', '_recording_sub_file', '_size',
'_parameter', '_parent', '_recording_file_name', '_recording_sub_mini', '_recording_mini_ch',
'_raw_serial_number', '_mini_serial_number', '_device_id')
def __init__(self, filepath: Union[str, Path], data_format: bytes = None, id_db = 0, database = None):
@@ -167,6 +165,10 @@ class RecordingMetaFile(JsonSerialize):
self._raw_serial_number = {}
self._mini_serial_number = {}
self._recording_sub_file = {}
self._recording_sub_mini = {}
self._size = 0
self._dirty = True
@@ -304,6 +306,7 @@ class RecordingMetaFile(JsonSerialize):
if database is not None :
self._database = database
self._database.put_queue(['data_meta_write', meta_data, self._device_id, str(self._file_uuid), self._id_db])
# database.put_queue(['data_meta_write', self, meta_data, _path, self._id_db])
with self._filepath.open('wb') as _f:
f = FileEncoder(_f)
@@ -353,15 +356,19 @@ class RecordingMetaFile(JsonSerialize):
def update_subfile(self, database = None):
meta_data = {
'raw_data': self._recording_sub_file,
'mini_data': self._recording_sub_mini,
'channels': str(self._channel_mask.channels()),
'size': str(self._size),
'time_duration': str(self._last_time),
'uuid': str(self._file_uuid),
}
_path = str(self._filepath).replace('/', '^')
if database is not None :
self._database = database
self._database.put_queue(['data_meta_write', meta_data, self._device_id, str(self._file_uuid), self._id_db])
# database.put_queue(['data_meta_write', self, meta_data, _path, self._id_db])
return None
@property
@@ -510,6 +517,11 @@ class RecordingMetaFile(JsonSerialize):
'start_time': str(_start_time),
}
# if database is not None:
# database.data_raw_create(self, f, raw_data, _channel)
# self._recording_file_ch[_channel]
return f, raw_data
def new_recording_mini(self, _channel: int, _start_time, scale, database = None) -> 'RecordingMini':
@@ -555,6 +567,9 @@ class RecordingMetaFile(JsonSerialize):
'start_time': str(_start_time),
}
# if database is not None:
# database.data_mini_create(self, f, mini_data, _channel, scale)
return f, mini_data
def clear_recording_file(self):
@@ -613,6 +628,15 @@ class RecordingMetaFile(JsonSerialize):
'device': self._device,
}
# d = self._device
# if d is not None:
# ret['device'] = {
# 'device_name': d.device_name,
# 'device_address': list(d.mac_address),
# 'serial_number': d.serial_number.as_json(),
# }
return ret
@@ -768,10 +792,14 @@ class RecordingFile:
'end_time': str(_end_time),
'size': str(self._size)
}
# if self._meta_file._id_db == 0:
# _path = str(self._meta_file.filepath).replace('/', '^')
# self._database.put_queue(['data_meta_id_get_by_path', _path])
# # self._meta_file._id_db = self._database.put_queue(['data_meta_id_get_by_path', _path])
if self._meta_file._id_db != 0:
_data['parent'] = self._meta_file._id_db
self._database.put_queue(['data_raw_update', self._id_db, self._channel, _data])
# self._database.put_queue(['data_raw_update', self._id_db, self._channel, _data])
self._status = False
return None
@@ -937,7 +965,10 @@ class RecordingMini:
'end_time': str(_end_time),
'size': str(self._size)
}
# if self._meta_file._id_db == 0:
# _path = str(self._meta_file.filepath).replace('/', '^')
# self._database.put_queue(['data_meta_id_get_by_path', _path])
# # self._meta_file._id_db = self._database.put_queue(['data_meta_id_get_by_path', _path])
if self._meta_file._id_db != 0:
_data['parent'] = self._meta_file._id_db
self._database.put_queue(['data_mini_update', self._id_db, self._channel, _data])
@@ -965,7 +996,7 @@ class RecordingFileWriter:
'_data_value_ch', '_close', '_data_mini_ch',
'_mini_scale_list', '_time_real_time', '_data_rl', '_data_db',
'_raw_save', '_mini_save', '_data_time_ch', '_data_value_ch_for_rl',
'_data_time_ch_for_rl', '_device_id', '_send_data', '_data_mqtt_ch', '_id_db_save')
'_data_time_ch_for_rl', '_device_id', '_send_data', '_data_mqtt_ch')
def __init__(self, meta: RecordingMetaFile, device_id, database = None):
self._meta = meta
@@ -986,9 +1017,7 @@ class RecordingFileWriter:
self._raw_save = {
'id': {},
'data': {},
'end_time': {},
'size': {}
'data': {}
}
self._mini_save = {
'10': {
@@ -1023,7 +1052,6 @@ class RecordingFileWriter:
self._data_value_ch_for_rl = {}
self._data_time_ch_for_rl = {}
self._data_time_ch = {}
self._id_db_save = {}
# mini data
self._data_mini_ch = {}
@@ -1040,7 +1068,7 @@ class RecordingFileWriter:
# splitting
self.splitting_threshold_time = 30 * 60 * 1000 # one minute
self.splitting_threshold_size = 16 * 1024 # 16 * 16KB
self.splitting_threshold_size = 16 * 16 * 1024 # 16 * 16KB
self._writer_batch_size = 8192
@@ -1066,7 +1094,6 @@ class RecordingFileWriter:
def channels_update(self, channels):
channels.sort()
self._database.put_queue(['data_meta_update_raw_empty_channel', self._meta._id_db, channels])
self._channel_list.extend(channels)
return self._channel_list
@@ -1080,6 +1107,9 @@ class RecordingFileWriter:
return None
def close(self):
# if self._recording_file is not None:
# self._recording_file.close()
# self._recording_file = None
print('close1')
self._close = True
if len(self._recording_file_dict) > 0:
@@ -1093,7 +1123,7 @@ class RecordingFileWriter:
self._meta._size += self._recording_file_dict[ch]._size
# self._data_db.clear()
if self._database is not None:
self._database.put_queue(['data_raw_recording', self._raw_save['id'], self._channel_list, self._raw_save['data'], self._id_db_save])
self._database.put_queue(['data_raw_recording', self._raw_save['id'], self._channel_list, self._raw_save['data']])
# self._database.put_queue(['data_raw_recording', self._raw_save['id'], self._channel_list, self._raw_save['data']])
self._recording_file_dict.clear()
for scale in self._mini_scale_list:
@@ -1318,10 +1348,6 @@ class RecordingFileWriter:
self.get_data_iter(d, mqtt_thread)
for ch in self._recording_file_dict:
if self._recording_file_dict[ch]._id_db == 0:
return None
data_save = False
mini_save = False
if len(self._recording_file_dict) > 0:
@@ -1329,19 +1355,29 @@ class RecordingFileWriter:
if self._time_now - self._time_real_time[ch] > 1000000:
self._send_data[ch] = True
self._time_real_time[ch] = self._time_now
if self._time_now - self._time[ch] > 2000000:
# # if self._time_now - self._time_real_time[ch] > 500000:
# self._data_rl[ch].append(str(self._time_now))
# mes = ' '.join(self._data_rl[ch])
# # print(mes)
# # if mqtt_thread is not None:
# # mqtt_thread.publish('data_server/device_data_stream/' + str(self._device_id) + '/' + str(ch), mes)
# # mqtt_queue.put([self._device_id, ch, mes])
# mqtt_thread[ch].on_message(mes)
# self._data_rl[ch].clear()
# # self._time_real_time[ch] = self._time_now
if self._time_now - self._time[ch] > 5000000:
if self._recording_file_dict[ch]._status:
_data = ' '.join(self._data_db[ch])
write_sz = self._recording_file_dict[ch].write(_data, self._channel_list)
sz = sz + write_sz
self._raw_save['data'][ch] = _data
self._raw_save['id'][ch] = self._recording_file_dict[ch]._id_db
self._raw_save['end_time'][ch] = self._time_now
self._raw_save['size'][ch] = self._recording_file_dict[ch]._size
data_save = True
self._data_db[ch].clear()
self._time[ch] = self._time_now
self._splitting_size += sz
self._meta._last_time = self._time_now
self._splitting_size += write_sz
data_save = True
self._recording_file_dict[ch].update_endtime(self._time_now)
if len(self._data_mini_ch[ch]['1000']['mean']) >= 10:
mini_save = True
for scale in self._mini_scale_list:
@@ -1358,14 +1394,14 @@ class RecordingFileWriter:
if data_save is True:
if self._database is not None:
recording_input = ['data_raw_recording_new', copy(self._raw_save['id']), copy(self._channel_list), copy(self._raw_save['data']), copy(self._raw_save['end_time']), copy(self._raw_save['size'])]
self._database.put_queue(recording_input)
self._database.put_queue(['data_raw_recording', self._raw_save['id'], self._channel_list, self._raw_save['data']])
self._meta.update_subfile(database = self._database)
if mini_save is True:
if self._database is not None:
for scale in self._mini_scale_list:
self._database.put_queue(['data_mini_recording', self._mini_save[str(scale)]['id'], self._channel_list, self._mini_save[str(scale)]['start_time'], self._mini_save[str(scale)]['data_mean']])
self._meta.update_subfile(database = self._database)
del data
@@ -1373,9 +1409,11 @@ class RecordingFileWriter:
def _switch_recording_file(self):
# if self._recording_file is not None:
# self._recording_file.close()
if len(self._recording_file_dict) > 0:
for ch in self._recording_file_dict.keys():
self._id_db_save[ch] = self._recording_file_dict[ch]._id_db
self._recording_file_dict[ch].close(self._time_now)
self._meta._size += self._recording_file_dict[ch]._size
@@ -1391,6 +1429,7 @@ class RecordingFileWriter:
if self._database is not None:
self._database.put_queue(['data_raw_create', raw_data_dict, self._channel_list, self._device_id])
# self._database.put_queue(['data_raw_create', self._meta, self._recording_file_dict, raw_data_dict, self._channel_list])
self._meta._last_time = self._time_now
self._meta.update_subfile(database = self._database)
@@ -1417,21 +1456,29 @@ class RecordingFileWriter:
if self._database is not None:
self._database.put_queue(['data_mini_create', mini_data_dict, self._channel_list, scale, self._device_id])
# self._database.put_queue(['data_mini_create', self._meta, self._recording_mini_dict[str(scale)], mini_data_dict, self._channel_list, scale])
self._meta._last_time = self._time_now
self._meta.update_subfile(database = self._database)
return None
def update_meta_id(self, _id):
# print('update meta')
self._meta._id_db = _id
return None
def update_raw_dict_id(self, _channel, _id):
self._recording_file_dict[int(_channel)]._id_db = _id
self._database.put_queue(['data_meta_update_channel_raw_id', self._meta._id_db, _channel, _id])
if int(_channel) not in self._meta._recording_sub_file:
self._meta._recording_sub_file[int(_channel)] = []
self._meta._recording_sub_file[int(_channel)].append(_id)
return None
def update_mini_dict_id(self, _scale, _channel, _id):
self._recording_mini_dict[str(_scale)][int(_channel)]._id_db = _id
self._database.put_queue(['data_meta_update_channel_mini_id', self._meta._id_db, _channel, _scale, _id])
if int(_channel) not in self._meta._recording_sub_mini:
self._meta._recording_sub_mini[int(_channel)] = {}
if int(_scale) not in self._meta._recording_sub_mini[int(_channel)]:
self._meta._recording_sub_mini[int(_channel)][int(_scale)] = []
self._meta._recording_sub_mini[int(_channel)][int(_scale)].append(_id)
return None

Some files were not shown because too many files have changed in this diff Show More