Compare commits

...

29 Commits

Author SHA1 Message Date
Roy 27497a09c3 [update] update cali table for 9 hstia 2023-03-27 13:56:01 +08:00
Roy 5dc2d22686 [update] fix cali table for 4 hstia 2023-03-27 11:15:24 +08:00
Roy 56b239eb8b [update] fix cali table for 4 hstia 2023-03-25 17:38:58 +08:00
Roy 8bc5815db9 [update] fix cali table for 4 hstia 2023-03-25 16:26:11 +08:00
Roy 940a2d32fa [update] clean eis decoder code 2023-03-23 14:26:44 +08:00
Roy 22eb8a09f4 [update] fix hsrtia_a & hsrtia_b & hsrtia_c Negative number error 2023-03-22 16:52:40 +08:00
Roy dbd7431124 [update] hsrtia_a & hsrtia_b & hsrtia_c receive from elite is 5bytes 2023-03-22 13:39:14 +08:00
Roy 15c15275a7 [update] update AC_AMP defalut value 2023-03-21 16:04:27 +08:00
Roy 836d75b77e [update] new idle mode (eis1.0) 2023-03-21 16:02:49 +08:00
Roy 417bdd91a4 [update] update librery parameter:CA_VOLT 2023-03-08 10:09:06 +08:00
Roy 62ee763e2c [update] update EDC decoder 2023-03-07 17:55:00 +08:00
Roy 44e9e4cb67 [update] update BAT library 2023-03-07 17:43:41 +08:00
Roy 38537563fd [update] new idle mode 2023-01-09 17:27:03 +08:00
Roy 375372996d [update] update TRIG local name pattern 2023-01-07 16:55:03 +08:00
Roy d79491db8b [update] optimize connection 2023-01-07 11:00:44 +08:00
peterlu14 5a35da98ac [update] trigger json add parameter TIME_DURATION 2023-01-03 15:31:55 +08:00
peterlu14 9c054bd733 [update] change table name project_report -> project_reports & project_meta -> project_metas 2022-12-28 13:21:00 +08:00
peterlu14 64412f9376 [update] change meta_project_info to project_meta & alter table project_meta column cycle type string to jsonb 2022-12-28 11:13:37 +08:00
peterlu14 97034d6b32 [update] remove README $ text & add apache2 install 2022-12-22 09:39:44 +00:00
peterlu14 f065bad826 delete db first controller info 2022-12-20 11:31:35 +08:00
peterlu14 9c1dafd003 [debug] fix create project log error 2022-12-19 11:06:53 +08:00
Roy 03443ada99 [update] take EIS_AC_AMP parameter error 2022-12-07 14:20:30 +08:00
Roy 17dc5470e7 Merge remote-tracking branch 'origin/dev/scheduler_log' into dev/fix_Amp_cali 2022-12-02 17:44:13 +08:00
peterlu14 695f37c2dd [update] gitignore log 2022-12-01 15:18:47 +08:00
peterlu14 690f859e86 [update] idle fix & scheduler log & cycle count 2022-12-01 15:18:04 +08:00
Roy 0ed4d0594a [update] print something 2022-11-29 14:44:00 +08:00
peterlu14 959d86c0fe [update] fix eis highz default error 2022-11-28 10:41:08 +08:00
peterlu14 24c07a7fa5 [update] EDC1.5re, EIS1.1, EISMini support idle instruction 2022-11-28 10:18:34 +08:00
peterlu14 e43857a5bc [update] add idle instruction 2022-11-28 10:13:08 +08:00
23 changed files with 2191 additions and 312 deletions
+1
View File
@@ -7,3 +7,4 @@
/.vscode /.vscode
/media /media
python/biopro/sever/_identify.py python/biopro/sever/_identify.py
*.log
+34 -27
View File
@@ -158,8 +158,8 @@ reboot
###### Set pi password ###### Set pi password
``` ```
$cd ~ cd ~
$passwd passwd
Current password:raspberry Current password:raspberry
New password:5k6zj454778225 New password:5k6zj454778225
Retype new password:5k6zj454778225 Retype new password:5k6zj454778225
@@ -198,11 +198,11 @@ exit 0
### MQTT broker install ### MQTT broker install
###### 1.Install mosquitto ###### 1.Install mosquitto
$sudo apt-get install mosquitto mosquitto-clients sudo apt-get install mosquitto mosquitto-clients
###### 2.Enable Remote Access ###### 2.Enable Remote Access
$sudo vim /etc/mosquitto/conf.d/default.conf sudo vim /etc/mosquitto/conf.d/default.conf
add the code following as: add the code following as:
``` ```
@@ -213,13 +213,13 @@ protocol websockets
allow_anonymous true allow_anonymous true
``` ```
###### 3.restart mqtt broker ###### 3.restart mqtt broker
$sudo systemctl restart mosquitto sudo systemctl restart mosquitto
###### 4.Robust MQTT ###### 4.Robust MQTT
create mosquitto_restart.sh create mosquitto_restart.sh
$cd ~ cd ~
$sudo vim mosquitto_restart.sh sudo vim mosquitto_restart.sh
add the code following as: add the code following as:
@@ -236,16 +236,16 @@ echo "$SERVICE is currently running" >> /home/ubuntu/cron.log
exit 0 exit 0
``` ```
###### 5.add mosquitto_restart.sh to root routing ###### 5.add mosquitto_restart.sh to root routing
$sudo chmod +x mosquitto_restart.sh sudo chmod +x mosquitto_restart.sh
$sudo -i sudo -i
$crontab -e crontab -e
add the code following as: add the code following as:
``` ```
*/5 * * * * /home/pi/mosquitto_restart.sh */5 * * * * /home/pi/mosquitto_restart.sh
``` ```
###### 6.Auto run MQTT broker when when pi-start ###### 6.Auto run MQTT broker when when pi-start
$sudo vim /etc/rc.local sudo vim /etc/rc.local
add the code following as: add the code following as:
``` ```
@@ -254,31 +254,31 @@ sudo nohup systemctl restart mosquitto
### Setting up a Routed Wireless Access Point ### Setting up a Routed Wireless Access Point
###### 1.Install AP and Management Software ###### 1.Install AP and Management Software
$sudo apt install hostapd sudo apt install hostapd
$sudo systemctl unmask hostapd sudo systemctl unmask hostapd
$sudo systemctl enable hostapd sudo systemctl enable hostapd
$sudo apt install dnsmasq sudo apt install dnsmasq
$sudo DEBIAN_FRONTEND=noninteractive apt install -y netfilter-persistent iptables-persistent sudo DEBIAN_FRONTEND=noninteractive apt install -y netfilter-persistent iptables-persistent
###### 2.Set up the Network Router ###### 2.Set up the Network Router
$sudo nano /etc/dhcpcd.conf sudo nano /etc/dhcpcd.conf
``` ```
interface wlan0 interface wlan0
static ip_address=192.168.2.1/24 static ip_address=192.168.2.1/24
nohook wpa_supplicant nohook wpa_supplicant
``` ```
$sudo nano /etc/sysctl.d/routed-ap.conf sudo nano /etc/sysctl.d/routed-ap.conf
``` ```
# Enable IPv4 routing # Enable IPv4 routing
net.ipv4.ip_forward=1 net.ipv4.ip_forward=1
``` ```
$sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
$sudo netfilter-persistent save sudo netfilter-persistent save
$sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
$sudo nano /etc/dnsmasq.conf sudo nano /etc/dnsmasq.conf
``` ```
interface=wlan0 # Listening interface interface=wlan0 # Listening interface
@@ -289,10 +289,10 @@ address=/gw.wlan/192.168.2.1
# Alias for this router # Alias for this router
``` ```
###### 3.Ensure Wireless Operation ###### 3.Ensure Wireless Operation
$sudo rfkill unblock wlan sudo rfkill unblock wlan
###### 4.Configure the AP Software ###### 4.Configure the AP Software
$sudo nano /etc/hostapd/hostapd.conf sudo nano /etc/hostapd/hostapd.conf
``` ```
country_code=TW country_code=TW
@@ -317,11 +317,13 @@ wme_enabled=1
ht_capab=[HT40+][SHORT-GI-40] ht_capab=[HT40+][SHORT-GI-40]
``` ```
###### 5.Running the new Wireless AP ###### 5.Running the new Wireless AP
$sudo systemctl reboot sudo systemctl reboot
### Install Apache2
sudo apt install apache2
### Set web site ### Deploy web site
$sudo vim ./sites-available/000-default.conf sudo vim /etc/apache2/sites-available/000-default.conf
``` ```
<VirtualHost *:8080> #80------>8080 <VirtualHost *:8080> #80------>8080
# The ServerName directive sets the request scheme, hostname and port that # The ServerName directive sets the request scheme, hostname and port that
@@ -363,6 +365,11 @@ $sudo vim ./sites-available/000-default.conf
> https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md > https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md
# ChangeLog # ChangeLog
[2022.12.28]
change meta_project_info to project_metas
change project_report to project_reports
alter table project_meta column cycle type string to jsonb
[2022.11.16] [2022.11.16]
add python package SQLAlchemy add python package SQLAlchemy
add new column project(int4) in postgresSQL table recording_meta_datas add new column project(int4) in postgresSQL table recording_meta_datas
@@ -6,11 +6,11 @@ from sqlalchemy.dialects.postgresql import JSONB
from .base import Base from .base import Base
class MetaProjectInfo(Base): class MetaProjectInfo(Base):
__tablename__ = "meta_project_info" __tablename__ = "project_metas"
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
project = Column(String(36)) project = Column(String(36))
cycle = Column(String) cycle = Column(JSONB)
task = Column(JSONB) task = Column(JSONB)
serial_number = Column(Integer) serial_number = Column(Integer)
deleted = Column(Boolean, default = False) deleted = Column(Boolean, default = False)
+1 -1
View File
@@ -6,7 +6,7 @@ from sqlalchemy.dialects.postgresql import JSONB
from .base import Base from .base import Base
class ProjectReport(Base): class ProjectReport(Base):
__tablename__ = "project_report" __tablename__ = "project_reports"
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
name = Column(String) name = Column(String)
+6 -16
View File
@@ -660,9 +660,9 @@ class CC2650Device(Device):
break break
elif device_type == 'EISZeroOne': elif device_type == 'EISZeroOne':
i = 0 i = 1
request_times = 0 request_times = 0
while i < 13: while i <= 24:
try: try:
# send # send
code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, i) code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, i)
@@ -2177,23 +2177,12 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
else: else:
for dev in self._found: for dev in self._found:
if dev.mac_address == address: if dev.mac_address == address:
# send device mac and addrType
try:
# print('send_connect',bytes(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? # connection establish done?
for retry_recv_ack in range(5): for retry_recv_ack in range(5):
self._cc2650.send("bytes", bytes((0, 0, 0, 0)))
try: try:
# send device mac and addrType
self._cc2650.send("bytes", bytes(connect_ins))
sleep(1.5)
con_done = self._cc2650.recv_uart(timeout = 0.1) con_done = self._cc2650.recv_uart(timeout = 0.1)
except RecvTimeout: except RecvTimeout:
@@ -2202,6 +2191,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
# is the ack valid? # is the ack valid?
if con_done is None: if con_done is None:
self.log_info("recv connection timeout, retry... ")
continue continue
elif con_done[0] is 46 and \ elif con_done[0] is 46 and \
+8
View File
@@ -832,6 +832,9 @@ class DeviceManager(MasterDevice, Synchronized):
elif func == InternalInstruction.PREDEFINED_DISABLE_CACHE: elif func == InternalInstruction.PREDEFINED_DISABLE_CACHE:
self._device_disable_cache(device, *para) self._device_disable_cache(device, *para)
elif func == InternalInstruction.PREDEFINED_IDLE:
self._idle(device, *para)
elif isinstance(device, DebugDevice): elif isinstance(device, DebugDevice):
if func == InternalInstruction.PREDEFINED_NOTIFY: if func == InternalInstruction.PREDEFINED_NOTIFY:
@@ -851,6 +854,11 @@ class DeviceManager(MasterDevice, Synchronized):
InternalInstruction.PREDEFINED_DATA_FORMAT, InternalInstruction.PREDEFINED_DATA_FORMAT,
f) f)
def _idle(self, device: Device, expr: AnyStr):
self._handler.device_internal_command(device.device_id,
InternalInstruction.PREDEFINED_IDLE,
None)
def _device_data_format_cali(self, device: Device, expr: str, cali: bytes = None): def _device_data_format_cali(self, device: Device, expr: str, cali: bytes = None):
if cali is None: if cali is None:
cali = device.calibration_info(expr) cali = device.calibration_info(expr)
+325 -221
View File
@@ -884,20 +884,54 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
def decode(self, data: bytes) -> Optional[RecordingData]: def decode(self, data: bytes) -> Optional[RecordingData]:
if len(data) < 18: if len(data) < 18:
return None return None
voltage = 0
mem_cnt = data[1] #/* Elite Notify data:
time_stamp: float = struct.unpack('<I', data[4:8])[0] # unit: ms 0x18030000 # * +--------+----------+---------+---------+---------+-----------+-----------------+
current = struct.unpack('<i', data[8:12])[0] # unit: nA # * | id(1B) | time(4B) | ch1(4B) | ch2(4B) | ch3(4B) | cycle(2B) | finish_flag(1B) |
voltage = struct.unpack('<i', data[12:16])[0] # unit: uV # * | bat(4B) | notify#(1B) | ch4(4B) | ch5(4B) | ch6(4B) | __(3B) |
impedance = struct.unpack('<i', data[16:20])[0] # unit: mOm # * +---------+-------------+---------+---------+---------+--------+
# */
#/*
# * EliteADCControl(): use ADC plot, and send what data to controller
# * +---------------------------+-----------+-----------+-----------+-----------+-----------+
# * | MODE | ch1 | ch2 | ch3 | cycle | ch4 |
# * +---------------------------+-----------+-----------+-----------+-----------+-----------+
# * | CURVE_IV | Iin | Vout | Vin | | Vmon |
# * | CURVE_IV_CY | Iin | Vout | Vin | v | Vmon |
# * | CURVE_VO | Iin | Vout | Vin | | Vmon |
# * | CURVE_RT | Iin | Vout | R | | Vmon |
# * | CURVE_VT | Iin | Vin | | | |
# * | CURVE_IT | Iin | Vin | Vout | | Vmon |
# * | CURVE_CC | Iin | Vin | Vout | | Vmon |
# * | CURVE_CP | Iin | Vout-Vin | Vout | | Vmon |
# * | CURVE_CV | Iin | Vout-Vin | Vout | v | Vmon |
# * | CURVE_LSV | Iin | Vout-Vin | Vout | | Vmon |
# * | CURVE_CA | Iin | Vout-Vin | Vout | | Vmon |
# * | CURVE_OCP | Iin | Vmon-Vin | Vin | | Vmon |
# * | CURVE_UNI_PULSE | pul1_Iin | pul2_Iin | | | |
# * | CURVE_DPV | c1&c2_avg | Vout-Vin | Vout | | Vmon |
# * | CURVE_DPV_SMPRATE | Iin | Vout-Vin | Vout | | Vmon |
# * | CURVE_DPV_ADVANCE | c1&c2_avg | Vout-Vin | Vout | | Vmon |
# * | CURVE_DPV_ADVANCE_SMPRATE | Iin | Vout-Vin | Vout | | Vmon |
# * +---------------------------+-----------+-----------+-----------+-----------+-----------+
# *
# * ps. c1_avg = pul1_Iin
# * ps. c2_avg = pul2_Iin
# */
cycle_number = struct.unpack('<H', data[20:22])[0] mem_cnt = data[1]
finish_mode_falg = data[22] time_stamp: float = struct.unpack('<I', data[1+3:5+3])[0]
battery = struct.unpack('<i', data[23:27])[0] ch1 = struct.unpack('<i', data[5+3:9+3])[0] # unit: nA
elite_notify_times = data[27] ch2 = struct.unpack('<i', data[9+3:13+3])[0] # unit: uV
notify_one = struct.unpack('<i', data[28:32])[0] ch3 = struct.unpack('<i', data[13+3:17+3])[0] # unit: mOm
notify_two = struct.unpack('<i', data[32:36])[0]
notify_three = struct.unpack('<i', data[36:40])[0] cycle_number = struct.unpack('<H', data[17+3:19+3])[0]
finish_mode_falg = data[19+3]
battery = struct.unpack('<i', data[20+3:24+3])[0]
elite_notify_times = data[24+3]
ch4 = struct.unpack('<i', data[25+3:29+3])[0]
ch5 = struct.unpack('<i', data[29+3:33+3])[0]
ch6 = struct.unpack('<i', data[33+3:37+3])[0]
# self._show_data = True # self._show_data = True
mem_wrong_information = struct.unpack('<i', data[43:47])[0] # mem_wrong_information = green retry, green wrong, red retry, red wrong mem_wrong_information = struct.unpack('<i', data[43:47])[0] # mem_wrong_information = green retry, green wrong, red retry, red wrong
@@ -924,25 +958,29 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
else: else:
if self._show_data: if self._show_data:
print('|', time_stamp, '|', delta, '|', int(time_stamp * 1000 / 2), print('|', time_stamp, '|', delta, '|', int(time_stamp * 1000 / 2),
'|', current, '|', voltage, '|', impedance, '|', cycle_number, '|', ch1, '|', ch2, '|', ch3, '|', cycle_number,
'|', notify_one, '|', notify_two, '|', notify_three, '|', ch4, '|', ch5, '|', ch6,
'|', finishMode, '@', str(self.device)) '|', finishMode, '@', str(self.device), flush = True)
# print('|', '{:10}'.format(time_stamp), # print('|', '{:10}'.format(time_stamp),
# '|', '{:4}'.format(delta), # '|', '{:4}'.format(delta),
# '|', '{:10}'.format(int(time_stamp * 1000 / 2)), # '|', '{:10}'.format(int(time_stamp * 1000 / 2)), #[usec]
# '|', '{:10}'.format(current), # '|', '{:10}'.format(ch1), #[nA]
# '|', '{:10}'.format(voltage), # '|', '{:10}'.format(ch2), #[uV]
# '|', '{:10}'.format(impedance), # '|', '{:10}'.format(ch3),
# '|', '{:5}'.format(cycle_number), # '|', '{:5}'.format(cycle_number),
# '|', '{:1}'.format(finishMode), # '|', '{:10}'.format(ch4), #Voutin[uV]
# '@', str(self.device), '|') # '|', '{:10}'.format(ch5),
# '|', '{:10}'.format(ch6),
# '|', '{:5}'.format(battery), #[mV]
# '|', '{:4}'.format(elite_notify_times),
# '|', '{:1}'.format(finishMode),
# '@', str(self.device), '|', flush = True)
# print('|', '{:5}'.format(mem_wrong_information), # print('|', '{:5}'.format(mem_wrong_information),
# '|', '{:2}'.format(ram_num), # '|', '{:2}'.format(ram_num),
# '|', '{:2}'.format(broken_flag), # '|', '{:2}'.format(broken_flag),
# '@', str(self.device), '|') # '@', str(self.device), '|')
pass
if finishMode == True: if finishMode == True:
print("finishMode full data:", list(data), datetime.now()) print("finishMode full data:", list(data), datetime.now())
@@ -951,13 +989,13 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
self._mode_stop = 0 self._mode_stop = 0
ret = RecordingData(self.device, int(time_stamp * 1000 / 2), 0) ret = RecordingData(self.device, int(time_stamp * 1000 / 2), 0)
ret.append_data(0, current) ret.append_data(0, ch1)
ret.append_data(1, voltage) ret.append_data(1, ch2)
ret.append_data(2, impedance) ret.append_data(2, ch3)
ret.append_data(3, cycle_number) ret.append_data(3, cycle_number)
ret.append_data(4, notify_one) ret.append_data(4, ch4)
ret.append_data(5, notify_two) ret.append_data(5, ch5)
ret.append_data(6, notify_three) ret.append_data(6, ch6)
# ret.append_data(4, battery) # ret.append_data(4, battery)
# ret.append_data(5, elite_notify_times) # ret.append_data(5, elite_notify_times)
# ret.append_data(6, mem_cnt) # ret.append_data(6, mem_cnt)
@@ -1360,7 +1398,6 @@ class EISZeroOneDataDecoder(RecDataDecoder):
self._mode_stop = 0 self._mode_stop = 0
self._cycle_start_time = [] self._cycle_start_time = []
self._ac_amp: int = 0
self._mode: int = 0 self._mode: int = 0
self._last_phase = 0 self._last_phase = 0
self._first_phase_flag = 1 self._first_phase_flag = 1
@@ -1376,128 +1413,204 @@ class EISZeroOneDataDecoder(RecDataDecoder):
@staticmethod @staticmethod
def _decode_cali_coeff(cali_coeff: bytes) -> Optional[List[Tuple[int, int]]]: def _decode_cali_coeff(cali_coeff: bytes) -> Optional[List[Tuple[int, int]]]:
if cali_coeff != b'': #####################################################
cali_table = [] # phase_coeff/phase_offset/hsrtia_a/hsrtia_b/rolloff
hsrtia_a = []
hsrtia_b = []
hsrtia_c = []
hsrtia_d = []
phase_coeff = []
phase_offset = []
# phase_coeff = [[0]*4 for i in range(4)]
# phase_offset = [[0]*4 for i in range(4)]
phase_coeff = numpy.zeros([4, 4], dtype = int)
phase_offset = numpy.zeros([4, 4], dtype = int)
########################################
# phase_coeff
# [[gain0, g1, g2, g3] ----->最高頻 # [[gain0, g1, g2, g3] ----->最高頻
# [gain0, g1, g2, g3] ----->中頻 # [gain0, g1, g2, g3] ----->中頻
# [gain0, g1, g2, g3] ----->低頻 # [gain0, g1, g2, g3] ----->低頻
# [gain0, g1, g2, g3] ----->最低頻 # [gain0, g1, g2, g3] ----->最低頻
# ] # ]
####################################### #####################################################
print('cali_coeff=', cali_coeff)
if cali_coeff != b'':
cali_table = []
hsrtia_a = numpy.zeros([4, 8], dtype = int) #hsrtia_a[freq][gain]
hsrtia_b = numpy.zeros([4, 8], dtype = numpy.int64) #hsrtia_b[freq][gain]
rolloff = numpy.zeros([4, 8], dtype = int) #rolloff[freq][gain]
phase_coeff = numpy.zeros([4, 8], dtype = int) #phase_coeff[freq][gain]
phase_offset = numpy.zeros([4, 8], dtype = int) #phase_offset[freq][gain]
cis_data_len = 20
# print('cali_coeff', cali_coeff) #gain=0
cutoff_freq = struct.unpack('>I', cali_coeff[1:5])[0] * 100 #4 cis_cali_packet = 1
# temp = struct.unpack('>B', cali_coeff[5:6])[0] #1 index = (cis_cali_packet - 1) * cis_data_len
# hsrtia_200r = struct.unpack('>B', cali_coeff[6:7])[0] #1 hsrtia_a[0][0] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
# hsrtia_5k = struct.unpack('>H', cali_coeff[7:9])[0] #2 hsrtia_b[0][0] = struct.unpack('>q', cali_coeff[index+5:index+13])[0]
# hsrtia_20k = struct.unpack('>H', cali_coeff[6:8])[0] #2 rolloff[0][0] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
# hsrtia_160k = struct.unpack('>I', cali_coeff[8:12])[0] #4
index = 20 cis_cali_packet = 2
g = 0 index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] phase_coeff[0][0] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_offset[0][0] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_coeff[1][0] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_offset[1][0] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 40
g = 0
phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
#Lv[0] 160k
index = 60
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])
#Lv[1] 20k cis_cali_packet = 3
index = 80 index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8) phase_coeff[2][0] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8) phase_offset[2][0] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]) phase_coeff[3][0] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][0] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
#Lv[2] 5k #gain=1
index = 100 cis_cali_packet = 4
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8) index = (cis_cali_packet - 1) * cis_data_len
hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8) hsrtia_a[0][1] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]) hsrtia_b[0][1] = struct.unpack('>q', cali_coeff[index+5:index+13])[0]
rolloff[0][1] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
#Lv[3] 200R cis_cali_packet = 5
index = 120 index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8) phase_coeff[0][1] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8) phase_offset[0][1] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]) phase_coeff[1][1] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][1] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 140 cis_cali_packet = 6
g = 1 index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0] phase_coeff[2][1] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0] phase_offset[2][1] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0] phase_coeff[3][1] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0] phase_offset[3][1] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 160
g = 1
phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 180
g = 2
phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 200
g = 2
phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 220
g = 3
phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 240
g = 3
phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
# print('cutoff_freq', cutoff_freq) #gain=2
# print('hsrtia_a', hsrtia_a) cis_cali_packet = 7
# print('hsrtia_b', hsrtia_b) index = (cis_cali_packet - 1) * cis_data_len
# print('hsrtia_c', hsrtia_c) hsrtia_a[0][2] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
# print('phase_coeff') hsrtia_b[0][2] = struct.unpack('>q', cali_coeff[index+5:index+13])[0]
# print(phase_coeff) rolloff[0][2] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
# print('phase_offset')
# print(phase_offset)
cali_table.append((cutoff_freq, phase_coeff, phase_offset, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d)) cis_cali_packet = 8
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][2] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][2] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][2] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][2] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
cis_cali_packet = 9
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][2] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][2] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][2] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][2] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
#gain=3
cis_cali_packet = 10
index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][3] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
hsrtia_b[0][3] = struct.unpack('>q', cali_coeff[index+5:index+13])[0]
rolloff[0][3] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
cis_cali_packet = 11
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][3] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][3] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][3] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][3] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
cis_cali_packet = 12
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][3] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][3] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][3] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][3] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
#gain=4
cis_cali_packet = 13
index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][4] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
hsrtia_b[0][4] = struct.unpack('>q', cali_coeff[index+5:index+13])[0]
rolloff[0][4] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
cis_cali_packet = 14
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][4] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][4] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][4] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][4] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
cis_cali_packet = 15
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][4] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][4] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][4] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][4] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
#gain=5
cis_cali_packet = 16
index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][5] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
hsrtia_b[0][5] = struct.unpack('>q', cali_coeff[index+5:index+13])[0]
rolloff[0][5] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
cis_cali_packet = 17
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][5] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][5] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][5] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][5] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
cis_cali_packet = 18
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][5] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][5] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][5] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][5] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
#gain=6
cis_cali_packet = 19
index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][6] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
hsrtia_b[0][6] = struct.unpack('>q', cali_coeff[index+5:index+13])[0]
rolloff[0][6] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
cis_cali_packet = 20
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][6] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][6] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][6] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][6] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
cis_cali_packet = 21
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][6] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][6] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][6] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][6] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
#gain=7
cis_cali_packet = 22
index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][7] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
hsrtia_b[0][7] = struct.unpack('>q', cali_coeff[index+5:index+13])[0]
rolloff[0][7] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
cis_cali_packet = 23
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][7] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][7] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][7] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][7] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
cis_cali_packet = 24
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][7] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][7] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][7] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][7] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
print('hsrtia_a')
print(hsrtia_a)
print('hsrtia_b')
print(hsrtia_b)
print('rolloff')
print(rolloff)
print('phase_coeff')
print(phase_coeff)
print('phase_offset')
print(phase_offset)
cali_table.append((phase_coeff, phase_offset, hsrtia_a, hsrtia_b, rolloff))
return cali_table return cali_table
else: else:
@@ -1521,15 +1634,20 @@ class EISZeroOneDataDecoder(RecDataDecoder):
if len(data) < 18: if len(data) < 18:
return None return None
ch1 = struct.unpack('>i', data[1+3:5+3])[0] # unit: 1/1000 nA ch1 = struct.unpack('>i', data[1+3:5+3])[0]
ch2 = struct.unpack('>i', data[5+3:9+3])[0] # unit: mV ch2 = struct.unpack('>i', data[5+3:9+3])[0]
ch3 = struct.unpack('>i', data[9+3:13+3])[0] # unit: kOm ch3 = struct.unpack('>i', data[9+3:13+3])[0]
time_stamp: float = struct.unpack('<I', data[13+3:17+3])[0] # unit: ms time_stamp: float = struct.unpack('<I', data[13+3:17+3])[0] # unit: ms
cycle_number = struct.unpack('>H', data[17+3:19+3])[0] cycle_number = struct.unpack('>H', data[17+3:19+3])[0]
d19 = data[19+3] d19 = data[19+3]
gain = data[20+3] gain = data[20+3]
finishMode = (d19 & 0x80) >> 7 finishMode = (d19 & 0x80) >> 7
ch4 = struct.unpack('<i', data[21+3:25+3])[0]
notify_one = struct.unpack('<i', data[25+3:29+3])[0]
notify_two = struct.unpack('<i', data[29+3:33+3])[0]
notify_three = struct.unpack('<i', data[33+3:37+3])[0]
if time_stamp == 0: if time_stamp == 0:
self._start_return_data = True self._start_return_data = True
@@ -1547,90 +1665,68 @@ class EISZeroOneDataDecoder(RecDataDecoder):
return None return None
else: else:
if self.cali_coeff is not None and (self._mode == 0 or self._mode == 5): if self.cali_coeff is not None and (self._mode == 0 or self._mode == 5):
hsrtia_a = [] phase_coeff, phase_offset, hsrtia_a, hsrtia_b, rolloff = self.cali_coeff[0]
hsrtia_b = []
hsrtia_c = []
hsrtia_d = []
cutoff_freq, phase_coeff, phase_offset, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d = self.cali_coeff[0]
voltage_amp = round(self._ac_amp * 800 / 2047) # use UI value
if (self._mode == 0 or self._mode == 5): if (self._mode == 0 or self._mode == 5):
img = ch1
real = ch2 img = ch1 #img[ohm]
freq = ch3 real = ch2 #real[ohm]
freq = ch3 #freq[10mHz]
fre_idx = 0 fre_idx = 0
voltage_amp = round(ch4 / 1000) #ch4=Amp[uV] #voltage_amp[mV]
rolloff_cali = rolloff[0][gain]
# rolloff_cali = cutoff_freq/1e5
rolloff_cali = hsrtia_c[gain]
voltage_mag = math.sqrt(img ** 2 + real ** 2) * (1 + freq ** 2 / rolloff_cali ** 2 / 1e4) voltage_mag = math.sqrt(img ** 2 + real ** 2) * (1 + freq ** 2 / rolloff_cali ** 2 / 1e4)
current = (voltage_mag ** 2 * hsrtia_a[0][gain] + voltage_mag * hsrtia_b[0][gain]) / 1e8 #current[nA]
# 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]
# 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 (current != 0): if (current != 0):
# impedance = voltage_amp * 1000_000 / 1.414213 / current # impedance[mOhm] = voltage_amp[mV] * 1000000 / 1.414213 / current[nA] #RMS=amp*SQRT(2), SQRT(2)=1.414213
impedance = voltage_amp * 707106.78 / current impedance = voltage_amp * 707106.78 / current
else: else:
impedance = 0 impedance = 0
raw_phase = math.atan2(img , real) * 180 / math.pi raw_phase = math.atan2(img , real) * 180 / math.pi
if (freq >= 1000000): # 10000 Hz if (freq >= 1000000): #10000Hz
fre_idx = 0 fre_idx = 0
elif (freq >= 10000): # 100 Hz elif (freq >= 10000): #100Hz
fre_idx = 1 fre_idx = 1
elif (freq >= 1000): # 10 Hz elif (freq >= 1000): #10Hz
fre_idx = 2 fre_idx = 2
elif (freq >= 1): # 0.01 Hz elif (freq >= 1): #0.01Hz
fre_idx = 3 fre_idx = 3
ideal_raw_phase = phase_coeff[gain][fre_idx] /1e10 * freq + phase_offset[gain][fre_idx] / 1e6 ideal_raw_phase = phase_coeff[gain][fre_idx] /1e10 * freq + phase_offset[gain][fre_idx] / 1e6
phase = raw_phase - ideal_raw_phase phase = raw_phase - ideal_raw_phase
phase = phase % 180 if phase % 180<=90 else phase % 180-180 phase = phase % 180 if phase % 180<=90 else phase % 180-180
# last_phase_to90 = self._last_phase % 180 if self._last_phase % 180<=90 else self._last_phase % 180-180 imag_after_cal = impedance * math.sin(phase * math.pi / 180)
# diff = phase - last_phase_to90 real_after_cal = impedance * math.cos(phase * math.pi / 180)
# if (self._first_phase_flag):
# # self._last_phase = phase
# self._first_phase_flag = 0
# elif (abs(diff) >= 90):
# phase = self._last_phase + diff + (180 if diff<0 else-180)
# else:
# phase = self._last_phase + diff
# self._last_phase = phase
imag_after_cal = impedance * math.sin(round(phase) * math.pi / 180)
real_after_cal = impedance * math.cos(round(phase) * math.pi / 180)
if self._show_data: if self._show_data:
if (self._mode == 0 or self._mode == 5): if (self._mode == 0 or self._mode == 5):
print('|', '{:10}'.format(time_stamp), print('|', '{:10}'.format(time_stamp),
'|', '{:5}'.format(delta), '|', '{:5}'.format(delta),
'|', '{:6}'.format(ch1), '|', '{:5}'.format(img),
'|', '{:6}'.format(ch2), '|', '{:5}'.format(real),
'|', '{:8}'.format(ch3 / 100), '|', '{:9}'.format(freq*10), '[mHz]',
'|', '{:6}'.format(round(voltage_mag)), '|', '{:5}'.format(cycle_number),
'|', '{:5}'.format(int(imag_after_cal)), '|', '{:5}'.format(round(imag_after_cal)), '[Ohm]', #Z_imag[Ohm]
'|', '{:5}'.format(int(real_after_cal)), '|', '{:5}'.format(round(real_after_cal)), '[Ohm]', #Z_real[Ohm]
'|', '{:5}'.format(round(impedance)), '|', '{:5}'.format(round(impedance)), '[mOhm]',
'|', '{:5}'.format(round(phase, 1)), '|', '{:5}'.format(round(phase*1000)), '[mdegree]',
'|', '{:5}'.format(round(current, 3)), '|', '{:10}'.format(round(current)), '[nA]',
'|', '{:1}'.format(gain), '|', '{:1}'.format(gain),
'|', '{:1}'.format(finishMode), '|', '{:1}'.format(finishMode),
'@', str(self.device), '|', flush = True) '@', str(self.device), '|', flush = True)
print('|', '{:10}'.format(time_stamp),
'|', '{:5}'.format(delta),
'|', '{:5}'.format(notify_one),
'|', '{:5}'.format(notify_two),
'|', '{:5}'.format(notify_three),
'|', '{:5}'.format(voltage_amp), '[mV]',
'|', flush = True)
pass pass
else: else:
print('|', '{:10}'.format(time_stamp), print('|', '{:10}'.format(time_stamp),
@@ -1651,22 +1747,30 @@ class EISZeroOneDataDecoder(RecDataDecoder):
self._mode_stop = 0 self._mode_stop = 0
ret = RecordingData(self.device, int(time_stamp * 1000 / 2), 0) ret = RecordingData(self.device, int(time_stamp * 1000 / 2), 0)
if self._mode == 0 or self._mode == 5: #EIS Mode if self._mode == 0 or self._mode == 5: #EIS/CF Mode
ret.append_data(0, ch1) #Raw Imag ret.append_data(0, img)
ret.append_data(1, ch2) #Raw Real ret.append_data(1, real)
ret.append_data(2, ch3 * 10) #Frequency [mHz] ret.append_data(2, freq * 10) #[mHz]
ret.append_data(3, cycle_number) ret.append_data(3, cycle_number)
ret.append_data(4, round(imag_after_cal)) #Z_imag [Ohm] ret.append_data(4, round(imag_after_cal)) #Z_imag [Ohm]
ret.append_data(5, round(real_after_cal)) #Z_real [Ohm] ret.append_data(5, round(real_after_cal)) #Z_real [Ohm]
ret.append_data(6, round(impedance)) #Impedance [Ohm] ret.append_data(6, round(impedance)) #[mOhm]
ret.append_data(7, round(phase)) #Phase [degree] ret.append_data(7, round(phase*1000)) #[millidegree]
ret.append_data(8, round(current)) #Current [nA] ret.append_data(8, round(current)) #[nA]
ret.append_data(9, gain) #Gain Level ret.append_data(9, gain)
#debug data
ret.append_data(10, notify_one)
ret.append_data(11, notify_two)
ret.append_data(12, notify_three)
ret.append_data(13, voltage_amp) #mV
else: #CV Mode else: #CV Mode
ret.append_data(0, ch1) #Iin [nA] ret.append_data(0, ch1) #Iin [nA]?
ret.append_data(1, ch2) #Vset [nV] ret.append_data(1, ch2) #Vset [nV]?
ret.append_data(2, ch3) #Vout [nV] ret.append_data(2, ch3) #Vout [nV]?
ret.append_data(3, cycle_number) ret.append_data(3, cycle_number)
if cycle_number != self._cycle_number: if cycle_number != self._cycle_number:
+2
View File
@@ -283,6 +283,7 @@ class InternalInstruction(SingleInstruction):
PREDEFINED_SET = '_set' PREDEFINED_SET = '_set'
PREDEFINED_CDR = '_cdr' PREDEFINED_CDR = '_cdr'
PREDEFINED_DISABLE_CACHE = '_disable_cache' PREDEFINED_DISABLE_CACHE = '_disable_cache'
PREDEFINED_IDLE = '_idle'
PREDEFINED = ( PREDEFINED = (
PREDEFINED_SLEEP, PREDEFINED_SLEEP,
@@ -294,6 +295,7 @@ class InternalInstruction(SingleInstruction):
PREDEFINED_SET, PREDEFINED_SET,
PREDEFINED_CDR, PREDEFINED_CDR,
PREDEFINED_DISABLE_CACHE, PREDEFINED_DISABLE_CACHE,
PREDEFINED_IDLE,
) )
__slots__ = ('_expr', '_para') __slots__ = ('_expr', '_para')
+34 -4
View File
@@ -1,6 +1,7 @@
import sys import sys
import json import json
import threading import threading
import logging
from time import time, sleep from time import time, sleep
from datetime import datetime from datetime import datetime
@@ -46,10 +47,20 @@ class Project(threading.Thread):
self._count = 1 #流水號 self._count = 1 #流水號
self.log_verbose = log_verbose self.log_verbose = log_verbose
self._logger = logging.getLogger('project')
self._logger.setLevel('DEBUG')
self._formatter = logging.Formatter('[%(asctime)s.%(msecs)03d] %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
self._formatter_with_nothing = logging.Formatter('%(message)s')
self.setup_project(project) self.setup_project(project)
self.setup_device(self._device) self.setup_device(self._device)
# create log file handler
fh = logging.FileHandler(f'/home/pi/logger/project/{self.uuid}.log', mode="w")
fh.setFormatter(self._formatter)
self._logger.addHandler(fh)
def setup_project(self, project): def setup_project(self, project):
for (key, value) in project.items(): for (key, value) in project.items():
if key in key_list.keys(): if key in key_list.keys():
@@ -141,9 +152,19 @@ class Project(threading.Thread):
parameter_set = self._task_manager.running_task.parameter_set parameter_set = self._task_manager.running_task.parameter_set
return next((x for x in parameter_set if parameter_set[x]['target'] == device_address), None) return next((x for x in parameter_set if parameter_set[x]['target'] == device_address), None)
def get_cycle(self, task):
for index, _cycle in enumerate(self.cycle):
if task.uuid in _cycle['range']:
return _cycle
def run(self): def run(self):
# project status change running (1)
self._status = 1 self._status = 1
# save start time
self._start_time = time() self._start_time = time()
# saving & broadcast message
self._logger.info('Project ' + self.name + ' start')
self.log_verbose('Project ' + self.name + ' start') self.log_verbose('Project ' + self.name + ' start')
self.mqtt_thread.broadcast_command('project:' + self._name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]) self.mqtt_thread.broadcast_command('project:' + self._name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
@@ -171,8 +192,12 @@ class Project(threading.Thread):
if action.type == 'cycle' and condition.type == 'previous_task_done': if action.type == 'cycle' and condition.type == 'previous_task_done':
self.mqtt_thread.broadcast_command('project:task ' + task.name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]) self.mqtt_thread.broadcast_command('project:task ' + task.name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
self._task_manager.set_running_task(task) self._task_manager.set_running_task(task)
cycle_info = self.get_cycle(task)
if cycle_info['useID'] == False:
self._logger.info(f'---------- Cycle {task.name} Round {cycle_info["count"]} -----------')
if action.type == 'cycle' and condition.type == 'until_button_trigger': if action.type == 'cycle' and condition.type == 'until_button_trigger':
self._task_manager.running_task.stop() self._task_manager.running_task.stop()
self._logger.info(f'---------- Cycle {cycle_info["id"]} Round {cycle_info["count"]} -----------')
if self._task_manager.running_task != None: if self._task_manager.running_task != None:
if self._task_manager.running_task.uuid == task.uuid and action.type == 'cycle' and condition.type == 'after_task_run': if self._task_manager.running_task.uuid == task.uuid and action.type == 'cycle' and condition.type == 'after_task_run':
@@ -181,6 +206,7 @@ class Project(threading.Thread):
if action.type == 'start': if action.type == 'start':
if task.status != 1: if task.status != 1:
self._task_manager.set_running_task(task) self._task_manager.set_running_task(task)
self._logger.info(f'Task {str(self._task_manager.running_task.name)} start')
self.mqtt_thread.broadcast_command('project:task ' + task.name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]) self.mqtt_thread.broadcast_command('project:task ' + task.name + ' start at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
# elif action.type == 'stop': # elif action.type == 'stop':
# 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.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])
@@ -198,6 +224,7 @@ class Project(threading.Thread):
if action.target is not None: if action.target is not None:
device = self._complete_device[action.target] device = self._complete_device[action.target]
if ((action.type == 'start' and device.status == 0) or (action.type == 'stop' and device.status == 1)): if ((action.type == 'start' and device.status == 0) or (action.type == 'stop' and device.status == 1)):
self._logger.info(f'Device {device.mac_address_in_str} {action.type}')
self.log_verbose('Project' + self.name + 'Task ' + task.name + ' match_condition ' + condition.type + ' trigger_action ' + action.type + ' ' + str(action.target)) self.log_verbose('Project' + self.name + 'Task ' + task.name + ' match_condition ' + condition.type + ' trigger_action ' + action.type + ' ' + str(action.target))
task_info = task.get_task_info(action) task_info = task.get_task_info(action)
instruction_set = getattr(self._instruction_set, action.type, None) instruction_set = getattr(self._instruction_set, action.type, None)
@@ -232,26 +259,28 @@ class Project(threading.Thread):
self.log_verbose('file name ' + task_info['file_name']) self.log_verbose('file name ' + task_info['file_name'])
if instruction_set != None and self.get_device_parameter_set(action.target) != None: if instruction_set != None and self.get_device_parameter_set(action.target) != None:
if action.type == 'start':
self._count += 1
for instruction in instruction_set: for instruction in instruction_set:
print('instruction 1', device, instruction, datetime.now()) print('instruction 1', device, instruction, datetime.now())
args = list(map(lambda arg: task_info[arg], instruction['arguments'])) args = list(map(lambda arg: task_info[arg], instruction['arguments']))
target=getattr(device, instruction['method'])(*args) target=getattr(device, instruction['method'])(*args)
print('instruction 2', device, instruction, datetime.now()) print('instruction 2', device, instruction, datetime.now())
if action.type == 'start':
self._count += 1
delay_time += (time() - now) delay_time += (time() - now)
# check task not running then stop # check task not running then stop
if self.check_running_task_not_run() == True: if self.check_running_task_not_run() == True:
# self._logger.info(f'taskType {self._task_manager.running_task.name} {self._task_manager.running_task.type}')
if self._task_manager.running_task.type == '': if self._task_manager.running_task.type == '':
self._logger.info(f'Task {self._task_manager.running_task.name} stop')
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.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() self._task_manager.running_task.stop()
# check project done then close project # check project done then close project
if self.check_project_done() == True: if self.check_project_done() == True:
print('project stop at', datetime.now()) print('project stop at', datetime.now())
self.close() self.stop()
if self._time_interval - delay_time > 0: if self._time_interval - delay_time > 0:
sleep(self._time_interval - delay_time) sleep(self._time_interval - delay_time)
@@ -268,6 +297,7 @@ class Project(threading.Thread):
self._status = 2 self._status = 2
self._end_time = time() self._end_time = time()
self._stop_flag = True self._stop_flag = True
self._logger.info('Project ' + self.name + ' stop')
self.mqtt_thread.broadcast_command('project:project ' + str(self._name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]) self.mqtt_thread.broadcast_command('project:project ' + str(self._name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
def close(self): def close(self):
+15 -2
View File
@@ -56,6 +56,11 @@ class TaskManager():
def get_index_by_uuid(self, uuid): def get_index_by_uuid(self, uuid):
return next((i for i, x in enumerate(self.task_list) if x.uuid == uuid), None) return next((i for i, x in enumerate(self.task_list) if x.uuid == uuid), None)
def check_task_is_cycle_start(self, task):
for index, cycle in enumerate(self._cycle_list):
if cycle['range'][0] == task.uuid:
return index
def check_task_is_cycle_end(self, task): def check_task_is_cycle_end(self, task):
for index, cycle in enumerate(self._cycle_list): for index, cycle in enumerate(self._cycle_list):
@@ -121,6 +126,7 @@ class TaskManager():
if self._prev_task.status == 1: if self._prev_task.status == 1:
self._prev_task.stop() self._prev_task.stop()
# if reach cycle end, count < max, then go to cycle start # if reach cycle end, count < max, then go to cycle start
cycle_start_index = self.check_task_is_cycle_start(task)
cycle_index = self.check_task_is_cycle_end(task) cycle_index = self.check_task_is_cycle_end(task)
if cycle_index is None: if cycle_index is None:
# print('next', self._running_task.name, self._running_task.next) # print('next', self._running_task.name, self._running_task.next)
@@ -135,14 +141,21 @@ class TaskManager():
cycle = self._cycle_list[cycle_index] cycle = self._cycle_list[cycle_index]
if int(cycle['count']) < int(cycle['max']): if int(cycle['count']) < int(cycle['max']):
self._next_task.append(self.get_task_by_uuid(cycle['range'][0])) self._next_task.append(self.get_task_by_uuid(cycle['range'][0]))
cycle['count'] += 1 # cycle['count'] += 1
else: else:
for task_uuid in self._running_task.next: for task_uuid in self._running_task.next:
_task = next((task for task in self._task_list if task.uuid == task_uuid), None) _task = next((task for task in self._task_list if task.uuid == task_uuid), None)
if _task != None: if _task != None:
_task.reset() _task.reset()
self._next_task.append(_task) self._next_task.append(_task)
cycle['count'] = 1 # cycle['count'] = 1
if cycle_start_index != None:
cycle = self._cycle_list[cycle_start_index]
if int(cycle['count']) < int(cycle['max']):
cycle['count'] += 1
else:
cycle['count'] = 1
except RuntimeError as e: except RuntimeError as e:
print(e) print(e)
+1 -1
View File
@@ -553,7 +553,7 @@ class DataBaseProcess(Process):
return True return True
def project_insert(self, device_id, _data): def project_insert(self, device_id, _data):
sql_str = 'INSERT INTO "public"."meta_project_info" (' sql_str = 'INSERT INTO "public"."project_metas" ('
sql_set = [] sql_set = []
for item in _data.keys(): for item in _data.keys():
sql_str = sql_str + str(item) + ', ' sql_str = sql_str + str(item) + ', '
+5 -1
View File
@@ -34,7 +34,7 @@ from biopro.api.device import DeviceAPI
from biopro.project.project_manager import ProjectManager from biopro.project.project_manager import ProjectManager
from biopro.db.base import Base, Session, engine from biopro.db.base import Base, Session, engine
from biopro.db.project_report import ProjectReport from biopro.db.project_report import ProjectReport
from biopro.db.meta_project_info import MetaProjectInfo from biopro.db.project_meta import MetaProjectInfo
_RUNTIME_COMPILE = False _RUNTIME_COMPILE = False
@@ -1083,6 +1083,10 @@ class ControlServer(SocketServer, ControlServerAPI):
elif oper == InternalInstruction.PREDEFINED_DISABLE_CACHE: elif oper == InternalInstruction.PREDEFINED_DISABLE_CACHE:
return True return True
elif oper == InternalInstruction.PREDEFINED_IDLE:
device.status = 1
return True
else: else:
return False return False
-1
View File
@@ -158,7 +158,6 @@ class RecordingProcess(Process):
elif isinstance(decoder, EISZeroOneDataDecoder): elif isinstance(decoder, EISZeroOneDataDecoder):
# get amp_gain from meta file # get amp_gain from meta file
decoder._mode = self._meta_file.configuration.get_parameter('MODE') decoder._mode = self._meta_file.configuration.get_parameter('MODE')
decoder._ac_amp = self._meta_file.configuration.get_parameter('EIS_AC_AMP')
return decoder return decoder
File diff suppressed because it is too large Load Diff
@@ -6,7 +6,7 @@
"major_product_number": 0, "major_product_number": 0,
"minor_product_number": 3, "minor_product_number": 3,
"major_version_number": 1, "major_version_number": 1,
"minor_version_number": 0 "minor_version_number": 1
}, },
"constant": { "constant": {
"TIME_MAX": 100000, "TIME_MAX": 100000,
@@ -780,7 +780,7 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_VSCAN": { "CA_VOLT": {
"description": "Voltage of VScan", "description": "Voltage of VScan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
@@ -1301,7 +1301,7 @@
"curve_const_vscan": { "curve_const_vscan": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_VSCAN", "va": "CA_VOLT",
"pa": "ADC_LEVEL_I_15", "pa": "ADC_LEVEL_I_15",
"pb": "ADC_LEVEL_V_IN_15", "pb": "ADC_LEVEL_V_IN_15",
"pc": "DAC_LEVEL_V_OUT_15", "pc": "DAC_LEVEL_V_OUT_15",
@@ -33,6 +33,7 @@
0, 0,
1, 1,
1, 1,
1,
1 1
], ],
"domain": { "domain": {
@@ -617,7 +618,8 @@
"Open Circuit Potential", "Open Circuit Potential",
"Pulse Sensing", "Pulse Sensing",
"Differential Pulse Voltammetry (DPV)", "Differential Pulse Voltammetry (DPV)",
"Chronopotentiometry" "Chronopotentiometry",
"Idle"
] ]
}, },
"VOLT_ORIGIN": { "VOLT_ORIGIN": {
@@ -818,7 +820,7 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_VSCAN": { "CA_VOLT": {
"description": "Voltage of VScan", "description": "Voltage of VScan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
@@ -949,6 +951,7 @@
"10": "cali_dac_test", "10": "cali_dac_test",
"11": "cali_adc_test", "11": "cali_adc_test",
"12": "", "12": "",
"17": "idle",
"*": "start_data" "*": "start_data"
} }
} }
@@ -976,6 +979,9 @@
"VIS_STI", "VIS_STI",
"_cdr('1X;4X>ADC_VALUE_I')" "_cdr('1X;4X>ADC_VALUE_I')"
], ],
"idle": [
"_idle()"
],
"start_data": [ "start_data": [
"data_format", "data_format",
"_notify(True)", "_notify(True)",
@@ -1023,7 +1029,7 @@
"6": "const_current", "6": "const_current",
"7": "curve_cv3", "7": "curve_cv3",
"8": "curve_lsv", "8": "curve_lsv",
"9": "curve_const_vscan", "9": "curve_ca",
"13": "curve_ocp", "13": "curve_ocp",
"14": "curve_pulse_sensing", "14": "curve_pulse_sensing",
"15": "curve_dpv", "15": "curve_dpv",
@@ -1360,10 +1366,10 @@
"2B>pe" "2B>pe"
] ]
}, },
"curve_const_vscan": { "curve_ca": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_VSCAN", "va": "CA_VOLT",
"pa": "ADC_LEVEL_I_15", "pa": "ADC_LEVEL_I_15",
"pb": "ADC_LEVEL_V_IN_15", "pb": "ADC_LEVEL_V_IN_15",
"pc": "DAC_LEVEL_V_OUT_15", "pc": "DAC_LEVEL_V_OUT_15",
@@ -1,12 +1,12 @@
{ {
"name": "Elite_EDC_1.5r2", "name": "Elite_EDC_1.5re",
"version": "1.2.30", "version": "1.2.30",
"match_rule": { "match_rule": {
"local_name_pattern": "Elite.*", "local_name_pattern": "Elite.*",
"major_product_number": 0, "major_product_number": 0,
"minor_product_number": 2, "minor_product_number": 2,
"major_version_number": 1, "major_version_number": 1,
"minor_version_number": 8 "minor_version_number": 7
}, },
"constant": { "constant": {
"TIME_MAX": 100000, "TIME_MAX": 100000,
@@ -33,6 +33,7 @@
0, 0,
1, 1,
1, 1,
1,
1 1
], ],
"domain": { "domain": {
@@ -617,7 +618,8 @@
"Open Circuit Potential", "Open Circuit Potential",
"Pulse Sensing", "Pulse Sensing",
"Differential Pulse Voltammetry (DPV)", "Differential Pulse Voltammetry (DPV)",
"Chronopotentiometry" "Chronopotentiometry",
"Idle"
] ]
}, },
"VOLT_ORIGIN": { "VOLT_ORIGIN": {
@@ -818,7 +820,7 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_VSCAN": { "CA_VOLT": {
"description": "Voltage of VScan", "description": "Voltage of VScan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
@@ -949,6 +951,7 @@
"10": "cali_dac_test", "10": "cali_dac_test",
"11": "cali_adc_test", "11": "cali_adc_test",
"12": "", "12": "",
"17": "idle",
"*": "start_data" "*": "start_data"
} }
} }
@@ -976,6 +979,9 @@
"VIS_STI", "VIS_STI",
"_cdr('1X;4X>ADC_VALUE_I')" "_cdr('1X;4X>ADC_VALUE_I')"
], ],
"idle": [
"_idle()"
],
"start_data": [ "start_data": [
"data_format", "data_format",
"_notify(True)", "_notify(True)",
@@ -1023,7 +1029,7 @@
"6": "const_current", "6": "const_current",
"7": "curve_cv3", "7": "curve_cv3",
"8": "curve_lsv", "8": "curve_lsv",
"9": "curve_const_vscan", "9": "curve_ca",
"13": "curve_ocp", "13": "curve_ocp",
"14": "curve_pulse_sensing", "14": "curve_pulse_sensing",
"15": "curve_dpv", "15": "curve_dpv",
@@ -1360,10 +1366,10 @@
"2B>pe" "2B>pe"
] ]
}, },
"curve_const_vscan": { "curve_ca": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_VSCAN", "va": "CA_VOLT",
"pa": "ADC_LEVEL_I_15", "pa": "ADC_LEVEL_I_15",
"pb": "ADC_LEVEL_V_IN_15", "pb": "ADC_LEVEL_V_IN_15",
"pc": "DAC_LEVEL_V_OUT_15", "pc": "DAC_LEVEL_V_OUT_15",
@@ -820,7 +820,7 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_VSCAN": { "CA_VOLT": {
"description": "Voltage of VScan", "description": "Voltage of VScan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
@@ -951,7 +951,7 @@
"10": "cali_dac_test", "10": "cali_dac_test",
"11": "cali_adc_test", "11": "cali_adc_test",
"12": "", "12": "",
"17": "start_data_with_empty_ins", "17": "idle",
"*": "start_data" "*": "start_data"
} }
} }
@@ -979,10 +979,8 @@
"VIS_STI", "VIS_STI",
"_cdr('1X;4X>ADC_VALUE_I')" "_cdr('1X;4X>ADC_VALUE_I')"
], ],
"start_data_with_empty_ins": [ "idle": [
"data_format", "_idle()"
"_sync(True)",
"VIS_STI"
], ],
"start_data": [ "start_data": [
"data_format", "data_format",
@@ -1031,7 +1029,7 @@
"6": "const_current", "6": "const_current",
"7": "curve_cv3", "7": "curve_cv3",
"8": "curve_lsv", "8": "curve_lsv",
"9": "curve_const_vscan", "9": "curve_ca",
"13": "curve_ocp", "13": "curve_ocp",
"14": "curve_pulse_sensing", "14": "curve_pulse_sensing",
"15": "curve_dpv", "15": "curve_dpv",
@@ -1368,10 +1366,10 @@
"2B>pe" "2B>pe"
] ]
}, },
"curve_const_vscan": { "curve_ca": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_VSCAN", "va": "CA_VOLT",
"pa": "ADC_LEVEL_I_15", "pa": "ADC_LEVEL_I_15",
"pb": "ADC_LEVEL_V_IN_15", "pb": "ADC_LEVEL_V_IN_15",
"pc": "DAC_LEVEL_V_OUT_15", "pc": "DAC_LEVEL_V_OUT_15",
@@ -34,6 +34,7 @@
0, 0,
1, 1,
1, 1,
1,
1 1
], ],
"domain": { "domain": {
@@ -98,7 +99,8 @@
"V-T Graph", "V-T Graph",
"R-T Graph", "R-T Graph",
"EIS constant frequency", "EIS constant frequency",
"Dev Mode" "Dev Mode",
"Idle"
] ]
}, },
"GENERAL_HS_RTIA": { "GENERAL_HS_RTIA": {
@@ -141,7 +143,7 @@
"EIS_AC_AMP": { "EIS_AC_AMP": {
"description": "AC Amplitude", "description": "AC Amplitude",
"record_meta": true, "record_meta": true,
"initial": 25, "initial": 26,
"domain": [ "domain": [
2048 2048
] ]
@@ -213,7 +215,7 @@
"CF_AC_AMP": { "CF_AC_AMP": {
"description": "AC Amplitude", "description": "AC Amplitude",
"record_meta": true, "record_meta": true,
"initial": 25, "initial": 26,
"domain": [ "domain": [
2048 2048
] ]
@@ -370,10 +372,14 @@
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"7": "idle",
"*": "start_data" "*": "start_data"
} }
} }
], ],
"idle": [
"_idle()"
],
"start_data": [ "start_data": [
"data_format_cali", "data_format_cali",
"_notify(True)", "_notify(True)",
@@ -34,6 +34,7 @@
0, 0,
1, 1,
1, 1,
1,
1 1
], ],
"domain": { "domain": {
@@ -98,7 +99,8 @@
"V-T Graph", "V-T Graph",
"R-T Graph", "R-T Graph",
"EIS constant frequency", "EIS constant frequency",
"Dev Mode" "Dev Mode",
"Idle"
] ]
}, },
"GENERAL_HS_RTIA": { "GENERAL_HS_RTIA": {
@@ -141,7 +143,7 @@
"EIS_AC_AMP": { "EIS_AC_AMP": {
"description": "AC Amplitude", "description": "AC Amplitude",
"record_meta": true, "record_meta": true,
"initial": 25, "initial": 26,
"domain": [ "domain": [
2048 2048
] ]
@@ -213,7 +215,7 @@
"CF_AC_AMP": { "CF_AC_AMP": {
"description": "AC Amplitude", "description": "AC Amplitude",
"record_meta": true, "record_meta": true,
"initial": 25, "initial": 26,
"domain": [ "domain": [
2048 2048
] ]
@@ -370,10 +372,14 @@
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"7": "idle",
"*": "start_data" "*": "start_data"
} }
} }
], ],
"idle": [
"_idle()"
],
"start_data": [ "start_data": [
"data_format_cali", "data_format_cali",
"_notify(True)", "_notify(True)",
@@ -34,6 +34,7 @@
0, 0,
1, 1,
1, 1,
1,
1 1
], ],
"domain": { "domain": {
@@ -98,7 +99,8 @@
"V-T Graph", "V-T Graph",
"R-T Graph", "R-T Graph",
"EIS constant frequency", "EIS constant frequency",
"Dev Mode" "Dev Mode",
"Idle"
] ]
}, },
"GENERAL_HS_RTIA": { "GENERAL_HS_RTIA": {
@@ -141,7 +143,7 @@
"EIS_AC_AMP": { "EIS_AC_AMP": {
"description": "AC Amplitude", "description": "AC Amplitude",
"record_meta": true, "record_meta": true,
"initial": 25, "initial": 26,
"domain": [ "domain": [
2048 2048
] ]
@@ -213,7 +215,7 @@
"CF_AC_AMP": { "CF_AC_AMP": {
"description": "AC Amplitude", "description": "AC Amplitude",
"record_meta": true, "record_meta": true,
"initial": 25, "initial": 26,
"domain": [ "domain": [
2048 2048
] ]
@@ -370,10 +372,14 @@
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"7": "idle",
"*": "start_data" "*": "start_data"
} }
} }
], ],
"idle": [
"_idle()"
],
"start_data": [ "start_data": [
"data_format_cali", "data_format_cali",
"_notify(True)", "_notify(True)",
@@ -2,16 +2,27 @@
"name": "Elite_TRIG_0.1", "name": "Elite_TRIG_0.1",
"version": "1.2.30", "version": "1.2.30",
"match_rule": { "match_rule": {
"local_name_pattern": "Trigger.*", "local_name_pattern": "Elite.*",
"major_product_number": 0, "major_product_number": 0,
"minor_product_number": 5, "minor_product_number": 5,
"major_version_number": 1, "major_version_number": 1,
"minor_version_number": 0 "minor_version_number": 0
}, },
"constant": { "constant": {
"TIME_MAX": 100000
}, },
"parameters": { "parameters": {
"TIME_DURATION": {
"description": "timer",
"record_meta": true,
"initial": 0,
"domain": [
"TIME_MAX"
],
"value": {
"expression": "VALUE"
}
},
"ACC_a_out0": { "ACC_a_out0": {
"description": "Switch of analog current channel 1", "description": "Switch of analog current channel 1",
"record_meta": true, "record_meta": true,
@@ -142,7 +153,8 @@
"description": "working mode", "description": "working mode",
"record_meta": true, "record_meta": true,
"value": [ "value": [
"Analog Current Control (ACC)" "Analog Current Control (ACC)",
"Idle"
] ]
}, },
+15
View File
@@ -7,8 +7,23 @@ sudo apt-get install python3-numpy
# install python module SQLAlchemy # install python module SQLAlchemy
pip3 install SQLAlchemy pip3 install SQLAlchemy
# create folder to save project logger
mkdir -p /home/pi/logger/project
# add column cycle in projects # add column cycle in projects
sudo su -c "psql -d postgres -c \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS cycle JSONB;\"" postgres sudo su -c "psql -d postgres -c \"ALTER TABLE projects ADD COLUMN IF NOT EXISTS cycle JSONB;\"" postgres
# add column project in recording_data_metas # add column project in recording_data_metas
sudo su -c "psql -d postgres -c \"ALTER TABLE recording_data_metas ADD COLUMN IF NOT EXISTS project Int4;\"" postgres sudo su -c "psql -d postgres -c \"ALTER TABLE recording_data_metas ADD COLUMN IF NOT EXISTS project Int4;\"" postgres
# remove default controller info
sudo su -c "psql -d postgres -c \"DELETE FROM controllers WHERE name='WTP_NONE';\"" postgres
# change table name from meta_project_info to project_metas
sudo su -c "psql -d postgres -c \"ALTER TABLE IF EXISTS meta_project_info RENAME TO project_metas;\"" postgres
# change table name from project_report to project_reports
sudo su -c "psql -d postgres -c \"ALTER TABLE IF EXISTS project_report RENAME TO project_reports;\"" postgres
# change table project_meta column cycle to type jsonb
sudo su -c "psql -d postgres -c \"ALTER TABLE project_metas ALTER COLUMN cycle type jsonb USING (cycle::jsonb);\"" postgres