Compare commits

...

46 Commits

Author SHA1 Message Date
peterlu14 0cd0fd7027 [update] project task name rename 2022-04-27 13:24:31 +08:00
peterlu14 fa8c219f76 Merge branch 'rel/v1.5.1' into feature/project 2022-04-25 10:48:22 +08:00
peterlu14 f233c019fd [update] auto get eth0 mac address 2022-04-25 10:36:02 +08:00
peterlu14 ced466f3aa [update] add condition & first task issue & add boardcast 2022-04-18 01:52:52 +08:00
peterlu14 f36906c034 [update] restruct project 2022-04-17 23:05:21 +08:00
peterlu14 0b5c62e525 [update] temp save 2022-04-16 10:50:37 +08:00
peterlu14 abe86238ca remove print messages 2022-04-13 15:58:27 +08:00
peterlu14 f9ab0bc59b [update] remove duplicate code 2022-04-13 15:49:04 +08:00
peterlu14 5dbe231c73 [update] add cacheClient communicate with control server & add comment 2022-04-13 14:08:57 +08:00
peterlu14 c721950bf7 [update] add complete device status 2022-04-12 14:28:04 +08:00
peterlu14 70c0271771 [remove] duplicate code 2022-04-11 16:35:04 +08:00
peterlu14 13825fe9ff [update] hide print 2022-04-08 18:22:44 +08:00
peterlu14 dd2e31d01f [update] fix index problem 2022-04-08 18:16:31 +08:00
peterlu14 455fa1f86b [update] fix stop error & relative_time 2022-04-08 11:17:07 +08:00
Roy 71850b31a8 [update] fix recording error 2022-04-07 12:33:02 +08:00
peterlu14 8d52fef4c1 [update] hide print message 2022-04-07 12:29:18 +08:00
peterlu14 e091f220fa Merge branch 'test/update_data_server' into rel/v1.4.0_schedule/channel_lost_data 2022-03-28 18:19:29 +08:00
peterlu14 6049154fae [update] change check time to 1 2022-03-28 18:18:35 +08:00
peterlu14 3502472021 [update] recover update mini file 2022-03-28 17:27:04 +08:00
peterlu14 5e48c8ae0a [update] update_subfile change 2022-03-28 17:17:07 +08:00
peterlu14 cb2a4c9d56 Revert "[update] solve meta raw&mini id grwon up problem"
This reverts commit cd60e14cbe.
2022-03-28 16:14:23 +08:00
peterlu14 b253aca73f [update] meta_id & mini_id update 2022-03-28 16:12:15 +08:00
Roy 2fd05d18ed [update] fix battery value 2022-03-25 13:41:48 +08:00
Roy 03011ebd5f Merge branch 'dev/check_sum/battery' into rel/v1.4.0_schedule/channel_lost_data 2022-03-25 12:11:05 +08:00
Roy 4b9bc30e28 [update] get battery value 2022-03-25 11:46:40 +08:00
Roy 4966113393 [update] use check sum 2022-03-25 11:44:52 +08:00
Roy 3371c21bbd [update] update log message 2022-03-25 11:34:30 +08:00
Roy afc87829d9 [update] head != tailer, delete data 2022-03-24 17:12:06 +08:00
peterlu14 952403cbf4 [update] subfile 64kB -> 16kB 2022-03-21 14:20:29 +08:00
peterlu14 1cdd04901c [update] fix size count error & close error & remove comments 2022-03-21 14:13:33 +08:00
peterlu14 cd60e14cbe [update] solve meta raw&mini id grwon up problem 2022-03-21 12:01:38 +08:00
peterlu14 ae55e6c789 [update] remove print message 2022-03-18 17:21:53 +08:00
peterlu14 b8addb7686 [update] prevent data loss 2022-03-18 17:12:40 +08:00
Roy da581ae225 [update] update log message 2022-03-18 15:12:37 +08:00
peterlu14 a941f7c060 [update] prevent duplicate address data 2022-03-17 11:34:36 +08:00
Roy 4b0472ecf4 [update] fix error for real_run_time 2022-03-17 09:56:16 +08:00
Roy de51f53657 [update] update log message 2022-03-16 11:50:00 +08:00
Roy 6974950d31 Merge remote-tracking branch 'origin/dev/elite_channel_position_and_skip_ram' into rel/v1.4.0_schedule/channel_lost_data 2022-03-15 15:38:53 +08:00
peterlu14 0887c48ddc [remove] pyc file untracked 2022-03-15 15:33:02 +08:00
Roy 184c7536a6 [update] fix error for reading spi(7000bytes) 2022-03-15 15:18:52 +08:00
Roy 1a3a833680 [update] green data has 12 byte, if ram read done, MEM_INS_MARKED = [5A,A5] 2022-03-15 15:17:38 +08:00
Roy df3c7db8bc [update] fix spi routine code and print log message when run_time >= 0.030 2022-03-15 15:01:55 +08:00
Roy 7287f4c19b [update] update print message 2022-03-15 15:00:34 +08:00
Roy 7d3f7a47ff [update] change position of elite channel 2022-03-15 14:55:11 +08:00
peterlu14 81c699e830 [update] recover previous way to execute data 2022-03-14 16:45:27 +08:00
peterlu14 71e469ec2f Merge branch 'dev/merge_channel_lost_data' into rel/v1.4.0_schedule/channel_lost_data 2022-03-11 10:58:14 +08:00
137 changed files with 1114 additions and 1145 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -1
View File
@@ -536,7 +536,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) == 4 :
if data is not None and len(data) > 2 :
battery = struct.unpack('<H', data[1:3])[0]
if battery is not None:
self._battery = battery
@@ -2035,6 +2035,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
# 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
+8 -8
View File
@@ -253,6 +253,7 @@ class DeviceInternalCommandHandler:
return True
# why inherit MasterDevice ?
class DeviceManager(MasterDevice, Synchronized):
"""device manager. It manager the device libraries, found device, connected device
and the control of the master device.
@@ -267,7 +268,6 @@ class DeviceManager(MasterDevice, Synchronized):
options: DeviceManagerOptions,
handler: Optional[DeviceInternalCommandHandler] = None):
"""
:param options: manager options.
:param handler: device internal command handler
"""
@@ -277,6 +277,7 @@ class DeviceManager(MasterDevice, Synchronized):
if handler is None:
handler = DeviceInternalCommandHandler()
# control server api
self._handler: DeviceInternalCommandHandler = handler
self._options: DeviceManagerOptions = options
@@ -286,7 +287,9 @@ class DeviceManager(MasterDevice, Synchronized):
# hardware
self._interface = options.interface
self._master: Optional[MasterDevice] = None
# memory board
self._centralMaster: Optional[MasterDevice] = None
# connected device
self._device: List[CompletedDevice] = []
# demo device
@@ -336,6 +339,10 @@ class DeviceManager(MasterDevice, Synchronized):
def library_path(self) -> List[Path]:
return self._repository.library_path
def get_device_status(self, mac_address) -> Optional[DeviceLibrary]:
device = self.get_device(mac_address)
return device.status
@logging_info
def reload_library(self):
"""reload device library"""
@@ -562,7 +569,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
@@ -1024,15 +1030,9 @@ class DeviceManager(MasterDevice, Synchronized):
raise RuntimeError(DEVICE_NOT_FOUND, device)
if DeviceCommonInstruction(instruction) is not None:
# print('deviceCommonInstr')
# print(instruction)
device.call_instruction(instruction)
elif instruction in device.library.instruction_table:
# print('instruction')
# print(instruction)
device.call_instruction(instruction)
else:
raise RuntimeError(INSTRUCTION_UNKNOWN, instruction)
+37 -37
View File
@@ -882,21 +882,18 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
if len(data) < 18:
return None
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_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]
mem_wrong_information = struct.unpack('>i', data[40:40+4])[0]
# print('decode', list(data[20:]))
mem_wrong = data[40]
mem_retry_cnt = data[41]
mem_green_wrong = data[42]
mem_green_retry_cnt = data[43]
ram_num = data[44]
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]
broken_flag = data[-1]
if (finish_mode_falg & 0b11110000 == 0b10100000):
@@ -917,10 +914,13 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
print("error timeStamp full data:", list(data), datetime.now(), '\n')
return None
else:
# print('|', time_stamp, '|', delta, '|', current, '|', voltage, '|', impedance,
# print('|', time_stamp, '|', delta, '|', int(time_stamp * 1000 / 2),
# '|', current, '|', voltage, '|', impedance,
# '|', cycle_number, '|', finishMode, '@', str(self.device))
# print('|', '{:10}'.format(time_stamp),
# '|', '{:10}'.format(delta),
# '|', '{:4}'.format(delta),
# '|', '{:10}'.format(int(time_stamp * 1000 / 2)),
# '|', '{:10}'.format(current),
# '|', '{:10}'.format(voltage),
# '|', '{:10}'.format(impedance),
@@ -928,13 +928,9 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
# '|', '{:1}'.format(finishMode),
# '@', str(self.device), '|')
# print('|', '{:5}'.format(mem_wrong),
# '|', '{:5}'.format(mem_retry_cnt),
# '|', '{:5}'.format(mem_green_wrong),
# '|', '{:5}'.format(mem_green_retry_cnt),
# '|', '{:5}'.format(mem_wrong_information),
# '|', '{:5}'.format(ram_num),
# '|', '{:5}'.format(broken_flag),
# print('|', '{:5}'.format(mem_wrong_information),
# '|', '{:2}'.format(ram_num),
# '|', '{:2}'.format(broken_flag),
# '@', str(self.device), '|')
pass
@@ -949,16 +945,20 @@ 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(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(4, ram_num)
ret.append_data(5, broken_flag)
ret.append_data(6, mem_wrong_information)
# ret.append_data(4, ram_num)
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))
if cycle_number != self._cycle_number:
# notify cycle_number change
@@ -1456,12 +1456,12 @@ class EISZeroOneDataDecoder(RecDataDecoder):
if len(data) < 18:
return None
ch1 = struct.unpack('>i', data[1:5])[0] # unit: 1/1000 nA
ch2 = struct.unpack('>i', data[5:9])[0] # unit: mV
ch3 = 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]
d19 = data[19]
ch1 = struct.unpack('>i', data[1+3:5+3])[0] # unit: 1/1000 nA
ch2 = struct.unpack('>i', data[5+3:9+3])[0] # unit: mV
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
cycle_number = struct.unpack('>H', data[17+3:19+3])[0]
d19 = data[19+3]
gain = (d19 & 0x0F)
finishMode = (d19 & 0x80) >> 7
+4 -2
View File
@@ -1268,14 +1268,15 @@ class InstructionTable(DictNode['Instruction']):
instruction: str):
"""call instruction. chain context with :class:`DeviceInternalInstructionScope`
:param master: master device
:param device: device
:param master: DeviceManager
:param device: CompletedDevice
:param context: scope
:param instruction: instruction name
:raises InstructionNotFound: If instruction not found.
"""
try:
# ex. start
ins = self[instruction]
except KeyError as e:
@@ -1284,6 +1285,7 @@ class InstructionTable(DictNode['Instruction']):
else:
context = context.chain(InstructionTableScope(self))
# ex. _data_format, _sync, _notify
for single in ins.eval_instruction(context):
if isinstance(single, InternalInstruction):
if not single.handle_internal_instruction(master, device, context):
+18 -2
View File
@@ -966,7 +966,7 @@ class CompletedDevice(Device):
"""
__slots__ = ('_master', '_device_id', '_device', '_library', '_context',
'_parameter', '_configuration', '_lock', '_feature_mask',
'_cache_battery', '_cache_battery_timestamp', '_coeff')
'_cache_battery', '_cache_battery_timestamp', '_coeff', '_status')
def __init__(self, master: MasterDevice, library: DeviceLibrary, device_id: int, device: Device):
"""
@@ -976,11 +976,15 @@ class CompletedDevice(Device):
:param device_id: device id
:param device: slave device implementation
"""
# DeviceManager
self._master = master
self._device = device
self._device_id = device_id
self._library = library
# device status ( 0: idle, 1: working, 2: error, 3: power off)
self._status = 0
# context
s1 = library.constant
s2 = DeviceScope(self)
@@ -1020,6 +1024,10 @@ class CompletedDevice(Device):
def mac_address(self) -> ADDRESS:
return self._device.mac_address
@property
def mac_address_in_str(self) -> str:
return ':'.join('{:02x}'.format(b) for b in self._device.mac_address)
@property
def device(self) -> Device:
return self._device
@@ -1056,11 +1064,18 @@ class CompletedDevice(Device):
return self._library
# device lock
@property
def lock(self) -> DeviceLock:
return self._lock
@property
def status(self) -> int:
return self._status
@status.setter
def status(self, new_status):
self._status = new_status
# device parameter getter/setter
def parameters(self) -> List[str]:
@@ -1261,6 +1276,7 @@ class CompletedDevice(Device):
'device_id': self.device_id,
'device_name': self.device_name,
'device_address': list(self.mac_address),
'device_status': self._status,
'battery': self.battery,
'parent': self.parent,
'recording_file_name': self.recording_file_name,
+117 -43
View File
@@ -24,8 +24,10 @@ def zero_buffer(size: int) -> List[int]:
return [0] * size
class MultiExtMemSpiInterface(LowLevelHardwareInterface):
MEM_INS_MARKED = [MEM_INS_WRITE, 0, 2, 1, 1]
MEM_INS_RESET = [MEM_INS_WRITE, 0, 2, 1, 1, 0, 0xFF]
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]
__slots__ = ('_selector', '_wait_for_first_data', '_spi', '_tx_buffer_header', '_tx_buffer_data',
'pin_busy', 'pin_mem_req', 'pin_mem_sel', 'pin_ram_sel',
@@ -44,11 +46,11 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
self._elite_data_len = 40
self._mem_header_len = 3
self._mem_tailer_len = 8
self._mem_tailer_len = 6
self._single_data_len = self._elite_data_len + self._mem_header_len + self._mem_tailer_len
# buffer
self._tx_buffer_header = [0] * 11
self._tx_buffer_header = [0] * 19
self._tx_buffer_data = [0] * (self._single_data_len * 10 + 3)
# memory control pin
@@ -165,6 +167,52 @@ 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)
@@ -191,7 +239,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
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[0:7]))
print(list(data))
data[0:3] = [255, 255, 255]
# ----------------------------------------------------------------------------------------------
@@ -210,13 +258,13 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
# 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[0:7]))
# print(list(data_first))
# 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[0:7]))
# print(list(data_second))
# if (data_first[3:] == data_second[3:]):
# data = data_first
@@ -228,59 +276,47 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
# data = self.compare_green_data(data_first, data_second, data_third, len(tx_h))
# ----------------------------------------------------------------------------------------------
# debug use
# green_data = []
# green_data = data
# print("_[Debug] @ spi green data = ", green_data)
green_data_section = self._compare_green_data_addr_and_flag(data, device)
length = (data[3] << 8) | data[4]
header = data[7]
elite_data_len = data[9]
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()
if length <= 4:
# print("length <= 4")
# print("green data print:", data, device, datetime.now())
return None
if data[5] != 0 or data[6] != 0:
if green_data_section[2] != 0xA5 or green_data_section[3] != 0x5A:
# give a default length if the data header did not update
length = 7000
print("green data: is not [0,0], = ", data[5:7])
print("green data: is not [0xA5, 0x5A], = ", data[5:7])
print("green data print:", data, device, datetime.now())
return None
if (length >= 7000):
if (length >= 4000):
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())
print("green data print:", data, device, datetime.now(), '\n')
# 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
address = 12
red_length = int(length / 2)
tx_d = [0] * red_length
# elite read len(_tx_buffer_data) byte
# address = 4
# tx_d = self._tx_buffer_data
tx_d = [0] * (red_length + 3)
while True:
tx_d[0] = MEM_INS_READ
@@ -319,22 +355,60 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
address += len(data) - 3
del data
# print("_[Debug] @ spi recv data rx = ")
# last_index = 0
# print("_[Debug] @ spi recv data rx, ram_select:", self._pin_ram_sel_value[device], ",", datetime.now())
# for i in range(0, len(rx), self._single_data_len):
# print(rx[i:i+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()
# /*
# * red data formate:
# * ramHdr, ramHdr, ramHdr, (3B)
# * 255, #, data_length, (3B)
# * data, (20B)
# * data, (40B)
# * red_wrong, red_retry_cnt, green_wrong, green_retry_cnt, (4B)
# * 255, #, data_length, (3B)
# * check_num, (1B)
# * */
# 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_MARKED)
self._spi.send_byte(self.MEM_INS_MARKED1)
self._spi.send_byte(self.MEM_INS_MARKED2)
self._spi.send_byte(self.MEM_INS_MARKED3)
except BaseException as e:
print(e)
+20 -59
View File
@@ -1,65 +1,26 @@
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()
def __init__(self, action_id, action):
self._id: str = action_id
self._type: str = action['type']
self._target: str = action['target']
self._condition : list[str] = action['condition']
# self._duration = action.get('duration', None)
# self._goto = action.get('goto', None)
# self._cycle = action.get('cycle', None)
@property
def id(self):
return self._id
@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])
@property
def target(self):
return self._target
@property
def condition(self):
return self._condition
+48 -27
View File
@@ -3,70 +3,91 @@ 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']
self._active = False
@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
@id.setter
def id(self, new_id):
self._id = new_id
def set_value(self, value):
self._value = value
@type.setter
def type(self, new_type):
self._type = new_type
def compareWith(self, operator:str, x, y) -> bool:
@comparsion.setter
def comparsion(self, new_comparsion):
self._comparsion = new_comparsion
@value.setter
def value(self, new_value):
self._value = new_value
def compareWith(self, operator, x, y) -> bool:
# print(operator, x, y)
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)()
# print(self._type, self._comparsion, self._value)
return getattr(self, self.type)(**kwargs)
def absolute_time(self, **kwargs):
now = time()
time_condition = self.datetime_to_timestamp(self.str_to_datetime(self._value))
now = int(time())
time_condition = round(self.datetime_to_timestamp(self.str_to_datetime(self._value)))
return self.compareWith(self.comparsion, int(now), int(time_condition))
return self.compareWith(self.comparsion, now, time_condition)
def relative_time(self, **kwargs):
now = time()
def after_project_run(self, **kwargs):
project_start_time = kwargs['project_start_time']
delay_time = kwargs['delay_time']
time_diff = int(time() - project_start_time - delay_time)
return self.compareWith(self.comparsion, time_diff, int(self._value))
def after_task_run(self, **kwargs):
# print('relative_time_from_task', kwargs,kwargs['task_start_time'],kwargs['delay_time'])
if len(kwargs['task_start_time']) == 0:
return False
task_start_time = kwargs['task_start_time'][-1]
delay_time = kwargs['delay_time']
time_diff = int(time() - task_start_time - delay_time)
# print('time_diff', time_diff)
return self.compareWith(self.comparsion, time_diff, int(self._value))
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 previous_task_done(self, **kwargs):
running_task = kwargs['running_task']
if running_task.status == 2 and self._active == False:
self._active = True
return True
return False
def str_to_datetime(self, time_str):
return datetime.strptime(time_str,'%Y-%m-%dT%H:%M')
+32
View File
@@ -0,0 +1,32 @@
class Instruction():
def __init__(self):
self._instruction_set = {
'set_file_name': {
'method': 'update_recording_file_name_info',
'arguments': ['file_name']
},
'set_parent': {
'method': 'update_parent_info',
'arguments': ['parent']
},
'set_parameter':{
'method': 'set_multi_parameters',
'arguments': ['parameter']
},
'call_instruction': {
'method': 'call_instruction',
'arguments': ['instruction']
},
}
self._start_instruction = list(map(lambda ins: self._instruction_set[ins] ,['set_file_name', 'set_parent', 'set_parameter', 'call_instruction']))
self._stop_instruction = list(map(lambda ins: self._instruction_set[ins] ,['call_instruction']))
@property
def start(self) -> list:
return self._start_instruction
@property
def stop(self) -> list:
return self._stop_instruction
+172 -41
View File
@@ -1,14 +1,23 @@
from .task import Task
from .task_manager import TaskManager
import sys
import json
import threading
import time
from time import time, sleep
from datetime import datetime
from collections import deque
from copy import copy
from uuid import uuid4
from .task import Task
from .task_manager import TaskManager
from .instruction import Instruction
from biopro.device.manager import DeviceManager
from biopro.text import *
key_list = {
'deviceList': 'device',
}
class Project(threading.Thread):
def __init__(self, project, device_manager: DeviceManager, mqttThread = None, name="project"):
super(Project, self).__init__(name = name)
@@ -17,62 +26,184 @@ class Project(threading.Thread):
self._mqtt_thread = mqttThread
self._time_interval = 1
self._start_time = None
self._end_time = None
self._task_manager = TaskManager(self._project['taskList'])
self._id = None
self._uuid = uuid4()
self._name = None
self._desc = None
self._device = None
self._complete_device = []
self._status = None
self._instruction_set = Instruction()
self._stop_flag = False
self.setup_project(project)
self.setup_device(self._device)
def setup_project(self, project):
for (key, value) in project.items():
if key in key_list.keys():
key = key_list[key]
if key == 'task':
self._task_manager = TaskManager(project['task'])
else:
setattr(self, key, value)
def setup_device(self, device_list):
for device in device_list:
complete_device = self._device_manager.get_device(device['connectDevice']['device_address'])
self._complete_device.append(complete_device)
@property
def id(self) -> int:
return self._id
@id.setter
def id(self, new_id):
self._id = new_id
@property
def uuid(self) -> str:
return self._uuid
@uuid.setter
def uuid(self, new_uuid):
self._uuid = new_uuid
@property
def name(self) -> str:
return self._name
@name.setter
def name(self, new_name):
self._name = new_name
self._start_time = None
@property
def desc(self) -> str:
return self._project['desc']
return self._desc
@desc.setter
def desc(self, new_desc):
self._desc = new_desc
@property
def status(self) -> str:
return self._project['status']
return self._status
@status.setter
def status(self, new_status):
self._status = new_status
@property
def device(self) -> list:
return self._project['deviceList']
return self._device
@device.setter
def device(self, new_device):
self._device = new_device
@property
def task(self) -> list:
return self._task_manager.get()
def task_list(self):
return self.task_manager.task_list
@property
def get_current_task(self) -> str:
return self._task_manager.get_current_task()
def mqtt_thread(self):
return self._mqtt_thread
def run(self):
self._start_time = time.time()
self._start_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'])
self.mqtt_thread.broadcast_command('project:' + self._name + ' start_at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
while not self._stop_flag :
# check running task first
delay_time = 0
check_list = copy(self._task_manager.check_list)
if device is None:
raise RuntimeError(DEVICE_NOT_FOUND, device)
for task in check_list:
if task != None:
now = time()
# print('round task', task.name)
# print('running task', self._task_manager.running_task.name, self._task_manager.running_task.status)
# if self._task_manager.prev_task != None:
# print('previous_task', self._task_manager.prev_task.name, self._task_manager.prev_task.status)
match_condition_list = task.check_condition(
project_start_time = self._start_time,
delay_time = delay_time,
running_task= self._task_manager.running_task,
previous_task = self._task_manager.prev_task
)
# print('match_condition_list', match_condition_list)
for condition in match_condition_list:
match_action_list = task.get_match_action(condition.id)
for action in match_action_list:
# print('match_action', action.type, action.target)
if action.type == 'start' and task.status != 1:
self._task_manager.set_running_task(task)
self.mqtt_thread.broadcast_command('project:task ' + task.name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
device = self._complete_device[action.target]
task_info = task.get_task_info(action)
instruction_set = getattr(self._instruction_set, action.type, None)
# print('instruction_set',instruction_set)
# print(instruction['header'], *instruction['arguments'].values())
getattr(device, instruction['header'])(*instruction['arguments'].values())
if instruction_set != None:
for instruction in instruction_set:
args = list(map(lambda arg: task_info[arg], instruction['arguments']))
threading.Thread(target=getattr(device, instruction['method'])(*args))
delay_time += (time() - now)
time.sleep(self._time_interval)
def stop(self):
return
# check task not running then stop
if self.check_running_task_not_run() == True:
self.mqtt_thread.broadcast_command('project:task ' + str(self._task_manager.running_task.name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
self._task_manager.running_task.stop()
# check project done then close project
if self.check_project_done() == True:
self.mqtt_thread.broadcast_command('project:project ' + str(self._name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
print('project stop at', datetime.now())
self.close()
if self._time_interval - delay_time > 0:
sleep(self._time_interval - delay_time)
def pause(self):
# TODO
pass
def close(self):
return
self._end_time = time()
self._stop_flag = True
def check_project_done(self):
for task in self._task_manager.task_list:
# if task never start or still task is running then reject
if task.status == 1 or task.status == -1:
return False
return True
def check_running_task_not_run(self):
# if no running task
if self._task_manager.running_task == None:
return False
device_list = self._task_manager.running_task.device
for device in device_list:
if self._complete_device[device].status == 1:
return False
return True
def as_json(self):
return {
'id': self._id,
'name': self._name,
'uuid': self._uuid,
'desc': self._desc,
'status': self._status,
'device': self._device,
'task_list': self.task_list,
}
+1 -1
View File
@@ -18,7 +18,7 @@ class ProjectManager():
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]
+202 -118
View File
@@ -1,110 +1,187 @@
from typing import List
from .condition import Condition
from .action import Action
from time import time
from datetime import datetime
key_list = {
'deviceList': 'device',
'parameterSet': 'parameter_set'
}
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._id = None
self._name = None
self._parent = None
self._cycle = None
self._device = None
self._event = None
self._trigger = None
self._parameter_set = None
self._condition = None
self._action = None
# -1: initial 0: start(idle), 1: running, 2: close(idle)
self._status = 0
self._next = None
self._condition_list: List[Condition] = []
self._action_list: List[Action] = []
self._instruction_list = []
self._record_list = []
self.setup()
self._start_time = []
self._idle_time = []
self._end_time = []
self._period = None
self.load_task(task)
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)
def load_task(self, task) -> None:
# update task attribute
for key, value in task.items():
if key in key_list.keys():
key = key_list[key]
if key == 'condition':
self.update_condition_list(value)
if key == 'action':
self.update_action_list(value)
# print(key, value)
setattr(self, key, value)
# add action
for key, action in self._task['action'].items():
new_action = Action(self, key, action)
self._action_list.append(new_action)
def update_condition_list(self, condition_dict):
self._condition_list.clear()
for key, condition in condition_dict.items():
self._condition_list.append(Condition(key, condition))
def update_action_list(self, action_dict):
self._action_list.clear()
for key, action in action_dict.items():
self._action_list.append(Action(key, action))
@property
def id(self) -> str:
return self._task['id']
return self._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']
@id.setter
def id(self, new_id):
self._id = new_id
@property
def uuid(self) -> str:
return self._task['uuid']
return self._uuid
@uuid.setter
def uuid(self, new_uuid):
self._uuid = new_uuid
@property
def name(self):
return self._name
@name.setter
def name(self, new_name):
self._name = new_name
@property
def parent(self):
if self._parent == None:
return {"folder": [2]}
return self._parent
@parent.setter
def parent(self, new_parent):
self._parent = new_parent
@property
def cycle(self) -> int:
return self._cycle
@cycle.setter
def cycle(self, new_cycle):
self._cycle = new_cycle
@property
def device(self) -> dict:
return self._device
@device.setter
def device(self, new_device):
self._device = new_device
@property
def event(self) -> list:
return self._event
@event.setter
def event(self, new_event):
self._event = new_event
@property
def trigger(self) -> list:
return self._trigger
@trigger.setter
def trigger(self, new_trigger):
self._trigger = new_trigger
@property
def parameter_set(self) -> list:
return self._parameter_set
@parameter_set.setter
def parameter_set(self, new_parameter_set):
self._parameter_set = new_parameter_set
@property
def condition(self) -> list:
return self._condition
@condition.setter
def condition(self, new_condition):
self._condition = new_condition
@property
def action(self) -> list:
return self._action
@action.setter
def action(self, new_action):
self._action = new_action
@property
def status(self) -> str:
return self._status
@status.setter
def status(self, new_status):
self._status = new_status
@property
def next(self) -> str:
return self._task['next']
return self._next
@next.setter
def next(self, new_next):
self._next = new_next
@property
def instruction_list(self) -> List:
return self._instruction_list
@property
def start_time(self) -> List:
return self._start_time
@property
def end_time(self) -> List:
return self._end_time
def new_start_time(self):
self._start_time.append(time())
def new_end_time(self):
self._end_time.append(time())
def get_parameter_set_by_device(self, device):
return [parameter_set for parameter_set in self.parameter_set.values() if device == parameter_set['target']]
@@ -121,48 +198,55 @@ class Task:
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
print(self._name, 'run at', datetime.now())
self._status = 1
self._start_time.append(time())
def start(self):
self.set_status('running')
self.status = 1
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')
self.status = 2
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 get_match_action(self, condition_id):
return [action for action in self._action_list if condition_id in action.condition]
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, **kwargs):
kwargs['task_start_time'] = self._start_time
return [condition for condition in self._condition_list if condition.match_or_not(**kwargs)]
def get_task_info(self, action):
_type = action.type
if _type == 'stop':
_type = 'interrupt'
def check_condition(self, type):
return [condition for condition in self._condition_list if condition.match_or_not()]
return {
'device': action.target,
'parameter': self.get_parameter_set_by_device(action.target),
'file_name': self._name + '-' + str(action.target),
'parent': self.parent,
'instruction': _type
}
def as_json(self):
return {
'id': self.id,
'name': self.name,
'parent': self.parent,
'cycle': self.cycle,
'device': self.device,
'event': self.event,
'trigger': self.trigger,
'parameter_set': self.parameter_set,
'condition': self.condition,
'action': self.action,
'status': self.status,
'next': self.next,
}
+62 -34
View File
@@ -1,5 +1,6 @@
from json import loads as json_parse, dumps as _json_stringify
from typing import Dict, Optional, Any
from socket import if_nametoindex
from typing import Dict, List, Optional, Any
from xml.dom.expatbuilder import parseString
import paho.mqtt.client as mqtt
from biopro.text import *
@@ -12,45 +13,72 @@ def json_stringify(o: Any) -> str:
class TaskManager():
def __init__(self, task_list):
self._current_task = None
self._task_list = []
self._need_to_check_task_list = []
self._next_task = []
self._prev_task = None
self._running_task = None
self.load_task_list(task_list)
# self.set_running_task(self._task_list[0])
# self._running_task.run()
self._next_task.append(self._task_list[0])
@property
def task_list(self):
return self._task_list
@property
def prev_task(self):
return self._prev_task
@property
def running_task(self):
return self._running_task
@property
def next_task(self):
return self._next_task
@property
def check_list(self):
return [self._running_task, *self._next_task]
@property
def check_list(self):
return [self._running_task, *self._next_task]
def load_task_list(self, 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 set_running_task(self, task):
try:
# if there is task running & same task active ,then reject
if self._running_task != None and self._running_task.uuid == task.uuid:
return False
# save running task
self._prev_task = self._running_task
# clear next task list
self._next_task.clear()
self._running_task = task
self._running_task.run()
if self._prev_task != None:
# if previous task is still running, then need to close
if self._prev_task.status == 1:
self._prev_task.stop()
print('prev', 'run', self._prev_task.name, self._running_task.name)
for task_uuid in self._running_task.next:
_task = next((task for task in self._task_list if task.uuid == task_uuid), None)
if _task != None:
self._next_task.append(_task)
except RuntimeError as e:
print(e)
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)
+95 -64
View File
@@ -8,6 +8,7 @@ import gc
from biopro.util.json import JSON
from biopro.util.stack import print_exception
from biopro.util.logger import calculate_time
from .data import RecordingData
from .loader import *
@@ -19,6 +20,8 @@ from statistics import mean
import random
# from numba import jit
from copy import copy
def json_stringify(o) -> str:
return _json_stringify(o, separators=(',', ':'))
@@ -370,6 +373,45 @@ class RecordingMetaFile(JsonSerialize):
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
def update_subfile_time_size(self, database = None):
meta_data = {
'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
def update_subfile_raw(self, database = None):
meta_data = {
'raw_data': self._recording_sub_file,
}
_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
def update_subfile_mini(self, database = None):
meta_data = {
'mini_data': self._recording_sub_mini,
}
_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
def filename(self) -> str:
@@ -517,11 +559,6 @@ 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':
@@ -567,9 +604,6 @@ 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):
@@ -628,15 +662,6 @@ 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
@@ -792,14 +817,10 @@ 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
@@ -965,10 +986,7 @@ 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])
@@ -996,7 +1014,8 @@ 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', '_id_db_save', '_raw_create_not_done',
'_mini_create_not_done')
def __init__(self, meta: RecordingMetaFile, device_id, database = None):
self._meta = meta
@@ -1017,7 +1036,9 @@ class RecordingFileWriter:
self._raw_save = {
'id': {},
'data': {}
'data': {},
'end_time': {},
'size': {}
}
self._mini_save = {
'10': {
@@ -1069,12 +1090,15 @@ class RecordingFileWriter:
# splitting
self.splitting_threshold_time = 30 * 60 * 1000 # one minute
self.splitting_threshold_size = 4 * 16 * 1024 # 16 * 16KB
self.splitting_threshold_size = 16 * 1024 # 16 * 16KB
self._writer_batch_size = 8192
self._splitting_size = None
self._raw_create_not_done = True
self._mini_create_not_done = True
@property
def meta_file(self) -> RecordingMetaFile:
@@ -1290,7 +1314,8 @@ class RecordingFileWriter:
self._data_db[c].append(str(v))
self._time_now = int(t)
return
# @calculate_time(1)
def write(self, data: Union[bytes, RecordingData, List[bytes], List[RecordingData]], mqtt_thread) -> int:
# check size
ths = self.splitting_threshold_size
@@ -1349,42 +1374,54 @@ class RecordingFileWriter:
self.get_data_iter(d, mqtt_thread)
data_save = False
mini_save = False
if len(self._recording_file_dict) > 0:
for ch in self._data_db.keys():
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_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] > 2000000:
for ch in self._recording_file_dict:
if self._recording_file_dict[ch]._id_db == 0:
return None
for ch in self._data_db.keys():
for scale in self._mini_scale_list:
if self._recording_mini_dict[str(scale)][ch]._id_db == 0:
return None
if self._raw_create_not_done :
self._raw_create_not_done = False
self._meta.update_subfile_raw(database = self._database)
if self._mini_create_not_done :
self._mini_create_not_done = False
self._meta.update_subfile_mini(database = self._database)
data_save = False
mini_save = False
if len(self._recording_file_dict) > 0:
for ch in self._data_db.keys():
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
data_save = True
self._raw_save['end_time'][ch] = self._time_now
self._raw_save['size'][ch] = self._recording_file_dict[ch]._size
self._data_db[ch].clear()
self._time[ch] = self._time_now
self._splitting_size += sz
self._meta._last_time = self._time_now
self._recording_file_dict[ch].update_endtime(self._time_now)
self._splitting_size += write_sz
data_save = True
if len(self._data_mini_ch[ch]['1000']['mean']) >= 10:
mini_save = True
for scale in self._mini_scale_list:
str_mean = [str(int) for int in self._data_mini_ch[ch][str(scale)]['mean']]
data_mean = str(self._data_mini_ch[ch][str(scale)]['start_time']) + ' ' + ' '.join(str_mean) + '"***"'
self._mini_save[str(scale)]['id'][ch] = self._recording_mini_dict[str(scale)][ch]._id_db
self._mini_save[str(scale)]['start_time'][ch] = str(self._data_mini_ch[ch][str(scale)]['start_time'])
self._mini_save[str(scale)]['data_mean'][ch] = self._data_mini_ch[ch][str(scale)]['mean'].copy()
self._mini_save[str(scale)]['data_mean'][ch] = data_mean
# self._mini_save[str(scale)]['data_random'][ch] = self._data_mini_ch[ch][str(scale)]['random'].copy()
# self._mini_save[str(scale)]['data_bar'][ch] = self._data_mini_ch[ch][str(scale)]['bar'].copy()
self._recording_mini_dict[str(scale)][ch].write(self._mini_save[str(scale)]['data_mean'][ch])
@@ -1395,26 +1432,22 @@ class RecordingFileWriter:
if data_save is True:
if self._database is not None:
# print('raw_save', self._raw_save['id'])
# print('id_save', self._id_db_save)
self._database.put_queue(['data_raw_recording', self._raw_save['id'], self._channel_list, self._raw_save['data'], self._id_db_save])
self._meta.update_subfile(database = self._database)
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._meta.update_subfile_time_size(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)
self._database.put_queue(['data_mini_recording_new', copy(self._mini_save[str(scale)]['id']), self._channel_list, copy(self._mini_save[str(scale)]['data_mean'])])
self._meta.update_subfile_time_size(database = self._database)
del data
return None
def _switch_recording_file(self):
# if self._recording_file is not None:
# self._recording_file.close()
self._raw_create_not_done = True
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
@@ -1433,16 +1466,16 @@ 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)
# self._meta.update_subfile(database = self._database)
self._splitting_size = 0
return None
def _switch_recording_mini(self, scale):
self._mini_create_not_done = True
if len(self._recording_mini_dict[str(scale)]) > 0:
for ch in self._recording_mini_dict[str(scale)].keys():
@@ -1460,14 +1493,12 @@ 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)
# 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

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