Compare commits

...

33 Commits

Author SHA1 Message Date
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
peterlu14 c084f29f06 [update] add script to auto update db columns & python pacakges 2022-11-16 16:27:12 +08:00
peterlu14 130d260add Update README.md 2022-11-16 06:30:19 +00:00
peterlu14 575d5d8af1 [update] rolloff_cali from cutoff_freq/1e5 to hsrtia_c[gain] 2022-11-16 13:37:51 +08:00
peterlu14 fbf6297047 Merge remote-tracking branch 'origin/dev/update_eis_parameter' into dev/scheduler_cf 2022-11-16 13:34:17 +08:00
Roy c540013d19 [update] new cf mode 2022-11-16 11:51:15 +08:00
Roy 7f0b00a323 [update] update highz instruction 2022-11-15 17:28:51 +08:00
Roy 4828c85668 [update] clean up eis parameter 2022-11-15 16:08:43 +08:00
Roy 4ce9fe5b8d [update] remove ADC_LEVEL_V_IN_15 parameter 2022-11-15 16:08:09 +08:00
Roy d74f09254e [update] update high z status 2022-11-15 16:07:58 +08:00
Roy 79ecff69cc [update] update VT_MEASURE_VIN_RANGE parameter 2022-11-15 16:03:06 +08:00
Roy df45126ead [update] update CA_VOLT parameter 2022-11-15 16:00:53 +08:00
Roy 9fade3469a [update] update CV_SCAN_RATE parameter 2022-11-15 15:51:42 +08:00
Roy a77331176c [update] update CV_E2 parameter 2022-11-15 15:47:49 +08:00
Roy 8f98337267 [update] update CV_E1 parameter 2022-11-15 15:44:42 +08:00
Roy 205d39cb11 [update] update CV_E_INITIAL parameter 2022-11-15 15:41:38 +08:00
Roy a5ea3243fa [update] new lprtia function 2022-11-15 15:39:31 +08:00
peterlu14 2edf28c7ba Merge branch 'release/v1.6.8/sqlAlchemy+projectTable' into dev/scheduler_idle_mode 2022-11-15 15:35:06 +08:00
peterlu14 5531dcc0f0 [update] add MetaProjectInfo table 2022-11-15 15:34:27 +08:00
peterlu14 b20d46daa8 [update] add new mode idle & project stop condition change 2022-11-15 13:23:49 +08:00
peterlu14 c0bb567bf7 [update] binding project info with meta file & create running project table with sqlAlchemy 2022-11-02 11:12:55 +08:00
23 changed files with 1066 additions and 409 deletions
+1
View File
@@ -7,3 +7,4 @@
/.vscode /.vscode
/media /media
python/biopro/sever/_identify.py python/biopro/sever/_identify.py
*.log
+56 -27
View File
@@ -78,6 +78,8 @@ add ssh.txt in boot folder
###### Install dependencies ###### Install dependencies
sudo apt-get install vim git wiringpi build-essential libi2c-dev i2c-tools python-dev libffi-dev python3-pip postgresql npm sudo apt-get install vim git wiringpi build-essential libi2c-dev i2c-tools python-dev libffi-dev python3-pip postgresql npm
sudo apt-get install libatlas-base-dev
sudo apt-get install python3-numpy
###### wiringpi conflict ###### wiringpi conflict
need to install wiringpi: https://github.com/WiringPi/WiringPi need to install wiringpi: https://github.com/WiringPi/WiringPi
@@ -94,6 +96,7 @@ git clone https://gitlab.com/wisetop/controller/wisetopdataserver.git
``` ```
cd ~/wisetopdataserver cd ~/wisetopdataserver
pip3 install -r requirements.txt pip3 install -r requirements.txt
pip3 install SQLAlchemy
``` ```
##### Packages version ##### Packages version
``` ```
@@ -155,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
@@ -195,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:
``` ```
@@ -210,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:
@@ -233,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:
``` ```
@@ -251,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
@@ -286,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
@@ -314,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
@@ -358,3 +363,27 @@ $sudo vim ./sites-available/000-default.conf
##### raspberry website document: ##### raspberry website document:
> https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md > https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md
# 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]
add python package SQLAlchemy
add new column project(int4) in postgresSQL table recording_meta_datas
add new postgresSQL table project_report
add new postgresSQL table meta_project_info
[2022.10.18]
socektTimeout from 1s -> 5s
socketListen from 3 -> 20
[2022.09.30]
add new column cycle(jsonb) in postgresSQL table projects
[2022.9.28]
add python package numpy
+5 -3
View File
@@ -87,7 +87,8 @@ class DataAPI(metaclass=abc.ABCMeta):
def update_device_configuration(self, def update_device_configuration(self,
device: Union[int, Device], device: Union[int, Device],
meta_file: Union[str, Path, RecordingMetaFile], meta_file: Union[str, Path, RecordingMetaFile],
data_format: Union[AnyStr, DataDecodeFormat]): data_format: Union[AnyStr, DataDecodeFormat],
project_info: str):
"""set device configuration. """set device configuration.
:param device: device ID :param device: device ID
@@ -154,7 +155,8 @@ class DataClient(SocketClient, DataAPI, metaclass=SocketClientMacro(DataAPI)):
def update_device_configuration(self, def update_device_configuration(self,
device: Union[int, Device], device: Union[int, Device],
meta_file: Union[str, Path, RecordingMetaFile], meta_file: Union[str, Path, RecordingMetaFile],
data_format: Union[AnyStr, DataDecodeFormat]): data_format: Union[AnyStr, DataDecodeFormat],
project_info: str):
# meta file # meta file
if isinstance(meta_file, str): if isinstance(meta_file, str):
@@ -186,7 +188,7 @@ class DataClient(SocketClient, DataAPI, metaclass=SocketClientMacro(DataAPI)):
raise TypeError('not a data decode format : ' + data_format.__class__.__name__) raise TypeError('not a data decode format : ' + data_format.__class__.__name__)
# send # send
self.send_command('update_device_configuration', device, meta_file, data_format) self.send_command('update_device_configuration', device, meta_file, data_format, project_info)
def is_sync(self, device: Union[None, int, Device] = None) -> bool: def is_sync(self, device: Union[None, int, Device] = None) -> bool:
if isinstance(device, Device): if isinstance(device, Device):
+10
View File
@@ -0,0 +1,10 @@
from sqlalchemy import create_engine
# from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, declarative_base
SQLALCHEMY_DATABASE_URL = "postgresql://biopro:BioProControlBox@127.0.0.1:5432/postgres"
engine = create_engine(SQLALCHEMY_DATABASE_URL)
Session = sessionmaker(bind=engine)
Base = declarative_base()
+21
View File
@@ -0,0 +1,21 @@
from sqlalchemy import Table, Column, String, MetaData, ForeignKey, JSON
from sqlalchemy.sql import select, func
from sqlalchemy.types import Integer, BigInteger, String, Boolean, TIMESTAMP, Numeric
from sqlalchemy.dialects.postgresql import JSONB
from .base import Base
class MetaProjectInfo(Base):
__tablename__ = "project_metas"
id = Column(Integer, primary_key=True)
project = Column(String(36))
cycle = Column(JSONB)
task = Column(JSONB)
serial_number = Column(Integer)
deleted = Column(Boolean, default = False)
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
# def __repr__(self):
# return f"User(id={self.id!r}, name={self.name!r}, fullname={self.task!r})"
+24
View File
@@ -0,0 +1,24 @@
from sqlalchemy import Table, Column, String, MetaData, ForeignKey, JSON
from sqlalchemy.sql import select, func
from sqlalchemy.types import Integer, BigInteger, String, Boolean, TIMESTAMP, Numeric
from sqlalchemy.dialects.postgresql import JSONB
from .base import Base
class ProjectReport(Base):
__tablename__ = "project_reports"
id = Column(Integer, primary_key=True)
name = Column(String)
desc = Column(String)
task = Column(JSONB)
cycle = Column(JSONB)
device = Column(JSONB)
uuid = Column(String(36))
user_auth = Column(JSONB)
deleted = Column(Boolean, default = False)
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
# def __repr__(self):
# return f"User(id={self.id!r}, name={self.name!r}, fullname={self.task!r})"
+23 -12
View File
@@ -574,20 +574,23 @@ class DeviceManager(MasterDevice, Synchronized):
:param device: device ID or response info :param device: device ID or response info
:return: CompletedDevice, None if not found. :return: CompletedDevice, None if not found.
""" """
if isinstance(device, int): try:
for slave in self._device: if isinstance(device, int):
if slave.device_id == device: for slave in self._device:
return slave if slave.device_id == device:
return slave
elif isinstance(device, str): elif isinstance(device, str):
for slave in self._device: for slave in self._device:
if ':'.join('{:02x}'.format(b) for b in slave.mac_address) == device.lower(): if ':'.join('{:02x}'.format(b) for b in slave.mac_address) == device.lower():
return slave return slave
elif isinstance(device, DeviceInfo): elif isinstance(device, DeviceInfo):
for slave in self._device: for slave in self._device:
if device.match(slave): if device.match(slave):
return slave return slave
except BaseException as e:
self.log_error('device not found', str(device))
return None return None
@@ -829,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:
@@ -848,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)
+60 -46
View File
@@ -1360,7 +1360,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
@@ -1488,14 +1487,14 @@ class EISZeroOneDataDecoder(RecDataDecoder):
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[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] phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
# print('cutoff_freq', cutoff_freq) print('cutoff_freq', cutoff_freq)
# print('hsrtia_a', hsrtia_a) print('hsrtia_a', hsrtia_a)
# print('hsrtia_b', hsrtia_b) print('hsrtia_b', hsrtia_b)
# print('hsrtia_c', hsrtia_c) print('hsrtia_c', hsrtia_c)
# print('phase_coeff') print('phase_coeff')
# print(phase_coeff) print(phase_coeff)
# print('phase_offset') print('phase_offset')
# print(phase_offset) print(phase_offset)
cali_table.append((cutoff_freq, phase_coeff, phase_offset, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d)) cali_table.append((cutoff_freq, phase_coeff, phase_offset, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d))
@@ -1528,8 +1527,13 @@ class EISZeroOneDataDecoder(RecDataDecoder):
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] # Amp[uV]
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
@@ -1537,7 +1541,7 @@ class EISZeroOneDataDecoder(RecDataDecoder):
return None return None
if time_stamp != 0 and self._start_return_data == True: if time_stamp != 0 and self._start_return_data == True:
if (self._mode == 0): if (self._mode == 0 or self._mode == 5):
time_stamp, delta, ret_get_time_stamp = self.eis_get_time_stamp(time_stamp) time_stamp, delta, ret_get_time_stamp = self.eis_get_time_stamp(time_stamp)
else: else:
time_stamp, delta, ret_get_time_stamp = self.get_time_stamp(time_stamp) time_stamp, delta, ret_get_time_stamp = self.get_time_stamp(time_stamp)
@@ -1546,22 +1550,22 @@ class EISZeroOneDataDecoder(RecDataDecoder):
print("error timeStamp full data:", list(data), datetime.now(), '\n') print("error timeStamp full data:", list(data), datetime.now(), '\n')
return None return None
else: else:
if self.cali_coeff is not None and self._mode == 0: if self.cali_coeff is not None and (self._mode == 0 or self._mode == 5):
hsrtia_a = [] hsrtia_a = []
hsrtia_b = [] hsrtia_b = []
hsrtia_c = [] hsrtia_c = []
hsrtia_d = [] hsrtia_d = []
cutoff_freq, phase_coeff, phase_offset, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d = self.cali_coeff[0] 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):
img = ch1 img = ch1
real = ch2 real = ch2
freq = ch3 freq = ch3
fre_idx = 0 fre_idx = 0
voltage_amp = round(ch4 / 1000) # Amp[mV]
rolloff_cali = cutoff_freq/1e5 # 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)
# if (gain == 3): # if (gain == 3):
@@ -1572,15 +1576,9 @@ class EISZeroOneDataDecoder(RecDataDecoder):
# current = voltage_mag ** 2 * hsrtia_a[gain] + voltage_mag * hsrtia_b[gain] + hsrtia_c[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
@@ -1611,25 +1609,33 @@ class EISZeroOneDataDecoder(RecDataDecoder):
# phase = self._last_phase + diff # phase = self._last_phase + diff
# self._last_phase = phase # self._last_phase = phase
imag_after_cal = impedance * math.sin(round(phase) * math.pi / 180) imag_after_cal = impedance * math.sin(phase * math.pi / 180)
real_after_cal = impedance * math.cos(round(phase) * math.pi / 180) real_after_cal = impedance * math.cos(phase * math.pi / 180)
if self._show_data: if self._show_data:
if (self._mode == 0): 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(ch1), #raw_img
'|', '{:6}'.format(ch2), '|', '{:5}'.format(ch2), #raw_real
'|', '{:8}'.format(ch3 / 100), '|', '{:8}'.format(ch3 * 10), '[mHz]', #Frequency [mHz]
'|', '{:6}'.format(round(voltage_mag)), '|', '{:5}'.format(cycle_number), #cycle
'|', '{: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)), '[Ohm]', #Impedance [Ohm]
'|', '{:5}'.format(round(phase, 1)), '|', '{:5}'.format(round(phase*1000)), '[mdegree]', #Phase [millidegree]
'|', '{:5}'.format(round(current, 3)), '|', '{:5}'.format(round(current)), '[nA]', #Current [nA]
'|', '{:1}'.format(gain), '|', '{:1}'.format(gain), #gain
'|', '{:1}'.format(finishMode), '|', '{:1}'.format(finishMode), #finishMode
'@', str(self.device), '|', flush = True) '@', str(self.device), '|', flush = True)
print('|', '{:10}'.format(time_stamp),
'|', '{:5}'.format(delta),
'|', '{:5}'.format(notify_one),
'|', '{:5}'.format(notify_two),
'|', '{:5}'.format(notify_three),
'|', '{:5}'.format(voltage_amp), #amp[mV]
'|', flush = True)
pass pass
else: else:
print('|', '{:10}'.format(time_stamp), print('|', '{:10}'.format(time_stamp),
@@ -1650,17 +1656,25 @@ 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): #EIS Mode if self._mode == 0 or self._mode == 5: #EIS Mode
ret.append_data(0, ch1) #Raw Imag ret.append_data(0, ch1) #raw_img
ret.append_data(1, ch2) #Raw Real ret.append_data(1, ch2) #raw_real
ret.append_data(2, ch3 * 10) #Frequency [mHz] ret.append_data(2, ch3 * 10) #Frequency [mHz]
ret.append_data(3, cycle_number) ret.append_data(3, cycle_number) #cycle
ret.append_data(4, round(imag_after_cal)) #Z_imag [Ohm] ret.append_data(4, 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)) #Impedance [Ohm]
ret.append_data(7, round(phase)) #Phase [degree] ret.append_data(7, round(phase*1000)) #Phase [millidegree]
ret.append_data(8, round(current)) #Current [nA] ret.append_data(8, round(current)) #Current [nA]
ret.append_data(9, gain) #Gain Level ret.append_data(9, gain) #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) #amp[mV]
else: #CV Mode else: #CV Mode
ret.append_data(0, ch1) #Iin [nA] ret.append_data(0, ch1) #Iin [nA]
+1 -1
View File
@@ -738,7 +738,7 @@ class DeviceCommonInstruction:
elif instruction == cls.START: elif instruction == cls.START:
return '_data_format("TDC4VAF2")', '_notify(True)', 'VIS_STI', '_sync(True)' return '_data_format("TDC4VAF2")', '_notify(True)', 'VIS_STI', '_sync(True)'
elif instruction == cls.INTERRUPT: elif instruction == cls.INTERRUPT:
return '_sync(False)', '_notify(False)', 'VIS_INT' return '_notify(False)', 'VIS_INT', '_sync(False)'
elif instruction == cls.CLOSE: elif instruction == cls.CLOSE:
return '_sync(False)', '_notify(False)', 'VIS_INT' return '_sync(False)', '_notify(False)', 'VIS_INT'
elif instruction == cls.CALL: elif instruction == cls.CALL:
+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')
+13 -2
View File
@@ -968,7 +968,7 @@ class CompletedDevice(Device):
""" """
__slots__ = ('_master', '_device_id', '_device', '_library', '_context', __slots__ = ('_master', '_device_id', '_device', '_library', '_context',
'_parameter', '_configuration', '_lock', '_feature_mask', '_parameter', '_configuration', '_lock', '_feature_mask',
'_cache_battery', '_cache_battery_timestamp', '_coeff', '_status') '_cache_battery', '_cache_battery_timestamp', '_coeff', '_status', '_occupied_by_project')
def __init__(self, master: MasterDevice, library: DeviceLibrary, device_id: int, device: Device): def __init__(self, master: MasterDevice, library: DeviceLibrary, device_id: int, device: Device):
""" """
@@ -986,6 +986,8 @@ class CompletedDevice(Device):
# device status ( 0: idle, 1: working, 2: error, 3: power off) # device status ( 0: idle, 1: working, 2: error, 3: power off)
self._status = 0 self._status = 0
# device be occupied by project
self._occupied_by_project = None
# context # context
s1 = library.constant s1 = library.constant
@@ -1082,6 +1084,14 @@ class CompletedDevice(Device):
def status(self, new_status): def status(self, new_status):
self._status = new_status self._status = new_status
@property
def occupied_by_project(self) -> str:
return self._occupied_by_project
@occupied_by_project.setter
def occupied_by_project(self, new_occupied_by_project):
self._occupied_by_project = new_occupied_by_project
# device parameter getter/setter # device parameter getter/setter
def parameters(self) -> List[str]: def parameters(self) -> List[str]:
@@ -1131,7 +1141,7 @@ class CompletedDevice(Device):
# raise RuntimeError('illegal parameter value : ' + value) from e # raise RuntimeError('illegal parameter value : ' + value) from e
else: else:
if name == 'MODE': if name == 'MODE':
if self.library_name.startswith('Elite_EDC'): if self.library_name.startswith('Elite_EDC') or 'EIS' in self.library_name:
self.set_parameter('CTRL_HIGH_Z_15', self.get_parameter('HIGHZ_TABLE')[value]) self.set_parameter('CTRL_HIGH_Z_15', self.get_parameter('HIGHZ_TABLE')[value])
self.set_parameter('TIME_DURATION', 0) self.set_parameter('TIME_DURATION', 0)
@@ -1303,6 +1313,7 @@ class CompletedDevice(Device):
'recording_file_name': self.recording_file_name, 'recording_file_name': self.recording_file_name,
'library_name': self._library.name, 'library_name': self._library.name,
'library_version': str(self._library.version), 'library_version': str(self._library.version),
'occupied_by_project': self._occupied_by_project,
'configuration': self.configuration.as_json(list_hide=True), 'configuration': self.configuration.as_json(list_hide=True),
} }
+60 -6
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():
@@ -66,6 +77,7 @@ class Project(threading.Thread):
for device in device_list: for device in device_list:
mac_address = device_list[device]['pair'] mac_address = device_list[device]['pair']
complete_device = self._device_manager.get_device(mac_address) complete_device = self._device_manager.get_device(mac_address)
complete_device.occupied_by_project = self._uuid
self._complete_device[device] = complete_device self._complete_device[device] = complete_device
@property @property
@@ -136,9 +148,23 @@ class Project(threading.Thread):
def running_task(self): def running_task(self):
return self._task_manager.running_task return self._task_manager.running_task
def get_device_parameter_set(self, device_address):
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)
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])
@@ -161,12 +187,17 @@ class Project(threading.Thread):
for condition in match_condition_list: for condition in match_condition_list:
match_action_list = task.get_match_action(condition.id) match_action_list = task.get_match_action(condition.id)
print('match_action_list', match_action_list, match_action_list)
for action in match_action_list: for action in match_action_list:
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':
@@ -175,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])
@@ -184,12 +216,15 @@ class Project(threading.Thread):
elif action.type == 'idle': elif action.type == 'idle':
self._task_manager.running_task.stop() self._task_manager.running_task.stop()
# elif action.type == 'stop':
# self._task_manager.running_task.stop()
instruction_set = None instruction_set = None
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)
@@ -223,27 +258,29 @@ class Project(threading.Thread):
task_info['file_name'] += '#' + str(cycle_info['name']) + '-' + str(cycle_info['count']) task_info['file_name'] += '#' + str(cycle_info['name']) + '-' + str(cycle_info['count'])
self.log_verbose('file name ' + task_info['file_name']) self.log_verbose('file name ' + task_info['file_name'])
if instruction_set != None and len(task.parameter_set) > 0: 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)
@@ -253,14 +290,19 @@ class Project(threading.Thread):
pass pass
def stop(self): def stop(self):
for device in self._complete_device:
self._complete_device[device].occupied_by_project = None
self._task_manager.running_task.stop() self._task_manager.running_task.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._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):
for device in self._complete_device:
self._complete_device[device].occupied_by_project = None
self._status = 2 self._status = 2
self._end_time = time() self._end_time = time()
self._stop_flag = True self._stop_flag = True
@@ -319,6 +361,18 @@ class Project(threading.Thread):
'device': self._device, 'device': self._device,
'task': self.task_list, 'task': self.task_list,
'running_task': running_task, 'running_task': running_task,
'cycle': self._cycle 'cycle': self._cycle,
'count': self._count,
}
return data
def info_pass_data_server(self):
if self._task_manager.running_task is not None:
running_task = self._task_manager.running_task.as_json()
data = {
'project': self._uuid,
'task': running_task,
'cycle': self._cycle,
'serial_number': self._count,
} }
return data return data
+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)
+15 -4
View File
@@ -118,7 +118,7 @@ class RecordingMetaFile(JsonSerialize):
'_dirty', '_last_modify_time', '_file_size_cache', '_dirty', '_last_modify_time', '_file_size_cache',
'_recording_file_ch', '_recording_sub_file', '_size', '_recording_file_ch', '_recording_sub_file', '_size',
'_parameter', '_parent', '_recording_file_name', '_recording_sub_mini', '_recording_mini_ch', '_parameter', '_parent', '_recording_file_name', '_recording_sub_mini', '_recording_mini_ch',
'_raw_serial_number', '_mini_serial_number', '_device_id') '_raw_serial_number', '_mini_serial_number', '_device_id', '_project_id')
def __init__(self, filepath: Union[str, Path], data_format: bytes = None, id_db = 0, database = None): def __init__(self, filepath: Union[str, Path], data_format: bytes = None, id_db = 0, database = None):
if isinstance(filepath, str): if isinstance(filepath, str):
@@ -153,6 +153,7 @@ class RecordingMetaFile(JsonSerialize):
self._parent = '' self._parent = ''
self._recording_file_name = '' self._recording_file_name = ''
self._device_id = -1 self._device_id = -1
self._project_id = None
# recording parameter # recording parameter
self._configuration = None self._configuration = None
@@ -297,6 +298,7 @@ class RecordingMetaFile(JsonSerialize):
'uuid': str(self._file_uuid), 'uuid': str(self._file_uuid),
'data_format': 'rec', 'data_format': 'rec',
'device': self._device, 'device': self._device,
'project': self._project_id,
} }
if len(self._parent) > 0: if len(self._parent) > 0:
@@ -462,7 +464,7 @@ class RecordingMetaFile(JsonSerialize):
def parameter(self) -> str: def parameter(self) -> str:
return self._parameter return self._parameter
@device.setter @parameter.setter
def parameter(self, parameter): def parameter(self, parameter):
self._parameter = parameter self._parameter = parameter
return None return None
@@ -471,7 +473,7 @@ class RecordingMetaFile(JsonSerialize):
def parent(self) -> str: def parent(self) -> str:
return self._parent return self._parent
@device.setter @parent.setter
def parent(self, parent): def parent(self, parent):
self._parent = parent self._parent = parent
@@ -479,7 +481,7 @@ class RecordingMetaFile(JsonSerialize):
def recording_file_name(self) -> str: def recording_file_name(self) -> str:
return self._recording_file_name return self._recording_file_name
@device.setter @recording_file_name.setter
def recording_file_name(self, recording_file_name): def recording_file_name(self, recording_file_name):
self._recording_file_name = recording_file_name self._recording_file_name = recording_file_name
@@ -492,6 +494,15 @@ class RecordingMetaFile(JsonSerialize):
self._configuration = conf self._configuration = conf
self._dirty = True self._dirty = True
return None return None
@property
def project_id(self) -> int:
return self._project_id
@project_id.setter
def project_id(self, project: int):
self._project_id = project
return None
@property @property
def channels(self) -> List[int]: def channels(self) -> List[int]:
+18 -10
View File
@@ -4,7 +4,6 @@ from time import time, sleep
from typing import Iterable from typing import Iterable
from datetime import datetime from datetime import datetime
import gc import gc
import base64 import base64
from biopro.data import * from biopro.data import *
@@ -27,7 +26,6 @@ from .mqtt import MqttDataMessageHandler, MqttThread
from .database import DataBaseProcess from .database import DataBaseProcess
from .recording import RecordingProcess from .recording import RecordingProcess
from multiprocessing import Queue from multiprocessing import Queue
import queue
from json import loads as json_parse, dumps as _json_stringify from json import loads as json_parse, dumps as _json_stringify
import json import json
@@ -317,7 +315,8 @@ class DataServer(SocketServer, DataAPI):
def update_device_configuration(self, def update_device_configuration(self,
device: str, device: str,
meta_file: Union[str, Path, RecordingMetaFile], meta_file: Union[str, Path, RecordingMetaFile],
data_format: Union[AnyStr, DataDecodeFormat]): data_format: Union[AnyStr, DataDecodeFormat],
project_info: str):
# meta file # meta file
device_id = -1 device_id = -1
@@ -345,6 +344,8 @@ class DataServer(SocketServer, DataAPI):
_parent = json_stringify(_device['parent']) _parent = json_stringify(_device['parent'])
_recording_file_name = _device['recording_file_name'] _recording_file_name = _device['recording_file_name']
mac_address = json.loads(device)['device_address'] mac_address = json.loads(device)['device_address']
device_id = _device['device_id']
del _device['configuration'] del _device['configuration']
del _device['parent'] del _device['parent']
del _device['recording_file_name'] del _device['recording_file_name']
@@ -354,13 +355,22 @@ class DataServer(SocketServer, DataAPI):
# meta_file.parameter = _parameter # meta_file.parameter = _parameter
# meta_file.parent = _parent # meta_file.parent = _parent
# meta_file.recording_file_name = _recording_file_name # meta_file.recording_file_name = _recording_file_name
device_id = int(json.loads(device)['device_id'])
if device_id < 0: if device_id < 0:
raise ValueError('illegal device ID : ' + str(device_id)) raise ValueError('illegal device ID : ' + str(device_id))
self.log_verbose('device ID', device_id) self.log_verbose('device ID', device_id)
# project binding meta file
project_id = None
_project = None
if project_info != None:
_project = json.loads(project_info)
self.database_process.put_queue(['project_insert', device_id, _project])
result = self._queue_ds_dict[int(device_id)].get()
if result[0] == 'project_id':
project_id = result[1]
# while len(self._configurations) <= device_id: # while len(self._configurations) <= device_id:
# self._configurationsappend(None) # self._configurationsappend(None)
@@ -380,8 +390,6 @@ class DataServer(SocketServer, DataAPI):
else: else:
data_format = data_format.name data_format = data_format.name
# self.log_verbose('device data format', data_format)
self.log_verbose('device meta file', meta_file) self.log_verbose('device meta file', meta_file)
# data runtime # data runtime
@@ -406,15 +414,15 @@ class DataServer(SocketServer, DataAPI):
c.shutdown() c.shutdown()
c.join() c.join()
self._spi.set_wait_flag(c._device, True) self._spi.set_wait_flag(c._device, True)
data_runtime_process = RecordingProcess('data_server', self.log_verbose, device_id, data_runtime_process = RecordingProcess('data_server', self.log_verbose, device_id,
Queue(), self._queue_ds_dict[int(device_id)], self._queue_msg, meta_file, Queue(), self._queue_ds_dict[int(device_id)], self._queue_msg, meta_file,
json_stringify(_device), _parameter, _parent, _recording_file_name, json_stringify(_device), _parameter, _parent, _recording_file_name,
data_format, self.socket_mqtt_ip, self.socket_mqtt_port, data_format, self.socket_mqtt_ip, self.socket_mqtt_port,
database = self.database_process ) project_id = project_id,
# data_runtime_process.start() database = self.database_process)
# check channel # check channel
if isinstance(data_runtime_process, RecordingProcess) and device_id not in self._available_channel: if isinstance(data_runtime_process, RecordingProcess) and device_id not in self._available_channel:
raise RuntimeError('set device configuration on un-available channel', device_id) raise RuntimeError('set device configuration on un-available channel', device_id)
+30 -1
View File
@@ -550,4 +550,33 @@ class DataBaseProcess(Process):
except psycopg2.Error as e: except psycopg2.Error as e:
print('e', e) print('e', e)
return True return True
def project_insert(self, device_id, _data):
sql_str = 'INSERT INTO "public"."project_metas" ('
sql_set = []
for item in _data.keys():
sql_str = sql_str + str(item) + ', '
if isinstance(_data[item], dict) or isinstance(_data[item], list):
sql_set.append(json_stringify(_data[item]))
else:
sql_set.append(_data[item])
sql_str = sql_str[0:-2] + ') VALUES ('
for item in _data.keys():
sql_str = sql_str + '%s, '
sql_str = sql_str[0:-2] + ') RETURNING id'
sql_cursor = self._psql_conn.cursor()
try:
sql_cursor.execute(sql_str, sql_set)
except BaseException as e:
print('insert error', e)
self._psql_conn.commit()
sql_cursor.close()
self._queue_error.put()
finally:
self._queue_ds[int(device_id)].put(['project_id', int(sql_cursor.fetchone()[0])])
self._psql_conn.commit()
sql_cursor.close()
+43 -17
View File
@@ -1,6 +1,7 @@
from time import sleep from time import sleep
from typing import Iterable from typing import Iterable
from datetime import datetime from datetime import datetime
import json
import biopro.impl.vcgencmd as vcg import biopro.impl.vcgencmd as vcg
from biopro.data import DataServerOptions, DataAPI from biopro.data import DataServerOptions, DataAPI
@@ -31,8 +32,10 @@ from biopro.api.auth import AuthAPI
from biopro.api.controller import ControllerAPI from biopro.api.controller import ControllerAPI
from biopro.api.device import DeviceAPI from biopro.api.device import DeviceAPI
from biopro.project.project_manager import ProjectManager from biopro.project.project_manager import ProjectManager
### do not import Websocket mode from biopro.db.base import Base, Session, engine
###from .websocket import WebsocketThread from biopro.db.project_report import ProjectReport
from biopro.db.project_meta import MetaProjectInfo
_RUNTIME_COMPILE = False _RUNTIME_COMPILE = False
@@ -117,8 +120,8 @@ class ControlServer(SocketServer, ControlServerAPI):
self.ups_thread = UPSDetectThread(self, c.flag_ups_wait_time) self.ups_thread = UPSDetectThread(self, c.flag_ups_wait_time)
# user session # user session
self._session = {} # self._session = {}
self._user_session_expire = c.user_session_expire_days * 24 * 60 * 60 # sec # self._user_session_expire = c.user_session_expire_days * 24 * 60 * 60 # sec
# indicate those device together # indicate those device together
self._device_instruction_group = None self._device_instruction_group = None
@@ -129,6 +132,10 @@ class ControlServer(SocketServer, ControlServerAPI):
# _api request build # _api request build
self._api = ApiRequests() self._api = ApiRequests()
# sqlalchemy
Base.metadata.create_all(engine)
self._session = Session()
# init method # init method
def _init_file_manager(self, option: ControlServerOptions) -> FileManager: def _init_file_manager(self, option: ControlServerOptions) -> FileManager:
@@ -820,16 +827,19 @@ class ControlServer(SocketServer, ControlServerAPI):
@logging_info @logging_info
def device_battery(self, device:int) -> List[int]: def device_battery(self, device:int) -> List[int]:
battery = {} try:
if device == 'all': battery = {}
device_list = self.device_manager.list_device() if device == 'all':
if len(device_list) > 0: device_list = self.device_manager.list_device()
battery = list(map(lambda x: {"device": x.memory_board, "battery":self.device_manager.get_device(x).battery}, device_list)) if len(device_list) > 0:
else: battery = list(map(lambda x: {"device": x.memory_board, "battery":self.device_manager.get_device(x).battery}, device_list))
battery = { else:
"device": device, battery = {
"battery": self.device_manager.get_device(device).battery "device": device,
} "battery": self.device_manager.get_device(device).battery
}
except AttributeError as e:
print('device_battery', device, 'not found', e)
return battery return battery
@logging_info @logging_info
@@ -1021,8 +1031,17 @@ class ControlServer(SocketServer, ControlServerAPI):
@logging_info @logging_info
def run_project(self, project) -> bool: def run_project(self, project) -> bool:
if project is not None: if project is not None:
# print(project)
project = self._project_manager.create(project) project = self._project_manager.create(project)
with self._session as session:
project_report = ProjectReport(
name = project.name,
uuid = project.uuid,
cycle = project.cycle,
task = project.task_list,
device = project.device
)
session.add(project_report)
session.commit()
self._project_manager.run_project(project) self._project_manager.run_project(project)
return project.as_json() return project.as_json()
@@ -1064,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
@@ -1078,6 +1101,7 @@ class ControlServer(SocketServer, ControlServerAPI):
self.log_verbose('update data format', value) self.log_verbose('update data format', value)
client = self.data_server.client() client = self.data_server.client()
project = None
if client is not None: if client is not None:
info = self.file_manager.use(device) info = self.file_manager.use(device)
@@ -1088,9 +1112,12 @@ class ControlServer(SocketServer, ControlServerAPI):
filename = self._file_save_cache.get(device.device_id, self.TEMP_FILENAME_EXPR) filename = self._file_save_cache.get(device.device_id, self.TEMP_FILENAME_EXPR)
filename = format_filename(filename, device) filename = format_filename(filename, device)
info = self.file_manager.save(device, filename) info = self.file_manager.save(device, filename)
if device.occupied_by_project != None:
project = json.dumps(self.project_manager.get(device.occupied_by_project).info_pass_data_server())
with client: with client:
client.update_device_configuration(device, info.meta_file, value) client.update_device_configuration(device, info.meta_file, value, project)
def _device_set_disable_cache(self, device: CompletedDevice, disable): def _device_set_disable_cache(self, device: CompletedDevice, disable):
if disable: if disable:
@@ -1124,7 +1151,6 @@ class ControlServer(SocketServer, ControlServerAPI):
filename = format_filename(self.TEMP_FILENAME_EXPR, device) filename = format_filename(self.TEMP_FILENAME_EXPR, device)
info = self.file_manager.save(device, filename) info = self.file_manager.save(device, filename)
client.update_device_configuration(device, info.meta_file, RawDataDecoder()) client.update_device_configuration(device, info.meta_file, RawDataDecoder())
if self._device_instruction_group is None: if self._device_instruction_group is None:
client.start_sync(device) client.start_sync(device)
+4 -2
View File
@@ -44,7 +44,9 @@ class RecordingProcess(Process):
def __init__(self, client_id: str, log_verbose, device_id, queue_rec, queue_ds, queue_msg, meta_path, def __init__(self, client_id: str, log_verbose, device_id, queue_rec, queue_ds, queue_msg, meta_path,
device_info, parameter, parent, recording_file_name, data_format, device_info, parameter, parent, recording_file_name, data_format,
mqtt_ip, mqtt_port, mqtt_ip, mqtt_port,
name = 'Recording-Process', database = None): name = 'Recording-Process',
project_id = None,
database = None):
super(RecordingProcess, self).__init__(name = name) super(RecordingProcess, self).__init__(name = name)
self._database = database self._database = database
@@ -57,6 +59,7 @@ class RecordingProcess(Process):
self._meta_file._parent = parent self._meta_file._parent = parent
self._meta_file._recording_file_name = recording_file_name self._meta_file._recording_file_name = recording_file_name
self._meta_file._device_id = device_id self._meta_file._device_id = device_id
self._meta_file._project_id = project_id
print(self._meta_file._device, self._meta_file._parameter, self._meta_file._parent, self._meta_file._filepath) print(self._meta_file._device, self._meta_file._parameter, self._meta_file._parent, self._meta_file._filepath)
self._meta_file.write(self._database) self._meta_file.write(self._database)
@@ -155,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
@@ -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": {
@@ -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)",
+205 -91
View File
@@ -26,11 +26,43 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"CHANNEL": { "HIGHZ_TABLE": {
"derzteription": "record channels", "initial": [
1,
1,
1,
0,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"record_meta": true, "record_meta": true,
"domain": "property", "initial": 1,
"value": "[0, 1, 2]" "value": [
"On",
"Off"
],
"on_change": "set_ctrl_highZ"
},
"CYCLE_NUMBER": {
"description": "CV cycle number",
"record_meta": true,
"initial": 1,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
}, },
"SAMPLE_RATE": { "SAMPLE_RATE": {
"description": "data sampling rate", "description": "data sampling rate",
@@ -44,6 +76,12 @@
}, },
"on_change": "set_sample_rate" "on_change": "set_sample_rate"
}, },
"CHANNEL": {
"derzteription": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"AMP_GAIN": { "AMP_GAIN": {
"description": "amp gain", "description": "amp gain",
"record_meta": true, "record_meta": true,
@@ -59,6 +97,7 @@
"Chronoamperometric", "Chronoamperometric",
"V-T Graph", "V-T Graph",
"R-T Graph", "R-T Graph",
"EIS constant frequency",
"Dev Mode" "Dev Mode"
] ]
}, },
@@ -75,6 +114,19 @@
], ],
"on_change": "set_general_hs_rtia" "on_change": "set_general_hs_rtia"
}, },
"GENERAL_LP_RTIA": {
"description": "Low power rtia gain",
"record_meta": true,
"initial": 4,
"value": [
"0",
"1",
"2",
"3",
"auto"
],
"on_change": "set_general_lp_rtia"
},
"EIS_DC_BIAS": { "EIS_DC_BIAS": {
"description": "DC voltage bias", "description": "DC voltage bias",
"record_meta": true, "record_meta": true,
@@ -147,57 +199,76 @@
8 8
] ]
}, },
"CF_DC_BIAS": {
"ADC_VALUE_I": { "description": "DC voltage bias",
"description": "ADC value current value",
"domain": "int"
},
"Scan_Rate": {
"description": "Voltage Scan Rate",
"record_meta": true, "record_meta": true,
"initial": 10000, "initial": 25000,
"domain": [ "domain": [
100001 "VOLT_MAX"
], ],
"value": { "value": {
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"CTRL_HIGH_Z_15": { "CF_AC_AMP": {
"description": "ctrl highZ level", "description": "AC Amplitude",
"record_meta": true, "record_meta": true,
"initial": 1, "initial": 25,
"value": [ "domain": [
"On", 2048
"Off"
],
"on_change": "set_ctrl_highZ"
},
"ADC_LEVEL_I_15": {
"description": "ADC level",
"record_meta": true,
"initial": 4,
"value": [
"0",
"1",
"2",
"3",
"auto"
],
"on_change": "set_adc_gain_I"
},
"ADC_LEVEL_V_IN_15": {
"description": "ADC level",
"record_meta": true,
"initial": 3,
"value": [
"0",
"1",
"2",
"auto"
] ]
}, },
"VOLT_INITIAL": { "CF_FREQ": {
"description": "frequency of cf",
"record_meta": true,
"initial": 13333333,
"domain": [
"FREQ_MAX"
],
"value": {
"expression": "VALUE"
}
},
"CF_PPD": {
"description": "Point per decades",
"record_meta": true,
"initial": 10,
"domain": [
11
]
},
"CF_SCALE": {
"description": "Point spacing pattern",
"record_meta": true,
"initial": 0,
"value": [
0,
1
]
},
"CF_DELAY": {
"description": "Wait x peroid before start taking measurements",
"record_meta": true,
"initial": 0,
"domain": [
101
],
"value": {
"expression": "VALUE"
}
},
"CF_AVERAGE_NUM": {
"description": "Number of sample used for average funciton",
"record_meta": true,
"initial": 8,
"value": [
2,
4,
6,
8
]
},
"CV_E_INITIAL": {
"description": "Initial Voltage of Scan", "description": "Initial Voltage of Scan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
@@ -208,8 +279,8 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_MAX": { "CV_E1": {
"description": "Max Voltage of Scan", "description": "First voltage of Scan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
"domain": [ "domain": [
@@ -219,8 +290,8 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_MIN": { "CV_E2": {
"description": "Min Voltage of Scan", "description": "Second voltage of Scan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
"domain": [ "domain": [
@@ -230,19 +301,19 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"CYCLE_NUMBER": { "CV_SCAN_RATE": {
"description": "CV cycle number", "description": "Voltage scan rate",
"record_meta": true, "record_meta": true,
"initial": 1, "initial": 10000,
"domain": [ "domain": [
65536 100001
], ],
"value": { "value": {
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_VSCAN": { "CA_VOLT": {
"description": "Voltage of VScan", "description": "Voltage of ca",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
"domain": [ "domain": [
@@ -252,7 +323,7 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"MEASURE_VIN_RANGE": { "VT_MEASURE_VIN_RANGE": {
"description": "measure range of Vin", "description": "measure range of Vin",
"record_meta": true, "record_meta": true,
"initial": 0, "initial": 0,
@@ -275,6 +346,10 @@
}, },
"on_change": "set_para_RT_VOLT_SET" "on_change": "set_para_RT_VOLT_SET"
}, },
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"BLE_WRITE": { "BLE_WRITE": {
"description": "send msg to elite", "description": "send msg to elite",
"domain": { "domain": {
@@ -306,10 +381,11 @@
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "set_general_hs_rtia", "0": "set_general_hs_rtia",
"1": "set_adc_gain_I", "1": "set_general_lp_rtia",
"2": "set_adc_gain_I", "2": "set_general_lp_rtia",
"3": "set_adc_gain_I", "3": "set_general_lp_rtia",
"4": "set_adc_gain_I" "4": "set_general_lp_rtia",
"5": "set_general_hs_rtia"
} }
}, },
{ {
@@ -317,22 +393,25 @@
"when": { "when": {
"0": "curve_eis", "0": "curve_eis",
"1": "curve_cv3", "1": "curve_cv3",
"2": "curve_const_vscan", "2": "curve_ca",
"3": "curve_vt", "3": "curve_vt",
"4": "curve_rt" "4": "curve_rt",
"5": "curve_cf"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "curve_eis_para2", "0": "curve_eis_para2",
"1": "curve_cv3_para2" "1": "curve_cv3_para2",
"5": "curve_cf_para2"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "curve_eis_mode" "0": "curve_eis_mode",
"5": "curve_cf_mode"
} }
}, },
"_sync(True)", "_sync(True)",
@@ -358,6 +437,12 @@
"1XFF;1X70;1B>GENERAL_HS_RTIA" "1XFF;1X70;1B>GENERAL_HS_RTIA"
] ]
}, },
"set_general_lp_rtia": {
"type": "RIS",
"data": [
"1XFF;1X71;1B>GENERAL_LP_RTIA"
]
},
"set_sample_rate": { "set_sample_rate": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
@@ -367,16 +452,10 @@
"XE0;2B>va" "XE0;2B>va"
] ]
}, },
"set_adc_gain_I": {
"type": "RIS",
"data": [
"XE1;X05;B>ADC_LEVEL_I_15"
]
},
"set_ctrl_highZ": { "set_ctrl_highZ": {
"type": "RIS", "type": "RIS",
"data": [ "data": [
"XE1;X03;B>CTRL_HIGH_Z_15" "1XFF;1X72;1B>CTRL_HIGH_Z_15"
] ]
}, },
"curve_eis": { "curve_eis": {
@@ -419,13 +498,51 @@
"1X12;1XFF" "1X12;1XFF"
] ]
}, },
"curve_cf": {
"type": "RIS",
"parameter": {
"fa": "CF_FREQ",
"dp": "CF_DELAY",
"dc": "CF_DC_BIAS",
"am": "CF_AC_AMP",
"an": "CF_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "CF_PPD",
"sp": "CF_SCALE"
},
"data": [
"1X13;1X01;4B>fa;4B>0;2B>dp"
]
},
"curve_cf_para2": {
"type": "RIS",
"parameter": {
"fa": "CF_FREQ",
"dp": "CF_DELAY",
"dc": "CF_DC_BIAS",
"am": "CF_AC_AMP",
"an": "CF_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "CF_PPD",
"sp": "CF_SCALE"
},
"data": [
"1X13;1X02;2B>dc;2B>am;B>an;B>rt;2B>pp;B>sp"
]
},
"curve_cf_mode": {
"type": "RIS",
"data": [
"1X13;1XFF"
]
},
"curve_cv3": { "curve_cv3": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_INITIAL", "va": "CV_E_INITIAL",
"vb": "VOLT_MAX", "vb": "CV_E1",
"vc": "VOLT_MIN", "vc": "CV_E2",
"ve": "Scan_Rate", "ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE", "vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER" "cn": "CYCLE_NUMBER"
}, },
@@ -436,10 +553,10 @@
"curve_cv3_para2": { "curve_cv3_para2": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_INITIAL", "va": "CV_E_INITIAL",
"vb": "VOLT_MAX", "vb": "CV_E1",
"vc": "VOLT_MIN", "vc": "CV_E2",
"ve": "Scan_Rate", "ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE", "vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER" "cn": "CYCLE_NUMBER"
}, },
@@ -447,19 +564,18 @@
"1X09;1X02;4B>ve;2B>vf;2B>cn" "1X09;1X02;4B>ve;2B>vf;2B>cn"
] ]
}, },
"curve_const_vscan": { "curve_ca": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_VSCAN", "va": "CA_VOLT",
"pa": "ADC_LEVEL_I_15", "pa": "GENERAL_LP_RTIA",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15", "pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE" "pe": "SAMPLE_RATE"
}, },
"data": [ "data": [
"1X0B;", "1X0B;",
"2B>va;", "2B>va;",
"4b>pa;4b>pb;", "4b>pa;4b>0;",
"4b>0;4b>pd;", "4b>0;4b>pd;",
"2B>pe" "2B>pe"
] ]
@@ -468,15 +584,14 @@
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "RT_VOLT_SET", "va": "RT_VOLT_SET",
"pa": "ADC_LEVEL_I_15", "pa": "GENERAL_LP_RTIA",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15", "pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE" "pe": "SAMPLE_RATE"
}, },
"data": [ "data": [
"X04;", "X04;",
"2B>va;", "2B>va;",
"4b>pa;4b>pb;", "4b>pa;4b>0;",
"4b>0;4b>pd;", "4b>0;4b>pd;",
"2B>pe" "2B>pe"
] ]
@@ -484,15 +599,14 @@
"curve_vt": { "curve_vt": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"pa": "ADC_LEVEL_I_15", "pa": "GENERAL_LP_RTIA",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15", "pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE", "pe": "SAMPLE_RATE",
"va": "MEASURE_VIN_RANGE" "va": "VT_MEASURE_VIN_RANGE"
}, },
"data": [ "data": [
"X05;", "X05;",
"4b>pa;4b>pb;", "4b>pa;4b>0;",
"4b>0;4b>pd;", "4b>0;4b>pd;",
"2B>pe;", "2B>pe;",
"1B>va" "1B>va"
+212 -92
View File
@@ -26,11 +26,44 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"CHANNEL": { "HIGHZ_TABLE": {
"derzteription": "record channels", "initial": [
1,
1,
1,
0,
1,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"record_meta": true, "record_meta": true,
"domain": "property", "initial": 1,
"value": "[0, 1, 2]" "value": [
"On",
"Off"
],
"on_change": "set_ctrl_highZ"
},
"CYCLE_NUMBER": {
"description": "CV cycle number",
"record_meta": true,
"initial": 1,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
}, },
"SAMPLE_RATE": { "SAMPLE_RATE": {
"description": "data sampling rate", "description": "data sampling rate",
@@ -44,6 +77,12 @@
}, },
"on_change": "set_sample_rate" "on_change": "set_sample_rate"
}, },
"CHANNEL": {
"derzteription": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"AMP_GAIN": { "AMP_GAIN": {
"description": "amp gain", "description": "amp gain",
"record_meta": true, "record_meta": true,
@@ -59,7 +98,9 @@
"Chronoamperometric", "Chronoamperometric",
"V-T Graph", "V-T Graph",
"R-T Graph", "R-T Graph",
"Dev Mode" "EIS constant frequency",
"Dev Mode",
"Idle"
] ]
}, },
"GENERAL_HS_RTIA": { "GENERAL_HS_RTIA": {
@@ -75,6 +116,19 @@
], ],
"on_change": "set_general_hs_rtia" "on_change": "set_general_hs_rtia"
}, },
"GENERAL_LP_RTIA": {
"description": "Low power rtia gain",
"record_meta": true,
"initial": 4,
"value": [
"0",
"1",
"2",
"3",
"auto"
],
"on_change": "set_general_lp_rtia"
},
"EIS_DC_BIAS": { "EIS_DC_BIAS": {
"description": "DC voltage bias", "description": "DC voltage bias",
"record_meta": true, "record_meta": true,
@@ -147,57 +201,76 @@
8 8
] ]
}, },
"CF_DC_BIAS": {
"ADC_VALUE_I": { "description": "DC voltage bias",
"description": "ADC value current value",
"domain": "int"
},
"Scan_Rate": {
"description": "Voltage Scan Rate",
"record_meta": true, "record_meta": true,
"initial": 10000, "initial": 25000,
"domain": [ "domain": [
100001 "VOLT_MAX"
], ],
"value": { "value": {
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"CTRL_HIGH_Z_15": { "CF_AC_AMP": {
"description": "ctrl highZ level", "description": "AC Amplitude",
"record_meta": true, "record_meta": true,
"initial": 1, "initial": 25,
"value": [ "domain": [
"On", 2048
"Off"
],
"on_change": "set_ctrl_highZ"
},
"ADC_LEVEL_I_15": {
"description": "ADC level",
"record_meta": true,
"initial": 4,
"value": [
"0",
"1",
"2",
"3",
"auto"
],
"on_change": "set_adc_gain_I"
},
"ADC_LEVEL_V_IN_15": {
"description": "ADC level",
"record_meta": true,
"initial": 3,
"value": [
"0",
"1",
"2",
"auto"
] ]
}, },
"VOLT_INITIAL": { "CF_FREQ": {
"description": "frequency of cf",
"record_meta": true,
"initial": 13333333,
"domain": [
"FREQ_MAX"
],
"value": {
"expression": "VALUE"
}
},
"CF_PPD": {
"description": "Point per decades",
"record_meta": true,
"initial": 10,
"domain": [
11
]
},
"CF_SCALE": {
"description": "Point spacing pattern",
"record_meta": true,
"initial": 0,
"value": [
0,
1
]
},
"CF_DELAY": {
"description": "Wait x peroid before start taking measurements",
"record_meta": true,
"initial": 0,
"domain": [
101
],
"value": {
"expression": "VALUE"
}
},
"CF_AVERAGE_NUM": {
"description": "Number of sample used for average funciton",
"record_meta": true,
"initial": 8,
"value": [
2,
4,
6,
8
]
},
"CV_E_INITIAL": {
"description": "Initial Voltage of Scan", "description": "Initial Voltage of Scan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
@@ -208,8 +281,8 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_MAX": { "CV_E1": {
"description": "Max Voltage of Scan", "description": "First voltage of Scan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
"domain": [ "domain": [
@@ -219,8 +292,8 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_MIN": { "CV_E2": {
"description": "Min Voltage of Scan", "description": "Second voltage of Scan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
"domain": [ "domain": [
@@ -230,19 +303,19 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"CYCLE_NUMBER": { "CV_SCAN_RATE": {
"description": "CV cycle number", "description": "Voltage scan rate",
"record_meta": true, "record_meta": true,
"initial": 1, "initial": 10000,
"domain": [ "domain": [
65536 100001
], ],
"value": { "value": {
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_VSCAN": { "CA_VOLT": {
"description": "Voltage of VScan", "description": "Voltage of ca",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
"domain": [ "domain": [
@@ -252,7 +325,7 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"MEASURE_VIN_RANGE": { "VT_MEASURE_VIN_RANGE": {
"description": "measure range of Vin", "description": "measure range of Vin",
"record_meta": true, "record_meta": true,
"initial": 0, "initial": 0,
@@ -275,6 +348,10 @@
}, },
"on_change": "set_para_RT_VOLT_SET" "on_change": "set_para_RT_VOLT_SET"
}, },
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"BLE_WRITE": { "BLE_WRITE": {
"description": "send msg to elite", "description": "send msg to elite",
"domain": { "domain": {
@@ -295,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)",
@@ -306,10 +387,11 @@
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "set_general_hs_rtia", "0": "set_general_hs_rtia",
"1": "set_adc_gain_I", "1": "set_general_lp_rtia",
"2": "set_adc_gain_I", "2": "set_general_lp_rtia",
"3": "set_adc_gain_I", "3": "set_general_lp_rtia",
"4": "set_adc_gain_I" "4": "set_general_lp_rtia",
"5": "set_general_hs_rtia"
} }
}, },
{ {
@@ -317,22 +399,25 @@
"when": { "when": {
"0": "curve_eis", "0": "curve_eis",
"1": "curve_cv3", "1": "curve_cv3",
"2": "curve_const_vscan", "2": "curve_ca",
"3": "curve_vt", "3": "curve_vt",
"4": "curve_rt" "4": "curve_rt",
"5": "curve_cf"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "curve_eis_para2", "0": "curve_eis_para2",
"1": "curve_cv3_para2" "1": "curve_cv3_para2",
"5": "curve_cf_para2"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "curve_eis_mode" "0": "curve_eis_mode",
"5": "curve_cf_mode"
} }
}, },
"_sync(True)", "_sync(True)",
@@ -358,6 +443,12 @@
"1XFF;1X70;1B>GENERAL_HS_RTIA" "1XFF;1X70;1B>GENERAL_HS_RTIA"
] ]
}, },
"set_general_lp_rtia": {
"type": "RIS",
"data": [
"1XFF;1X71;1B>GENERAL_LP_RTIA"
]
},
"set_sample_rate": { "set_sample_rate": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
@@ -367,16 +458,10 @@
"XE0;2B>va" "XE0;2B>va"
] ]
}, },
"set_adc_gain_I": {
"type": "RIS",
"data": [
"XE1;X05;B>ADC_LEVEL_I_15"
]
},
"set_ctrl_highZ": { "set_ctrl_highZ": {
"type": "RIS", "type": "RIS",
"data": [ "data": [
"XE1;X03;B>CTRL_HIGH_Z_15" "1XFF;1X72;1B>CTRL_HIGH_Z_15"
] ]
}, },
"curve_eis": { "curve_eis": {
@@ -419,13 +504,51 @@
"1X12;1XFF" "1X12;1XFF"
] ]
}, },
"curve_cf": {
"type": "RIS",
"parameter": {
"fa": "CF_FREQ",
"dp": "CF_DELAY",
"dc": "CF_DC_BIAS",
"am": "CF_AC_AMP",
"an": "CF_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "CF_PPD",
"sp": "CF_SCALE"
},
"data": [
"1X13;1X01;4B>fa;4B>0;2B>dp"
]
},
"curve_cf_para2": {
"type": "RIS",
"parameter": {
"fa": "CF_FREQ",
"dp": "CF_DELAY",
"dc": "CF_DC_BIAS",
"am": "CF_AC_AMP",
"an": "CF_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "CF_PPD",
"sp": "CF_SCALE"
},
"data": [
"1X13;1X02;2B>dc;2B>am;B>an;B>rt;2B>pp;B>sp"
]
},
"curve_cf_mode": {
"type": "RIS",
"data": [
"1X13;1XFF"
]
},
"curve_cv3": { "curve_cv3": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_INITIAL", "va": "CV_E_INITIAL",
"vb": "VOLT_MAX", "vb": "CV_E1",
"vc": "VOLT_MIN", "vc": "CV_E2",
"ve": "Scan_Rate", "ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE", "vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER" "cn": "CYCLE_NUMBER"
}, },
@@ -436,10 +559,10 @@
"curve_cv3_para2": { "curve_cv3_para2": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_INITIAL", "va": "CV_E_INITIAL",
"vb": "VOLT_MAX", "vb": "CV_E1",
"vc": "VOLT_MIN", "vc": "CV_E2",
"ve": "Scan_Rate", "ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE", "vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER" "cn": "CYCLE_NUMBER"
}, },
@@ -447,19 +570,18 @@
"1X09;1X02;4B>ve;2B>vf;2B>cn" "1X09;1X02;4B>ve;2B>vf;2B>cn"
] ]
}, },
"curve_const_vscan": { "curve_ca": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_VSCAN", "va": "CA_VOLT",
"pa": "ADC_LEVEL_I_15", "pa": "GENERAL_LP_RTIA",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15", "pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE" "pe": "SAMPLE_RATE"
}, },
"data": [ "data": [
"1X0B;", "1X0B;",
"2B>va;", "2B>va;",
"4b>pa;4b>pb;", "4b>pa;4b>0;",
"4b>0;4b>pd;", "4b>0;4b>pd;",
"2B>pe" "2B>pe"
] ]
@@ -468,15 +590,14 @@
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "RT_VOLT_SET", "va": "RT_VOLT_SET",
"pa": "ADC_LEVEL_I_15", "pa": "GENERAL_LP_RTIA",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15", "pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE" "pe": "SAMPLE_RATE"
}, },
"data": [ "data": [
"X04;", "X04;",
"2B>va;", "2B>va;",
"4b>pa;4b>pb;", "4b>pa;4b>0;",
"4b>0;4b>pd;", "4b>0;4b>pd;",
"2B>pe" "2B>pe"
] ]
@@ -484,15 +605,14 @@
"curve_vt": { "curve_vt": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"pa": "ADC_LEVEL_I_15", "pa": "GENERAL_LP_RTIA",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15", "pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE", "pe": "SAMPLE_RATE",
"va": "MEASURE_VIN_RANGE" "va": "VT_MEASURE_VIN_RANGE"
}, },
"data": [ "data": [
"X05;", "X05;",
"4b>pa;4b>pb;", "4b>pa;4b>0;",
"4b>0;4b>pd;", "4b>0;4b>pd;",
"2B>pe;", "2B>pe;",
"1B>va" "1B>va"
@@ -26,11 +26,44 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"CHANNEL": { "HIGHZ_TABLE": {
"derzteription": "record channels", "initial": [
1,
1,
1,
0,
1,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"record_meta": true, "record_meta": true,
"domain": "property", "initial": 1,
"value": "[0, 1, 2]" "value": [
"On",
"Off"
],
"on_change": "set_ctrl_highZ"
},
"CYCLE_NUMBER": {
"description": "CV cycle number",
"record_meta": true,
"initial": 1,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
}, },
"SAMPLE_RATE": { "SAMPLE_RATE": {
"description": "data sampling rate", "description": "data sampling rate",
@@ -44,6 +77,12 @@
}, },
"on_change": "set_sample_rate" "on_change": "set_sample_rate"
}, },
"CHANNEL": {
"derzteription": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"AMP_GAIN": { "AMP_GAIN": {
"description": "amp gain", "description": "amp gain",
"record_meta": true, "record_meta": true,
@@ -59,7 +98,9 @@
"Chronoamperometric", "Chronoamperometric",
"V-T Graph", "V-T Graph",
"R-T Graph", "R-T Graph",
"Dev Mode" "EIS constant frequency",
"Dev Mode",
"Idle"
] ]
}, },
"GENERAL_HS_RTIA": { "GENERAL_HS_RTIA": {
@@ -75,6 +116,19 @@
], ],
"on_change": "set_general_hs_rtia" "on_change": "set_general_hs_rtia"
}, },
"GENERAL_LP_RTIA": {
"description": "Low power rtia gain",
"record_meta": true,
"initial": 4,
"value": [
"0",
"1",
"2",
"3",
"auto"
],
"on_change": "set_general_lp_rtia"
},
"EIS_DC_BIAS": { "EIS_DC_BIAS": {
"description": "DC voltage bias", "description": "DC voltage bias",
"record_meta": true, "record_meta": true,
@@ -147,57 +201,76 @@
8 8
] ]
}, },
"CF_DC_BIAS": {
"ADC_VALUE_I": { "description": "DC voltage bias",
"description": "ADC value current value",
"domain": "int"
},
"Scan_Rate": {
"description": "Voltage Scan Rate",
"record_meta": true, "record_meta": true,
"initial": 10000, "initial": 25000,
"domain": [ "domain": [
100001 "VOLT_MAX"
], ],
"value": { "value": {
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"CTRL_HIGH_Z_15": { "CF_AC_AMP": {
"description": "ctrl highZ level", "description": "AC Amplitude",
"record_meta": true, "record_meta": true,
"initial": 1, "initial": 25,
"value": [ "domain": [
"On", 2048
"Off"
],
"on_change": "set_ctrl_highZ"
},
"ADC_LEVEL_I_15": {
"description": "ADC level",
"record_meta": true,
"initial": 4,
"value": [
"0",
"1",
"2",
"3",
"auto"
],
"on_change": "set_adc_gain_I"
},
"ADC_LEVEL_V_IN_15": {
"description": "ADC level",
"record_meta": true,
"initial": 3,
"value": [
"0",
"1",
"2",
"auto"
] ]
}, },
"VOLT_INITIAL": { "CF_FREQ": {
"description": "frequency of cf",
"record_meta": true,
"initial": 13333333,
"domain": [
"FREQ_MAX"
],
"value": {
"expression": "VALUE"
}
},
"CF_PPD": {
"description": "Point per decades",
"record_meta": true,
"initial": 10,
"domain": [
11
]
},
"CF_SCALE": {
"description": "Point spacing pattern",
"record_meta": true,
"initial": 0,
"value": [
0,
1
]
},
"CF_DELAY": {
"description": "Wait x peroid before start taking measurements",
"record_meta": true,
"initial": 0,
"domain": [
101
],
"value": {
"expression": "VALUE"
}
},
"CF_AVERAGE_NUM": {
"description": "Number of sample used for average funciton",
"record_meta": true,
"initial": 8,
"value": [
2,
4,
6,
8
]
},
"CV_E_INITIAL": {
"description": "Initial Voltage of Scan", "description": "Initial Voltage of Scan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
@@ -208,8 +281,8 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_MAX": { "CV_E1": {
"description": "Max Voltage of Scan", "description": "First voltage of Scan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
"domain": [ "domain": [
@@ -219,8 +292,8 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_MIN": { "CV_E2": {
"description": "Min Voltage of Scan", "description": "Second voltage of Scan",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
"domain": [ "domain": [
@@ -230,19 +303,19 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"CYCLE_NUMBER": { "CV_SCAN_RATE": {
"description": "CV cycle number", "description": "Voltage scan rate",
"record_meta": true, "record_meta": true,
"initial": 1, "initial": 10000,
"domain": [ "domain": [
65536 100001
], ],
"value": { "value": {
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"VOLT_VSCAN": { "CA_VOLT": {
"description": "Voltage of VScan", "description": "Voltage of ca",
"record_meta": true, "record_meta": true,
"initial": 25000, "initial": 25000,
"domain": [ "domain": [
@@ -252,7 +325,7 @@
"expression": "VALUE" "expression": "VALUE"
} }
}, },
"MEASURE_VIN_RANGE": { "VT_MEASURE_VIN_RANGE": {
"description": "measure range of Vin", "description": "measure range of Vin",
"record_meta": true, "record_meta": true,
"initial": 0, "initial": 0,
@@ -275,6 +348,10 @@
}, },
"on_change": "set_para_RT_VOLT_SET" "on_change": "set_para_RT_VOLT_SET"
}, },
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"BLE_WRITE": { "BLE_WRITE": {
"description": "send msg to elite", "description": "send msg to elite",
"domain": { "domain": {
@@ -295,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)",
@@ -306,10 +387,11 @@
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "set_general_hs_rtia", "0": "set_general_hs_rtia",
"1": "set_adc_gain_I", "1": "set_general_lp_rtia",
"2": "set_adc_gain_I", "2": "set_general_lp_rtia",
"3": "set_adc_gain_I", "3": "set_general_lp_rtia",
"4": "set_adc_gain_I" "4": "set_general_lp_rtia",
"5": "set_general_hs_rtia"
} }
}, },
{ {
@@ -317,22 +399,25 @@
"when": { "when": {
"0": "curve_eis", "0": "curve_eis",
"1": "curve_cv3", "1": "curve_cv3",
"2": "curve_const_vscan", "2": "curve_ca",
"3": "curve_vt", "3": "curve_vt",
"4": "curve_rt" "4": "curve_rt",
"5": "curve_cf"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "curve_eis_para2", "0": "curve_eis_para2",
"1": "curve_cv3_para2" "1": "curve_cv3_para2",
"5": "curve_cf_para2"
} }
}, },
{ {
"expression": "MODE", "expression": "MODE",
"when": { "when": {
"0": "curve_eis_mode" "0": "curve_eis_mode",
"5": "curve_cf_mode"
} }
}, },
"_sync(True)", "_sync(True)",
@@ -358,6 +443,12 @@
"1XFF;1X70;1B>GENERAL_HS_RTIA" "1XFF;1X70;1B>GENERAL_HS_RTIA"
] ]
}, },
"set_general_lp_rtia": {
"type": "RIS",
"data": [
"1XFF;1X71;1B>GENERAL_LP_RTIA"
]
},
"set_sample_rate": { "set_sample_rate": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
@@ -367,16 +458,10 @@
"XE0;2B>va" "XE0;2B>va"
] ]
}, },
"set_adc_gain_I": {
"type": "RIS",
"data": [
"XE1;X05;B>ADC_LEVEL_I_15"
]
},
"set_ctrl_highZ": { "set_ctrl_highZ": {
"type": "RIS", "type": "RIS",
"data": [ "data": [
"XE1;X03;B>CTRL_HIGH_Z_15" "1XFF;1X72;1B>CTRL_HIGH_Z_15"
] ]
}, },
"curve_eis": { "curve_eis": {
@@ -419,13 +504,51 @@
"1X12;1XFF" "1X12;1XFF"
] ]
}, },
"curve_cf": {
"type": "RIS",
"parameter": {
"fa": "CF_FREQ",
"dp": "CF_DELAY",
"dc": "CF_DC_BIAS",
"am": "CF_AC_AMP",
"an": "CF_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "CF_PPD",
"sp": "CF_SCALE"
},
"data": [
"1X13;1X01;4B>fa;4B>0;2B>dp"
]
},
"curve_cf_para2": {
"type": "RIS",
"parameter": {
"fa": "CF_FREQ",
"dp": "CF_DELAY",
"dc": "CF_DC_BIAS",
"am": "CF_AC_AMP",
"an": "CF_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "CF_PPD",
"sp": "CF_SCALE"
},
"data": [
"1X13;1X02;2B>dc;2B>am;B>an;B>rt;2B>pp;B>sp"
]
},
"curve_cf_mode": {
"type": "RIS",
"data": [
"1X13;1XFF"
]
},
"curve_cv3": { "curve_cv3": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_INITIAL", "va": "CV_E_INITIAL",
"vb": "VOLT_MAX", "vb": "CV_E1",
"vc": "VOLT_MIN", "vc": "CV_E2",
"ve": "Scan_Rate", "ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE", "vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER" "cn": "CYCLE_NUMBER"
}, },
@@ -436,10 +559,10 @@
"curve_cv3_para2": { "curve_cv3_para2": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_INITIAL", "va": "CV_E_INITIAL",
"vb": "VOLT_MAX", "vb": "CV_E1",
"vc": "VOLT_MIN", "vc": "CV_E2",
"ve": "Scan_Rate", "ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE", "vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER" "cn": "CYCLE_NUMBER"
}, },
@@ -447,19 +570,18 @@
"1X09;1X02;4B>ve;2B>vf;2B>cn" "1X09;1X02;4B>ve;2B>vf;2B>cn"
] ]
}, },
"curve_const_vscan": { "curve_ca": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "VOLT_VSCAN", "va": "CA_VOLT",
"pa": "ADC_LEVEL_I_15", "pa": "GENERAL_LP_RTIA",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15", "pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE" "pe": "SAMPLE_RATE"
}, },
"data": [ "data": [
"1X0B;", "1X0B;",
"2B>va;", "2B>va;",
"4b>pa;4b>pb;", "4b>pa;4b>0;",
"4b>0;4b>pd;", "4b>0;4b>pd;",
"2B>pe" "2B>pe"
] ]
@@ -468,15 +590,14 @@
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"va": "RT_VOLT_SET", "va": "RT_VOLT_SET",
"pa": "ADC_LEVEL_I_15", "pa": "GENERAL_LP_RTIA",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15", "pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE" "pe": "SAMPLE_RATE"
}, },
"data": [ "data": [
"X04;", "X04;",
"2B>va;", "2B>va;",
"4b>pa;4b>pb;", "4b>pa;4b>0;",
"4b>0;4b>pd;", "4b>0;4b>pd;",
"2B>pe" "2B>pe"
] ]
@@ -484,15 +605,14 @@
"curve_vt": { "curve_vt": {
"type": "RIS", "type": "RIS",
"parameter": { "parameter": {
"pa": "ADC_LEVEL_I_15", "pa": "GENERAL_LP_RTIA",
"pb": "ADC_LEVEL_V_IN_15",
"pd": "CTRL_HIGH_Z_15", "pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE", "pe": "SAMPLE_RATE",
"va": "MEASURE_VIN_RANGE" "va": "VT_MEASURE_VIN_RANGE"
}, },
"data": [ "data": [
"X05;", "X05;",
"4b>pa;4b>pb;", "4b>pa;4b>0;",
"4b>0;4b>pd;", "4b>0;4b>pd;",
"2B>pe;", "2B>pe;",
"1B>va" "1B>va"
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
# install python module numpy
sudo apt-get install libatlas-base-dev
sudo apt-get install python3-numpy
# install python module SQLAlchemy
pip3 install SQLAlchemy
# create folder to save project logger
mkdir -p /home/pi/logger/project
# add column cycle in projects
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
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