Compare commits

...

126 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
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
Roy 789d9b3a81 [update] fix hstia gain 2022-11-15 11:51:16 +08:00
Roy 0d0427ed14 [update] receive hsrtia & lprtia gain level 2022-11-09 17:19:48 +08:00
Roy d434509c5b [update] new hsrtia function 2022-11-09 16:03:45 +08:00
Roy 787d76d48c [update] update eis instruction 2022-11-08 17:55:20 +08:00
Roy 50f2432088 [update] update number of mode 2022-11-08 17:28:03 +08:00
Roy 1cff19ac58 [update] update GENERAL_HS_RTIA parameter 2022-11-08 16:13:20 +08:00
Roy baef447c0e [update] update EIS_AVERAGE_NUM parameter 2022-11-08 15:57:52 +08:00
Roy ee9c13d4c5 [update] update EIS_DELAY parameter 2022-11-08 15:44:57 +08:00
Roy 9076f2f10b [update] update EIS_SCALE parameter 2022-11-08 15:36:22 +08:00
Roy 9b2e2964b0 [update] update EIS_PPD parameter 2022-11-08 14:49:07 +08:00
Roy 2622109c89 [update] update EIS_FREQ parameter 2022-11-08 14:35:32 +08:00
Roy a3fe6b87af [update] update EIS_AC_AMP parameter 2022-11-08 14:24:07 +08:00
Roy 64419ca1c5 [update] update EIS_DC_BIAS parameter 2022-11-08 14:17:31 +08:00
Roy 7d77c44741 [update] update EIS_FREQ parameter 2022-11-08 12:09:42 +08:00
Roy 29b4dd5cc7 [update] update EIS_FREQ parameter 2022-11-08 12:07:49 +08:00
Roy f151ae6fce [update] delete FREQ_START & FREQ_STOP parameter 2022-11-08 11:08:01 +08:00
peterlu14 e535e3d2b1 Merge remote-tracking branch 'origin/EIS_10test' into release/v1.7.0/fix_EIS_freq-RT 2022-11-08 09:38:19 +08:00
10 06c36aa737 Merge remote-tracking branch 'origin/dev/RT_mode' into EIS_10test 2022-11-07 16:54:28 +08:00
10 402022c451 cutoff freq 2022-11-07 16:44:54 +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
Roy 4daff72d39 [update] update RT mode 2022-10-27 17:43:16 +08:00
Roy f99719832a [update] short instruction for RT mode 2022-10-27 17:13:38 +08:00
Roy 58e09bfcda [update] hide mem board message 2022-10-26 10:23:50 +08:00
Roy 55780514b9 [update] new RT mode 2022-10-26 10:23:12 +08:00
peterlu14 936514871f [update] timeout 3 -> 5 2022-10-18 11:23:53 +08:00
peterlu14 f25d9221c6 Merge branch 'release/v1.6.9/fix_phase_90ToN90' into release/v1.6.7/scheduler_debug 2022-10-14 10:53:40 +08:00
peterlu14 2ee9fa6b19 [update] project device change 2022-10-14 10:52:41 +08:00
10 fcc39dbfed Merge branch 'release/v1.6.9/fix_phase_90ToN90' into EIS_10test 2022-10-13 15:28:39 +08:00
10 e2f7bba961 fix phase in PEIS mode 2022-10-13 15:27:27 +08:00
10 1174d54bc0 fix phase in PEIS mode 2022-10-13 15:13:00 +08:00
peterlu14 bff75dc49e Merge commit '35912f614e7283bb4b8df5355952162fea9a9395' into release/v1.6.9/fix_phase_90ToN90 2022-10-12 17:18:49 +08:00
peterlu14 35912f614e [update] EIS Mini vt mode add 2022-10-12 17:18:14 +08:00
10 cfc4e39c8a force raw phase and raw phase - ideal phase stay in [90, -90) in PEIS mode 2022-10-12 16:41:55 +08:00
10 8c4916d1e8 fix phase calibration 2022-10-11 17:19:40 +08:00
Roy e3c252f204 [update] FREQ 133333 2022-10-05 11:58:37 +08:00
Roy c2164da48b [update] new vt mode on EIS 2022-10-05 11:16:09 +08:00
Roy ab2d746afb Merge branch 'release/v1.6.7/scheduler_cycle' into release/v1.6.7/scheduler_debug 2022-10-05 10:57:53 +08:00
Roy 8a870a860a [update] socket listen 3 -> 20 2022-10-05 10:57:30 +08:00
Roy f4c5cf0135 [update] socket timeout 1s -> 3s 2022-10-04 13:53:53 +08:00
Roy 1f01fd3b9b [update] count +1 when start 2022-10-04 13:53:30 +08:00
Roy d1fe388c27 [debug] fix multi device in one project stop problem 2022-10-04 13:42:03 +08:00
Roy 91d5e73c5e [debug] fix after task run equal error 2022-10-04 13:41:37 +08:00
Roy d1b6c2892f [debug] configurations key error 2022-10-04 13:18:38 +08:00
Roy 4243a13536 Merge remote-tracking branch 'origin/dev/fix_no_data' into release/v1.6.7/scheduler_debug 2022-09-30 10:58:41 +08:00
Roy 97188abff8 [update] uart write timeout 0.01 -> 1 2022-09-30 10:56:47 +08:00
Roy 9d8178d11a [update] add project cycle 2022-09-30 10:56:37 +08:00
Roy bbde653a8e [update] update cali value 2022-09-28 14:50:22 +08:00
Roy 6c0cef7925 [update] test function: print mem board info 2022-09-27 14:38:00 +08:00
Roy 3bbf0c912a [update] test function: print mem board info 2022-09-27 13:41:32 +08:00
Roy 4333958ebe [update] fix eis's FREQ default value 2022-09-16 17:49:28 +08:00
Roy 3239a691e3 [update] test function: print ram info 2022-09-16 13:12:40 +08:00
Roy 30183788d8 [update] test function: print ram info 2022-09-14 18:12:53 +08:00
Roy 13df921b1c [update] test function: print ram info 2022-09-14 17:14:47 +08:00
Roy d182a04ed3 [update] add channel data 2022-09-14 15:36:01 +08:00
Roy 35a09ff9a0 [update] switch mode set default highz & time_duration in Elite_EDC 2022-09-06 18:51:32 +08:00
Roy e134b9780c [update] add new api set_project & add new condition until_button_trigger & add new action idle 2022-09-06 16:28:38 +08:00
peterlu14 df39f241b3 [update] add battery 2022-08-22 19:57:02 +08:00
peterlu14 0b72ac0c9d Merge branch 'dev/scheduler_cycle' into release/v1.6.6/merge_scheduler 2022-08-22 17:42:57 +08:00
JayC319 0afbe66229 [update] edc 1.5 library 2022-08-22 13:58:39 +08:00
108000207 9846cfd708 [update] set _time_interval as 0.1 to avoid delay 2022-08-19 15:44:51 +08:00
108000207 b4ad2a7fba [update] remove useless comments 2022-08-18 17:51:51 +08:00
108000207 675fdc2226 [update] cycle_next use uuid version 2022-08-18 17:39:59 +08:00
108000207 a847b1222d [debug] fix the bug of first task can't idle 2022-08-17 15:51:29 +08:00
108000207 bd0c36923a [update] scheduler cycle version 1 2022-08-17 11:50:22 +08:00
peterlu14 612785f51a [update] EIS show data 2022-08-16 19:40:27 +08:00
peterlu14 7dbf09e9a5 [update] EIS show data 2022-08-16 19:39:06 +08:00
peterlu14 ee64d43de1 [update] ca instruction b0 -> D3 2022-08-16 19:31:33 +08:00
peterlu14 60b91f0c1e [update] EIS add show data 2022-08-16 19:15:04 +08:00
Roy 8ac01bdf54 [update] update eis library 2022-08-16 19:10:18 +08:00
JayC319 0f90b16b6e [update] library product number 2022-08-16 17:35:06 +08:00
peterlu14 cd98a14e84 [debug] fix idle send instruction & remove deepcopy & close task by device 2022-08-16 14:25:37 +08:00
peterlu14 2e97ad23eb [debug] fix parameter empty 2022-08-16 12:11:35 +08:00
108000207 e0dd5a6972 [update] add schdeuler cycle attribute 2022-08-16 11:34:47 +08:00
Roy 76e0a150d1 Merge remote-tracking branch 'origin/dev/Cali_mode' into dev/cc_cp_separate 2022-08-15 18:11:20 +08:00
JayC319 ecd4b9325d [update] 2022-08-15 18:09:40 +08:00
peterlu14 978b1254f0 Merge branch 'dev/debug' into dev/cc_cp_separate 2022-08-11 13:53:13 +08:00
peterlu14 26e02f2d40 [update] add data_show function print device data 2022-08-11 00:58:30 +08:00
Roy 257958768f [update] new ca mode instruvtion 2022-08-05 18:34:33 +08:00
38 changed files with 4189 additions and 887 deletions
+1
View File
@@ -7,3 +7,4 @@
/.vscode
/media
python/biopro/sever/_identify.py
*.log
+56 -27
View File
@@ -78,6 +78,8 @@ add ssh.txt in boot folder
###### 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 libatlas-base-dev
sudo apt-get install python3-numpy
###### wiringpi conflict
need to install wiringpi: https://github.com/WiringPi/WiringPi
@@ -94,6 +96,7 @@ git clone https://gitlab.com/wisetop/controller/wisetopdataserver.git
```
cd ~/wisetopdataserver
pip3 install -r requirements.txt
pip3 install SQLAlchemy
```
##### Packages version
```
@@ -155,8 +158,8 @@ reboot
###### Set pi password
```
$cd ~
$passwd
cd ~
passwd
Current password:raspberry
New password:5k6zj454778225
Retype new password:5k6zj454778225
@@ -195,11 +198,11 @@ exit 0
### MQTT broker install
###### 1.Install mosquitto
$sudo apt-get install mosquitto mosquitto-clients
sudo apt-get install mosquitto mosquitto-clients
###### 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:
```
@@ -210,13 +213,13 @@ protocol websockets
allow_anonymous true
```
###### 3.restart mqtt broker
$sudo systemctl restart mosquitto
sudo systemctl restart mosquitto
###### 4.Robust MQTT
create mosquitto_restart.sh
$cd ~
$sudo vim mosquitto_restart.sh
cd ~
sudo vim mosquitto_restart.sh
add the code following as:
@@ -233,16 +236,16 @@ echo "$SERVICE is currently running" >> /home/ubuntu/cron.log
exit 0
```
###### 5.add mosquitto_restart.sh to root routing
$sudo chmod +x mosquitto_restart.sh
$sudo -i
$crontab -e
sudo chmod +x mosquitto_restart.sh
sudo -i
crontab -e
add the code following as:
```
*/5 * * * * /home/pi/mosquitto_restart.sh
```
###### 6.Auto run MQTT broker when when pi-start
$sudo vim /etc/rc.local
sudo vim /etc/rc.local
add the code following as:
```
@@ -251,31 +254,31 @@ sudo nohup systemctl restart mosquitto
### Setting up a Routed Wireless Access Point
###### 1.Install AP and Management Software
$sudo apt install hostapd
$sudo systemctl unmask hostapd
$sudo systemctl enable hostapd
$sudo apt install dnsmasq
$sudo DEBIAN_FRONTEND=noninteractive apt install -y netfilter-persistent iptables-persistent
sudo apt install hostapd
sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo apt install dnsmasq
sudo DEBIAN_FRONTEND=noninteractive apt install -y netfilter-persistent iptables-persistent
###### 2.Set up the Network Router
$sudo nano /etc/dhcpcd.conf
sudo nano /etc/dhcpcd.conf
```
interface wlan0
static ip_address=192.168.2.1/24
nohook wpa_supplicant
```
$sudo nano /etc/sysctl.d/routed-ap.conf
sudo nano /etc/sysctl.d/routed-ap.conf
```
# Enable IPv4 routing
net.ipv4.ip_forward=1
```
$sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
$sudo netfilter-persistent save
$sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo netfilter-persistent save
sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
$sudo nano /etc/dnsmasq.conf
sudo nano /etc/dnsmasq.conf
```
interface=wlan0 # Listening interface
@@ -286,10 +289,10 @@ address=/gw.wlan/192.168.2.1
# Alias for this router
```
###### 3.Ensure Wireless Operation
$sudo rfkill unblock wlan
sudo rfkill unblock wlan
###### 4.Configure the AP Software
$sudo nano /etc/hostapd/hostapd.conf
sudo nano /etc/hostapd/hostapd.conf
```
country_code=TW
@@ -314,11 +317,13 @@ wme_enabled=1
ht_capab=[HT40+][SHORT-GI-40]
```
###### 5.Running the new Wireless AP
$sudo systemctl reboot
sudo systemctl reboot
### Install Apache2
sudo apt install apache2
### Set web site
$sudo vim ./sites-available/000-default.conf
### Deploy web site
sudo vim /etc/apache2/sites-available/000-default.conf
```
<VirtualHost *:8080> #80------>8080
# 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:
> 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
+9
View File
@@ -1585,6 +1585,15 @@ class ControlAPI(metaclass=Router):
def stop_project(self, project) -> bool:
raise NotImplementedError()
def set_project(self, project, content) -> bool:
raise NotImplementedError()
def set_project_cycle(self, project, index, content) -> bool:
raise NotImplementedError()
def show_device_data(self, device) -> bool:
raise NotImplementedError()
# noinspection PyAbstractClass
class ControlClient(SocketClient, ControlAPI, metaclass=SocketClientMacro(ControlAPI)):
+16 -3
View File
@@ -87,7 +87,8 @@ class DataAPI(metaclass=abc.ABCMeta):
def update_device_configuration(self,
device: Union[int, Device],
meta_file: Union[str, Path, RecordingMetaFile],
data_format: Union[AnyStr, DataDecodeFormat]):
data_format: Union[AnyStr, DataDecodeFormat],
project_info: str):
"""set device configuration.
:param device: device ID
@@ -130,6 +131,14 @@ class DataAPI(metaclass=abc.ABCMeta):
def hardware_test(self) -> JSON_OBJECT:
""""""
pass
@abc.abstractmethod
def show_data(self, device: Union[int, Device]):
"""show device data
:param device: device ID
"""
pass
# noinspection PyAbstractClass
@@ -146,7 +155,8 @@ class DataClient(SocketClient, DataAPI, metaclass=SocketClientMacro(DataAPI)):
def update_device_configuration(self,
device: Union[int, Device],
meta_file: Union[str, Path, RecordingMetaFile],
data_format: Union[AnyStr, DataDecodeFormat]):
data_format: Union[AnyStr, DataDecodeFormat],
project_info: str):
# meta file
if isinstance(meta_file, str):
@@ -178,7 +188,7 @@ class DataClient(SocketClient, DataAPI, metaclass=SocketClientMacro(DataAPI)):
raise TypeError('not a data decode format : ' + data_format.__class__.__name__)
# 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:
if isinstance(device, Device):
@@ -191,6 +201,9 @@ class DataClient(SocketClient, DataAPI, metaclass=SocketClientMacro(DataAPI)):
def stop_sync(self, *device: Union[int, Device]):
self.send_command('stop_sync', *self._to_device_id(*device))
def show_data(self, device: int):
self.send_command('show_data', device)
@staticmethod
def _to_device_id(*device: Union[int, Device]) -> Tuple[int, ...]:
+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})"
+6 -16
View File
@@ -660,9 +660,9 @@ class CC2650Device(Device):
break
elif device_type == 'EISZeroOne':
i = 0
i = 1
request_times = 0
while i < 7:
while i <= 24:
try:
# send
code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, i)
@@ -2177,23 +2177,12 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
else:
for dev in self._found:
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?
for retry_recv_ack in range(5):
self._cc2650.send("bytes", bytes((0, 0, 0, 0)))
try:
# send device mac and addrType
self._cc2650.send("bytes", bytes(connect_ins))
sleep(1.5)
con_done = self._cc2650.recv_uart(timeout = 0.1)
except RecvTimeout:
@@ -2202,6 +2191,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
# is the ack valid?
if con_done is None:
self.log_info("recv connection timeout, retry... ")
continue
elif con_done[0] is 46 and \
+23 -12
View File
@@ -574,20 +574,23 @@ class DeviceManager(MasterDevice, Synchronized):
:param device: device ID or response info
:return: CompletedDevice, None if not found.
"""
if isinstance(device, int):
for slave in self._device:
if slave.device_id == device:
return slave
try:
if isinstance(device, int):
for slave in self._device:
if slave.device_id == device:
return slave
elif isinstance(device, str):
for slave in self._device:
if ':'.join('{:02x}'.format(b) for b in slave.mac_address) == device.lower():
return slave
elif isinstance(device, str):
for slave in self._device:
if ':'.join('{:02x}'.format(b) for b in slave.mac_address) == device.lower():
return slave
elif isinstance(device, DeviceInfo):
for slave in self._device:
if device.match(slave):
return slave
elif isinstance(device, DeviceInfo):
for slave in self._device:
if device.match(slave):
return slave
except BaseException as e:
self.log_error('device not found', str(device))
return None
@@ -829,6 +832,9 @@ class DeviceManager(MasterDevice, Synchronized):
elif func == InternalInstruction.PREDEFINED_DISABLE_CACHE:
self._device_disable_cache(device, *para)
elif func == InternalInstruction.PREDEFINED_IDLE:
self._idle(device, *para)
elif isinstance(device, DebugDevice):
if func == InternalInstruction.PREDEFINED_NOTIFY:
@@ -848,6 +854,11 @@ class DeviceManager(MasterDevice, Synchronized):
InternalInstruction.PREDEFINED_DATA_FORMAT,
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):
if cali is None:
cali = device.calibration_info(expr)
+365 -189
View File
@@ -1,6 +1,7 @@
import abc
import struct
import math
import numpy
from typing import Optional, TypeVar, Generic, Tuple, Dict, List, AnyStr
from datetime import datetime
@@ -853,7 +854,7 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
__slots__ = ('_message', '_cycle_number', '_start_return_data', '_time_stamp',
'_total_time_stamp', '_mode', '_cycle_start_time',
'_mode_stop')
'_mode_stop', '_show_data')
def __init__(self):
super().__init__()
@@ -868,6 +869,8 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
self._mode = 0
self._cycle_start_time = []
self._show_data = False
@property
def name(self) -> str:
return self.NAME
@@ -881,17 +884,55 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
def decode(self, data: bytes) -> Optional[RecordingData]:
if len(data) < 18:
return None
voltage = 0
mem_cnt = data[1]
time_stamp: float = struct.unpack('<I', data[4:8])[0] # unit: ms 0x18030000
current = struct.unpack('<i', data[8:12])[0] # unit: nA
voltage = struct.unpack('<i', data[12:16])[0] # unit: uV
impedance = struct.unpack('<i', data[16:20])[0] # unit: mOm
#/* Elite Notify data:
# * +--------+----------+---------+---------+---------+-----------+-----------------+
# * | id(1B) | time(4B) | ch1(4B) | ch2(4B) | ch3(4B) | cycle(2B) | finish_flag(1B) |
# * | bat(4B) | notify#(1B) | ch4(4B) | ch5(4B) | ch6(4B) | __(3B) |
# * +---------+-------------+---------+---------+---------+--------+
# */
#/*
# * 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]
finish_mode_falg = data[22]
battery = struct.unpack('<i', data[23:27])[0]
elite_notify_times = data[27]
mem_cnt = data[1]
time_stamp: float = struct.unpack('<I', data[1+3:5+3])[0]
ch1 = struct.unpack('<i', data[5+3:9+3])[0] # unit: nA
ch2 = struct.unpack('<i', data[9+3:13+3])[0] # unit: uV
ch3 = struct.unpack('<i', data[13+3:17+3])[0] # unit: mOm
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
mem_wrong_information = struct.unpack('<i', data[43:47])[0] # mem_wrong_information = green retry, green wrong, red retry, red wrong
ram_num = data[47]
@@ -915,25 +956,31 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
print("error timeStamp full data:", list(data), datetime.now(), '\n')
return None
else:
# print('|', time_stamp, '|', delta, '|', int(time_stamp * 1000 / 2),
# '|', current, '|', voltage, '|', impedance,
# '|', cycle_number, '|', finishMode, '@', str(self.device))
if self._show_data:
print('|', time_stamp, '|', delta, '|', int(time_stamp * 1000 / 2),
'|', ch1, '|', ch2, '|', ch3, '|', cycle_number,
'|', ch4, '|', ch5, '|', ch6,
'|', finishMode, '@', str(self.device), flush = True)
# print('|', '{:10}'.format(time_stamp),
# '|', '{:4}'.format(delta),
# '|', '{:10}'.format(int(time_stamp * 1000 / 2)),
# '|', '{:10}'.format(current),
# '|', '{:10}'.format(voltage),
# '|', '{:10}'.format(impedance),
# '|', '{:5}'.format(cycle_number),
# '|', '{:1}'.format(finishMode),
# '@', str(self.device), '|')
# print('|', '{:10}'.format(time_stamp),
# '|', '{:4}'.format(delta),
# '|', '{:10}'.format(int(time_stamp * 1000 / 2)), #[usec]
# '|', '{:10}'.format(ch1), #[nA]
# '|', '{:10}'.format(ch2), #[uV]
# '|', '{:10}'.format(ch3),
# '|', '{:5}'.format(cycle_number),
# '|', '{:10}'.format(ch4), #Voutin[uV]
# '|', '{: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),
# '|', '{:2}'.format(ram_num),
# '|', '{:2}'.format(broken_flag),
# '@', str(self.device), '|')
pass
# print('|', '{:5}'.format(mem_wrong_information),
# '|', '{:2}'.format(ram_num),
# '|', '{:2}'.format(broken_flag),
# '@', str(self.device), '|')
if finishMode == True:
print("finishMode full data:", list(data), datetime.now())
@@ -942,10 +989,13 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
self._mode_stop = 0
ret = RecordingData(self.device, int(time_stamp * 1000 / 2), 0)
ret.append_data(0, current)
ret.append_data(1, voltage)
ret.append_data(2, impedance)
ret.append_data(0, ch1)
ret.append_data(1, ch2)
ret.append_data(2, ch3)
ret.append_data(3, cycle_number)
ret.append_data(4, ch4)
ret.append_data(5, ch5)
ret.append_data(6, ch6)
# ret.append_data(4, battery)
# ret.append_data(5, elite_notify_times)
# ret.append_data(6, mem_cnt)
@@ -1334,8 +1384,8 @@ class EISZeroOneDataDecoder(RecDataDecoder):
__slots__ = ('_message', '_cycle_number', '_start_return_data', '_time_stamp',
'_total_time_stamp', '_mode', '_cycle_start_time',
'_mode_stop', '_last_time_stamp', '_last_delta', '_cali_coeff',
'cali_coeff', '_ac_amp', '_mode', '_freq_start', '_freq_stop',
'_freq_direction', '_last_phase', '_first_phase_flag')
'cali_coeff', '_ac_amp', '_mode',
'_last_phase', '_first_phase_flag', '_show_data')
def __init__(self, cali_coeff: bytes = None):
super().__init__()
@@ -1348,86 +1398,219 @@ class EISZeroOneDataDecoder(RecDataDecoder):
self._mode_stop = 0
self._cycle_start_time = []
self._ac_amp: int = 0
self._mode: int = 0
self._freq_start: int = 0
self._freq_stop: int = 0
self._freq_direction = 0
self._last_phase = 0
self._first_phase_flag = 1
self._cali_coeff: Optional[bytes] = None
self.cali_coeff: Optional[List[Tuple[int, int]]] = None
self._show_data = False
if cali_coeff is not None:
self._cali_coeff = cali_coeff
self.cali_coeff = self._decode_cali_coeff(cali_coeff)
@staticmethod
def _decode_cali_coeff(cali_coeff: bytes) -> Optional[List[Tuple[int, int]]]:
#####################################################
# phase_coeff/phase_offset/hsrtia_a/hsrtia_b/rolloff
# [[gain0, g1, g2, g3] ----->最高頻
# [gain0, g1, g2, g3] ----->中頻
# [gain0, g1, g2, g3] ----->低頻
# [gain0, g1, g2, g3] ----->最低頻
# ]
#####################################################
print('cali_coeff=', cali_coeff)
if cali_coeff != b'':
cali_table = []
phase_para_a = []
phase_para_b = []
hsrtia_a = []
hsrtia_b = []
hsrtia_c = []
hsrtia_d = []
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)
cutoff_freq = struct.unpack('>I', cali_coeff[1:5])[0] * 100 #4
# temp = struct.unpack('>B', cali_coeff[5:6])[0] #1
# hsrtia_200r = struct.unpack('>B', cali_coeff[6:7])[0] #1
# hsrtia_5k = struct.unpack('>H', cali_coeff[7:9])[0] #2
# hsrtia_20k = struct.unpack('>H', cali_coeff[6:8])[0] #2
# hsrtia_160k = struct.unpack('>I', cali_coeff[8:12])[0] #4
#gain=0
cis_cali_packet = 1
index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][0] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
hsrtia_b[0][0] = struct.unpack('>q', cali_coeff[index+5:index+13])[0]
rolloff[0][0] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 20
for i in range(index, index+16, 8):
phase_para_a.append(struct.unpack('>i', cali_coeff[i+1:i+5])[0])
phase_para_b.append(struct.unpack('>i', cali_coeff[i+5:i+9])[0])
cis_cali_packet = 2
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][0] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][0] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[1][0] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[1][0] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
index = 40
for i in range(index, index+16, 8):
phase_para_a.append(struct.unpack('>i', cali_coeff[i+1:i+5])[0])
phase_para_b.append(struct.unpack('>i', cali_coeff[i+5:i+9])[0])
cis_cali_packet = 3
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][0] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][0] = struct.unpack('>i', cali_coeff[index+5:index+9])[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[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]/1e4)
#gain=1
cis_cali_packet = 4
index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][1] = struct.unpack('>i', cali_coeff[index+1:index+5])[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[1] 20k
index = 80
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8)
hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8)
hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]/1e4)
cis_cali_packet = 5
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[0][1] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[0][1] = struct.unpack('>i', cali_coeff[index+5:index+9])[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]
#Lv[2] 5k
index = 100
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8)
hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8)
hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]/1e4)
cis_cali_packet = 6
index = (cis_cali_packet - 1) * cis_data_len
phase_coeff[2][1] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
phase_offset[2][1] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
phase_coeff[3][1] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
phase_offset[3][1] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
#Lv[3] 200R
index = 120
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+1:index+5])[0]/1e8)
hsrtia_b.append(struct.unpack('>i', cali_coeff[index+5:index+9])[0]/1e8)
hsrtia_c.append(struct.unpack('>i', cali_coeff[index+9:index+13])[0]/1e4)
#gain=2
cis_cali_packet = 7
index = (cis_cali_packet - 1) * cis_data_len
hsrtia_a[0][2] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
hsrtia_b[0][2] = struct.unpack('>q', cali_coeff[index+5:index+13])[0]
rolloff[0][2] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
# hsrtia_a.append(struct.unpack('>I', cali_coeff[index+1:index+5])[0])
# hsrtia_b.append(struct.unpack('>I', cali_coeff[index+5:index+9])[0]/1e6)
# hsrtia_c.append(struct.unpack('>I', cali_coeff[index+9:index+13])[0]/1e5)
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]
# print('cutoff_freq', cutoff_freq)
# print('hsrtia_a', hsrtia_a)
# print('hsrtia_b', hsrtia_b)
# print('hsrtia_c', hsrtia_c)
# print('phase_para_a', phase_para_a)
# print('phase_para_b', phase_para_b)
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]
cali_table.append((cutoff_freq, phase_para_a, phase_para_b, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d))
#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
else:
@@ -1451,15 +1634,20 @@ class EISZeroOneDataDecoder(RecDataDecoder):
if len(data) < 18:
return None
ch1 = struct.unpack('>i', data[1+3:5+3])[0] # unit: 1/1000 nA
ch2 = struct.unpack('>i', data[5+3:9+3])[0] # unit: mV
ch3 = struct.unpack('>i', data[9+3:13+3])[0] # unit: kOm
ch1 = struct.unpack('>i', data[1+3:5+3])[0]
ch2 = struct.unpack('>i', data[5+3:9+3])[0]
ch3 = struct.unpack('>i', data[9+3:13+3])[0]
time_stamp: float = struct.unpack('<I', data[13+3:17+3])[0] # unit: ms
cycle_number = struct.unpack('>H', data[17+3:19+3])[0]
d19 = data[19+3]
gain = (d19 & 0x0F)
finishMode = (d19 & 0x80) >> 7
gain = data[20+3]
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:
self._start_return_data = True
@@ -1467,7 +1655,7 @@ class EISZeroOneDataDecoder(RecDataDecoder):
return None
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)
else:
time_stamp, delta, ret_get_time_stamp = self.get_time_stamp(time_stamp)
@@ -1476,101 +1664,81 @@ class EISZeroOneDataDecoder(RecDataDecoder):
print("error timeStamp full data:", list(data), datetime.now(), '\n')
return None
else:
if self.cali_coeff is not None and self._mode == 0:
phase_para_a = []
phase_para_b = []
hsrtia_a = []
hsrtia_b = []
hsrtia_c = []
hsrtia_d = []
cutoff_freq, phase_para_a, phase_para_b, 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._freq_start > self._freq_stop):
self._freq_direction = 0
else:
self._freq_direction = 1
if self.cali_coeff is not None and (self._mode == 0 or self._mode == 5):
phase_coeff, phase_offset, hsrtia_a, hsrtia_b, rolloff = self.cali_coeff[0]
if (self._mode == 0):
img = ch1
real = ch2
freq = ch3
voltage_mag = math.sqrt(img ** 2 + real ** 2) * (1 + freq ** 2 / cutoff_freq ** 2)
# if (gain == 3):
# current = hsrtia_a[gain] * math.exp(hsrtia_b[gain] * voltage_mag) + hsrtia_c[gain] * math.exp(hsrtia_d[gain] * voltage_mag)
# else:
current = voltage_mag ** 2 * hsrtia_a[gain] + voltage_mag * hsrtia_b[gain] + hsrtia_c[gain]
# print(current)
# print(voltage_mag)
# print(hsrtia_a[gain])
# print(hsrtia_b[gain])
# print(hsrtia_c[gain])
if (self._mode == 0 or self._mode == 5):
img = ch1 #img[ohm]
real = ch2 #real[ohm]
freq = ch3 #freq[10mHz]
fre_idx = 0
voltage_amp = round(ch4 / 1000) #ch4=Amp[uV] #voltage_amp[mV]
rolloff_cali = rolloff[0][gain]
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 (current != 0):
# impedance = voltage_amp * 1000_000 / 1.414213 / current
impedance = voltage_amp * 707106.78 / 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
else:
impedance = 0
if (real > 0):
raw_phase = math.atan(img / real) * 180 / math.pi
elif (real == 0):
raw_phase = 90
else:
raw_phase = math.atan(img / real) * 180 / math.pi + 180
raw_phase = math.atan2(img , real) * 180 / math.pi
if (freq >= 1000000): # 10000 Hz
i = 0
elif (freq >= 10000): # 100 Hz
i = 1
elif (freq >= 1000): # 10 Hz
i = 2
elif (freq >= 1): # 0.01 Hz
i = 3
if (freq >= 1000000): #10000Hz
fre_idx = 0
elif (freq >= 10000): #100Hz
fre_idx = 1
elif (freq >= 1000): #10Hz
fre_idx = 2
elif (freq >= 1): #0.01Hz
fre_idx = 3
ideal_raw_phase = phase_para_a[i] /1e10 * freq + phase_para_b[i] / 1e6
ideal_raw_phase = phase_coeff[gain][fre_idx] /1e10 * freq + phase_offset[gain][fre_idx] / 1e6
phase = raw_phase - ideal_raw_phase
phase = phase % 180 if phase % 180<=90 else phase % 180-180
if (self._first_phase_flag):
self._last_phase = phase
self._first_phase_flag = 0
elif (abs(phase - self._last_phase) >= 200):
phase -= 360
self._last_phase = phase
imag_after_cal = impedance * math.sin(phase * math.pi / 180)
real_after_cal = impedance * math.cos(phase * math.pi / 180)
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._mode == 0 or self._mode == 5):
print('|', '{:10}'.format(time_stamp),
'|', '{:5}'.format(delta),
'|', '{:5}'.format(img),
'|', '{:5}'.format(real),
'|', '{:9}'.format(freq*10), '[mHz]',
'|', '{:5}'.format(cycle_number),
'|', '{:5}'.format(round(imag_after_cal)), '[Ohm]', #Z_imag[Ohm]
'|', '{:5}'.format(round(real_after_cal)), '[Ohm]', #Z_real[Ohm]
'|', '{:5}'.format(round(impedance)), '[mOhm]',
'|', '{:5}'.format(round(phase*1000)), '[mdegree]',
'|', '{:10}'.format(round(current)), '[nA]',
'|', '{:1}'.format(gain),
'|', '{:1}'.format(finishMode),
'@', str(self.device), '|', flush = True)
if (self._mode == 0):
# print('|', '{:10}'.format(time_stamp),
# '|', '{:5}'.format(delta),
# '|', '{:6}'.format(ch1),
# '|', '{:6}'.format(ch2),
# '|', '{:8}'.format(ch3 / 100),
# '|', '{:6}'.format(round(voltage_mag)),
# '|', '{:5}'.format(int(imag_after_cal)),
# '|', '{:5}'.format(int(real_after_cal)),
# '|', '{:5}'.format(round(impedance)),
# '|', '{:5}'.format(round(phase, 1)),
# '|', '{:5}'.format(round(current, 3)),
# '|', '{:1}'.format(gain),
# '|', '{:1}'.format(finishMode),
# '@', str(self.device), '|')
pass
else:
# print('|', '{:10}'.format(time_stamp),
# '|', '{:5}'.format(delta),
# '|', '{:5}'.format(ch1),
# '|', '{:5}'.format(ch2),
# '|', '{:5}'.format(ch3),
# '|', '{:5}'.format(cycle_number),
# '|', '{:1}'.format(gain),
# '|', '{:1}'.format(finishMode),
# '@', str(self.device), '|')
pass
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
else:
print('|', '{:10}'.format(time_stamp),
'|', '{:5}'.format(delta),
'|', '{:5}'.format(ch1),
'|', '{:5}'.format(ch2),
'|', '{:5}'.format(ch3),
'|', '{:5}'.format(cycle_number),
'|', '{:1}'.format(gain),
'|', '{:1}'.format(finishMode),
'@', str(self.device), '|', flush = True)
pass
if finishMode == True:
print("finishMode full data:", list(data), datetime.now())
@@ -1579,22 +1747,30 @@ class EISZeroOneDataDecoder(RecDataDecoder):
self._mode_stop = 0
ret = RecordingData(self.device, int(time_stamp * 1000 / 2), 0)
if (self._mode == 0): #EIS Mode
ret.append_data(0, ch1) #Raw Imag
ret.append_data(1, ch2) #Raw Real
ret.append_data(2, ch3 * 10) #Frequency [mHz]
if self._mode == 0 or self._mode == 5: #EIS/CF Mode
ret.append_data(0, img)
ret.append_data(1, real)
ret.append_data(2, freq * 10) #[mHz]
ret.append_data(3, cycle_number)
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(6, round(impedance)) #Impedance [Ohm]
ret.append_data(7, round(phase)) #Phase [degree]
ret.append_data(8, round(current)) #Current [nA]
ret.append_data(9, gain) #Gain Level
ret.append_data(6, round(impedance)) #[mOhm]
ret.append_data(7, round(phase*1000)) #[millidegree]
ret.append_data(8, round(current)) #[nA]
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
ret.append_data(0, ch1) #Iin [nA]
ret.append_data(1, ch2) #Vset [nV]
ret.append_data(2, ch3) #Vout [nV]
ret.append_data(0, ch1) #Iin [nA]?
ret.append_data(1, ch2) #Vset [nV]?
ret.append_data(2, ch3) #Vout [nV]?
ret.append_data(3, cycle_number)
if cycle_number != self._cycle_number:
+1 -1
View File
@@ -738,7 +738,7 @@ class DeviceCommonInstruction:
elif instruction == cls.START:
return '_data_format("TDC4VAF2")', '_notify(True)', 'VIS_STI', '_sync(True)'
elif instruction == cls.INTERRUPT:
return '_sync(False)', '_notify(False)', 'VIS_INT'
return '_notify(False)', 'VIS_INT', '_sync(False)'
elif instruction == cls.CLOSE:
return '_sync(False)', '_notify(False)', 'VIS_INT'
elif instruction == cls.CALL:
+2
View File
@@ -283,6 +283,7 @@ class InternalInstruction(SingleInstruction):
PREDEFINED_SET = '_set'
PREDEFINED_CDR = '_cdr'
PREDEFINED_DISABLE_CACHE = '_disable_cache'
PREDEFINED_IDLE = '_idle'
PREDEFINED = (
PREDEFINED_SLEEP,
@@ -294,6 +295,7 @@ class InternalInstruction(SingleInstruction):
PREDEFINED_SET,
PREDEFINED_CDR,
PREDEFINED_DISABLE_CACHE,
PREDEFINED_IDLE,
)
__slots__ = ('_expr', '_para')
+20 -2
View File
@@ -968,7 +968,7 @@ class CompletedDevice(Device):
"""
__slots__ = ('_master', '_device_id', '_device', '_library', '_context',
'_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):
"""
@@ -986,6 +986,8 @@ class CompletedDevice(Device):
# device status ( 0: idle, 1: working, 2: error, 3: power off)
self._status = 0
# device be occupied by project
self._occupied_by_project = None
# context
s1 = library.constant
@@ -1032,7 +1034,7 @@ class CompletedDevice(Device):
@property
def mac_address_in_str(self) -> str:
return ':'.join('{:02x}'.format(b) for b in self._device.mac_address)
return ':'.join('{:02x}'.format(b) for b in self._device.mac_address).upper()
@property
def device(self) -> Device:
@@ -1082,6 +1084,14 @@ class CompletedDevice(Device):
def status(self, 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
def parameters(self) -> List[str]:
@@ -1105,6 +1115,8 @@ class CompletedDevice(Device):
return self._configuration.get_parameter(name, False)
def set_multi_parameters(self, parameter):
if len(parameter) == 0:
return
for (name, value) in parameter[0].items():
if name != 'target':
self.set_parameter(name, value)
@@ -1128,6 +1140,11 @@ class CompletedDevice(Device):
self._parameter.set_parameter(name, value)
# raise RuntimeError('illegal parameter value : ' + value) from e
else:
if name == 'MODE':
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('TIME_DURATION', 0)
self._parameter.set_parameter(name, value)
on_change = info.on_change
@@ -1296,6 +1313,7 @@ class CompletedDevice(Device):
'recording_file_name': self.recording_file_name,
'library_name': self._library.name,
'library_version': str(self._library.version),
'occupied_by_project': self._occupied_by_project,
'configuration': self.configuration.as_json(list_hide=True),
}
+21 -7
View File
@@ -35,7 +35,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
'_pin_ram_sel_value', '_pin_mem_sel_value', '_pin_mem_req_value',
'_read_green_times','_read_red_times',
'_elite_data_len', '_mem_header_len', '_mem_tailer_len', '_single_data_len',
'_head_wrong_cnt')
'_head_wrong_cnt', '_pin_busy_value')
def __init__(self,
select: Selector,
@@ -50,11 +50,11 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
self._single_data_len = self._elite_data_len + self._mem_header_len + self._mem_tailer_len
# buffer
self._tx_buffer_header = [0] * 19
self._tx_buffer_header = [0] * 64
self._tx_buffer_data = [0] * (self._single_data_len * 10 + 3)
# memory control pin
self.pin_busy = OutputPin.get_used(P3Pin.MEM_BZY, True)
self.pin_busy: Optional[InputPin] = InputPin.get_used(P3Pin.MEM_BZY)
self.pin_mem_req = OutputPin.get_used(P3Pin.MEM_REQ, False)
self.pin_mem_sel = OutputPin.get_used(P3Pin.MEM_RST, True) # MEM_RST -> actually which memory board is assign
self.pin_ram_sel: Optional[InputPin] = InputPin.get_used(P3Pin.MEM_SEL) # MEM_SEL -> actually is RAM_SEL, which RAM is assign
@@ -62,6 +62,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
self._pin_ram_sel_value = [bool(self.pin_ram_sel) for _ in range(Selector.SIZE)]
self._pin_mem_sel_value = [bool(self.pin_mem_sel) for _ in range(Selector.SIZE)]
self._pin_mem_req_value = [bool(self.pin_mem_req) for _ in range(Selector.SIZE)]
self._pin_busy_value = [bool(self.pin_busy) for _ in range(Selector.SIZE)]
self._read_green_times = 0
self._read_red_times = 0
@@ -98,6 +99,14 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
self._pin_ram_sel_value[channel] = True
return self._pin_ram_sel_value[channel]
def get_pin_busy(self):
channel = self.select
if self.pin_busy.input() == 0:
self._pin_busy_value[channel] = False
else:
self._pin_busy_value[channel] = True
return self._pin_busy_value[channel]
@property
def select(self) -> int:
return self._selector.channel
@@ -216,7 +225,9 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
return
def recv_memory(self, device: int) -> Optional[bytes]:
self.pin_busy.output(False)
# self.pin_busy.output(False)
# print('mem_req==ram_sel,[', self._pin_mem_req_value[device], ',', self._pin_ram_sel_value[device], ']')
rx = []
@@ -300,6 +311,9 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
print("green data print:", data, device, datetime.now())
return None
# print('data=', list(data))
# print('Ram:', data[62])
if (length >= 4000):
flag_print = True
print("green data: big length:", length)
@@ -415,9 +429,9 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
except BaseException as e:
print(e)
finally:
# print("\n")
self.pin_busy.output(True)
# finally:
# # print("\n")
# self.pin_busy.output(True)
return bytes(rx)
+1 -1
View File
@@ -28,7 +28,7 @@ class UARTInterface(LowLevelHardwareInterface):
self._serial = serial.Serial(self._port,
baudrate=self._baudrate,
timeout=0,
writeTimeout=0.01)
writeTimeout=1)
# deprecate function name which change at version 3.0
self._serial.flushInput()
self._serial.flushOutput()
+8
View File
@@ -24,3 +24,11 @@ class Action():
@property
def condition(self):
return self._condition
def as_json(self):
return {
'id': self._id,
'type': self._type,
'target': self._target,
'condition': self._condition
}
+61 -12
View File
@@ -45,8 +45,8 @@ class Condition():
# print(operator, x, y)
cases = {
"equal": lambda a, b: a == b,
"bigger": lambda a, b: a > b,
"smaller": lambda a, b: a < b,
"bigger": lambda a, b: a >= b,
"smaller": lambda a, b: a <= b,
}
return cases[operator](x, y)
@@ -56,7 +56,8 @@ class Condition():
return getattr(self, self.type)(**kwargs)
def absolute_time(self, **kwargs):
now = int(time())
# now = int(time())
now = round(time(), 1)
time_condition = round(self.datetime_to_timestamp(self.str_to_datetime(self._value)))
return self.compareWith(self.comparsion, now, time_condition)
@@ -65,32 +66,80 @@ class Condition():
project_start_time = kwargs['project_start_time']
delay_time = kwargs['delay_time']
time_diff = int(time() - project_start_time - delay_time)
return self.compareWith(self.comparsion, time_diff, int(self._value))
# time_diff = int(time() - project_start_time - delay_time)
time_diff = round(time() - project_start_time - delay_time, 1)
return self.compareWith(self.comparsion, time_diff, round(int(self._value), 1))
def after_task_run(self, **kwargs):
# print('relative_time_from_task', kwargs,kwargs['task_start_time'],kwargs['delay_time'])
# print('relative_time_from_task', kwargs['task_start_time'],kwargs['delay_time'])
if len(kwargs['task_start_time']) == 0:
return False
task = kwargs['self_task']
running_task = kwargs['running_task']
task_start_time = kwargs['task_start_time'][-1]
delay_time = kwargs['delay_time']
time_diff = int(time() - task_start_time - delay_time)
# print('time_diff', time_diff)
return self.compareWith(self.comparsion, time_diff, int(self._value))
time_diff = round(time() - task_start_time - delay_time, 1)
# print('real_diff', time() - task_start_time - delay_time)
# print(task.name, task.uuid, time_diff, round(int(self._value), 1), running_task.name, running_task.uuid)
# if round(int(self._value), 1) == 0 and time_diff == 0.1:
# return True
if task.uuid != running_task.uuid:
return False
return self.compareWith('bigger', time_diff, round(int(self._value), 1))
# return self.compareWith(self.comparsion, time_diff, round(int(self._value), 1))
def device(self, **kwargs):
print('device')
def previous_task_done(self, **kwargs):
""" def previous_task_done(self, **kwargs):
running_task = kwargs['running_task']
if running_task.status == 2 and self._active == False:
self._active = True
return True
return False """
def previous_task_done(self, **kwargs):
running_task = kwargs['running_task']
self_task = kwargs['self_task']
# if running_task != None and self_task != None:
# print('\nprevious_task_done: ', running_task.status, ' ', self._active)
if running_task != self_task:
if running_task == None:
return True
if running_task.status == 2 and self._active == False:
# self._active = True
return True
return False
def until_button_trigger(self, **kwargs):
running_task = kwargs['running_task']
if running_task != None:
if running_task.button_trigger == True:
running_task.button_trigger = False
return True
return False
""" def cycle(self, **kwargs):
running_task = kwargs['running_task']
self_task = kwargs['self_task']
if running_task != self_task:
if running_task.status == 2 and self._active == False:
# self._active = True
return True
return False """
def str_to_datetime(self, time_str):
return datetime.strptime(time_str,'%Y-%m-%dT%H:%M')
def datetime_to_timestamp(self, date):
return datetime.timestamp(date)
return datetime.timestamp(date)
def as_json(self):
return {
'id': self._id,
'type': self._type,
'comparsion': self._comparsion,
'value': self._value,
'active': self._active
}
+6 -1
View File
@@ -22,6 +22,7 @@ class Instruction():
self._start_instruction = list(map(lambda ins: self._instruction_set[ins] ,['set_file_name', 'set_parent', 'set_parameter', 'call_instruction']))
self._stop_instruction = list(map(lambda ins: self._instruction_set[ins] ,['call_instruction']))
self._idle_instruction = []
@property
def start(self) -> list:
@@ -29,4 +30,8 @@ class Instruction():
@property
def stop(self) -> list:
return self._stop_instruction
return self._stop_instruction
@property
def idle(self) -> list:
return self.idle_instruction
+180 -29
View File
@@ -1,6 +1,7 @@
import sys
import json
import threading
import logging
from time import time, sleep
from datetime import datetime
@@ -19,12 +20,12 @@ key_list = {
}
class Project(threading.Thread):
def __init__(self, project, device_manager: DeviceManager, mqttThread = None, name="project"):
def __init__(self, project, device_manager: DeviceManager, mqttThread = None, log_verbose = None, name="project"):
super(Project, self).__init__(name = name)
self._project = project
self._device_manager = device_manager
self._mqtt_thread = mqttThread
self._time_interval = 1
self._time_interval = 0.1
self._start_time = None
self._end_time = None
@@ -33,7 +34,7 @@ class Project(threading.Thread):
self._name = None
self._desc = None
self._device = None
self._complete_device = []
self._complete_device = {}
self._status = 0
self._instruction_set = Instruction()
@@ -41,16 +42,32 @@ class Project(threading.Thread):
self._task_manager = None
self._cycle = []
self._count = 1 #流水號
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_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):
for (key, value) in project.items():
if key in key_list.keys():
key = key_list[key]
if key == 'task':
self._task_manager = TaskManager(project['task'])
self._task_manager = TaskManager(project['task'], project['cycle'])
elif key == 'uuid':
pass
else:
@@ -58,8 +75,10 @@ class Project(threading.Thread):
def setup_device(self, device_list):
for device in device_list:
complete_device = self._device_manager.get_device(device['connectDevice']['device_address'])
self._complete_device.append(complete_device)
mac_address = device_list[device]['pair']
complete_device = self._device_manager.get_device(mac_address)
complete_device.occupied_by_project = self._uuid
self._complete_device[device] = complete_device
@property
def id(self) -> int:
@@ -84,6 +103,14 @@ class Project(threading.Thread):
@name.setter
def name(self, new_name):
self._name = new_name
@property
def cycle(self) -> list:
return self._cycle
@cycle.setter
def cycle(self, new_cycle):
self._cycle = new_cycle
@property
def desc(self) -> str:
@@ -117,9 +144,28 @@ class Project(threading.Thread):
def mqtt_thread(self):
return self._mqtt_thread
@property
def running_task(self):
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):
# project status change running (1)
self._status = 1
# save start time
self._start_time = time()
# saving & broadcast message
self._logger.info('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])
while not self._stop_flag :
@@ -130,47 +176,111 @@ class Project(threading.Thread):
for task in check_list:
if task != None:
now = time()
# print('round task', task.name)
# print('running task', self._task_manager.running_task.name, self._task_manager.running_task.status)
# if self._task_manager.prev_task != None:
# print('previous_task', self._task_manager.prev_task.name, self._task_manager.prev_task.status)
match_condition_list = task.check_condition(
project_start_time = self._start_time,
delay_time = delay_time,
running_task= self._task_manager.running_task,
previous_task = self._task_manager.prev_task
previous_task = self._task_manager.prev_task,
self_task = task
)
# print('match_condition_list', match_condition_list)
for condition in match_condition_list:
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:
# print('match_action', action.type, action.target)
if action.type == 'start' and task.status != 1:
self._task_manager.set_running_task(task)
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._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':
self._task_manager.running_task.stop()
self._logger.info(f'---------- Cycle {cycle_info["id"]} Round {cycle_info["count"]} -----------')
device = self._complete_device[action.target]
task_info = task.get_task_info(action)
instruction_set = getattr(self._instruction_set, action.type, None)
# print('instruction_set',instruction_set)
if instruction_set != None:
for instruction in instruction_set:
args = list(map(lambda arg: task_info[arg], instruction['arguments']))
threading.Thread(target=getattr(device, instruction['method'])(*args))
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':
self._task_manager.running_task.stop()
if action.type == 'start':
if task.status != 1:
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])
# 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._count += 1
# if self.check_running_task_not_run() == True:
# self._task_manager.running_task.stop()
elif action.type == 'idle':
self._task_manager.running_task.stop()
# elif action.type == 'stop':
# self._task_manager.running_task.stop()
instruction_set = None
if action.target is not None:
device = self._complete_device[action.target]
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))
task_info = task.get_task_info(action)
instruction_set = getattr(self._instruction_set, action.type, None)
# 檔名修正
# device
task_info['file_name'] += '#' + device.mac_address_in_str[12:].upper()
# 流水號
task_info['file_name'] += '#' + str(self._count)
# 添加cycle資訊
if len(self.cycle) > 0:
index = self._task_manager.get_index_by_task(task)
# get list of cycle determine by index of task
filtered = list(filter(lambda info: self._task_manager.get_index_by_uuid(info['range'][0]) < index and self._task_manager.get_index_by_uuid(info['range'][1]) > index, self.cycle))
if len(filtered) == 0:
pass
elif len(filtered) == 1:
if filtered[0]['useID'] == True:
task_info['file_name'] += '#' + str(filtered[0]['id'])
else:
task_info['file_name'] += '#' + str(filtered[0]['name']) + '-' + str(filtered[0]['count'])
else:
# if multi cycle, then sort by range from task index to cycle start index, then loop concat filename
filtered.sort(key=lambda info: abs(self._task_manager.get_index_by_uuid(info['range'][0]) - index))
for cycle_info in filtered:
if cycle_info['useID'] == True:
task_info['file_name'] += '#' + str(cycle_info['id'])
else:
task_info['file_name'] += '#' + str(cycle_info['name']) + '-' + str(cycle_info['count'])
self.log_verbose('file name ' + task_info['file_name'])
if instruction_set != None and self.get_device_parameter_set(action.target) != None:
for instruction in instruction_set:
print('instruction 1', device, instruction, datetime.now())
args = list(map(lambda arg: task_info[arg], instruction['arguments']))
target=getattr(device, instruction['method'])(*args)
print('instruction 2', device, instruction, datetime.now())
if action.type == 'start':
self._count += 1
delay_time += (time() - now)
# check task not running then stop
if self.check_running_task_not_run() == True:
self.mqtt_thread.broadcast_command('project:task ' + str(self._task_manager.running_task.name) + ' stop at ' + datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
# self._logger.info(f'taskType {self._task_manager.running_task.name} {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._task_manager.running_task.stop()
# check project done then close project
if self.check_project_done() == True:
print('project stop at', datetime.now())
self.close()
self.stop()
if self._time_interval - delay_time > 0:
sleep(self._time_interval - delay_time)
@@ -180,14 +290,19 @@ class Project(threading.Thread):
pass
def stop(self):
for device in self._complete_device:
self._complete_device[device].occupied_by_project = None
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._status = 2
self._end_time = time()
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])
def close(self):
for device in self._complete_device:
self._complete_device[device].occupied_by_project = None
self._status = 2
self._end_time = time()
self._stop_flag = True
@@ -200,11 +315,34 @@ class Project(threading.Thread):
return False
return True
def set_content(self, content):
self.running_task.button_trigger = True
def set_cycle(self, index, content):
# change cycle name
for key in content:
self.cycle[index][key] = content[key]
# change task name
# self._task_manager.get_task_by_uuid(self.cycle[index]['range'][0]).name = content['name']
# self._task_manager.get_task_by_uuid(self.cycle[index]['range'][1]).name = content['name']
def check_running_task_not_run(self):
# if no running task
if self._task_manager.running_task == None:
return False
# if running is cycle then no need to stop by device
if self._task_manager.running_task.type == 'cycle':
return False
for key in self._task_manager.running_task.action:
# print('action key', key, self._task_manager.running_task, self._task_manager.running_task.action[key])
if len(self._task_manager.running_task.parameter_set) == 0 and self._task_manager.running_task.action[key]['type'] == 'stop':
return False
if len(self._task_manager.running_task.parameter_set) == 0 and self._task_manager.running_task.action[key]['type'] == 'idle':
return False
for device in self._task_manager.running_task.device:
if self._complete_device[device].status == 1:
return False
@@ -222,6 +360,19 @@ class Project(threading.Thread):
'status': self._status,
'device': self._device,
'task': self.task_list,
'running_task': running_task
'running_task': running_task,
'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
+11 -2
View File
@@ -9,13 +9,14 @@ def json_stringify(o: Any) -> str:
return _json_stringify(o, separators=(',', ':'))
class ProjectManager():
def __init__(self, device_manager: DeviceManager, mqtt_thread=None) :
def __init__(self, device_manager: DeviceManager, mqtt_thread=None, log_verbose = None) :
self._project_list = []
self._mqtt_thread = mqtt_thread
self._device_manager = device_manager
self.log_verbose = log_verbose
def create(self, project):
new_project = Project(project, self._device_manager, self._mqtt_thread)
new_project = Project(project, self._device_manager, self._mqtt_thread, self.log_verbose)
self._project_list.append(new_project)
return new_project
@@ -37,3 +38,11 @@ class ProjectManager():
def stop_project(self, project):
_project = self.get(project)
_project.stop()
def set_project(self, project_uuid, content):
_project = self.get(project_uuid)
_project.set_content(content)
def set_project_cycle(self, project_uuid, index, content):
_project = self.get(project_uuid)
_project.set_cycle(index, content)
+62 -2
View File
@@ -12,29 +12,39 @@ key_list = {
class Task:
def __init__(self, task):
self._id = None
self._uuid = None
self._type = None
self._name = None
self._parent = None
self._cycle = None
self._cycle_count = 0
self._cycle_next = None
self._cycle_next_uuid = None
self._device = None
self._event = None
self._trigger = None
self._parameter_set = None
self._condition = None
self._action = None
# -1: initial 0: start(idle), 1: running, 2: close(idle)
# -1: init 0: start(idle), 1: run, 2: close(idle)
self._status = 0
self._next = None
# action & condition info
self._condition_list: List[Condition] = []
self._action_list: List[Action] = []
self._instruction_list = []
self._record_list = []
# time info
self._start_time = []
self._idle_time = []
self._end_time = []
self._period = None
# trigger info
self._button_trigger = False
self.load_task(task)
def load_task(self, task) -> None:
@@ -74,6 +84,14 @@ class Task:
@uuid.setter
def uuid(self, new_uuid):
self._uuid = new_uuid
@property
def type(self):
return self._type
@type.setter
def type(self, new_type):
self._type = new_type
@property
def name(self):
@@ -100,6 +118,31 @@ class Task:
@cycle.setter
def cycle(self, new_cycle):
self._cycle = new_cycle
# TODO: not sure needed?
@property
def cycle_count(self) -> int:
return self._cycle_count
@cycle_count.setter
def cycle_count(self, new_cycle_count):
self._cycle_count = new_cycle_count
@property
def cycle_next(self) -> str:
return self._cycle_next
@cycle_next.setter
def cycle_next(self, new_cycle_next):
self._cycle_next = new_cycle_next
@property
def cycle_next_uuid(self) -> str:
return self._cycle_next_uuid
@cycle_next_uuid.setter
def cycle_next_uuid(self, new_cycle_next_uuid):
self._cycle_next_uuid = new_cycle_next_uuid
@property
def device(self) -> dict:
@@ -177,6 +220,14 @@ class Task:
def end_time(self) -> List:
return self._end_time
@property
def button_trigger(self) -> List:
return self._button_trigger
@button_trigger.setter
def button_trigger(self, button_trigger):
self._button_trigger = button_trigger
def new_start_time(self):
self._start_time.append(time())
@@ -207,6 +258,10 @@ class Task:
def stop(self):
self.status = 2
def reset(self):
self.status = -1
# self.status = 0
def get_match_action_list(self, match_condition_list):
return map(lambda condition: [x for x in self._action_list if condition.id in x.get_condition_list()], match_condition_list)
@@ -230,7 +285,7 @@ class Task:
return {
'device': action.target,
'parameter': self.get_parameter_set_by_device(action.target),
'file_name': self._name + '-' + str(action.target),
'file_name': self._name,
'parent': self.parent,
'instruction': _type
}
@@ -240,7 +295,12 @@ class Task:
'id': self.id,
'name': self.name,
'parent': self.parent,
'type': self.type,
'uuid': self.uuid,
'cycle': self.cycle,
'cycle_count': self.cycle_count,
'cycle_next': self.cycle_next,
'cycle_next_uuid': self.cycle_next_uuid,
'device': self.device,
'event': self.event,
'trigger': self.trigger,
+79 -2
View File
@@ -12,11 +12,12 @@ def json_stringify(o: Any) -> str:
return _json_stringify(o, separators=(',', ':'))
class TaskManager():
def __init__(self, task_list):
def __init__(self, task_list, cycle_list):
self._task_list = []
self._next_task = []
self._prev_task = None
self._running_task = None
self._cycle_list = cycle_list
self.load_task_list(task_list)
@@ -44,6 +45,28 @@ class TaskManager():
def next_task(self):
return self._next_task
def get_task_by_index(self, index):
return self._task_list[index]
def get_task_by_uuid(self, uuid):
return next((x for x in self.task_list if x.uuid == uuid), None)
def get_index_by_task(self, task):
return next((i for i, x in enumerate(self.task_list) if x.uuid == task.uuid), None)
def get_index_by_uuid(self, uuid):
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):
for index, cycle in enumerate(self._cycle_list):
if cycle['range'][1] == task.uuid:
return index
@property
def check_list(self):
return [self._running_task, *self._next_task]
@@ -57,7 +80,8 @@ class TaskManager():
task = Task(task)
self._task_list.append(task)
def set_running_task(self, task):
# original version
""" def set_running_task(self, task):
try:
# if there is task running & same task active ,then reject
if self._running_task != None and self._running_task.uuid == task.uuid:
@@ -80,6 +104,59 @@ class TaskManager():
_task = next((task for task in self._task_list if task.uuid == task_uuid), None)
if _task != None:
self._next_task.append(_task)
except RuntimeError as e:
print(e) """
def set_running_task(self, task):
try:
# if there is task running & same task active ,then reject
if self._running_task != None and self._running_task.uuid == task.uuid:
return False
# save task
self._prev_task = self._running_task
# clear next task list
self._next_task.clear()
# set task to running_task
self._running_task = task
self._running_task.run()
# if previous task is still running, then need to close
if self._prev_task != None:
if self._prev_task.status == 1:
self._prev_task.stop()
# 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)
if cycle_index is None:
# print('next', self._running_task.name, 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)
if _task != None:
_task.reset()
self._next_task.append(_task)
# print('self._next_task', self._next_task)
else:
# print('cycle', self._cycle_list[cycle_index])
cycle = self._cycle_list[cycle_index]
if int(cycle['count']) < int(cycle['max']):
self._next_task.append(self.get_task_by_uuid(cycle['range'][0]))
# cycle['count'] += 1
else:
for task_uuid in self._running_task.next:
_task = next((task for task in self._task_list if task.uuid == task_uuid), None)
if _task != None:
_task.reset()
self._next_task.append(_task)
# 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:
print(e)
+15 -4
View File
@@ -118,7 +118,7 @@ class RecordingMetaFile(JsonSerialize):
'_dirty', '_last_modify_time', '_file_size_cache',
'_recording_file_ch', '_recording_sub_file', '_size',
'_parameter', '_parent', '_recording_file_name', '_recording_sub_mini', '_recording_mini_ch',
'_raw_serial_number', '_mini_serial_number', '_device_id')
'_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):
if isinstance(filepath, str):
@@ -153,6 +153,7 @@ class RecordingMetaFile(JsonSerialize):
self._parent = ''
self._recording_file_name = ''
self._device_id = -1
self._project_id = None
# recording parameter
self._configuration = None
@@ -297,6 +298,7 @@ class RecordingMetaFile(JsonSerialize):
'uuid': str(self._file_uuid),
'data_format': 'rec',
'device': self._device,
'project': self._project_id,
}
if len(self._parent) > 0:
@@ -462,7 +464,7 @@ class RecordingMetaFile(JsonSerialize):
def parameter(self) -> str:
return self._parameter
@device.setter
@parameter.setter
def parameter(self, parameter):
self._parameter = parameter
return None
@@ -471,7 +473,7 @@ class RecordingMetaFile(JsonSerialize):
def parent(self) -> str:
return self._parent
@device.setter
@parent.setter
def parent(self, parent):
self._parent = parent
@@ -479,7 +481,7 @@ class RecordingMetaFile(JsonSerialize):
def recording_file_name(self) -> str:
return self._recording_file_name
@device.setter
@recording_file_name.setter
def recording_file_name(self, recording_file_name):
self._recording_file_name = recording_file_name
@@ -492,6 +494,15 @@ class RecordingMetaFile(JsonSerialize):
self._configuration = conf
self._dirty = True
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
def channels(self) -> List[int]:
+36 -18
View File
@@ -4,7 +4,6 @@ from time import time, sleep
from typing import Iterable
from datetime import datetime
import gc
import base64
from biopro.data import *
@@ -27,7 +26,6 @@ from .mqtt import MqttDataMessageHandler, MqttThread
from .database import DataBaseProcess
from .recording import RecordingProcess
from multiprocessing import Queue
import queue
from json import loads as json_parse, dumps as _json_stringify
import json
@@ -65,7 +63,7 @@ class DataServer(SocketServer, DataAPI):
"""
global _FLAG_DATA_LOST_STATS_
super().__init__(DataAPI, 'DataServer', self.ADDR, socket_listen=3)
super().__init__(DataAPI, 'DataServer', self.ADDR, socket_listen=20)
data_options = DataServerOptions.get_options(*options)
@@ -317,7 +315,8 @@ class DataServer(SocketServer, DataAPI):
def update_device_configuration(self,
device: str,
meta_file: Union[str, Path, RecordingMetaFile],
data_format: Union[AnyStr, DataDecodeFormat]):
data_format: Union[AnyStr, DataDecodeFormat],
project_info: str):
# meta file
device_id = -1
@@ -345,6 +344,8 @@ class DataServer(SocketServer, DataAPI):
_parent = json_stringify(_device['parent'])
_recording_file_name = _device['recording_file_name']
mac_address = json.loads(device)['device_address']
device_id = _device['device_id']
del _device['configuration']
del _device['parent']
del _device['recording_file_name']
@@ -354,13 +355,22 @@ class DataServer(SocketServer, DataAPI):
# meta_file.parameter = _parameter
# meta_file.parent = _parent
# meta_file.recording_file_name = _recording_file_name
device_id = int(json.loads(device)['device_id'])
if device_id < 0:
raise ValueError('illegal device ID : ' + str(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:
# self._configurationsappend(None)
@@ -380,8 +390,6 @@ class DataServer(SocketServer, DataAPI):
else:
data_format = data_format.name
# self.log_verbose('device data format', data_format)
self.log_verbose('device meta file', meta_file)
# data runtime
@@ -406,15 +414,15 @@ class DataServer(SocketServer, DataAPI):
c.shutdown()
c.join()
self._spi.set_wait_flag(c._device, True)
data_runtime_process = RecordingProcess('data_server', self.log_verbose, device_id,
Queue(), self._queue_ds_dict[int(device_id)], self._queue_msg, meta_file,
json_stringify(_device), _parameter, _parent, _recording_file_name,
data_format, self.socket_mqtt_ip, self.socket_mqtt_port,
database = self.database_process )
# data_runtime_process.start()
data_format, self.socket_mqtt_ip, self.socket_mqtt_port,
project_id = project_id,
database = self.database_process)
# check 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)
@@ -646,6 +654,7 @@ class DataServer(SocketServer, DataAPI):
def whether_to_record(self, device):
# if user click "start", return True; if user click "stop", return False;
if device in self._configurations.keys() and self._configurations[device] is not None:
# print(self._configurations.keys(), ',', device, datetime.now())
return True
else:
return False
@@ -654,6 +663,9 @@ class DataServer(SocketServer, DataAPI):
ret = False
sync = self.get_spi_obj()
busy = sync.get_pin_busy()
# print('pin_busy=', busy, device, datetime.now())
if sync.get_pin_mem_req() == sync.get_pin_ram_sel():
spi_data = sync.recv_memory(device)
signal = sync.get_pin_mem_req()
@@ -662,15 +674,18 @@ class DataServer(SocketServer, DataAPI):
else:
data = None
print('data=None, mem_req!=ram_sel, [', sync.get_pin_mem_req(), ', ', sync.get_pin_ram_sel(), ']', device, datetime.now())
if data is not None:
if self._configurations[device].queue_flag:
self._configurations[device].queue_flag = False
print("q size= ", self._configurations[device]._queue_rec.qsize())
self._configurations[device].put_rec_queue(data)
# self._no_data_total_duration = 0
ret = True
if self._configurations.get(device, None) != None:
if self._configurations[device].queue_flag:
self._configurations[device].queue_flag = False
print("q size= ", self._configurations[device]._queue_rec.qsize())
if self._configurations.get(device, None) != None:
self._configurations[device].put_rec_queue(data)
# self._no_data_total_duration = 0
ret = True
# else:
# time_diff = time() - self._recv_memory_cost_time
# self._no_data_total_duration += time_diff
@@ -699,6 +714,9 @@ class DataServer(SocketServer, DataAPI):
self.mqtt_thread.publish('device_instruction', json_stringify(content), inter = True)
return True
def show_data(self, device):
self._configurations[device].put_rec_queue('show_data')
class DataRuntime(metaclass=abc.ABCMeta):
__slots__ = ('_server', '_device', '_meta_file', '_data_format',
+30 -1
View File
@@ -550,4 +550,33 @@ class DataBaseProcess(Process):
except psycopg2.Error as 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()
+65 -13
View File
@@ -1,6 +1,7 @@
from time import sleep
from typing import Iterable
from datetime import datetime
import json
import biopro.impl.vcgencmd as vcg
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.device import DeviceAPI
from biopro.project.project_manager import ProjectManager
### do not import Websocket mode
###from .websocket import WebsocketThread
from biopro.db.base import Base, Session, engine
from biopro.db.project_report import ProjectReport
from biopro.db.project_meta import MetaProjectInfo
_RUNTIME_COMPILE = False
@@ -105,7 +108,7 @@ class ControlServer(SocketServer, ControlServerAPI):
# device detect
self._detect_device_thread = RoutineConnectDeviceThread(self._device_manager, self.mqtt_thread, self.led_thread, 3)
self._project_manager = ProjectManager(self.device_manager, self.mqtt_thread)
self._project_manager = ProjectManager(self.device_manager, self.mqtt_thread, self.log_verbose)
if not c.flag_disable_led_control:
self.led_thread.set_state(LED.COLOR_RED)
@@ -117,8 +120,8 @@ class ControlServer(SocketServer, ControlServerAPI):
self.ups_thread = UPSDetectThread(self, c.flag_ups_wait_time)
# user session
self._session = {}
self._user_session_expire = c.user_session_expire_days * 24 * 60 * 60 # sec
# self._session = {}
# self._user_session_expire = c.user_session_expire_days * 24 * 60 * 60 # sec
# indicate those device together
self._device_instruction_group = None
@@ -129,6 +132,10 @@ class ControlServer(SocketServer, ControlServerAPI):
# _api request build
self._api = ApiRequests()
# sqlalchemy
Base.metadata.create_all(engine)
self._session = Session()
# init method
def _init_file_manager(self, option: ControlServerOptions) -> FileManager:
@@ -819,12 +826,21 @@ class ControlServer(SocketServer, ControlServerAPI):
return True
@logging_info
def device_battery(self) -> List[int]:
device_list = self.device_manager.list_device()
if len(device_list) > 0:
battery_list = list(map(lambda x: self.device_manager.get_device(x).battery, device_list))
return battery_list
def device_battery(self, device:int) -> List[int]:
try:
battery = {}
if device == 'all':
device_list = self.device_manager.list_device()
if len(device_list) > 0:
battery = list(map(lambda x: {"device": x.memory_board, "battery":self.device_manager.get_device(x).battery}, device_list))
else:
battery = {
"device": device,
"battery": self.device_manager.get_device(device).battery
}
except AttributeError as e:
print('device_battery', device, 'not found', e)
return battery
@logging_info
def device_parent(self, device: int, content: Optional[str] = None) -> List[int]:
@@ -1016,6 +1032,16 @@ class ControlServer(SocketServer, ControlServerAPI):
def run_project(self, project) -> bool:
if project is not None:
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)
return project.as_json()
@@ -1024,6 +1050,18 @@ class ControlServer(SocketServer, ControlServerAPI):
if project is not None:
self._project_manager.stop_project(project)
return True
@logging_info
def set_project(self, project, content) -> bool:
if project is not None:
self._project_manager.set_project(project, content)
return True
@logging_info
def set_project_cycle(self, project, index, content) -> bool:
if project is not None:
self._project_manager.set_project_cycle(project, index, content)
return True
@logging_info
def get_running_project(self) -> bool:
@@ -1045,6 +1083,10 @@ class ControlServer(SocketServer, ControlServerAPI):
elif oper == InternalInstruction.PREDEFINED_DISABLE_CACHE:
return True
elif oper == InternalInstruction.PREDEFINED_IDLE:
device.status = 1
return True
else:
return False
@@ -1059,6 +1101,7 @@ class ControlServer(SocketServer, ControlServerAPI):
self.log_verbose('update data format', value)
client = self.data_server.client()
project = None
if client is not None:
info = self.file_manager.use(device)
@@ -1069,9 +1112,12 @@ class ControlServer(SocketServer, ControlServerAPI):
filename = self._file_save_cache.get(device.device_id, self.TEMP_FILENAME_EXPR)
filename = format_filename(filename, device)
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:
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):
if disable:
@@ -1105,7 +1151,6 @@ class ControlServer(SocketServer, ControlServerAPI):
filename = format_filename(self.TEMP_FILENAME_EXPR, device)
info = self.file_manager.save(device, filename)
client.update_device_configuration(device, info.meta_file, RawDataDecoder())
if self._device_instruction_group is None:
client.start_sync(device)
@@ -1339,6 +1384,13 @@ class ControlServer(SocketServer, ControlServerAPI):
def _hardware_send_test_set(self, options: Dict[str, str]) -> bool:
# TODO write options files
return False
@logging_info
def show_device_data(self, device: int):
client = self.data_server.client()
if client is not None:
with client:
client.show_data(device)
class _RandomCrashThread(ServerThread):
def __init__(self):
+6 -4
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,
device_info, parameter, parent, recording_file_name, data_format,
mqtt_ip, mqtt_port,
name = 'Recording-Process', database = None):
name = 'Recording-Process',
project_id = None,
database = None):
super(RecordingProcess, self).__init__(name = name)
self._database = database
@@ -57,6 +59,7 @@ class RecordingProcess(Process):
self._meta_file._parent = parent
self._meta_file._recording_file_name = recording_file_name
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)
self._meta_file.write(self._database)
@@ -155,9 +158,6 @@ class RecordingProcess(Process):
elif isinstance(decoder, EISZeroOneDataDecoder):
# get amp_gain from meta file
decoder._mode = self._meta_file.configuration.get_parameter('MODE')
decoder._ac_amp = self._meta_file.configuration.get_parameter('AC_AMP')
decoder._freq_start = self._meta_file.configuration.get_parameter('FREQ_START')
decoder._freq_stop = self._meta_file.configuration.get_parameter('FREQ_STOP')
return decoder
@@ -185,6 +185,8 @@ class RecordingProcess(Process):
self.final_write()
self.is_closed = True
return False
elif q == 'show_data':
self._decoder._show_data = not self._decoder._show_data
else:
self.rec_update()
self.sync_data(q)
+7 -5
View File
@@ -93,13 +93,15 @@ class SocketClient(metaclass=abc.ABCMeta):
if self._socket is None:
try:
self._socket = Socket(AF_UNIX, SOCK_STREAM)
self._socket.settimeout(1)
self._socket.settimeout(5)
self._socket.connect(self._socket_file)
except FileNotFoundError as e:
raise RuntimeError('server not available') from e
except Exception as e:
print('open_socket error:', e)
# except FileNotFoundError as e:
# raise RuntimeError('server not available') from e
except ConnectionRefusedError as e:
raise RuntimeError('server crash') from e
# except ConnectionRefusedError as e:
# raise RuntimeError('server crash') from e
def close_socket(self):
if self._socket is not None:
File diff suppressed because it is too large Load Diff
@@ -6,7 +6,7 @@
"major_product_number": 0,
"minor_product_number": 3,
"major_version_number": 1,
"minor_version_number": 0
"minor_version_number": 1
},
"constant": {
"TIME_MAX": 100000,
@@ -780,7 +780,7 @@
"expression": "VALUE"
}
},
"VOLT_VSCAN": {
"CA_VOLT": {
"description": "Voltage of VScan",
"record_meta": true,
"initial": 25000,
@@ -1203,7 +1203,7 @@
"pe": "SAMPLE_RATE"
},
"data": [
"X07;",
"X0C;",
"B>va;4B>vb;2B>vc;2B>vd;",
"4b>pa;4b>pb;",
"4b>pc;4b>pd;",
@@ -1301,7 +1301,7 @@
"curve_const_vscan": {
"type": "RIS",
"parameter": {
"va": "VOLT_VSCAN",
"va": "CA_VOLT",
"pa": "ADC_LEVEL_I_15",
"pb": "ADC_LEVEL_V_IN_15",
"pc": "DAC_LEVEL_V_OUT_15",
@@ -15,6 +15,34 @@
"BLE_WRITE_MAX": 255
},
"parameters": {
"HIGHZ_TABLE": {
"initial": [
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
1,
1,
1,
0,
1,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"DPV_e_init": {
"description": "DPV initial voltage ",
"record_meta": true,
@@ -590,7 +618,8 @@
"Open Circuit Potential",
"Pulse Sensing",
"Differential Pulse Voltammetry (DPV)",
"Chronopotentiometry"
"Chronopotentiometry",
"Idle"
]
},
"VOLT_ORIGIN": {
@@ -671,6 +700,17 @@
},
"on_change": "set_para_DAC_VOLT"
},
"DAC_VOLT_SCROLL": {
"description": "DAC scroll output Voltage",
"record_meta": true,
"initial": 25000,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
},
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
@@ -780,7 +820,7 @@
"expression": "VALUE"
}
},
"VOLT_VSCAN": {
"CA_VOLT": {
"description": "Voltage of VScan",
"record_meta": true,
"initial": 25000,
@@ -836,6 +876,18 @@
],
"on_change": "set_dac_gain_Vout"
},
"DAC_VOLT_BUTTON": {
"description": "DAC volt",
"record_meta": true,
"initial": 1,
"value": [
"10000",
"25000",
"50000",
"60000"
],
"on_change": "cali_Vout"
},
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"record_meta": true,
@@ -851,7 +903,8 @@
"initial": 0,
"value": [
"Iin",
"Vin"
"Vin",
"Vout"
]
},
"BLE_WRITE": {
@@ -898,6 +951,7 @@
"10": "cali_dac_test",
"11": "cali_adc_test",
"12": "",
"17": "idle",
"*": "start_data"
}
}
@@ -912,17 +966,22 @@
"_notify(True)",
"set_adc_gain_I",
"set_adc_gain_Vin",
"set_dac_gain_Vout",
{
"expression": "ADC_DAC_CHANNEL_15",
"when": {
"0": "cali_Iin",
"1": "cali_Vin"
"1": "cali_Vin",
"2": "cali_Vout"
}
},
"_sync(True)",
"VIS_STI",
"_cdr('1X;4X>ADC_VALUE_I')"
],
"idle": [
"_idle()"
],
"start_data": [
"data_format",
"_notify(True)",
@@ -970,7 +1029,7 @@
"6": "const_current",
"7": "curve_cv3",
"8": "curve_lsv",
"9": "curve_const_vscan",
"9": "curve_ca",
"13": "curve_ocp",
"14": "curve_pulse_sensing",
"15": "curve_dpv",
@@ -1007,12 +1066,6 @@
"XE0;2B>va"
]
},
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_adc_gain_I": {
"type": "RIS",
"data": [
@@ -1025,6 +1078,12 @@
"XE1;X01;B>ADC_LEVEL_V_IN_15"
]
},
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_ctrl_highZ": {
"type": "RIS",
"data": [
@@ -1052,6 +1111,15 @@
"XF1;B>ADC_DAC_CHANNEL_15;B>ADC_LEVEL_V_IN_15"
]
},
"cali_Vout": {
"type": "RIS",
"parameter": {
"v": "DAC_VOLT_BUTTON"
},
"data": [
"XF1;B>ADC_DAC_CHANNEL_15;B>v"
]
},
"curve_iv": {
"type": "RIS",
"parameter": {
@@ -1203,7 +1271,7 @@
"pe": "SAMPLE_RATE"
},
"data": [
"X07;",
"X0C;",
"B>va;4B>vb;2B>vc;2B>vd;",
"4b>pa;4b>pb;",
"4b>pc;4b>pd;",
@@ -1298,10 +1366,10 @@
"2B>pe"
]
},
"curve_const_vscan": {
"curve_ca": {
"type": "RIS",
"parameter": {
"va": "VOLT_VSCAN",
"va": "CA_VOLT",
"pa": "ADC_LEVEL_I_15",
"pb": "ADC_LEVEL_V_IN_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",
"match_rule": {
"local_name_pattern": "Elite.*",
"major_product_number": 0,
"minor_product_number": 2,
"major_version_number": 1,
"minor_version_number": 8
"minor_version_number": 7
},
"constant": {
"TIME_MAX": 100000,
@@ -15,6 +15,34 @@
"BLE_WRITE_MAX": 255
},
"parameters": {
"HIGHZ_TABLE": {
"initial": [
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
1,
1,
1,
0,
1,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"DPV_e_init": {
"description": "DPV initial voltage ",
"record_meta": true,
@@ -590,7 +618,8 @@
"Open Circuit Potential",
"Pulse Sensing",
"Differential Pulse Voltammetry (DPV)",
"Chronopotentiometry"
"Chronopotentiometry",
"Idle"
]
},
"VOLT_ORIGIN": {
@@ -671,6 +700,17 @@
},
"on_change": "set_para_DAC_VOLT"
},
"DAC_VOLT_SCROLL": {
"description": "DAC scroll output Voltage",
"record_meta": true,
"initial": 25000,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
},
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
@@ -780,7 +820,7 @@
"expression": "VALUE"
}
},
"VOLT_VSCAN": {
"CA_VOLT": {
"description": "Voltage of VScan",
"record_meta": true,
"initial": 25000,
@@ -836,6 +876,18 @@
],
"on_change": "set_dac_gain_Vout"
},
"DAC_VOLT_BUTTON": {
"description": "DAC volt",
"record_meta": true,
"initial": 1,
"value": [
"10000",
"25000",
"50000",
"60000"
],
"on_change": "cali_Vout"
},
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"record_meta": true,
@@ -851,7 +903,8 @@
"initial": 0,
"value": [
"Iin",
"Vin"
"Vin",
"Vout"
]
},
"BLE_WRITE": {
@@ -898,6 +951,7 @@
"10": "cali_dac_test",
"11": "cali_adc_test",
"12": "",
"17": "idle",
"*": "start_data"
}
}
@@ -912,17 +966,22 @@
"_notify(True)",
"set_adc_gain_I",
"set_adc_gain_Vin",
"set_dac_gain_Vout",
{
"expression": "ADC_DAC_CHANNEL_15",
"when": {
"0": "cali_Iin",
"1": "cali_Vin"
"1": "cali_Vin",
"2": "cali_Vout"
}
},
"_sync(True)",
"VIS_STI",
"_cdr('1X;4X>ADC_VALUE_I')"
],
"idle": [
"_idle()"
],
"start_data": [
"data_format",
"_notify(True)",
@@ -970,7 +1029,7 @@
"6": "const_current",
"7": "curve_cv3",
"8": "curve_lsv",
"9": "curve_const_vscan",
"9": "curve_ca",
"13": "curve_ocp",
"14": "curve_pulse_sensing",
"15": "curve_dpv",
@@ -1007,12 +1066,6 @@
"XE0;2B>va"
]
},
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_adc_gain_I": {
"type": "RIS",
"data": [
@@ -1025,6 +1078,12 @@
"XE1;X01;B>ADC_LEVEL_V_IN_15"
]
},
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_ctrl_highZ": {
"type": "RIS",
"data": [
@@ -1052,6 +1111,15 @@
"XF1;B>ADC_DAC_CHANNEL_15;B>ADC_LEVEL_V_IN_15"
]
},
"cali_Vout": {
"type": "RIS",
"parameter": {
"v": "DAC_VOLT_BUTTON"
},
"data": [
"XF1;B>ADC_DAC_CHANNEL_15;B>v"
]
},
"curve_iv": {
"type": "RIS",
"parameter": {
@@ -1203,7 +1271,7 @@
"pe": "SAMPLE_RATE"
},
"data": [
"X07;",
"X0C;",
"B>va;4B>vb;2B>vc;2B>vd;",
"4b>pa;4b>pb;",
"4b>pc;4b>pd;",
@@ -1298,10 +1366,10 @@
"2B>pe"
]
},
"curve_const_vscan": {
"curve_ca": {
"type": "RIS",
"parameter": {
"va": "VOLT_VSCAN",
"va": "CA_VOLT",
"pa": "ADC_LEVEL_I_15",
"pb": "ADC_LEVEL_V_IN_15",
"pc": "DAC_LEVEL_V_OUT_15",
@@ -15,6 +15,34 @@
"BLE_WRITE_MAX": 255
},
"parameters": {
"HIGHZ_TABLE": {
"initial": [
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
1,
1,
1,
0,
1,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"DPV_e_init": {
"description": "DPV initial voltage ",
"record_meta": true,
@@ -590,7 +618,8 @@
"Open Circuit Potential",
"Pulse Sensing",
"Differential Pulse Voltammetry (DPV)",
"Chronopotentiometry"
"Chronopotentiometry",
"Idle"
]
},
"VOLT_ORIGIN": {
@@ -671,6 +700,17 @@
},
"on_change": "set_para_DAC_VOLT"
},
"DAC_VOLT_SCROLL": {
"description": "DAC scroll output Voltage",
"record_meta": true,
"initial": 25000,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
},
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
@@ -780,7 +820,7 @@
"expression": "VALUE"
}
},
"VOLT_VSCAN": {
"CA_VOLT": {
"description": "Voltage of VScan",
"record_meta": true,
"initial": 25000,
@@ -836,6 +876,18 @@
],
"on_change": "set_dac_gain_Vout"
},
"DAC_VOLT_BUTTON": {
"description": "DAC volt",
"record_meta": true,
"initial": 1,
"value": [
"10000",
"25000",
"50000",
"60000"
],
"on_change": "cali_Vout"
},
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"record_meta": true,
@@ -851,7 +903,8 @@
"initial": 0,
"value": [
"Iin",
"Vin"
"Vin",
"Vout"
]
},
"BLE_WRITE": {
@@ -898,6 +951,7 @@
"10": "cali_dac_test",
"11": "cali_adc_test",
"12": "",
"17": "idle",
"*": "start_data"
}
}
@@ -912,17 +966,22 @@
"_notify(True)",
"set_adc_gain_I",
"set_adc_gain_Vin",
"set_dac_gain_Vout",
{
"expression": "ADC_DAC_CHANNEL_15",
"when": {
"0": "cali_Iin",
"1": "cali_Vin"
"1": "cali_Vin",
"2": "cali_Vout"
}
},
"_sync(True)",
"VIS_STI",
"_cdr('1X;4X>ADC_VALUE_I')"
],
"idle": [
"_idle()"
],
"start_data": [
"data_format",
"_notify(True)",
@@ -970,7 +1029,7 @@
"6": "const_current",
"7": "curve_cv3",
"8": "curve_lsv",
"9": "curve_const_vscan",
"9": "curve_ca",
"13": "curve_ocp",
"14": "curve_pulse_sensing",
"15": "curve_dpv",
@@ -1007,12 +1066,6 @@
"XE0;2B>va"
]
},
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_adc_gain_I": {
"type": "RIS",
"data": [
@@ -1025,6 +1078,12 @@
"XE1;X01;B>ADC_LEVEL_V_IN_15"
]
},
"set_dac_gain_Vout": {
"type": "RIS",
"data": [
"XE1;X02;B>DAC_LEVEL_V_OUT_15"
]
},
"set_ctrl_highZ": {
"type": "RIS",
"data": [
@@ -1052,6 +1111,15 @@
"XF1;B>ADC_DAC_CHANNEL_15;B>ADC_LEVEL_V_IN_15"
]
},
"cali_Vout": {
"type": "RIS",
"parameter": {
"v": "DAC_VOLT_BUTTON"
},
"data": [
"XF1;B>ADC_DAC_CHANNEL_15;B>v"
]
},
"curve_iv": {
"type": "RIS",
"parameter": {
@@ -1298,10 +1366,10 @@
"2B>pe"
]
},
"curve_const_vscan": {
"curve_ca": {
"type": "RIS",
"parameter": {
"va": "VOLT_VSCAN",
"va": "CA_VOLT",
"pa": "ADC_LEVEL_I_15",
"pb": "ADC_LEVEL_V_IN_15",
"pc": "DAC_LEVEL_V_OUT_15",
+362 -162
View File
@@ -9,7 +9,7 @@
"minor_version_number": 0
},
"constant": {
"FREQ_MAX": 4294967296,
"FREQ_MAX": 13333334,
"VOLT_MAX": 65536,
"BLE_WRITE_MAX": 255,
"TIME_MAX": 100000
@@ -26,17 +26,44 @@
"expression": "VALUE"
}
},
"CHANNEL": {
"derzteription": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
"HIGHZ_TABLE": {
"initial": [
1,
1,
1,
0,
1,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"CHANNEL_LABEL": {
"description": "channel label",
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"record_meta": true,
"domain": "property",
"value": "['current', 'voltage', 'impedance']"
"initial": 1,
"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": {
"description": "data sampling rate",
@@ -50,6 +77,12 @@
},
"on_change": "set_sample_rate"
},
"CHANNEL": {
"derzteription": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"AMP_GAIN": {
"description": "amp gain",
"record_meta": true,
@@ -62,14 +95,64 @@
"value": [
"EIS CURVE",
"Cyclic Voltammetry",
"Dev Mode"
"Chronoamperometric",
"V-T Graph",
"R-T Graph",
"EIS constant frequency",
"Dev Mode",
"Idle"
]
},
"FREQ": {
"description": "DPV current recording period start",
"GENERAL_HS_RTIA": {
"description": "High speed rtia gain",
"record_meta": true,
"initial": 4,
"value": [
0,
1,
2,
3,
4
],
"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": {
"description": "DC voltage bias",
"record_meta": true,
"initial": 25000,
"domain": [
"VOLT_MAX"
],
"value": {
"expression": "VALUE"
}
},
"EIS_AC_AMP": {
"description": "AC Amplitude",
"record_meta": true,
"initial": 26,
"domain": [
2048
]
},
"EIS_FREQ": {
"description": "[start, stop] of frequency scan",
"record_meta": true,
"initial": [
13422819,
13333333,
7
],
"domain": {
@@ -79,29 +162,24 @@
},
"value": "VALUE"
},
"FREQ_START": {
"description": "Start of Freq Scan",
"EIS_PPD": {
"description": "Point per decades",
"record_meta": true,
"initial": 13422819,
"initial": 10,
"domain": [
"FREQ_MAX"
],
"value": {
"expression": "VALUE"
}
11
]
},
"FREQ_STOP": {
"description": "End of Freq Scan",
"EIS_SCALE": {
"description": "Point spacing pattern",
"record_meta": true,
"initial": 7,
"domain": [
"FREQ_MAX"
],
"value": {
"expression": "VALUE"
}
"initial": 0,
"value": [
0,
1
]
},
"DELAY": {
"EIS_DELAY": {
"description": "Wait x peroid before start taking measurements",
"record_meta": true,
"initial": 0,
@@ -112,19 +190,19 @@
"expression": "VALUE"
}
},
"AVERAGE_NUM": {
"EIS_AVERAGE_NUM": {
"description": "Number of sample used for average funciton",
"record_meta": true,
"initial": 8,
"value": [
2,
4,
8,
16
6,
8
]
},
"DC_BIAS": {
"description": "DC voltage bias in mV",
"CF_DC_BIAS": {
"description": "DC voltage bias",
"record_meta": true,
"initial": 25000,
"domain": [
@@ -134,15 +212,34 @@
"expression": "VALUE"
}
},
"AC_AMP": {
"description": "AC Amplitude in mV",
"CF_AC_AMP": {
"description": "AC Amplitude",
"record_meta": true,
"initial": 25,
"initial": 26,
"domain": [
2048
]
},
"SCALE": {
"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,
@@ -151,77 +248,29 @@
1
]
},
"PPD": {
"description": "Point per decades",
"CF_DELAY": {
"description": "Wait x peroid before start taking measurements",
"record_meta": true,
"initial": 10,
"initial": 0,
"domain": [
11
]
},
"RTIA": {
"description": "High speed tia gain",
"record_meta": true,
"initial": 4,
"value": [
0,
1,
2,
3,
4
]
},
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"Scan_Rate": {
"description": "Voltage Scan Rate",
"record_meta": true,
"initial": 10000,
"domain": [
100001
101
],
"value": {
"expression": "VALUE"
}
},
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"CF_AVERAGE_NUM": {
"description": "Number of sample used for average funciton",
"record_meta": true,
"initial": 1,
"initial": 8,
"value": [
"On",
"Off"
],
"on_change": "set_ctrl_highZ"
2,
4,
6,
8
]
},
"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"
],
"on_change": "set_adc_gain_Vin"
},
"VOLT_INITIAL": {
"CV_E_INITIAL": {
"description": "Initial Voltage of Scan",
"record_meta": true,
"initial": 25000,
@@ -232,8 +281,8 @@
"expression": "VALUE"
}
},
"VOLT_MAX": {
"description": "Max Voltage of Scan",
"CV_E1": {
"description": "First voltage of Scan",
"record_meta": true,
"initial": 25000,
"domain": [
@@ -243,8 +292,8 @@
"expression": "VALUE"
}
},
"VOLT_MIN": {
"description": "Min Voltage of Scan",
"CV_E2": {
"description": "Second voltage of Scan",
"record_meta": true,
"initial": 25000,
"domain": [
@@ -254,16 +303,54 @@
"expression": "VALUE"
}
},
"CYCLE_NUMBER": {
"description": "CV cycle number",
"CV_SCAN_RATE": {
"description": "Voltage scan rate",
"record_meta": true,
"initial": 1,
"initial": 10000,
"domain": [
100001
],
"value": {
"expression": "VALUE"
}
},
"CA_VOLT": {
"description": "Voltage of ca",
"record_meta": true,
"initial": 25000,
"domain": [
"VOLT_MAX"
],
"value": {
"expression": "VALUE"
}
},
"VT_MEASURE_VIN_RANGE": {
"description": "measure range of Vin",
"record_meta": true,
"initial": 0,
"value": [
"0",
"1",
"2",
"auto"
]
},
"RT_VOLT_SET": {
"description": "DAC output Voltage",
"record_meta": true,
"initial": 37500,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
},
"on_change": "set_para_RT_VOLT_SET"
},
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"BLE_WRITE": {
"description": "send msg to elite",
@@ -285,37 +372,52 @@
{
"expression": "MODE",
"when": {
"7": "idle",
"*": "start_data"
}
}
],
"idle": [
"_idle()"
],
"start_data": [
"data_format_cali",
"_notify(True)",
{
"expression": "MODE",
"when": {
"1": "set_adc_gain_I"
}
},
{
"expression": "MODE",
"when": {
"1": "set_adc_gain_Vin"
"0": "set_general_hs_rtia",
"1": "set_general_lp_rtia",
"2": "set_general_lp_rtia",
"3": "set_general_lp_rtia",
"4": "set_general_lp_rtia",
"5": "set_general_hs_rtia"
}
},
{
"expression": "MODE",
"when": {
"0": "curve_eis",
"1": "curve_cv3"
"1": "curve_cv3",
"2": "curve_ca",
"3": "curve_vt",
"4": "curve_rt",
"5": "curve_cf"
}
},
{
"expression": "MODE",
"when": {
"0": "curve_eis_para2",
"1": "curve_cv3_para2"
"1": "curve_cv3_para2",
"5": "curve_cf_para2"
}
},
{
"expression": "MODE",
"when": {
"0": "curve_eis_mode",
"5": "curve_cf_mode"
}
},
"_sync(True)",
@@ -335,6 +437,18 @@
"data_format_cali": [
"_data_format_cali('EISZeroOne')"
],
"set_general_hs_rtia": {
"type": "RIS",
"data": [
"1XFF;1X70;1B>GENERAL_HS_RTIA"
]
},
"set_general_lp_rtia": {
"type": "RIS",
"data": [
"1XFF;1X71;1B>GENERAL_LP_RTIA"
]
},
"set_sample_rate": {
"type": "RIS",
"parameter": {
@@ -344,84 +458,170 @@
"XE0;2B>va"
]
},
"set_adc_gain_I": {
"type": "RIS",
"data": [
"XE1;X05;B>ADC_LEVEL_I_15"
]
},
"set_adc_gain_Vin": {
"type": "RIS",
"data": [
"XE1;X06;B>ADC_LEVEL_V_IN_15"
]
},
"set_ctrl_highZ": {
"type": "RIS",
"data": [
"XE1;X03;B>CTRL_HIGH_Z_15"
"1XFF;1X72;1B>CTRL_HIGH_Z_15"
]
},
"curve_eis": {
"type": "RIS",
"parameter": {
"fa": "FREQ[0]",
"fb": "FREQ[1]",
"dp": "DELAY",
"dc": "DC_BIAS",
"am": "AC_AMP",
"an": "AVERAGE_NUM",
"rt": "RTIA",
"pp": "PPD",
"sp": "SCALE"
"fa": "EIS_FREQ[0]",
"fb": "EIS_FREQ[1]",
"dp": "EIS_DELAY",
"dc": "EIS_DC_BIAS",
"am": "EIS_AC_AMP",
"an": "EIS_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "EIS_PPD",
"sp": "EIS_SCALE"
},
"data": [
"1XD1;1X01;4B>fa;4B>fb;2B>dp"
"1X12;1X01;4B>fa;4B>fb;2B>dp"
]
},
"curve_eis_para2": {
"type": "RIS",
"parameter": {
"fa": "FREQ[0]",
"fb": "FREQ[1]",
"dp": "DELAY",
"dc": "DC_BIAS",
"am": "AC_AMP",
"an": "AVERAGE_NUM",
"rt": "RTIA",
"pp": "PPD",
"sp": "SCALE"
"fa": "EIS_FREQ[0]",
"fb": "EIS_FREQ[1]",
"dp": "EIS_DELAY",
"dc": "EIS_DC_BIAS",
"am": "EIS_AC_AMP",
"an": "EIS_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "EIS_PPD",
"sp": "EIS_SCALE"
},
"data": [
"1XD1;1X02;2B>dc;2B>am;B>an;B>rt;2B>pp;B>sp"
"1X12;1X02;2B>dc;2B>am;B>an;B>rt;2B>pp;B>sp"
]
},
"curve_eis_mode": {
"type": "RIS",
"data": [
"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": {
"type": "RIS",
"parameter": {
"va": "VOLT_INITIAL",
"vb": "VOLT_MAX",
"vc": "VOLT_MIN",
"ve": "Scan_Rate",
"va": "CV_E_INITIAL",
"vb": "CV_E1",
"vc": "CV_E2",
"ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER"
},
"data": [
"1XD2;1X01;2B>va;2B>vb;2B>vc;"
"1X09;1X01;2B>va;2B>vb;2B>vc;"
]
},
"curve_cv3_para2": {
"type": "RIS",
"parameter": {
"va": "VOLT_INITIAL",
"vb": "VOLT_MAX",
"vc": "VOLT_MIN",
"ve": "Scan_Rate",
"va": "CV_E_INITIAL",
"vb": "CV_E1",
"vc": "CV_E2",
"ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER"
},
"data": [
"1XD2;1X02;4B>ve;2B>vf;2B>cn"
"1X09;1X02;4B>ve;2B>vf;2B>cn"
]
},
"curve_ca": {
"type": "RIS",
"parameter": {
"va": "CA_VOLT",
"pa": "GENERAL_LP_RTIA",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE"
},
"data": [
"1X0B;",
"2B>va;",
"4b>pa;4b>0;",
"4b>0;4b>pd;",
"2B>pe"
]
},
"curve_rt": {
"type": "RIS",
"parameter": {
"va": "RT_VOLT_SET",
"pa": "GENERAL_LP_RTIA",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE"
},
"data": [
"X04;",
"2B>va;",
"4b>pa;4b>0;",
"4b>0;4b>pd;",
"2B>pe"
]
},
"curve_vt": {
"type": "RIS",
"parameter": {
"pa": "GENERAL_LP_RTIA",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE",
"va": "VT_MEASURE_VIN_RANGE"
},
"data": [
"X05;",
"4b>pa;4b>0;",
"4b>0;4b>pd;",
"2B>pe;",
"1B>va"
]
},
"set_para_RT_VOLT_SET": {
"type": "RIS",
"data": [
"XE2;X01;2B>RT_VOLT_SET"
]
},
"ble_instru_send": [
+362 -162
View File
@@ -9,7 +9,7 @@
"minor_version_number": 1
},
"constant": {
"FREQ_MAX": 4294967296,
"FREQ_MAX": 13333334,
"VOLT_MAX": 65536,
"BLE_WRITE_MAX": 255,
"TIME_MAX": 100000
@@ -26,17 +26,44 @@
"expression": "VALUE"
}
},
"CHANNEL": {
"derzteription": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
"HIGHZ_TABLE": {
"initial": [
1,
1,
1,
0,
1,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"CHANNEL_LABEL": {
"description": "channel label",
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"record_meta": true,
"domain": "property",
"value": "['current', 'voltage', 'impedance']"
"initial": 1,
"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": {
"description": "data sampling rate",
@@ -50,6 +77,12 @@
},
"on_change": "set_sample_rate"
},
"CHANNEL": {
"derzteription": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"AMP_GAIN": {
"description": "amp gain",
"record_meta": true,
@@ -62,14 +95,64 @@
"value": [
"EIS CURVE",
"Cyclic Voltammetry",
"Dev Mode"
"Chronoamperometric",
"V-T Graph",
"R-T Graph",
"EIS constant frequency",
"Dev Mode",
"Idle"
]
},
"FREQ": {
"description": "DPV current recording period start",
"GENERAL_HS_RTIA": {
"description": "High speed rtia gain",
"record_meta": true,
"initial": 4,
"value": [
0,
1,
2,
3,
4
],
"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": {
"description": "DC voltage bias",
"record_meta": true,
"initial": 25000,
"domain": [
"VOLT_MAX"
],
"value": {
"expression": "VALUE"
}
},
"EIS_AC_AMP": {
"description": "AC Amplitude",
"record_meta": true,
"initial": 26,
"domain": [
2048
]
},
"EIS_FREQ": {
"description": "[start, stop] of frequency scan",
"record_meta": true,
"initial": [
13422819,
13333333,
7
],
"domain": {
@@ -79,29 +162,24 @@
},
"value": "VALUE"
},
"FREQ_START": {
"description": "Start of Freq Scan",
"EIS_PPD": {
"description": "Point per decades",
"record_meta": true,
"initial": 13422819,
"initial": 10,
"domain": [
"FREQ_MAX"
],
"value": {
"expression": "VALUE"
}
11
]
},
"FREQ_STOP": {
"description": "End of Freq Scan",
"EIS_SCALE": {
"description": "Point spacing pattern",
"record_meta": true,
"initial": 7,
"domain": [
"FREQ_MAX"
],
"value": {
"expression": "VALUE"
}
"initial": 0,
"value": [
0,
1
]
},
"DELAY": {
"EIS_DELAY": {
"description": "Wait x peroid before start taking measurements",
"record_meta": true,
"initial": 0,
@@ -112,19 +190,19 @@
"expression": "VALUE"
}
},
"AVERAGE_NUM": {
"EIS_AVERAGE_NUM": {
"description": "Number of sample used for average funciton",
"record_meta": true,
"initial": 8,
"value": [
2,
4,
8,
16
6,
8
]
},
"DC_BIAS": {
"description": "DC voltage bias in mV",
"CF_DC_BIAS": {
"description": "DC voltage bias",
"record_meta": true,
"initial": 25000,
"domain": [
@@ -134,15 +212,34 @@
"expression": "VALUE"
}
},
"AC_AMP": {
"description": "AC Amplitude in mV",
"CF_AC_AMP": {
"description": "AC Amplitude",
"record_meta": true,
"initial": 25,
"initial": 26,
"domain": [
2048
]
},
"SCALE": {
"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,
@@ -151,77 +248,29 @@
1
]
},
"PPD": {
"description": "Point per decades",
"CF_DELAY": {
"description": "Wait x peroid before start taking measurements",
"record_meta": true,
"initial": 10,
"initial": 0,
"domain": [
11
]
},
"RTIA": {
"description": "High speed tia gain",
"record_meta": true,
"initial": 4,
"value": [
0,
1,
2,
3,
4
]
},
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"Scan_Rate": {
"description": "Voltage Scan Rate",
"record_meta": true,
"initial": 10000,
"domain": [
100001
101
],
"value": {
"expression": "VALUE"
}
},
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"CF_AVERAGE_NUM": {
"description": "Number of sample used for average funciton",
"record_meta": true,
"initial": 1,
"initial": 8,
"value": [
"On",
"Off"
],
"on_change": "set_ctrl_highZ"
2,
4,
6,
8
]
},
"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"
],
"on_change": "set_adc_gain_Vin"
},
"VOLT_INITIAL": {
"CV_E_INITIAL": {
"description": "Initial Voltage of Scan",
"record_meta": true,
"initial": 25000,
@@ -232,8 +281,8 @@
"expression": "VALUE"
}
},
"VOLT_MAX": {
"description": "Max Voltage of Scan",
"CV_E1": {
"description": "First voltage of Scan",
"record_meta": true,
"initial": 25000,
"domain": [
@@ -243,8 +292,8 @@
"expression": "VALUE"
}
},
"VOLT_MIN": {
"description": "Min Voltage of Scan",
"CV_E2": {
"description": "Second voltage of Scan",
"record_meta": true,
"initial": 25000,
"domain": [
@@ -254,16 +303,54 @@
"expression": "VALUE"
}
},
"CYCLE_NUMBER": {
"description": "CV cycle number",
"CV_SCAN_RATE": {
"description": "Voltage scan rate",
"record_meta": true,
"initial": 1,
"initial": 10000,
"domain": [
100001
],
"value": {
"expression": "VALUE"
}
},
"CA_VOLT": {
"description": "Voltage of ca",
"record_meta": true,
"initial": 25000,
"domain": [
"VOLT_MAX"
],
"value": {
"expression": "VALUE"
}
},
"VT_MEASURE_VIN_RANGE": {
"description": "measure range of Vin",
"record_meta": true,
"initial": 0,
"value": [
"0",
"1",
"2",
"auto"
]
},
"RT_VOLT_SET": {
"description": "DAC output Voltage",
"record_meta": true,
"initial": 37500,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
},
"on_change": "set_para_RT_VOLT_SET"
},
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"BLE_WRITE": {
"description": "send msg to elite",
@@ -285,37 +372,52 @@
{
"expression": "MODE",
"when": {
"7": "idle",
"*": "start_data"
}
}
],
"idle": [
"_idle()"
],
"start_data": [
"data_format_cali",
"_notify(True)",
{
"expression": "MODE",
"when": {
"1": "set_adc_gain_I"
}
},
{
"expression": "MODE",
"when": {
"1": "set_adc_gain_Vin"
"0": "set_general_hs_rtia",
"1": "set_general_lp_rtia",
"2": "set_general_lp_rtia",
"3": "set_general_lp_rtia",
"4": "set_general_lp_rtia",
"5": "set_general_hs_rtia"
}
},
{
"expression": "MODE",
"when": {
"0": "curve_eis",
"1": "curve_cv3"
"1": "curve_cv3",
"2": "curve_ca",
"3": "curve_vt",
"4": "curve_rt",
"5": "curve_cf"
}
},
{
"expression": "MODE",
"when": {
"0": "curve_eis_para2",
"1": "curve_cv3_para2"
"1": "curve_cv3_para2",
"5": "curve_cf_para2"
}
},
{
"expression": "MODE",
"when": {
"0": "curve_eis_mode",
"5": "curve_cf_mode"
}
},
"_sync(True)",
@@ -335,6 +437,18 @@
"data_format_cali": [
"_data_format_cali('EISZeroOne')"
],
"set_general_hs_rtia": {
"type": "RIS",
"data": [
"1XFF;1X70;1B>GENERAL_HS_RTIA"
]
},
"set_general_lp_rtia": {
"type": "RIS",
"data": [
"1XFF;1X71;1B>GENERAL_LP_RTIA"
]
},
"set_sample_rate": {
"type": "RIS",
"parameter": {
@@ -344,84 +458,170 @@
"XE0;2B>va"
]
},
"set_adc_gain_I": {
"type": "RIS",
"data": [
"XE1;X05;B>ADC_LEVEL_I_15"
]
},
"set_adc_gain_Vin": {
"type": "RIS",
"data": [
"XE1;X06;B>ADC_LEVEL_V_IN_15"
]
},
"set_ctrl_highZ": {
"type": "RIS",
"data": [
"XE1;X03;B>CTRL_HIGH_Z_15"
"1XFF;1X72;1B>CTRL_HIGH_Z_15"
]
},
"curve_eis": {
"type": "RIS",
"parameter": {
"fa": "FREQ[0]",
"fb": "FREQ[1]",
"dp": "DELAY",
"dc": "DC_BIAS",
"am": "AC_AMP",
"an": "AVERAGE_NUM",
"rt": "RTIA",
"pp": "PPD",
"sp": "SCALE"
"fa": "EIS_FREQ[0]",
"fb": "EIS_FREQ[1]",
"dp": "EIS_DELAY",
"dc": "EIS_DC_BIAS",
"am": "EIS_AC_AMP",
"an": "EIS_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "EIS_PPD",
"sp": "EIS_SCALE"
},
"data": [
"1XD1;1X01;4B>fa;4B>fb;2B>dp"
"1X12;1X01;4B>fa;4B>fb;2B>dp"
]
},
"curve_eis_para2": {
"type": "RIS",
"parameter": {
"fa": "FREQ[0]",
"fb": "FREQ[1]",
"dp": "DELAY",
"dc": "DC_BIAS",
"am": "AC_AMP",
"an": "AVERAGE_NUM",
"rt": "RTIA",
"pp": "PPD",
"sp": "SCALE"
"fa": "EIS_FREQ[0]",
"fb": "EIS_FREQ[1]",
"dp": "EIS_DELAY",
"dc": "EIS_DC_BIAS",
"am": "EIS_AC_AMP",
"an": "EIS_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "EIS_PPD",
"sp": "EIS_SCALE"
},
"data": [
"1XD1;1X02;2B>dc;2B>am;B>an;B>rt;2B>pp;B>sp"
"1X12;1X02;2B>dc;2B>am;B>an;B>rt;2B>pp;B>sp"
]
},
"curve_eis_mode": {
"type": "RIS",
"data": [
"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": {
"type": "RIS",
"parameter": {
"va": "VOLT_INITIAL",
"vb": "VOLT_MAX",
"vc": "VOLT_MIN",
"ve": "Scan_Rate",
"va": "CV_E_INITIAL",
"vb": "CV_E1",
"vc": "CV_E2",
"ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER"
},
"data": [
"1XD2;1X01;2B>va;2B>vb;2B>vc;"
"1X09;1X01;2B>va;2B>vb;2B>vc;"
]
},
"curve_cv3_para2": {
"type": "RIS",
"parameter": {
"va": "VOLT_INITIAL",
"vb": "VOLT_MAX",
"vc": "VOLT_MIN",
"ve": "Scan_Rate",
"va": "CV_E_INITIAL",
"vb": "CV_E1",
"vc": "CV_E2",
"ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER"
},
"data": [
"1XD2;1X02;4B>ve;2B>vf;2B>cn"
"1X09;1X02;4B>ve;2B>vf;2B>cn"
]
},
"curve_ca": {
"type": "RIS",
"parameter": {
"va": "CA_VOLT",
"pa": "GENERAL_LP_RTIA",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE"
},
"data": [
"1X0B;",
"2B>va;",
"4b>pa;4b>0;",
"4b>0;4b>pd;",
"2B>pe"
]
},
"curve_rt": {
"type": "RIS",
"parameter": {
"va": "RT_VOLT_SET",
"pa": "GENERAL_LP_RTIA",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE"
},
"data": [
"X04;",
"2B>va;",
"4b>pa;4b>0;",
"4b>0;4b>pd;",
"2B>pe"
]
},
"curve_vt": {
"type": "RIS",
"parameter": {
"pa": "GENERAL_LP_RTIA",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE",
"va": "VT_MEASURE_VIN_RANGE"
},
"data": [
"X05;",
"4b>pa;4b>0;",
"4b>0;4b>pd;",
"2B>pe;",
"1B>va"
]
},
"set_para_RT_VOLT_SET": {
"type": "RIS",
"data": [
"XE2;X01;2B>RT_VOLT_SET"
]
},
"ble_instru_send": [
@@ -9,7 +9,7 @@
"minor_version_number": 2
},
"constant": {
"FREQ_MAX": 4294967296,
"FREQ_MAX": 13333334,
"VOLT_MAX": 65536,
"BLE_WRITE_MAX": 255,
"TIME_MAX": 100000
@@ -26,17 +26,44 @@
"expression": "VALUE"
}
},
"CHANNEL": {
"derzteription": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
"HIGHZ_TABLE": {
"initial": [
1,
1,
1,
0,
1,
1,
1,
1
],
"domain": {
"list": [
100
]
},
"value": "VALUE"
},
"CHANNEL_LABEL": {
"description": "channel label",
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"record_meta": true,
"domain": "property",
"value": "['current', 'voltage', 'impedance']"
"initial": 1,
"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": {
"description": "data sampling rate",
@@ -50,6 +77,12 @@
},
"on_change": "set_sample_rate"
},
"CHANNEL": {
"derzteription": "record channels",
"record_meta": true,
"domain": "property",
"value": "[0, 1, 2]"
},
"AMP_GAIN": {
"description": "amp gain",
"record_meta": true,
@@ -62,14 +95,64 @@
"value": [
"EIS CURVE",
"Cyclic Voltammetry",
"Dev Mode"
"Chronoamperometric",
"V-T Graph",
"R-T Graph",
"EIS constant frequency",
"Dev Mode",
"Idle"
]
},
"FREQ": {
"description": "DPV current recording period start",
"GENERAL_HS_RTIA": {
"description": "High speed rtia gain",
"record_meta": true,
"initial": 4,
"value": [
0,
1,
2,
3,
4
],
"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": {
"description": "DC voltage bias",
"record_meta": true,
"initial": 25000,
"domain": [
"VOLT_MAX"
],
"value": {
"expression": "VALUE"
}
},
"EIS_AC_AMP": {
"description": "AC Amplitude",
"record_meta": true,
"initial": 26,
"domain": [
2048
]
},
"EIS_FREQ": {
"description": "[start, stop] of frequency scan",
"record_meta": true,
"initial": [
13422819,
13333333,
7
],
"domain": {
@@ -79,29 +162,24 @@
},
"value": "VALUE"
},
"FREQ_START": {
"description": "Start of Freq Scan",
"EIS_PPD": {
"description": "Point per decades",
"record_meta": true,
"initial": 13422819,
"initial": 10,
"domain": [
"FREQ_MAX"
],
"value": {
"expression": "VALUE"
}
11
]
},
"FREQ_STOP": {
"description": "End of Freq Scan",
"EIS_SCALE": {
"description": "Point spacing pattern",
"record_meta": true,
"initial": 7,
"domain": [
"FREQ_MAX"
],
"value": {
"expression": "VALUE"
}
"initial": 0,
"value": [
0,
1
]
},
"DELAY": {
"EIS_DELAY": {
"description": "Wait x peroid before start taking measurements",
"record_meta": true,
"initial": 0,
@@ -112,19 +190,19 @@
"expression": "VALUE"
}
},
"AVERAGE_NUM": {
"EIS_AVERAGE_NUM": {
"description": "Number of sample used for average funciton",
"record_meta": true,
"initial": 8,
"value": [
2,
4,
8,
16
6,
8
]
},
"DC_BIAS": {
"description": "DC voltage bias in mV",
"CF_DC_BIAS": {
"description": "DC voltage bias",
"record_meta": true,
"initial": 25000,
"domain": [
@@ -134,15 +212,34 @@
"expression": "VALUE"
}
},
"AC_AMP": {
"description": "AC Amplitude in mV",
"CF_AC_AMP": {
"description": "AC Amplitude",
"record_meta": true,
"initial": 25,
"initial": 26,
"domain": [
2048
]
},
"SCALE": {
"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,
@@ -151,77 +248,29 @@
1
]
},
"PPD": {
"description": "Point per decades",
"CF_DELAY": {
"description": "Wait x peroid before start taking measurements",
"record_meta": true,
"initial": 10,
"initial": 0,
"domain": [
11
]
},
"RTIA": {
"description": "High speed tia gain",
"record_meta": true,
"initial": 4,
"value": [
0,
1,
2,
3,
4
]
},
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"Scan_Rate": {
"description": "Voltage Scan Rate",
"record_meta": true,
"initial": 10000,
"domain": [
100001
101
],
"value": {
"expression": "VALUE"
}
},
"CTRL_HIGH_Z_15": {
"description": "ctrl highZ level",
"CF_AVERAGE_NUM": {
"description": "Number of sample used for average funciton",
"record_meta": true,
"initial": 1,
"initial": 8,
"value": [
"On",
"Off"
],
"on_change": "set_ctrl_highZ"
2,
4,
6,
8
]
},
"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"
],
"on_change": "set_adc_gain_Vin"
},
"VOLT_INITIAL": {
"CV_E_INITIAL": {
"description": "Initial Voltage of Scan",
"record_meta": true,
"initial": 25000,
@@ -232,8 +281,8 @@
"expression": "VALUE"
}
},
"VOLT_MAX": {
"description": "Max Voltage of Scan",
"CV_E1": {
"description": "First voltage of Scan",
"record_meta": true,
"initial": 25000,
"domain": [
@@ -243,8 +292,8 @@
"expression": "VALUE"
}
},
"VOLT_MIN": {
"description": "Min Voltage of Scan",
"CV_E2": {
"description": "Second voltage of Scan",
"record_meta": true,
"initial": 25000,
"domain": [
@@ -254,16 +303,54 @@
"expression": "VALUE"
}
},
"CYCLE_NUMBER": {
"description": "CV cycle number",
"CV_SCAN_RATE": {
"description": "Voltage scan rate",
"record_meta": true,
"initial": 1,
"initial": 10000,
"domain": [
100001
],
"value": {
"expression": "VALUE"
}
},
"CA_VOLT": {
"description": "Voltage of ca",
"record_meta": true,
"initial": 25000,
"domain": [
"VOLT_MAX"
],
"value": {
"expression": "VALUE"
}
},
"VT_MEASURE_VIN_RANGE": {
"description": "measure range of Vin",
"record_meta": true,
"initial": 0,
"value": [
"0",
"1",
"2",
"auto"
]
},
"RT_VOLT_SET": {
"description": "DAC output Voltage",
"record_meta": true,
"initial": 37500,
"domain": [
65536
],
"value": {
"expression": "VALUE"
}
},
"on_change": "set_para_RT_VOLT_SET"
},
"ADC_VALUE_I": {
"description": "ADC value current value",
"domain": "int"
},
"BLE_WRITE": {
"description": "send msg to elite",
@@ -285,37 +372,52 @@
{
"expression": "MODE",
"when": {
"7": "idle",
"*": "start_data"
}
}
],
"idle": [
"_idle()"
],
"start_data": [
"data_format_cali",
"_notify(True)",
{
"expression": "MODE",
"when": {
"1": "set_adc_gain_I"
}
},
{
"expression": "MODE",
"when": {
"1": "set_adc_gain_Vin"
"0": "set_general_hs_rtia",
"1": "set_general_lp_rtia",
"2": "set_general_lp_rtia",
"3": "set_general_lp_rtia",
"4": "set_general_lp_rtia",
"5": "set_general_hs_rtia"
}
},
{
"expression": "MODE",
"when": {
"0": "curve_eis",
"1": "curve_cv3"
"1": "curve_cv3",
"2": "curve_ca",
"3": "curve_vt",
"4": "curve_rt",
"5": "curve_cf"
}
},
{
"expression": "MODE",
"when": {
"0": "curve_eis_para2",
"1": "curve_cv3_para2"
"1": "curve_cv3_para2",
"5": "curve_cf_para2"
}
},
{
"expression": "MODE",
"when": {
"0": "curve_eis_mode",
"5": "curve_cf_mode"
}
},
"_sync(True)",
@@ -335,6 +437,18 @@
"data_format_cali": [
"_data_format_cali('EISZeroOne')"
],
"set_general_hs_rtia": {
"type": "RIS",
"data": [
"1XFF;1X70;1B>GENERAL_HS_RTIA"
]
},
"set_general_lp_rtia": {
"type": "RIS",
"data": [
"1XFF;1X71;1B>GENERAL_LP_RTIA"
]
},
"set_sample_rate": {
"type": "RIS",
"parameter": {
@@ -344,84 +458,170 @@
"XE0;2B>va"
]
},
"set_adc_gain_I": {
"type": "RIS",
"data": [
"XE1;X05;B>ADC_LEVEL_I_15"
]
},
"set_adc_gain_Vin": {
"type": "RIS",
"data": [
"XE1;X06;B>ADC_LEVEL_V_IN_15"
]
},
"set_ctrl_highZ": {
"type": "RIS",
"data": [
"XE1;X03;B>CTRL_HIGH_Z_15"
"1XFF;1X72;1B>CTRL_HIGH_Z_15"
]
},
"curve_eis": {
"type": "RIS",
"parameter": {
"fa": "FREQ[0]",
"fb": "FREQ[1]",
"dp": "DELAY",
"dc": "DC_BIAS",
"am": "AC_AMP",
"an": "AVERAGE_NUM",
"rt": "RTIA",
"pp": "PPD",
"sp": "SCALE"
"fa": "EIS_FREQ[0]",
"fb": "EIS_FREQ[1]",
"dp": "EIS_DELAY",
"dc": "EIS_DC_BIAS",
"am": "EIS_AC_AMP",
"an": "EIS_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "EIS_PPD",
"sp": "EIS_SCALE"
},
"data": [
"1XD1;1X01;4B>fa;4B>fb;2B>dp"
"1X12;1X01;4B>fa;4B>fb;2B>dp"
]
},
"curve_eis_para2": {
"type": "RIS",
"parameter": {
"fa": "FREQ[0]",
"fb": "FREQ[1]",
"dp": "DELAY",
"dc": "DC_BIAS",
"am": "AC_AMP",
"an": "AVERAGE_NUM",
"rt": "RTIA",
"pp": "PPD",
"sp": "SCALE"
"fa": "EIS_FREQ[0]",
"fb": "EIS_FREQ[1]",
"dp": "EIS_DELAY",
"dc": "EIS_DC_BIAS",
"am": "EIS_AC_AMP",
"an": "EIS_AVERAGE_NUM",
"rt": "GENERAL_HS_RTIA",
"pp": "EIS_PPD",
"sp": "EIS_SCALE"
},
"data": [
"1XD1;1X02;2B>dc;2B>am;B>an;B>rt;2B>pp;B>sp"
"1X12;1X02;2B>dc;2B>am;B>an;B>rt;2B>pp;B>sp"
]
},
"curve_eis_mode": {
"type": "RIS",
"data": [
"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": {
"type": "RIS",
"parameter": {
"va": "VOLT_INITIAL",
"vb": "VOLT_MAX",
"vc": "VOLT_MIN",
"ve": "Scan_Rate",
"va": "CV_E_INITIAL",
"vb": "CV_E1",
"vc": "CV_E2",
"ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER"
},
"data": [
"1XD2;1X01;2B>va;2B>vb;2B>vc;"
"1X09;1X01;2B>va;2B>vb;2B>vc;"
]
},
"curve_cv3_para2": {
"type": "RIS",
"parameter": {
"va": "VOLT_INITIAL",
"vb": "VOLT_MAX",
"vc": "VOLT_MIN",
"ve": "Scan_Rate",
"va": "CV_E_INITIAL",
"vb": "CV_E1",
"vc": "CV_E2",
"ve": "CV_SCAN_RATE",
"vf": "SAMPLE_RATE",
"cn": "CYCLE_NUMBER"
},
"data": [
"1XD2;1X02;4B>ve;2B>vf;2B>cn"
"1X09;1X02;4B>ve;2B>vf;2B>cn"
]
},
"curve_ca": {
"type": "RIS",
"parameter": {
"va": "CA_VOLT",
"pa": "GENERAL_LP_RTIA",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE"
},
"data": [
"1X0B;",
"2B>va;",
"4b>pa;4b>0;",
"4b>0;4b>pd;",
"2B>pe"
]
},
"curve_rt": {
"type": "RIS",
"parameter": {
"va": "RT_VOLT_SET",
"pa": "GENERAL_LP_RTIA",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE"
},
"data": [
"X04;",
"2B>va;",
"4b>pa;4b>0;",
"4b>0;4b>pd;",
"2B>pe"
]
},
"curve_vt": {
"type": "RIS",
"parameter": {
"pa": "GENERAL_LP_RTIA",
"pd": "CTRL_HIGH_Z_15",
"pe": "SAMPLE_RATE",
"va": "VT_MEASURE_VIN_RANGE"
},
"data": [
"X05;",
"4b>pa;4b>0;",
"4b>0;4b>pd;",
"2B>pe;",
"1B>va"
]
},
"set_para_RT_VOLT_SET": {
"type": "RIS",
"data": [
"XE2;X01;2B>RT_VOLT_SET"
]
},
"ble_instru_send": [
@@ -2,16 +2,27 @@
"name": "Elite_TRIG_0.1",
"version": "1.2.30",
"match_rule": {
"local_name_pattern": "Trigger.*",
"local_name_pattern": "Elite.*",
"major_product_number": 0,
"minor_product_number": 5,
"major_version_number": 1,
"minor_version_number": 0
},
"constant": {
"TIME_MAX": 100000
},
"parameters": {
"TIME_DURATION": {
"description": "timer",
"record_meta": true,
"initial": 0,
"domain": [
"TIME_MAX"
],
"value": {
"expression": "VALUE"
}
},
"ACC_a_out0": {
"description": "Switch of analog current channel 1",
"record_meta": true,
@@ -142,7 +153,8 @@
"description": "working mode",
"record_meta": true,
"value": [
"Analog Current Control (ACC)"
"Analog Current Control (ACC)",
"Idle"
]
},
+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