Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 42e09a02a8 | |||
| fc4f931f9d | |||
| 57ba7ed94f | |||
| cf8433c7ee | |||
| 4d1eee6893 | |||
| 7a77c4d413 | |||
| 6f8d68f476 | |||
| 8ae45d3b50 | |||
| 5e4980a1d5 | |||
| 7716908a3b | |||
| 813ff7bc7d | |||
| c2224ed624 | |||
| 72943c3b6f | |||
| 4d47d07996 | |||
| 2fdcef998f | |||
| 2b6381fa46 | |||
| c29d9729ba | |||
| 001905ec96 | |||
| 5033381e64 | |||
| aa88201a93 | |||
| c02c59345b | |||
| 0386cf1847 | |||
| 62d8610191 | |||
| 991f5d06ea | |||
| 55711285e6 | |||
| 3ec5fee43b | |||
| 614a9c0b0f | |||
| 22eb8a09f4 | |||
| dbd7431124 | |||
| 15c15275a7 | |||
| 836d75b77e | |||
| 417bdd91a4 | |||
| 62ee763e2c | |||
| 44e9e4cb67 | |||
| 38537563fd | |||
| 375372996d | |||
| d79491db8b | |||
| 5a35da98ac | |||
| 9c054bd733 | |||
| 64412f9376 | |||
| 97034d6b32 | |||
| f065bad826 | |||
| 9c1dafd003 | |||
| 03443ada99 | |||
| 17dc5470e7 | |||
| 695f37c2dd | |||
| 690f859e86 | |||
| 0ed4d0594a | |||
| 959d86c0fe | |||
| 24c07a7fa5 | |||
| e43857a5bc | |||
| c084f29f06 | |||
| 130d260add | |||
| 575d5d8af1 | |||
| fbf6297047 | |||
| c540013d19 | |||
| 7f0b00a323 | |||
| 4828c85668 | |||
| 4ce9fe5b8d | |||
| d74f09254e | |||
| 79ecff69cc | |||
| df45126ead | |||
| 9fade3469a | |||
| a77331176c | |||
| 8f98337267 | |||
| 205d39cb11 | |||
| a5ea3243fa | |||
| 2edf28c7ba | |||
| 5531dcc0f0 | |||
| b20d46daa8 | |||
| 789d9b3a81 | |||
| 0d0427ed14 | |||
| d434509c5b | |||
| 787d76d48c | |||
| 50f2432088 | |||
| 1cff19ac58 | |||
| baef447c0e | |||
| ee9c13d4c5 | |||
| 9076f2f10b | |||
| 9b2e2964b0 | |||
| 2622109c89 | |||
| a3fe6b87af | |||
| 64419ca1c5 | |||
| 7d77c44741 | |||
| 29b4dd5cc7 | |||
| f151ae6fce | |||
| e535e3d2b1 | |||
| 06c36aa737 | |||
| 402022c451 | |||
| c0bb567bf7 | |||
| 4daff72d39 | |||
| f99719832a | |||
| fcc39dbfed | |||
| 1174d54bc0 |
@@ -7,3 +7,4 @@
|
||||
/.vscode
|
||||
/media
|
||||
python/biopro/sever/_identify.py
|
||||
*.log
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -154,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):
|
||||
@@ -186,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):
|
||||
|
||||
@@ -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()
|
||||
@@ -0,0 +1,60 @@
|
||||
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 biopro.db.base import Session
|
||||
|
||||
from .base import Base
|
||||
|
||||
class Collection(Base):
|
||||
__tablename__ = "collections"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String(255))
|
||||
parent = Column(JSONB)
|
||||
controller_id = Column(Integer)
|
||||
type = Column(String(255))
|
||||
description = Column(String(255))
|
||||
deleted = Column(Boolean)
|
||||
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
|
||||
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
|
||||
|
||||
@classmethod
|
||||
def create_collection(cls, collection_name, parent):
|
||||
with Session() as session:
|
||||
name = cls.check_name_duplicate(collection_name, parent, 0)
|
||||
collection = Collection(
|
||||
name = name,
|
||||
parent = parent,
|
||||
type= "folder",
|
||||
)
|
||||
session.add(collection)
|
||||
session.commit()
|
||||
print('a', collection.id)
|
||||
return collection
|
||||
|
||||
@classmethod
|
||||
def check_name_duplicate(cls, collection_name, parent, n):
|
||||
with Session() as session:
|
||||
result = session.query(Collection).filter(Collection.name == cls.generate_name(collection_name, n), Collection.parent == parent).first()
|
||||
if result is None:
|
||||
return cls.generate_name(collection_name, n)
|
||||
else:
|
||||
new_num = n + 1
|
||||
# new_name = f"{collection_name}({new_num})"
|
||||
return cls.check_name_duplicate(collection_name, parent, new_num)
|
||||
|
||||
@classmethod
|
||||
def generate_name(cls, collection_name, n):
|
||||
if n==0:
|
||||
return collection_name
|
||||
else:
|
||||
return f"{collection_name}({n})"
|
||||
|
||||
@classmethod
|
||||
def find_collection(cls, collection_name, parent):
|
||||
with Session() as session:
|
||||
result = session.query(Collection).filter(Collection.name == collection_name, Collection.parent == parent).first()
|
||||
return result
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
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, Float, BINARY, LargeBinary
|
||||
from sqlalchemy.dialects.postgresql import JSONB
|
||||
|
||||
from .base import Base, Session
|
||||
|
||||
class Device(Base):
|
||||
__tablename__ = "devices"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String(255))
|
||||
mac_address = Column(String(255))
|
||||
serial_number = Column(String(255))
|
||||
configuration = Column(JSONB)
|
||||
library = Column(String(255))
|
||||
library_version = Column(String(255))
|
||||
device_version = Column(String(255))
|
||||
type = Column(String(255))
|
||||
battery = Column(Integer)
|
||||
temperature = Column(Float)
|
||||
auto_connect = Column(Boolean)
|
||||
connect_priority = Column(Integer)
|
||||
connect_time = Column(BigInteger)
|
||||
parameter_set = Column(JSONB)
|
||||
running = Column(Boolean)
|
||||
calibration = Column(LargeBinary)
|
||||
calibration_version = Column(Integer, default=-1)
|
||||
user_auth = Column(JSONB)
|
||||
deleted = Column(Boolean)
|
||||
created_at = Column(TIMESTAMP(timezone=True), server_default=func.now())
|
||||
updated_at = Column(TIMESTAMP(timezone=True), onupdate=func.now())
|
||||
|
||||
@classmethod
|
||||
def update_device(cls, device, options):
|
||||
with Session() as session:
|
||||
result = session.query(Device).filter(Device.mac_address == device['mac_address']).first()
|
||||
for key, value in options.items():
|
||||
setattr(result, key, value)
|
||||
session.commit()
|
||||
|
||||
@classmethod
|
||||
def get_device(cls, device):
|
||||
with Session() as session:
|
||||
result = session.query(Device).filter(Device.mac_address == device['mac_address']).first()
|
||||
return result
|
||||
|
||||
|
||||
|
||||
# def __repr__(self):
|
||||
# return f"User(id={self.id!r}, name={self.name!r}, fullname={self.task!r})"
|
||||
@@ -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 Project(Base):
|
||||
__tablename__ = "project"
|
||||
|
||||
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})"
|
||||
@@ -0,0 +1,29 @@
|
||||
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, Session
|
||||
|
||||
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())
|
||||
|
||||
@classmethod
|
||||
def create_project_meta(cls, project):
|
||||
with Session() as session:
|
||||
project_meta = MetaProjectInfo(project = project['project'], cycle= project['cycle'], task=project['task'], serial_number=int(project['serial_number']))
|
||||
session.add(project_meta)
|
||||
session.commit()
|
||||
return project_meta.id
|
||||
|
||||
# def __repr__(self):
|
||||
# return f"User(id={self.id!r}, name={self.name!r}, fullname={self.task!r})"
|
||||
@@ -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})"
|
||||
@@ -350,6 +350,7 @@ class CC2650Device(Device):
|
||||
self._recording_file_name: str = 'recording_data'
|
||||
self._coeff: bytes = b''
|
||||
self._device_version = ""
|
||||
self._cali_version = -1
|
||||
|
||||
@property
|
||||
def device_id(self) -> int:
|
||||
@@ -432,12 +433,12 @@ class CC2650Device(Device):
|
||||
if length == 1 and instruction[0] < 0:
|
||||
return struct.pack('2B1b',
|
||||
(ins_type & 0xF0) | (self.device_id & 0x0F),
|
||||
(ins_oper & 0xF0) | (length & 0x0F),
|
||||
(ins_oper & 0xFF),
|
||||
*instruction)
|
||||
|
||||
return struct.pack('%dB' % (length + 2),
|
||||
(ins_type & 0xF0) | (self.device_id & 0x0F),
|
||||
(ins_oper & 0xF0) | (length & 0x0F),
|
||||
(ins_oper & 0xFF),
|
||||
*instruction)
|
||||
|
||||
def _decode_data(self, ins_oper: int, data: bytes) -> bytes:
|
||||
@@ -477,13 +478,13 @@ class CC2650Device(Device):
|
||||
|
||||
else:
|
||||
if data is not None and len(data) > 0:
|
||||
year = struct.unpack('<B', data[0:1])[0]
|
||||
month = struct.unpack('<B', data[1:2])[0]
|
||||
day = struct.unpack('<B', data[2:3])[0]
|
||||
hour = struct.unpack('<B', data[3:4])[0]
|
||||
minute = struct.unpack('<B', data[4:5])[0]
|
||||
mac1 = struct.unpack('<B', data[5:6])[0]
|
||||
mac2 = struct.unpack('<B', data[6:7])[0]
|
||||
year = struct.unpack('<B', data[2:3])[0]
|
||||
month = struct.unpack('<B', data[3:4])[0]
|
||||
day = struct.unpack('<B', data[4:5])[0]
|
||||
hour = struct.unpack('<B', data[5:6])[0]
|
||||
minute = struct.unpack('<B', data[6:7])[0]
|
||||
mac1 = struct.unpack('<B', data[7:8])[0]
|
||||
mac2 = struct.unpack('<B', data[8:9])[0]
|
||||
mac1 = "%02X" % mac1
|
||||
mac2 = "%02X" % mac2
|
||||
|
||||
@@ -537,7 +538,7 @@ class CC2650Device(Device):
|
||||
|
||||
else:
|
||||
if data is not None and len(data) > 2 :
|
||||
battery = struct.unpack('<H', data[1:3])[0]
|
||||
battery = struct.unpack('<H', data[2:4])[0]
|
||||
if battery is not None:
|
||||
self._battery = battery
|
||||
|
||||
@@ -549,6 +550,39 @@ class CC2650Device(Device):
|
||||
self.update_calibration_info(device_type)
|
||||
|
||||
return self._coeff
|
||||
|
||||
def _check_crc(self, data):
|
||||
data_chk_sum = data[-1]
|
||||
|
||||
# print('data:', list(data), 'data_chk_sum:', data_chk_sum)
|
||||
# print('data[0:-1]:', list(data[0:-1]), 'check_sum:', sum(data[0:-1]) & 0b11111111)
|
||||
|
||||
if data_chk_sum == sum(data[0:-1]) & 0b11111111:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def update_cali_version(self) -> bool:
|
||||
for _ in range(5):
|
||||
try:
|
||||
code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, 0)
|
||||
self._master.write_characteristic(self.device_id, CC2650MasterDevice.COMMAND_HANDLE, code)
|
||||
except SendInstructionTimeoutError:
|
||||
self._master.log_warn('device', self.device_id, 'update cali version error')
|
||||
return False
|
||||
except RuntimeError:
|
||||
self._master.log_warn('device', self.device_id, 'update cali version error')
|
||||
return False
|
||||
else:
|
||||
version = self._master.read_characteristic(self.device_id,CC2650MasterDevice.RETURN_HANDLE)
|
||||
|
||||
if self._check_crc(version):
|
||||
self._cali_version = struct.unpack('<H', version[2:4])[0]
|
||||
print('self._cali_version=', self._cali_version)
|
||||
return True
|
||||
|
||||
self._master.log_warn('device', self.device_id, 'update cali version error')
|
||||
return False
|
||||
|
||||
def update_calibration_info(self, device_type: str):
|
||||
""" get device calibration info """
|
||||
@@ -571,20 +605,6 @@ class CC2650Device(Device):
|
||||
elif device_type == 'TDC4VC':
|
||||
i = 0
|
||||
request_times = 0
|
||||
# neulive 2.1 (only support ch1~ch8)
|
||||
# try:
|
||||
# # send
|
||||
# code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, 0)
|
||||
# self._master.write_characteristic(self.device_id, CC2650MasterDevice.COMMAND_HANDLE, code)
|
||||
# # receive
|
||||
# data = self._master.read_characteristic(self.device_id, CC2650MasterDevice.RETURN_HANDLE)
|
||||
#
|
||||
# coeff.append(self._decode_data(DeviceInstruction.CIS_CALI, data))
|
||||
# except SendInstructionTimeoutError:
|
||||
# self._master.log_warn('device', self.device_id, 'update_calibration_info no response')
|
||||
# except RuntimeError:
|
||||
# self._master.log_warn('device', self.device_id, 'update_calibration_info no response')
|
||||
|
||||
while i < 4:
|
||||
try:
|
||||
# print('i', i)
|
||||
@@ -660,43 +680,34 @@ class CC2650Device(Device):
|
||||
break
|
||||
|
||||
elif device_type == 'EISZeroOne':
|
||||
i = 0
|
||||
request_times = 0
|
||||
while i < 13:
|
||||
try:
|
||||
# send
|
||||
code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, i)
|
||||
self._master.write_characteristic(self.device_id, CC2650MasterDevice.COMMAND_HANDLE, code)
|
||||
i = 1
|
||||
while i <= 24:
|
||||
for _ in range(5):
|
||||
try:
|
||||
# send
|
||||
code = self._encode_instruction(DeviceInstruction.TYP_CIS, DeviceInstruction.CIS_CALI, i)
|
||||
self._master.write_characteristic(self.device_id, CC2650MasterDevice.COMMAND_HANDLE, code)
|
||||
|
||||
sleep(0.1)
|
||||
|
||||
# receive
|
||||
data = self._master.read_characteristic(self.device_id,
|
||||
CC2650MasterDevice.RETURN_HANDLE)
|
||||
coeff.append(self._decode_data(DeviceInstruction.CIS_CALI, data))
|
||||
|
||||
except SendInstructionTimeoutError as e:
|
||||
print(e)
|
||||
self._master.log_warn('device', self.device_id, 'update_calibration_info no response')
|
||||
raise BaseException
|
||||
except RuntimeError as e:
|
||||
print(e)
|
||||
self._master.log_warn('device', self.device_id, 'update_calibration_info no response - 2')
|
||||
request_times += 1
|
||||
if request_times > 3:
|
||||
self._master.reset(self.device_id)
|
||||
break
|
||||
else:
|
||||
# print('data success')
|
||||
if len(data) > 0:
|
||||
i += 1
|
||||
except SerialTimeoutException:
|
||||
self._master.log_warn('device', self.device_id, 'send update_calibration_info instruction fail')
|
||||
continue
|
||||
|
||||
else:
|
||||
request_times += 1
|
||||
if request_times > 3:
|
||||
self._master.reset(self.device_id)
|
||||
break
|
||||
|
||||
try:
|
||||
# receive
|
||||
data = self._master.read_characteristic(self.device_id,
|
||||
CC2650MasterDevice.RETURN_HANDLE)
|
||||
except RecvTimeout:
|
||||
self._master.log_warn('device', self.device_id, 'update_calibration_info no response')
|
||||
|
||||
else:
|
||||
if self._check_crc(data) and data is not None:
|
||||
coeff.append(self._decode_data(DeviceInstruction.CIS_CALI, data))
|
||||
i += 1
|
||||
else:
|
||||
self._master.log_warn('device', self.device_id, 'update_calibration_info crc wrong')
|
||||
continue
|
||||
|
||||
else:
|
||||
# default: neulive 2.1
|
||||
for i in range(1):
|
||||
@@ -1950,120 +1961,6 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
"""initialize cc2650 (master)"""
|
||||
pass
|
||||
|
||||
def scan_send_ins(self):
|
||||
# send scan command
|
||||
try:
|
||||
print(':: scan_send_ins ::', self.CC2650_COMMAND_LEN, 3, 0, 0)
|
||||
self._cc2650.send(self.CC2650_COMMAND_LEN, 3, 0, 0)
|
||||
|
||||
except SerialTimeoutException as e:
|
||||
raise RecvTimeout('send scan fail') from e
|
||||
|
||||
else:
|
||||
# wait scanning
|
||||
# sleep(2)
|
||||
clean_buf = self._cc2650.receive_timeout("20B", timeout=3)
|
||||
print("clean_buf = ", clean_buf)
|
||||
|
||||
# def cc2650_uart_irq(self):
|
||||
# uart_irq = self.get_uart_irq_pin()
|
||||
# uart_irq.output(False)
|
||||
# sleep(0.001)
|
||||
# uart_irq.output(True)
|
||||
|
||||
@synchronized
|
||||
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
|
||||
self._found = found = []
|
||||
self._found_with_id = []
|
||||
hdr_BPHS = [66, 80, 72, 83]
|
||||
scan_response: Union[Optional[tuple], Any] = None
|
||||
|
||||
# build scan instruction
|
||||
scan_ins = bytearray()
|
||||
scan_ins.append(3) #scan instruction
|
||||
scan_ins.append(1) #length
|
||||
scan_ins.append(0xF1)
|
||||
|
||||
# print('send_scan', bytes(scan_ins))
|
||||
self._cc2650.send("bytes", bytes(scan_ins))
|
||||
|
||||
try:
|
||||
scan_response = self._cc2650.recv_uart(timeout)
|
||||
except RecvTimeout:
|
||||
# self.reset_internal()
|
||||
# self.reset_hardware()
|
||||
# self._interface.flush()
|
||||
return False
|
||||
|
||||
# instruction format:
|
||||
# ins[0]: get_scan_response = 0x04
|
||||
# ins[1]: number of scanned device=0; a certain device = device_id (could be 1~8)
|
||||
# ins[2]: addr=MAC=1, localName=2, company_code=3, version_info=4, battery_info=5, all_info=6;
|
||||
# attr_length=0, e.g. len(addr)=6, len(company_code)=4
|
||||
local_mac = None
|
||||
local_cc = None
|
||||
local_ver = None
|
||||
local_bat = None
|
||||
local_name = None
|
||||
|
||||
local_addr_type = None
|
||||
|
||||
# get device attribute length
|
||||
attr_length = [6, 4, 6, 5, 20]
|
||||
index = 0
|
||||
|
||||
local_mac = get_device_mac_in_address_format(scan_response[index:index + 6])
|
||||
index = index + 6
|
||||
# print("local_mac = ", hex(local_mac[0]), hex(local_mac[1]),
|
||||
# hex(local_mac[2]), hex(local_mac[3]),
|
||||
# hex(local_mac[4]), hex(local_mac[5]))
|
||||
|
||||
local_cc = get_device_company_code(scan_response[index:index + 4])
|
||||
index = index + 4
|
||||
# print("local_cc = ", local_cc)
|
||||
|
||||
local_ver = scan_response[index:index + 6]
|
||||
index = index + 6
|
||||
# print("local_ver = ", local_ver)
|
||||
|
||||
local_bat = get_device_battery_info(scan_response[index:index + 5])
|
||||
index = index + 5
|
||||
# print("local_bat = ", local_bat)
|
||||
|
||||
local_name = get_device_name_in_string_format(list(scan_response[index:index + 20]))
|
||||
index = index + 20
|
||||
# print("local_name = ", local_name)
|
||||
|
||||
# addr type is don't care in BMD380
|
||||
print('scan_response:', list(scan_response))
|
||||
local_addr_type = int(scan_response[index:index + 1][0])
|
||||
# local_addr_type = 0xFF
|
||||
index = index + 1
|
||||
# print("local_addr_type = ", local_addr_type)
|
||||
|
||||
response = is_headstage_device_central_version(local_mac,
|
||||
local_addr_type,
|
||||
local_name,
|
||||
local_cc,
|
||||
local_ver,
|
||||
local_bat)
|
||||
if response is not None:
|
||||
self.log_info('found', address_str(response.mac_address), response.serial_number)
|
||||
self._interface.flush_input()
|
||||
|
||||
# apppend into db
|
||||
devicesList = DeviceAPI.getByMac(address_str(response.mac_address))
|
||||
if devicesList is not None:
|
||||
if len(devicesList) == 0:
|
||||
DeviceAPI.create(response.device_name, local_ver, address_str(response.mac_address))
|
||||
|
||||
found.append(response)
|
||||
# print('scan_done_found', found)
|
||||
self._found_with_id.append((response, 0 + 1))
|
||||
callback(response)
|
||||
|
||||
return True
|
||||
|
||||
def decode_uart_preamble(self, raw_uart: tuple, expect_ret_len: int = 0) -> Optional[list]:
|
||||
# print("decode_uart_preamble: raw_uart = ", raw_uart)
|
||||
if raw_uart is None:
|
||||
@@ -2090,34 +1987,144 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
return self._found
|
||||
|
||||
def check_mem_survive(self) -> Optional[CC2650Device]:
|
||||
ack = []
|
||||
chk_mem_response = None
|
||||
ins = bytearray()
|
||||
ins.append(10)
|
||||
ins.append(1) #length
|
||||
|
||||
ins.append(0x0A)
|
||||
ins.append(0x01) #length
|
||||
ins.append(0xF1)
|
||||
# print('ins', list(ins))
|
||||
self._interface.flush_input()
|
||||
|
||||
try:
|
||||
self.log_verbose('[CC2650]', 'check_mem_survive att_write','0x'+str.upper(ins.hex()))
|
||||
self._cc2650.send("bytes", bytes(ins))
|
||||
|
||||
except SerialTimeoutException as e:
|
||||
raise RecvTimeout('device CC2650 check_mem_survive timeout') from e
|
||||
except SerialTimeoutException:
|
||||
self.log_verbose('[CC2650]', 'check_mem_survive send fail')
|
||||
|
||||
else:
|
||||
try:
|
||||
ack = self._cc2650.recv_uart(0.001)
|
||||
chk_mem_response = self._cc2650.recv_uart(0.001)
|
||||
|
||||
except RecvTimeout:
|
||||
self.log_info("no memory board")
|
||||
self.log_verbose('[CC2650]', 'check_mem_survive response timeout, no memory board')
|
||||
|
||||
# else:
|
||||
# print('ack=', ack)
|
||||
if chk_mem_response is None:
|
||||
return False
|
||||
|
||||
if ack == [3]:
|
||||
pack_len = chk_mem_response[0]
|
||||
mem_ack = chk_mem_response[1:pack_len+1]
|
||||
|
||||
if mem_ack == [3]:
|
||||
chk_mem_response_hex = ''.join(format(i, '02X') for i in chk_mem_response)
|
||||
self.log_verbose('[CC2650]', 'check_mem_survive success', '0x'+chk_mem_response_hex)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@synchronized
|
||||
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
|
||||
self._found = found = []
|
||||
self._found_with_id = []
|
||||
scan_response = None
|
||||
ins = bytearray()
|
||||
|
||||
ins.append(0x03)
|
||||
ins.append(0x01) #length
|
||||
ins.append(0xF1)
|
||||
self._interface.flush_input()
|
||||
|
||||
try:
|
||||
self.log_verbose('[CC2650]', 'scan_callback att_write','0x'+str.upper(ins.hex()))
|
||||
self._cc2650.send("bytes", bytes(ins))
|
||||
|
||||
except SerialTimeoutException:
|
||||
self.log_verbose('[CC2650]', 'scan_callback send fail')
|
||||
|
||||
else:
|
||||
try:
|
||||
scan_response = self._cc2650.recv_uart(0.01)
|
||||
|
||||
except RecvTimeout:
|
||||
self.log_verbose('[CC2650]', 'scan_callback response timeout, no device')
|
||||
return False
|
||||
|
||||
if scan_response is None:
|
||||
return False
|
||||
|
||||
scan_response_hex = ''.join(format(i, '02X') for i in scan_response)
|
||||
self.log_verbose('[CC2650]', 'scan_callback success', '0x'+scan_response_hex)
|
||||
|
||||
if len(scan_response) <= 2:
|
||||
print('******************************************************************')
|
||||
print('******************************************************************')
|
||||
print('******************************************************************')
|
||||
print('******************************************************************')
|
||||
print('****need to fix, len(scan) <= 2')
|
||||
print()
|
||||
return False
|
||||
|
||||
pack_len = scan_response[0]
|
||||
device_info_pkg = scan_response[1:pack_len+1]
|
||||
|
||||
# instruction format:
|
||||
# ins[0]: get_scan_response = 0x04
|
||||
# ins[1]: number of scanned device=0; a certain device = device_id (could be 1~8)
|
||||
# ins[2]: addr=MAC=1, localName=2, company_code=3, version_info=4, battery_info=5, all_info=6;
|
||||
# attr_length=0, e.g. len(addr)=6, len(company_code)=4
|
||||
local_mac = None
|
||||
local_cc = None
|
||||
local_ver = None
|
||||
local_bat = None
|
||||
local_name = None
|
||||
local_addr_type = None
|
||||
|
||||
# get device attribute length
|
||||
attr_length = [6, 4, 6, 5, 20]
|
||||
index = 0
|
||||
|
||||
local_mac = get_device_mac_in_address_format(device_info_pkg[index:index + 6])
|
||||
index = index + 6
|
||||
|
||||
local_cc = get_device_company_code(device_info_pkg[index:index + 4])
|
||||
index = index + 4
|
||||
|
||||
local_ver = device_info_pkg[index:index + 6]
|
||||
index = index + 6
|
||||
|
||||
local_bat = get_device_battery_info(device_info_pkg[index:index + 5])
|
||||
index = index + 5
|
||||
|
||||
local_name = get_device_name_in_string_format(list(device_info_pkg[index:index + 20]))
|
||||
index = index + 20
|
||||
|
||||
local_addr_type = int(device_info_pkg[index:index + 1][0])
|
||||
|
||||
index = index + 1
|
||||
|
||||
response = is_headstage_device_central_version(local_mac,
|
||||
local_addr_type,
|
||||
local_name,
|
||||
local_cc,
|
||||
local_ver,
|
||||
local_bat)
|
||||
if response is not None:
|
||||
self.log_info('found', address_str(response.mac_address), response.serial_number)
|
||||
self._interface.flush_input()
|
||||
|
||||
# apppend into db
|
||||
devicesList = DeviceAPI.getByMac(address_str(response.mac_address))
|
||||
if devicesList is not None:
|
||||
if len(devicesList) == 0:
|
||||
DeviceAPI.create(response.device_name, local_ver, address_str(response.mac_address))
|
||||
|
||||
found.append(response)
|
||||
# print('scan_done_found', found)
|
||||
self._found_with_id.append((response, 0 + 1))
|
||||
callback(response)
|
||||
|
||||
return True
|
||||
|
||||
@synchronized
|
||||
def connect(self, response: DeviceResponseInfo, direct_connect: bool = False) -> Optional[CC2650Device]:
|
||||
if self._handle is not None:
|
||||
@@ -2127,225 +2134,166 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
addr_type = response.addr_type
|
||||
address_s = cc2650.address_str(address)
|
||||
|
||||
self.log_info(DEVICE_CONNECTING, address_s)
|
||||
|
||||
connect_ins = bytearray()
|
||||
connect_ins.append(5)
|
||||
connect_ins.append(8) #length
|
||||
connect_ins.append(addr_type)
|
||||
connect_ins.append(address[0])
|
||||
connect_ins.append(address[1])
|
||||
connect_ins.append(address[2])
|
||||
connect_ins.append(address[3])
|
||||
connect_ins.append(address[4])
|
||||
connect_ins.append(address[5])
|
||||
connect_ins.append(0xF1)
|
||||
|
||||
connected = False
|
||||
connect_response = None
|
||||
ins = bytearray()
|
||||
|
||||
# send connect command
|
||||
if direct_connect is True:
|
||||
|
||||
# send device mac and addrType
|
||||
try:
|
||||
self._cc2650.send("bytes", bytes(connect_ins))
|
||||
|
||||
except SerialTimeoutException as e:
|
||||
raise RecvTimeout('device CC2650 connect fail') from e
|
||||
return None
|
||||
|
||||
# connection establish done?
|
||||
for retry_recv_ack in range(10):
|
||||
try:
|
||||
con_done = self._cc2650.recv_uart(timeout = 0.5)
|
||||
# print("con_done = ", con_done)
|
||||
|
||||
except RecvTimeout:
|
||||
self.log_info("recv connection timeout, retry... ")
|
||||
continue
|
||||
|
||||
# is the ack valid?
|
||||
if con_done is None:
|
||||
continue
|
||||
|
||||
elif con_done[0] is 46 and \
|
||||
con_done[1] is 80 and \
|
||||
con_done[2] is 48 and \
|
||||
con_done[3] is 4:
|
||||
connected = True
|
||||
break
|
||||
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:
|
||||
con_done = self._cc2650.recv_uart(timeout = 0.1)
|
||||
|
||||
except RecvTimeout:
|
||||
self.log_info("recv connection timeout, retry... ")
|
||||
continue
|
||||
|
||||
# is the ack valid?
|
||||
if con_done is None:
|
||||
continue
|
||||
|
||||
elif con_done[0] is 46 and \
|
||||
con_done[1] is 80 and \
|
||||
con_done[2] is 48 and \
|
||||
con_done[3] is 4:
|
||||
connected = True
|
||||
# print('con_done=', con_done)
|
||||
break
|
||||
else:
|
||||
continue
|
||||
|
||||
# if select device is invalid or connect failed
|
||||
ins.append(0x05)
|
||||
ins.append(0x08) #length
|
||||
ins.append(addr_type)
|
||||
ins.append(address[0])
|
||||
ins.append(address[1])
|
||||
ins.append(address[2])
|
||||
ins.append(address[3])
|
||||
ins.append(address[4])
|
||||
ins.append(address[5])
|
||||
ins.append(0xF1)
|
||||
self._interface.flush_input()
|
||||
if connected is False:
|
||||
if direct_connect is True:
|
||||
self.reset_internal()
|
||||
self.reset_hardware()
|
||||
self._interface.flush()
|
||||
return None
|
||||
|
||||
# CC2650Device(device_id, master, scan_response) is a slave device
|
||||
# device_id is don't care, because it will be overwrite later
|
||||
dont_care = 0
|
||||
self._device = ret = CC2650Device(device_id=dont_care, master=self, response_info=response)
|
||||
self.log_info(DEVICE_CONNECTED, address_s)
|
||||
sleep(0.5)
|
||||
print('ret',ret)
|
||||
for retry in range(5):
|
||||
try:
|
||||
self.log_verbose('[CC2650]', 'connect att_write', '0x'+str.upper(ins.hex()))
|
||||
self._cc2650.send("bytes", bytes(ins))
|
||||
|
||||
return ret
|
||||
except RecvTimeout:
|
||||
self.log_verbose('[CC2650]', 'connect send fail')
|
||||
continue
|
||||
|
||||
else:
|
||||
try:
|
||||
connect_response = self._cc2650.recv_uart(2)
|
||||
except RecvTimeout:
|
||||
self.log_verbose('[CC2650]', 'connect response timeout')
|
||||
if retry < 5:
|
||||
self.log_verbose('[CC2650]', 'connect retry')
|
||||
continue
|
||||
else:
|
||||
break
|
||||
|
||||
if connect_response is None:
|
||||
return False
|
||||
|
||||
pack_len = connect_response[0]
|
||||
connect_ack = connect_response[1:pack_len+1]
|
||||
|
||||
if connect_ack[0] == 46 and connect_ack[1] == 80 and \
|
||||
connect_ack[2] == 48 and connect_ack[3] == 4:
|
||||
connected = True
|
||||
connect_response_hex = ''.join(format(i, '02X') for i in connect_response)
|
||||
self.log_verbose('[CC2650]', 'connect success', '0x'+connect_response_hex)
|
||||
|
||||
if connected == True:
|
||||
# CC2650Device(device_id, master, scan_response) is a slave device
|
||||
# device_id is don't care, because it will be overwrite later
|
||||
dont_care = 0
|
||||
self._device = ret = CC2650Device(device_id=dont_care, master=self, response_info=response)
|
||||
self.log_verbose('[CC2650]', DEVICE_CONNECTED, address_s)
|
||||
return ret
|
||||
|
||||
self.log_verbose('[CC2650]', 'connect fail')
|
||||
return False
|
||||
|
||||
@synchronized
|
||||
def disconnect(self, device: int, force=False) -> bool:
|
||||
self.log_info(DEVICE_DISCONNECTING, device)
|
||||
|
||||
ins = bytearray()
|
||||
ins.append(8)
|
||||
ins.append(1) #length
|
||||
|
||||
ins.append(0x08)
|
||||
ins.append(0x01) #length
|
||||
ins.append(0xF1)
|
||||
self._interface.flush_input()
|
||||
|
||||
for _ in range(5):
|
||||
try:
|
||||
self.log_verbose('[CC2650]', 'disconnect att_write','0x'+str.upper(ins.hex()))
|
||||
self._cc2650.send("bytes", bytes(ins))
|
||||
|
||||
except SerialTimeoutException:
|
||||
self.log_verbose('[CC2650]', 'disconnect send fail')
|
||||
continue
|
||||
|
||||
else:
|
||||
self.reset_internal()
|
||||
self.reset_hardware()
|
||||
self.log_verbose('[CC2650]', 'disconnect success')
|
||||
return True
|
||||
|
||||
self.log_verbose('[CC2650]', 'disconnect fail')
|
||||
return False
|
||||
|
||||
@synchronized
|
||||
def write_characteristic(self, device: int, handle: int, data: bytes) -> bool:
|
||||
write_response = None
|
||||
ins = bytearray()
|
||||
|
||||
ins.append(0x06)
|
||||
ins.append(len(data)+2) #length = handle + C0C0XXXX(data len) + F1
|
||||
ins.append(handle)
|
||||
ins.extend(data)
|
||||
ins.append(0xF1)
|
||||
self._interface.flush_input()
|
||||
|
||||
try:
|
||||
# print('send_disconnect',bytes(ins))
|
||||
self.log_verbose('[CC2650]', 'write_characteristic', device, str(hex(handle).upper()))
|
||||
self.log_verbose('[CC2650]', 'write_characteristic att_write','0x'+str.upper(ins.hex()))
|
||||
self._cc2650.send("bytes", bytes(ins))
|
||||
|
||||
except RecvTimeout:
|
||||
self.log_warn('disconnect time out')
|
||||
return False
|
||||
|
||||
except RuntimeError as e:
|
||||
self.log_warn('suppressed error', str(e))
|
||||
return False
|
||||
|
||||
except SerialTimeoutException:
|
||||
self.log_verbose('[CC2650]', 'write_characteristic send fail')
|
||||
|
||||
else:
|
||||
sleep(0.01)
|
||||
try:
|
||||
write_response = self._cc2650.recv_uart(0.5)
|
||||
|
||||
except RecvTimeout:
|
||||
self.log_verbose('[CC2650]', 'write_characteristic response timeout')
|
||||
|
||||
if write_response is None:
|
||||
return False
|
||||
|
||||
pack_len = write_response[0]
|
||||
write_ack = write_response[1:pack_len+1]
|
||||
|
||||
if write_ack == [3]:
|
||||
write_response_hex = ''.join(format(i, '02X') for i in write_response)
|
||||
self.log_verbose('[CC2650]', 'write_characteristic success', '0x'+write_response_hex)
|
||||
return True
|
||||
|
||||
finally:
|
||||
self.log_info(DEVICE_DISCONNECTED, device)
|
||||
|
||||
# reset single 2650 after disconnected
|
||||
self.reset_internal()
|
||||
self.reset_hardware()
|
||||
self._interface.flush()
|
||||
self.log_verbose('[CC2650]', 'write_characteristic fail')
|
||||
return False
|
||||
|
||||
@synchronized
|
||||
def read_characteristic(self, device: int, handle: int) -> Optional[bytes]:
|
||||
|
||||
# print("read_characteristic, expect_data_length = ", expect_data_length)
|
||||
|
||||
ret = None
|
||||
read_response = None
|
||||
ins = bytearray()
|
||||
ins.append(7)
|
||||
ins.append(2) #length
|
||||
|
||||
ins.append(0x07)
|
||||
ins.append(0x02) #length
|
||||
ins.append(handle)
|
||||
ins.append(0xF1)
|
||||
|
||||
for _ in range(2):
|
||||
try:
|
||||
# print('send_read',bytes(ins))
|
||||
self._cc2650.send("bytes", bytes(ins))
|
||||
except SerialTimeoutException:
|
||||
raise RecvTimeout('device CC2650 send read_characteristic fail')
|
||||
|
||||
try:
|
||||
ret = self._cc2650.recv_uart(timeout = 2)
|
||||
except Exception as e2:
|
||||
raise RecvTimeout()
|
||||
else:
|
||||
# print("======== read ret = ", ret)
|
||||
self._interface.flush_input()
|
||||
|
||||
# try:
|
||||
# ret = self._cc2650.recv_uart(timeout = 1)
|
||||
# except Exception as e2:
|
||||
# raise RecvTimeout()
|
||||
# else:
|
||||
# # print("read_characteristic ret = ", ret)
|
||||
# pass
|
||||
|
||||
if ret is None:
|
||||
return None
|
||||
|
||||
return bytes(ret)
|
||||
|
||||
@synchronized
|
||||
def write_characteristic(self, device: int, handle: int, data: bytes):
|
||||
|
||||
# print("device", device)
|
||||
# print("handle", handle)
|
||||
# print("data", data.hex())
|
||||
# self.log_info('reset')
|
||||
self.log_verbose('write_characteristic', device, handle)
|
||||
self.log_verbose('[CC2650]', 'att_write', str.upper(data.hex()))
|
||||
ack = None
|
||||
ret = None
|
||||
|
||||
data_array = bytearray()
|
||||
data_array.append(6)
|
||||
data_array.append(len(data)+2) #length
|
||||
data_array.append(handle)
|
||||
data_array.extend(data)
|
||||
data_array.append(0xF1)
|
||||
|
||||
self._interface.flush_input()
|
||||
|
||||
try:
|
||||
self._cc2650.send("bytes", bytes(data_array))
|
||||
# print('send_write',bytes(data_array))
|
||||
self.log_verbose('[CC2650]', 'read_characteristic', device, str(hex(handle).upper()))
|
||||
self.log_verbose('[CC2650]', 'read_characteristic att_write','0x'+str.upper(ins.hex()))
|
||||
self._cc2650.send("bytes", bytes(ins))
|
||||
|
||||
except SerialTimeoutException as e:
|
||||
raise RecvTimeout('device CC2650 send instruction fail') from e
|
||||
|
||||
# read error code
|
||||
try:
|
||||
ret = self._cc2650.recv_uart()
|
||||
|
||||
# print("_______ write ack = ", ret)
|
||||
except Exception as e2:
|
||||
pass
|
||||
except SerialTimeoutException:
|
||||
self.log_verbose('[CC2650]', 'read_characteristic send fail')
|
||||
|
||||
else:
|
||||
pass
|
||||
try:
|
||||
read_response = self._cc2650.recv_uart(1)
|
||||
|
||||
self._interface.flush_input()
|
||||
self._interface.flush_output()
|
||||
except RecvTimeout:
|
||||
self.log_verbose('[CC2650]', 'read_characteristic response timeout')
|
||||
|
||||
if read_response is None:
|
||||
return None
|
||||
|
||||
read_response_hex = ''.join(format(i, '02X') for i in read_response)
|
||||
self.log_verbose('[CC2650]', 'read_characteristic success', '0x'+read_response_hex)
|
||||
|
||||
return bytes(read_response)
|
||||
|
||||
def set_notify(self, device: Union[int, Device], enable: bool):
|
||||
if isinstance(device, CompletedDevice):
|
||||
@@ -2446,7 +2394,6 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
self._cc2650_log_level = self.log_level
|
||||
|
||||
def read_characteristic(self, device: int, handle: int) -> Optional[bytes]:
|
||||
self.log_verbose('read_characteristic', device, '0x%02X' % handle)
|
||||
|
||||
master = self._cc2650[device]
|
||||
|
||||
@@ -2504,11 +2451,6 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
|
||||
self._interface.flush()
|
||||
self._selector.select(device_id)
|
||||
# self._mem_selector.select(device_id)
|
||||
# print("multiMaster selector = ", device_id)
|
||||
# print("\n")
|
||||
|
||||
# device._notify_flag = enable
|
||||
try:
|
||||
master.write_characteristic(device_id, self.NOTIFY_HANDLE, value)
|
||||
except SendInstructionTimeoutError:
|
||||
|
||||
@@ -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)
|
||||
|
||||
+330
-212
@@ -884,20 +884,54 @@ 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]
|
||||
notify_one = struct.unpack('<i', data[28:32])[0]
|
||||
notify_two = struct.unpack('<i', data[32:36])[0]
|
||||
notify_three = struct.unpack('<i', data[36:40])[0]
|
||||
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
|
||||
@@ -924,25 +958,29 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
|
||||
else:
|
||||
if self._show_data:
|
||||
print('|', time_stamp, '|', delta, '|', int(time_stamp * 1000 / 2),
|
||||
'|', current, '|', voltage, '|', impedance, '|', cycle_number,
|
||||
'|', notify_one, '|', notify_two, '|', notify_three,
|
||||
'|', finishMode, '@', str(self.device))
|
||||
'|', 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())
|
||||
@@ -951,13 +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, notify_one)
|
||||
ret.append_data(5, notify_two)
|
||||
ret.append_data(6, notify_three)
|
||||
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)
|
||||
@@ -1345,9 +1383,9 @@ 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', '_show_data')
|
||||
'_mode_stop', '_last_time_stamp', '_last_delta',
|
||||
'_cali_package', 'cali_coeff', '_ac_amp', '_mode',
|
||||
'_last_phase', '_first_phase_flag', '_show_data')
|
||||
|
||||
def __init__(self, cali_coeff: bytes = None):
|
||||
super().__init__()
|
||||
@@ -1360,147 +1398,234 @@ 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_package: 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)
|
||||
if self._cali_package is None:
|
||||
self._cali_package = cali_coeff
|
||||
self.cali_coeff = self._decode_cali_coeff(self._cali_package)
|
||||
|
||||
@staticmethod
|
||||
def _decode_cali_coeff(cali_coeff: bytes) -> Optional[List[Tuple[int, int]]]:
|
||||
if cali_coeff != b'':
|
||||
cis_data_len = 20
|
||||
cali_table = []
|
||||
hsrtia_a = []
|
||||
hsrtia_b = []
|
||||
hsrtia_c = []
|
||||
hsrtia_d = []
|
||||
rolloff = []
|
||||
phase_coeff = []
|
||||
phase_offset = []
|
||||
|
||||
# phase_coeff = [[0]*4 for i in range(4)]
|
||||
# phase_offset = [[0]*4 for i in range(4)]
|
||||
|
||||
phase_coeff = numpy.zeros([4, 4], dtype = int)
|
||||
phase_offset = numpy.zeros([4, 4], dtype = int)
|
||||
phase_coeff = numpy.zeros([8, 4], dtype = int)
|
||||
phase_offset = numpy.zeros([8, 4], dtype = int)
|
||||
|
||||
########################################
|
||||
# phase_coeff
|
||||
# [[gain0, g1, g2, g3] ----->最高頻
|
||||
# [gain0, g1, g2, g3] ----->中頻
|
||||
# [gain0, g1, g2, g3] ----->低頻
|
||||
# [gain0, g1, g2, g3] ----->最低頻
|
||||
# [[freq0, freq1, freq2, freq3] ----->gain0
|
||||
# [freq0, freq1, freq2, freq3] ----->gain1
|
||||
# [freq0, freq1, freq2, freq3] ----->gain2
|
||||
# [freq0, freq1, freq2, freq3] ----->gain3
|
||||
# ]
|
||||
#######################################
|
||||
|
||||
# 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
|
||||
#hstia=0
|
||||
cis_cali_packet = 1
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
|
||||
hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
|
||||
rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
|
||||
|
||||
index = 20
|
||||
cis_cali_packet = 2
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 0
|
||||
phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
|
||||
phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
|
||||
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
|
||||
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
|
||||
phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
index = 40
|
||||
cis_cali_packet = 3
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 0
|
||||
phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
|
||||
phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
|
||||
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
|
||||
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
|
||||
phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[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)
|
||||
#hstia=1
|
||||
cis_cali_packet = 4
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
|
||||
hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
|
||||
rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[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)
|
||||
|
||||
#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)
|
||||
|
||||
#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)
|
||||
|
||||
index = 140
|
||||
cis_cali_packet = 5
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 1
|
||||
phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
|
||||
phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
|
||||
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
|
||||
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
|
||||
phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
index = 160
|
||||
cis_cali_packet = 6
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 1
|
||||
phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
|
||||
phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
|
||||
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
|
||||
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
|
||||
|
||||
index = 180
|
||||
g = 2
|
||||
phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
|
||||
phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
|
||||
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
|
||||
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
|
||||
|
||||
index = 200
|
||||
g = 2
|
||||
phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
|
||||
phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
|
||||
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
|
||||
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
|
||||
|
||||
index = 220
|
||||
g = 3
|
||||
phase_coeff[0][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
|
||||
phase_offset[0][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
|
||||
phase_coeff[1][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
|
||||
phase_offset[1][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
|
||||
|
||||
index = 240
|
||||
g = 3
|
||||
phase_coeff[2][g] = struct.unpack('>i', cali_coeff[index+1:index+5])[0]
|
||||
phase_offset[2][g] = struct.unpack('>i', cali_coeff[index+5:index+9])[0]
|
||||
phase_coeff[3][g] = struct.unpack('>i', cali_coeff[index+9:index+13])[0]
|
||||
phase_offset[3][g] = struct.unpack('>i', cali_coeff[index+13:index+17])[0]
|
||||
phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
# print('cutoff_freq', cutoff_freq)
|
||||
# print('hsrtia_a', hsrtia_a)
|
||||
# print('hsrtia_b', hsrtia_b)
|
||||
# print('hsrtia_c', hsrtia_c)
|
||||
# print('phase_coeff')
|
||||
# print(phase_coeff)
|
||||
# print('phase_offset')
|
||||
# print(phase_offset)
|
||||
#hstia=2
|
||||
cis_cali_packet = 7
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
|
||||
hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
|
||||
rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
|
||||
|
||||
cali_table.append((cutoff_freq, phase_coeff, phase_offset, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d))
|
||||
cis_cali_packet = 8
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 2
|
||||
phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
cis_cali_packet = 9
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 2
|
||||
phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
#hstia=3
|
||||
cis_cali_packet = 10
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
|
||||
hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
|
||||
rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
|
||||
|
||||
cis_cali_packet = 11
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 3
|
||||
phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
cis_cali_packet = 12
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 3
|
||||
phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
#hstia=4
|
||||
cis_cali_packet = 13
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
|
||||
hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
|
||||
rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
|
||||
|
||||
cis_cali_packet = 14
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 4
|
||||
phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
cis_cali_packet = 15
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 4
|
||||
phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
#hstia=5
|
||||
cis_cali_packet = 16
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
|
||||
hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
|
||||
rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
|
||||
|
||||
cis_cali_packet = 17
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 5
|
||||
phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
cis_cali_packet = 18
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 5
|
||||
phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
#hstia=6
|
||||
cis_cali_packet = 19
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
|
||||
hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
|
||||
rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
|
||||
|
||||
cis_cali_packet = 20
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 6
|
||||
phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
cis_cali_packet = 21
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 6
|
||||
phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
#hstia=7
|
||||
cis_cali_packet = 22
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
hsrtia_a.append(struct.unpack('>i', cali_coeff[index+2:index+6])[0])
|
||||
hsrtia_b.append(struct.unpack('>q', cali_coeff[index+6:index+14])[0])
|
||||
rolloff.append(struct.unpack('>i', cali_coeff[index+14:index+18])[0])
|
||||
|
||||
cis_cali_packet = 23
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 7
|
||||
phase_coeff[g][0] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][0] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][1] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][1] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
|
||||
cis_cali_packet = 24
|
||||
index = (cis_cali_packet - 1) * cis_data_len
|
||||
g = 7
|
||||
phase_coeff[g][2] = struct.unpack('>i', cali_coeff[index+2:index+6])[0]
|
||||
phase_offset[g][2] = struct.unpack('>i', cali_coeff[index+6:index+10])[0]
|
||||
phase_coeff[g][3] = struct.unpack('>i', cali_coeff[index+10:index+14])[0]
|
||||
phase_offset[g][3] = struct.unpack('>i', cali_coeff[index+14:index+18])[0]
|
||||
print('hsrtia_a', hsrtia_a)
|
||||
print('hsrtia_b', hsrtia_b)
|
||||
print('rolloff', 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:
|
||||
@@ -1509,10 +1634,10 @@ class EISZeroOneDataDecoder(RecDataDecoder):
|
||||
|
||||
@property
|
||||
def name(self) -> AnyStr:
|
||||
if self._cali_coeff is None:
|
||||
if self._cali_package is None:
|
||||
return self.NAME
|
||||
else:
|
||||
return self.NAME.encode() + b':' + self._cali_coeff
|
||||
return self.NAME.encode() + b':' + self._cali_package
|
||||
|
||||
def message(self) -> Optional[str]:
|
||||
ret = self._message
|
||||
@@ -1530,9 +1655,14 @@ class EISZeroOneDataDecoder(RecDataDecoder):
|
||||
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] # Amp[uV]
|
||||
|
||||
notify_one = struct.unpack('<i', data[25+3:29+3])[0]
|
||||
notify_two = struct.unpack('<i', data[29+3:33+3])[0]
|
||||
notify_three = struct.unpack('<i', data[33+3:37+3])[0]
|
||||
|
||||
if time_stamp == 0:
|
||||
self._start_return_data = True
|
||||
|
||||
@@ -1540,7 +1670,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)
|
||||
@@ -1549,40 +1679,26 @@ 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:
|
||||
if self.cali_coeff is not None and (self._mode == 0 or self._mode == 5):
|
||||
hsrtia_a = []
|
||||
hsrtia_b = []
|
||||
hsrtia_c = []
|
||||
hsrtia_d = []
|
||||
cutoff_freq, phase_coeff, phase_offset, hsrtia_a, hsrtia_b, hsrtia_c, hsrtia_d = self.cali_coeff[0]
|
||||
rolloff = []
|
||||
phase_coeff, phase_offset, hsrtia_a, hsrtia_b, rolloff = 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._mode == 0):
|
||||
if (self._mode == 0 or self._mode == 5):
|
||||
img = ch1
|
||||
real = ch2
|
||||
freq = ch3
|
||||
fre_idx = 0
|
||||
voltage_amp = round(ch4 / 1000) # Amp[mV]
|
||||
rolloff_cali = rolloff[gain]
|
||||
|
||||
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])
|
||||
|
||||
voltage_mag = math.sqrt(img ** 2 + real ** 2) * (1 + freq ** 2 / rolloff_cali ** 2 / 1e4)
|
||||
current = (voltage_mag ** 2 * hsrtia_a[gain] + voltage_mag * hsrtia_b[gain]) / 1e8 #[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
|
||||
|
||||
@@ -1601,37 +1717,33 @@ class EISZeroOneDataDecoder(RecDataDecoder):
|
||||
phase = raw_phase - ideal_raw_phase
|
||||
phase = phase % 180 if phase % 180<=90 else phase % 180-180
|
||||
|
||||
# last_phase_to90 = self._last_phase % 180 if self._last_phase % 180<=90 else self._last_phase % 180-180
|
||||
# diff = phase - last_phase_to90
|
||||
|
||||
# if (self._first_phase_flag):
|
||||
# # self._last_phase = phase
|
||||
# self._first_phase_flag = 0
|
||||
# elif (abs(diff) >= 90):
|
||||
# phase = self._last_phase + diff + (180 if diff<0 else-180)
|
||||
# else:
|
||||
# phase = self._last_phase + diff
|
||||
# self._last_phase = phase
|
||||
|
||||
imag_after_cal = impedance * math.sin(round(phase) * math.pi / 180)
|
||||
real_after_cal = impedance * math.cos(round(phase) * math.pi / 180)
|
||||
imag_after_cal = round(impedance * math.sin(phase * math.pi / 180))
|
||||
real_after_cal = round(impedance * math.cos(phase * math.pi / 180))
|
||||
|
||||
if self._show_data:
|
||||
if (self._mode == 0):
|
||||
if (self._mode == 0 or self._mode == 5):
|
||||
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), '|')
|
||||
'|', '{:5}'.format(delta),
|
||||
'|', '{:5}'.format(ch1), #raw_img
|
||||
'|', '{:5}'.format(ch2), #raw_real
|
||||
'|', '{:8}'.format(ch3 * 10), '[mHz]', #Frequency [mHz]
|
||||
'|', '{:5}'.format(cycle_number), #cycle
|
||||
'|', '{:5}'.format(round(imag_after_cal)), '[Ohm]', #Z_imag [Ohm]
|
||||
'|', '{:5}'.format(round(real_after_cal)), '[Ohm]', #Z_real [Ohm]
|
||||
'|', '{:5}'.format(round(impedance)), '[Ohm]', #Impedance [Ohm]
|
||||
'|', '{:5}'.format(round(phase*1000)), '[mdegree]', #Phase [millidegree]
|
||||
'|', '{:5}'.format(round(current)), '[nA]', #Current [nA]
|
||||
'|', '{:1}'.format(gain), #gain
|
||||
'|', '{:1}'.format(finishMode), #finishMode
|
||||
'@', str(self.device), '|', flush = True)
|
||||
|
||||
print('|', '{:10}'.format(time_stamp),
|
||||
'|', '{:5}'.format(delta),
|
||||
'|', '{:5}'.format(notify_one),
|
||||
'|', '{:5}'.format(notify_two),
|
||||
'|', '{:5}'.format(notify_three),
|
||||
'|', '{:5}'.format(voltage_amp), #amp[mV]
|
||||
'|', flush = True)
|
||||
pass
|
||||
else:
|
||||
print('|', '{:10}'.format(time_stamp),
|
||||
@@ -1642,7 +1754,7 @@ class EISZeroOneDataDecoder(RecDataDecoder):
|
||||
'|', '{:5}'.format(cycle_number),
|
||||
'|', '{:1}'.format(gain),
|
||||
'|', '{:1}'.format(finishMode),
|
||||
'@', str(self.device), '|')
|
||||
'@', str(self.device), '|', flush = True)
|
||||
pass
|
||||
|
||||
if finishMode == True:
|
||||
@@ -1652,17 +1764,23 @@ 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
|
||||
if self._mode == 0 or self._mode == 5:
|
||||
ret.append_data(0, ch1) #raw_img
|
||||
ret.append_data(1, ch2) #raw_real
|
||||
ret.append_data(2, ch3 * 10) #Frequency [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(3, cycle_number) #cycle
|
||||
ret.append_data(4, imag_after_cal) #Z_imag [Ohm]
|
||||
ret.append_data(5, 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(7, round(phase*1000)) #Phase [millidegree]
|
||||
ret.append_data(8, round(current)) #Current [nA]
|
||||
ret.append_data(9, gain) #Gain Level
|
||||
ret.append_data(9, gain) #gain
|
||||
|
||||
#debug data
|
||||
ret.append_data(10, notify_one)
|
||||
ret.append_data(11, notify_two)
|
||||
ret.append_data(12, notify_three)
|
||||
ret.append_data(13, voltage_amp) #amp[mV]
|
||||
|
||||
else: #CV Mode
|
||||
ret.append_data(0, ch1) #Iin [nA]
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
@@ -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]:
|
||||
@@ -1131,7 +1141,7 @@ class CompletedDevice(Device):
|
||||
# raise RuntimeError('illegal parameter value : ' + value) from e
|
||||
else:
|
||||
if name == 'MODE':
|
||||
if self.library_name.startswith('Elite_EDC'):
|
||||
if self.library_name.startswith('Elite_EDC') or 'EIS' in self.library_name:
|
||||
self.set_parameter('CTRL_HIGH_Z_15', self.get_parameter('HIGHZ_TABLE')[value])
|
||||
self.set_parameter('TIME_DURATION', 0)
|
||||
|
||||
@@ -1303,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),
|
||||
}
|
||||
|
||||
@@ -1392,20 +1403,6 @@ class DebugDevice(CompletedDevice):
|
||||
def read_command_return_data(self) -> Optional[bytes]:
|
||||
return None
|
||||
|
||||
def send_command(self, ins_type: int, ins_oper: int, *instruction: int):
|
||||
length = len(instruction)
|
||||
print('instruction send :',
|
||||
'%02X' % ((ins_type & 0xF0) | (self.device_id & 0x0F)),
|
||||
'%02X' % ((ins_oper & 0xF0) | (length & 0x0F)),
|
||||
' '.join(map(lambda v: '%02X' % v, instruction)))
|
||||
|
||||
def send_instruction(self, ins_type: int, ins_oper: int, *instruction: int):
|
||||
length = len(instruction)
|
||||
print('instruction send :',
|
||||
'%02X' % ((ins_type & 0xF0) | (self.device_id & 0x0F)),
|
||||
'%02X' % ((ins_oper & 0xF0) | (length & 0x0F)),
|
||||
' '.join(map(lambda v: '%02X' % v, instruction)))
|
||||
|
||||
@property
|
||||
def battery(self) -> int:
|
||||
return 100
|
||||
|
||||
@@ -3697,7 +3697,6 @@ class CC2650Central(LoggerFlag):
|
||||
|
||||
def recv(self, timeout: Optional[float] = None) -> Optional[list]:
|
||||
packet = self._recv_byte()
|
||||
# print("packet = ", packet)
|
||||
|
||||
if packet is None:
|
||||
return None
|
||||
@@ -3709,6 +3708,8 @@ class CC2650Central(LoggerFlag):
|
||||
|
||||
def _recv_byte(self) -> Optional[int]:
|
||||
ret = self._recv_bytes(1)
|
||||
# if ret is not None:
|
||||
# print('packet = {0}'.format(hex(ret[0]).upper()))
|
||||
return ret[0] if ret is not None else None
|
||||
|
||||
def _recv_bytes(self, size: int = 1) -> Union[None, bytes]:
|
||||
@@ -3724,27 +3725,28 @@ class CC2650Central(LoggerFlag):
|
||||
return None
|
||||
|
||||
def _recv_event(self, timeout: Optional[float] = 1) -> Optional[list]:
|
||||
code = self._recv_byte()
|
||||
# print("code = ", code)
|
||||
packet = self._recv_byte()
|
||||
|
||||
if code is None:
|
||||
if packet is None:
|
||||
return None
|
||||
|
||||
length = self._recv_byte()
|
||||
# print('code::',code,'length::',length)
|
||||
|
||||
_start = _time()
|
||||
len_b = _struct.pack("B", length)
|
||||
data = b''
|
||||
|
||||
while len(data) < length:
|
||||
ret = self._recv_bytes(length - len(data))
|
||||
# print("ret = ", ret)
|
||||
_start = _time()
|
||||
|
||||
if ret is not None:
|
||||
data += ret
|
||||
while len(data) < length:
|
||||
packets = self._recv_bytes(length - len(data))
|
||||
# hex_packets = ''.join(format(i, '02x') for i in packets)
|
||||
# print("packets = ", hex_packets.upper())
|
||||
|
||||
if packets is not None:
|
||||
data += packets
|
||||
elif timeout is not None and _time() - _start > timeout:
|
||||
raise RecvTimeout()
|
||||
|
||||
data = len_b + data
|
||||
self._interface.flush()
|
||||
return list(data)
|
||||
|
||||
@@ -3760,5 +3762,7 @@ class CC2650Central(LoggerFlag):
|
||||
raise RecvTimeout()
|
||||
|
||||
else:
|
||||
uart_data_hex = ''.join(format(i, '02X') for i in uart_data)
|
||||
# print('uart_data: 0x{0}'.format(uart_data_hex.upper()))
|
||||
return uart_data
|
||||
|
||||
|
||||
@@ -53,6 +53,8 @@ class UARTInterface(LowLevelHardwareInterface):
|
||||
:param data: raw byte instruction
|
||||
:raises SerialTimeoutException:
|
||||
"""
|
||||
data_hex = ''.join(format(i, '02X') for i in data)
|
||||
# print('send_byte: 0x{0}'.format(data_hex.upper()))
|
||||
self._serial.write(data)
|
||||
|
||||
def recv_byte(self, size: int) -> Optional[bytes]:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import sys
|
||||
import json
|
||||
import threading
|
||||
import logging
|
||||
|
||||
from time import time, sleep
|
||||
from datetime import datetime
|
||||
@@ -14,6 +15,9 @@ from .instruction import Instruction
|
||||
from biopro.device.manager import DeviceManager
|
||||
from biopro.text import *
|
||||
|
||||
from biopro.db.base import Session
|
||||
from biopro.db.collection import Collection
|
||||
|
||||
key_list = {
|
||||
'deviceList': 'device',
|
||||
}
|
||||
@@ -46,10 +50,28 @@ class Project(threading.Thread):
|
||||
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)
|
||||
|
||||
default_name = 'admin'
|
||||
default_parent = {"folder": [1]}
|
||||
collection = Collection.find_collection(default_name, default_parent)
|
||||
parent = {"folder": [collection.id]}
|
||||
# create project folder
|
||||
collection = Collection.create_collection(self.name, parent)
|
||||
self.setup_collection(collection)
|
||||
|
||||
def setup_project(self, project):
|
||||
for (key, value) in project.items():
|
||||
if key in key_list.keys():
|
||||
@@ -66,7 +88,11 @@ class Project(threading.Thread):
|
||||
for device in device_list:
|
||||
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
|
||||
|
||||
def setup_collection(self, collection):
|
||||
self._task_manager.create_collection(collection)
|
||||
|
||||
@property
|
||||
def id(self) -> int:
|
||||
@@ -136,9 +162,23 @@ class Project(threading.Thread):
|
||||
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])
|
||||
|
||||
@@ -161,12 +201,17 @@ class Project(threading.Thread):
|
||||
|
||||
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:
|
||||
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"]} -----------')
|
||||
|
||||
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':
|
||||
@@ -175,6 +220,7 @@ class Project(threading.Thread):
|
||||
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])
|
||||
@@ -184,12 +230,15 @@ class Project(threading.Thread):
|
||||
|
||||
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)
|
||||
@@ -223,27 +272,29 @@ class Project(threading.Thread):
|
||||
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 len(task.parameter_set) > 0:
|
||||
if action.type == 'start':
|
||||
self._count += 1
|
||||
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._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)
|
||||
@@ -253,14 +304,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
|
||||
@@ -319,6 +375,18 @@ class Project(threading.Thread):
|
||||
'device': self._device,
|
||||
'task': self.task_list,
|
||||
'running_task': running_task,
|
||||
'cycle': self._cycle
|
||||
'cycle': self._cycle,
|
||||
'count': self._count,
|
||||
}
|
||||
return data
|
||||
|
||||
def info_pass_data_server(self):
|
||||
if self._task_manager.running_task is not None:
|
||||
running_task = self._task_manager.running_task.as_json()
|
||||
data = {
|
||||
'project': self._uuid,
|
||||
'task': running_task,
|
||||
'cycle': self._cycle,
|
||||
'serial_number': self._count,
|
||||
}
|
||||
return data
|
||||
|
||||
@@ -5,6 +5,7 @@ from xml.dom.expatbuilder import parseString
|
||||
import paho.mqtt.client as mqtt
|
||||
from biopro.text import *
|
||||
from .task import Task
|
||||
from biopro.db.collection import Collection
|
||||
|
||||
_RUNTIME_COMPILE = False
|
||||
|
||||
@@ -56,12 +57,24 @@ class TaskManager():
|
||||
|
||||
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
|
||||
|
||||
def check_task_in_cycle(self, task_index):
|
||||
for index, cycle in enumerate(self._cycle_list):
|
||||
if self.get_index_by_uuid(cycle['range'][0]) <= task_index:
|
||||
if self.get_index_by_uuid(cycle['range'][1]) >= task_index:
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def check_list(self):
|
||||
return [self._running_task, *self._next_task]
|
||||
@@ -121,6 +134,7 @@ class TaskManager():
|
||||
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)
|
||||
@@ -135,18 +149,33 @@ class TaskManager():
|
||||
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
|
||||
# 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
|
||||
# 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)
|
||||
|
||||
def get_task(self, task_id):
|
||||
return self._task_list[task_id]
|
||||
|
||||
|
||||
def create_collection(self, parent):
|
||||
for index, task in enumerate(self._task_list):
|
||||
if self.check_task_in_cycle(index) == True:
|
||||
if task.type == '':
|
||||
collection = Collection.create_collection(task.name, {"folder": [parent.id]})
|
||||
task.parent = {"folder": [collection.id]}
|
||||
else:
|
||||
task.parent = {"folder": [parent.id]}
|
||||
@@ -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]:
|
||||
|
||||
@@ -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
|
||||
@@ -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 = project_info
|
||||
|
||||
# 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)
|
||||
|
||||
|
||||
@@ -222,7 +222,8 @@ class DataBaseProcess(Process):
|
||||
|
||||
try:
|
||||
sql_cursor.execute(sql_str, sql_set)
|
||||
except:
|
||||
except BaseException as e:
|
||||
print('meta create error', e)
|
||||
self._psql_conn.commit()
|
||||
sql_cursor.close()
|
||||
self._queue_error.put(device_id)
|
||||
@@ -249,7 +250,8 @@ class DataBaseProcess(Process):
|
||||
|
||||
try:
|
||||
sql_cursor.execute(sql_str, sql_set)
|
||||
except:
|
||||
except BaseException as e:
|
||||
print('meta update error', e)
|
||||
self._psql_conn.commit()
|
||||
sql_cursor.close()
|
||||
self._queue_error.put(device_id)
|
||||
@@ -550,4 +552,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()
|
||||
|
||||
@@ -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,11 @@ 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
|
||||
from biopro.db.device import Device
|
||||
|
||||
|
||||
_RUNTIME_COMPILE = False
|
||||
|
||||
@@ -117,8 +121,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 +133,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:
|
||||
@@ -820,16 +828,19 @@ class ControlServer(SocketServer, ControlServerAPI):
|
||||
|
||||
@logging_info
|
||||
def device_battery(self, device:int) -> List[int]:
|
||||
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
|
||||
}
|
||||
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
|
||||
@@ -852,20 +863,32 @@ class ControlServer(SocketServer, ControlServerAPI):
|
||||
@logging_info
|
||||
def device_update_calibration(self, device: int) -> Union[bool, str]:
|
||||
connect_device = self.device_manager.get_device(device)
|
||||
mac_address = connect_device.mac_address
|
||||
|
||||
if connect_device == None:
|
||||
return
|
||||
mac_address = address_str(connect_device.mac_address)
|
||||
device = Device.get_device({"mac_address": mac_address})
|
||||
try:
|
||||
if connect_device.library.name.startswith('Neulive3.'):
|
||||
connect_device.calibration_info('NeuliveThreeOne')
|
||||
elif connect_device.library.name.startswith('Neulive'):
|
||||
connect_device.calibration_info('TDC4VC')
|
||||
elif connect_device.library.name.startswith('EliteEIS'):
|
||||
connect_device.calibration_info('EISZeroOne')
|
||||
|
||||
if connect_device.library.name.startswith('Elite_EIS_1.1'):
|
||||
# update calibration version
|
||||
connect_device._device.update_cali_version()
|
||||
# check if is first time or calibration version is different
|
||||
if connect_device._device._cali_version == -1 or (device.calibration_version != connect_device._device._cali_version):
|
||||
# get calibration info from device
|
||||
connect_device.calibration_info('EISZeroOne')
|
||||
# update_calibration_info
|
||||
Device.update_device(
|
||||
{ "mac_address": mac_address },
|
||||
{
|
||||
'calibration': connect_device.calibration ,
|
||||
'calibration_version': connect_device._device._cali_version
|
||||
}
|
||||
)
|
||||
else:
|
||||
connect_device._device._coeff = device.calibration
|
||||
except BaseException as e:
|
||||
# reset device info in db
|
||||
DeviceAPI.updateByMac(
|
||||
address_str(mac_address),
|
||||
mac_address,
|
||||
{
|
||||
'connect_id': -1,
|
||||
'connect_status': 'idle',
|
||||
@@ -877,14 +900,6 @@ class ControlServer(SocketServer, ControlServerAPI):
|
||||
print(e)
|
||||
return False
|
||||
else:
|
||||
# update_calibration_info
|
||||
DeviceAPI.updateByMac(
|
||||
address_str(mac_address),
|
||||
{
|
||||
'calibration': str(connect_device.calibration)
|
||||
}
|
||||
)
|
||||
# DeviceAPI.updateByAttrs('connect_status', 'update', {"connect_status": 'connect'})
|
||||
return True
|
||||
|
||||
@logging_info
|
||||
@@ -1021,8 +1036,17 @@ class ControlServer(SocketServer, ControlServerAPI):
|
||||
@logging_info
|
||||
def run_project(self, project) -> bool:
|
||||
if project is not None:
|
||||
# print(project)
|
||||
project = self._project_manager.create(project)
|
||||
with self._session as session:
|
||||
project_report = ProjectReport(
|
||||
name = project.name,
|
||||
uuid = project.uuid,
|
||||
cycle = project.cycle,
|
||||
task = project.task_list,
|
||||
device = project.device
|
||||
)
|
||||
session.add(project_report)
|
||||
session.commit()
|
||||
self._project_manager.run_project(project)
|
||||
return project.as_json()
|
||||
|
||||
@@ -1064,6 +1088,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
|
||||
@@ -1078,6 +1106,8 @@ class ControlServer(SocketServer, ControlServerAPI):
|
||||
self.log_verbose('update data format', value)
|
||||
|
||||
client = self.data_server.client()
|
||||
project = None
|
||||
project_meta_id = None
|
||||
if client is not None:
|
||||
info = self.file_manager.use(device)
|
||||
|
||||
@@ -1088,9 +1118,13 @@ 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 = self.project_manager.get(device.occupied_by_project).info_pass_data_server()
|
||||
project_meta_id = MetaProjectInfo.create_project_meta(project)
|
||||
|
||||
with client:
|
||||
client.update_device_configuration(device, info.meta_file, value)
|
||||
client.update_device_configuration(device, info.meta_file, value, project_meta_id)
|
||||
|
||||
def _device_set_disable_cache(self, device: CompletedDevice, disable):
|
||||
if disable:
|
||||
@@ -1124,7 +1158,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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
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,
|
||||
@@ -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",
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"domain": {
|
||||
@@ -617,7 +618,8 @@
|
||||
"Open Circuit Potential",
|
||||
"Pulse Sensing",
|
||||
"Differential Pulse Voltammetry (DPV)",
|
||||
"Chronopotentiometry"
|
||||
"Chronopotentiometry",
|
||||
"Idle"
|
||||
]
|
||||
},
|
||||
"VOLT_ORIGIN": {
|
||||
@@ -818,7 +820,7 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"VOLT_VSCAN": {
|
||||
"CA_VOLT": {
|
||||
"description": "Voltage of VScan",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
@@ -949,6 +951,7 @@
|
||||
"10": "cali_dac_test",
|
||||
"11": "cali_adc_test",
|
||||
"12": "",
|
||||
"17": "idle",
|
||||
"*": "start_data"
|
||||
}
|
||||
}
|
||||
@@ -976,6 +979,9 @@
|
||||
"VIS_STI",
|
||||
"_cdr('1X;4X>ADC_VALUE_I')"
|
||||
],
|
||||
"idle": [
|
||||
"_idle()"
|
||||
],
|
||||
"start_data": [
|
||||
"data_format",
|
||||
"_notify(True)",
|
||||
@@ -1023,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",
|
||||
@@ -1360,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,
|
||||
@@ -33,6 +33,7 @@
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"domain": {
|
||||
@@ -617,7 +618,8 @@
|
||||
"Open Circuit Potential",
|
||||
"Pulse Sensing",
|
||||
"Differential Pulse Voltammetry (DPV)",
|
||||
"Chronopotentiometry"
|
||||
"Chronopotentiometry",
|
||||
"Idle"
|
||||
]
|
||||
},
|
||||
"VOLT_ORIGIN": {
|
||||
@@ -818,7 +820,7 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"VOLT_VSCAN": {
|
||||
"CA_VOLT": {
|
||||
"description": "Voltage of VScan",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
@@ -949,6 +951,7 @@
|
||||
"10": "cali_dac_test",
|
||||
"11": "cali_adc_test",
|
||||
"12": "",
|
||||
"17": "idle",
|
||||
"*": "start_data"
|
||||
}
|
||||
}
|
||||
@@ -976,6 +979,9 @@
|
||||
"VIS_STI",
|
||||
"_cdr('1X;4X>ADC_VALUE_I')"
|
||||
],
|
||||
"idle": [
|
||||
"_idle()"
|
||||
],
|
||||
"start_data": [
|
||||
"data_format",
|
||||
"_notify(True)",
|
||||
@@ -1023,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",
|
||||
@@ -1360,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",
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"domain": {
|
||||
@@ -617,7 +618,8 @@
|
||||
"Open Circuit Potential",
|
||||
"Pulse Sensing",
|
||||
"Differential Pulse Voltammetry (DPV)",
|
||||
"Chronopotentiometry"
|
||||
"Chronopotentiometry",
|
||||
"Idle"
|
||||
]
|
||||
},
|
||||
"VOLT_ORIGIN": {
|
||||
@@ -818,7 +820,7 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"VOLT_VSCAN": {
|
||||
"CA_VOLT": {
|
||||
"description": "Voltage of VScan",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
@@ -949,6 +951,7 @@
|
||||
"10": "cali_dac_test",
|
||||
"11": "cali_adc_test",
|
||||
"12": "",
|
||||
"17": "idle",
|
||||
"*": "start_data"
|
||||
}
|
||||
}
|
||||
@@ -976,6 +979,9 @@
|
||||
"VIS_STI",
|
||||
"_cdr('1X;4X>ADC_VALUE_I')"
|
||||
],
|
||||
"idle": [
|
||||
"_idle()"
|
||||
],
|
||||
"start_data": [
|
||||
"data_format",
|
||||
"_notify(True)",
|
||||
@@ -1023,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",
|
||||
@@ -1360,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",
|
||||
|
||||
@@ -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,
|
||||
@@ -63,11 +96,64 @@
|
||||
"EIS CURVE",
|
||||
"Cyclic Voltammetry",
|
||||
"Chronoamperometric",
|
||||
"Dev Mode"
|
||||
"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": 8,
|
||||
"value": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8
|
||||
],
|
||||
"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": [
|
||||
13333333,
|
||||
@@ -80,29 +166,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,
|
||||
@@ -113,19 +194,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": [
|
||||
@@ -135,15 +216,35 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"AC_AMP": {
|
||||
"description": "AC Amplitude in mV",
|
||||
"CF_AC_AMP": {
|
||||
"description": "AC Amplitude",
|
||||
"record_meta": true,
|
||||
"initial": 25,
|
||||
"initial": 26,
|
||||
"domain": [
|
||||
2048
|
||||
],
|
||||
"on_change": "set_para_CF_AC_AMP"
|
||||
},
|
||||
"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
|
||||
]
|
||||
},
|
||||
"SCALE": {
|
||||
"CF_SCALE": {
|
||||
"description": "Point spacing pattern",
|
||||
"record_meta": true,
|
||||
"initial": 0,
|
||||
@@ -152,77 +253,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,
|
||||
@@ -233,8 +286,8 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"VOLT_MAX": {
|
||||
"description": "Max Voltage of Scan",
|
||||
"CV_E1": {
|
||||
"description": "First voltage of Scan",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
"domain": [
|
||||
@@ -244,8 +297,8 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"VOLT_MIN": {
|
||||
"description": "Min Voltage of Scan",
|
||||
"CV_E2": {
|
||||
"description": "Second voltage of Scan",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
"domain": [
|
||||
@@ -255,27 +308,55 @@
|
||||
"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"
|
||||
},
|
||||
"on_change": "set_ca_volt"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"VOLT_VSCAN": {
|
||||
"description": "Voltage of VScan",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
"domain": [
|
||||
"VOLT_MAX"
|
||||
],
|
||||
"value": {
|
||||
"expression": "VALUE"
|
||||
}
|
||||
"ADC_VALUE_I": {
|
||||
"description": "ADC value current value",
|
||||
"domain": "int"
|
||||
},
|
||||
"BLE_WRITE": {
|
||||
"description": "send msg to elite",
|
||||
@@ -297,25 +378,26 @@
|
||||
{
|
||||
"expression": "MODE",
|
||||
"when": {
|
||||
"7": "idle",
|
||||
"*": "start_data"
|
||||
}
|
||||
}
|
||||
],
|
||||
"idle": [
|
||||
"_idle()"
|
||||
],
|
||||
"start_data": [
|
||||
"data_format_cali",
|
||||
"_notify(True)",
|
||||
{
|
||||
"expression": "MODE",
|
||||
"when": {
|
||||
"1": "set_adc_gain_I",
|
||||
"2": "set_adc_gain_I"
|
||||
}
|
||||
},
|
||||
{
|
||||
"expression": "MODE",
|
||||
"when": {
|
||||
"1": "set_adc_gain_Vin",
|
||||
"2": "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"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -323,14 +405,25 @@
|
||||
"when": {
|
||||
"0": "curve_eis",
|
||||
"1": "curve_cv3",
|
||||
"2": "curve_const_vscan"
|
||||
"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)",
|
||||
@@ -350,6 +443,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": {
|
||||
@@ -359,103 +464,184 @@
|
||||
"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_const_vscan": {
|
||||
"curve_ca": {
|
||||
"type": "RIS",
|
||||
"parameter": {
|
||||
"va": "VOLT_VSCAN",
|
||||
"pa": "ADC_LEVEL_I_15",
|
||||
"pb": "ADC_LEVEL_V_IN_15",
|
||||
"va": "CA_VOLT",
|
||||
"pa": "GENERAL_LP_RTIA",
|
||||
"pd": "CTRL_HIGH_Z_15",
|
||||
"pe": "SAMPLE_RATE"
|
||||
},
|
||||
"data": [
|
||||
"1XD3;",
|
||||
"1X0B;",
|
||||
"2B>va;",
|
||||
"4b>pa;4b>pb;",
|
||||
"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"
|
||||
]
|
||||
},
|
||||
"set_para_CF_AC_AMP": {
|
||||
"type": "RIS",
|
||||
"data": [
|
||||
"XE2;X02;2B>CF_AC_AMP"
|
||||
]
|
||||
},
|
||||
"set_ca_volt": {
|
||||
"type": "RIS",
|
||||
"data": [
|
||||
"XFF;X74;2B>CA_VOLT"
|
||||
]
|
||||
},
|
||||
"ble_instru_send": [
|
||||
"ble_write",
|
||||
"_cdr('20X>ADC_VALUE_I')"
|
||||
|
||||
@@ -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,
|
||||
@@ -65,11 +98,62 @@
|
||||
"Chronoamperometric",
|
||||
"V-T Graph",
|
||||
"R-T Graph",
|
||||
"Dev Mode"
|
||||
"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": 8,
|
||||
"value": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8
|
||||
],
|
||||
"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": [
|
||||
13333333,
|
||||
@@ -82,29 +166,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,
|
||||
@@ -115,19 +194,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": [
|
||||
@@ -137,15 +216,35 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"AC_AMP": {
|
||||
"description": "AC Amplitude in mV",
|
||||
"CF_AC_AMP": {
|
||||
"description": "AC Amplitude",
|
||||
"record_meta": true,
|
||||
"initial": 25,
|
||||
"initial": 26,
|
||||
"domain": [
|
||||
2048
|
||||
],
|
||||
"on_change": "set_para_CF_AC_AMP"
|
||||
},
|
||||
"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
|
||||
]
|
||||
},
|
||||
"SCALE": {
|
||||
"CF_SCALE": {
|
||||
"description": "Point spacing pattern",
|
||||
"record_meta": true,
|
||||
"initial": 0,
|
||||
@@ -154,77 +253,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,
|
||||
@@ -235,8 +286,8 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"VOLT_MAX": {
|
||||
"description": "Max Voltage of Scan",
|
||||
"CV_E1": {
|
||||
"description": "First voltage of Scan",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
"domain": [
|
||||
@@ -246,8 +297,8 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"VOLT_MIN": {
|
||||
"description": "Min Voltage of Scan",
|
||||
"CV_E2": {
|
||||
"description": "Second voltage of Scan",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
"domain": [
|
||||
@@ -257,19 +308,19 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"CYCLE_NUMBER": {
|
||||
"description": "CV cycle number",
|
||||
"CV_SCAN_RATE": {
|
||||
"description": "Voltage scan rate",
|
||||
"record_meta": true,
|
||||
"initial": 1,
|
||||
"initial": 10000,
|
||||
"domain": [
|
||||
65536
|
||||
100001
|
||||
],
|
||||
"value": {
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"VOLT_VSCAN": {
|
||||
"description": "Voltage of VScan",
|
||||
"CA_VOLT": {
|
||||
"description": "Voltage of ca",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
"domain": [
|
||||
@@ -277,9 +328,10 @@
|
||||
],
|
||||
"value": {
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"on_change": "set_ca_volt"
|
||||
},
|
||||
"MEASURE_VIN_RANGE": {
|
||||
"VT_MEASURE_VIN_RANGE": {
|
||||
"description": "measure range of Vin",
|
||||
"record_meta": true,
|
||||
"initial": 0,
|
||||
@@ -290,7 +342,7 @@
|
||||
"auto"
|
||||
]
|
||||
},
|
||||
"DAC_VOLT": {
|
||||
"RT_VOLT_SET": {
|
||||
"description": "DAC output Voltage",
|
||||
"record_meta": true,
|
||||
"initial": 37500,
|
||||
@@ -299,7 +351,12 @@
|
||||
],
|
||||
"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",
|
||||
@@ -321,29 +378,26 @@
|
||||
{
|
||||
"expression": "MODE",
|
||||
"when": {
|
||||
"7": "idle",
|
||||
"*": "start_data"
|
||||
}
|
||||
}
|
||||
],
|
||||
"idle": [
|
||||
"_idle()"
|
||||
],
|
||||
"start_data": [
|
||||
"data_format_cali",
|
||||
"_notify(True)",
|
||||
{
|
||||
"expression": "MODE",
|
||||
"when": {
|
||||
"1": "set_adc_gain_I",
|
||||
"2": "set_adc_gain_I",
|
||||
"3": "set_adc_gain_I",
|
||||
"4": "set_adc_gain_I"
|
||||
}
|
||||
},
|
||||
{
|
||||
"expression": "MODE",
|
||||
"when": {
|
||||
"1": "set_adc_gain_Vin",
|
||||
"2": "set_adc_gain_Vin",
|
||||
"3": "set_adc_gain_Vin",
|
||||
"4": "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"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -351,16 +405,25 @@
|
||||
"when": {
|
||||
"0": "curve_eis",
|
||||
"1": "curve_cv3",
|
||||
"2": "curve_const_vscan",
|
||||
"2": "curve_ca",
|
||||
"3": "curve_vt",
|
||||
"4": "curve_zt"
|
||||
"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)",
|
||||
@@ -380,6 +443,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": {
|
||||
@@ -389,116 +464,146 @@
|
||||
"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_const_vscan": {
|
||||
"curve_ca": {
|
||||
"type": "RIS",
|
||||
"parameter": {
|
||||
"va": "VOLT_VSCAN",
|
||||
"pa": "ADC_LEVEL_I_15",
|
||||
"pb": "ADC_LEVEL_V_IN_15",
|
||||
"va": "CA_VOLT",
|
||||
"pa": "GENERAL_LP_RTIA",
|
||||
"pd": "CTRL_HIGH_Z_15",
|
||||
"pe": "SAMPLE_RATE"
|
||||
},
|
||||
"data": [
|
||||
"1XD3;",
|
||||
"1X0B;",
|
||||
"2B>va;",
|
||||
"4b>pa;4b>pb;",
|
||||
"4b>pa;4b>0;",
|
||||
"4b>0;4b>pd;",
|
||||
"2B>pe"
|
||||
]
|
||||
},
|
||||
"curve_zt": {
|
||||
"curve_rt": {
|
||||
"type": "RIS",
|
||||
"parameter": {
|
||||
"va": "DAC_VOLT",
|
||||
"pa": "ADC_LEVEL_I_15",
|
||||
"pb": "ADC_LEVEL_V_IN_15",
|
||||
"va": "RT_VOLT_SET",
|
||||
"pa": "GENERAL_LP_RTIA",
|
||||
"pd": "CTRL_HIGH_Z_15",
|
||||
"pe": "SAMPLE_RATE"
|
||||
},
|
||||
"data": [
|
||||
"X04;",
|
||||
"2B>va;",
|
||||
"4b>pa;4b>pb;",
|
||||
"4b>pa;4b>0;",
|
||||
"4b>0;4b>pd;",
|
||||
"2B>pe"
|
||||
]
|
||||
@@ -506,20 +611,37 @@
|
||||
"curve_vt": {
|
||||
"type": "RIS",
|
||||
"parameter": {
|
||||
"pa": "ADC_LEVEL_I_15",
|
||||
"pb": "ADC_LEVEL_V_IN_15",
|
||||
"pa": "GENERAL_LP_RTIA",
|
||||
"pd": "CTRL_HIGH_Z_15",
|
||||
"pe": "SAMPLE_RATE",
|
||||
"va": "MEASURE_VIN_RANGE"
|
||||
"va": "VT_MEASURE_VIN_RANGE"
|
||||
},
|
||||
"data": [
|
||||
"X05;",
|
||||
"4b>pa;4b>pb;",
|
||||
"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"
|
||||
]
|
||||
},
|
||||
"set_para_CF_AC_AMP": {
|
||||
"type": "RIS",
|
||||
"data": [
|
||||
"XE2;X02;2B>CF_AC_AMP"
|
||||
]
|
||||
},
|
||||
"set_ca_volt": {
|
||||
"type": "RIS",
|
||||
"data": [
|
||||
"XFF;X74;2B>CA_VOLT"
|
||||
]
|
||||
},
|
||||
"ble_instru_send": [
|
||||
"ble_write",
|
||||
"_cdr('20X>ADC_VALUE_I')"
|
||||
|
||||
@@ -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,
|
||||
@@ -64,11 +97,63 @@
|
||||
"Cyclic Voltammetry",
|
||||
"Chronoamperometric",
|
||||
"V-T Graph",
|
||||
"Dev Mode"
|
||||
"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": 8,
|
||||
"value": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8
|
||||
],
|
||||
"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": [
|
||||
13333333,
|
||||
@@ -81,29 +166,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,
|
||||
@@ -114,19 +194,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": [
|
||||
@@ -136,15 +216,35 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"AC_AMP": {
|
||||
"description": "AC Amplitude in mV",
|
||||
"CF_AC_AMP": {
|
||||
"description": "AC Amplitude",
|
||||
"record_meta": true,
|
||||
"initial": 25,
|
||||
"initial": 26,
|
||||
"domain": [
|
||||
2048
|
||||
],
|
||||
"on_change": "set_para_CF_AC_AMP"
|
||||
},
|
||||
"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
|
||||
]
|
||||
},
|
||||
"SCALE": {
|
||||
"CF_SCALE": {
|
||||
"description": "Point spacing pattern",
|
||||
"record_meta": true,
|
||||
"initial": 0,
|
||||
@@ -153,77 +253,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,
|
||||
@@ -234,8 +286,8 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"VOLT_MAX": {
|
||||
"description": "Max Voltage of Scan",
|
||||
"CV_E1": {
|
||||
"description": "First voltage of Scan",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
"domain": [
|
||||
@@ -245,8 +297,8 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"VOLT_MIN": {
|
||||
"description": "Min Voltage of Scan",
|
||||
"CV_E2": {
|
||||
"description": "Second voltage of Scan",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
"domain": [
|
||||
@@ -256,19 +308,19 @@
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"CYCLE_NUMBER": {
|
||||
"description": "CV cycle number",
|
||||
"CV_SCAN_RATE": {
|
||||
"description": "Voltage scan rate",
|
||||
"record_meta": true,
|
||||
"initial": 1,
|
||||
"initial": 10000,
|
||||
"domain": [
|
||||
65536
|
||||
100001
|
||||
],
|
||||
"value": {
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"VOLT_VSCAN": {
|
||||
"description": "Voltage of VScan",
|
||||
"CA_VOLT": {
|
||||
"description": "Voltage of ca",
|
||||
"record_meta": true,
|
||||
"initial": 25000,
|
||||
"domain": [
|
||||
@@ -276,9 +328,10 @@
|
||||
],
|
||||
"value": {
|
||||
"expression": "VALUE"
|
||||
}
|
||||
},
|
||||
"on_change": "set_ca_volt"
|
||||
},
|
||||
"MEASURE_VIN_RANGE": {
|
||||
"VT_MEASURE_VIN_RANGE": {
|
||||
"description": "measure range of Vin",
|
||||
"record_meta": true,
|
||||
"initial": 0,
|
||||
@@ -289,6 +342,22 @@
|
||||
"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",
|
||||
"domain": {
|
||||
@@ -309,27 +378,26 @@
|
||||
{
|
||||
"expression": "MODE",
|
||||
"when": {
|
||||
"7": "idle",
|
||||
"*": "start_data"
|
||||
}
|
||||
}
|
||||
],
|
||||
"idle": [
|
||||
"_idle()"
|
||||
],
|
||||
"start_data": [
|
||||
"data_format_cali",
|
||||
"_notify(True)",
|
||||
{
|
||||
"expression": "MODE",
|
||||
"when": {
|
||||
"1": "set_adc_gain_I",
|
||||
"2": "set_adc_gain_I",
|
||||
"3": "set_adc_gain_I"
|
||||
}
|
||||
},
|
||||
{
|
||||
"expression": "MODE",
|
||||
"when": {
|
||||
"1": "set_adc_gain_Vin",
|
||||
"2": "set_adc_gain_Vin",
|
||||
"3": "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"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -337,15 +405,25 @@
|
||||
"when": {
|
||||
"0": "curve_eis",
|
||||
"1": "curve_cv3",
|
||||
"2": "curve_const_vscan",
|
||||
"3": "curve_vt"
|
||||
"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)",
|
||||
@@ -365,6 +443,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": {
|
||||
@@ -374,99 +464,146 @@
|
||||
"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_const_vscan": {
|
||||
"curve_ca": {
|
||||
"type": "RIS",
|
||||
"parameter": {
|
||||
"va": "VOLT_VSCAN",
|
||||
"pa": "ADC_LEVEL_I_15",
|
||||
"pb": "ADC_LEVEL_V_IN_15",
|
||||
"va": "CA_VOLT",
|
||||
"pa": "GENERAL_LP_RTIA",
|
||||
"pd": "CTRL_HIGH_Z_15",
|
||||
"pe": "SAMPLE_RATE"
|
||||
},
|
||||
"data": [
|
||||
"1XD3;",
|
||||
"1X0B;",
|
||||
"2B>va;",
|
||||
"4b>pa;4b>pb;",
|
||||
"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"
|
||||
]
|
||||
@@ -474,20 +611,37 @@
|
||||
"curve_vt": {
|
||||
"type": "RIS",
|
||||
"parameter": {
|
||||
"pa": "ADC_LEVEL_I_15",
|
||||
"pb": "ADC_LEVEL_V_IN_15",
|
||||
"pa": "GENERAL_LP_RTIA",
|
||||
"pd": "CTRL_HIGH_Z_15",
|
||||
"pe": "SAMPLE_RATE",
|
||||
"va": "MEASURE_VIN_RANGE"
|
||||
"va": "VT_MEASURE_VIN_RANGE"
|
||||
},
|
||||
"data": [
|
||||
"X05;",
|
||||
"4b>pa;4b>pb;",
|
||||
"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"
|
||||
]
|
||||
},
|
||||
"set_para_CF_AC_AMP": {
|
||||
"type": "RIS",
|
||||
"data": [
|
||||
"XE2;X02;2B>CF_AC_AMP"
|
||||
]
|
||||
},
|
||||
"set_ca_volt": {
|
||||
"type": "RIS",
|
||||
"data": [
|
||||
"XFF;X74;2B>CA_VOLT"
|
||||
]
|
||||
},
|
||||
"ble_instru_send": [
|
||||
"ble_write",
|
||||
"_cdr('20X>ADC_VALUE_I')"
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#!/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
|
||||
|
||||
# drop column calibration default
|
||||
sudo su -c "psql -d postgres -c \"ALTER TABLE devices ALTER COLUMN calibration DROP DEFAULT;\"" postgres
|
||||
|
||||
# drop column calibration default
|
||||
sudo su -c "psql -d postgres -c \"ALTER TABLE devices ALTER COLUMN calibration TYPE bytea USING calibration::bytea;\"" postgres
|
||||
|
||||
# add column project in recording_data_metas
|
||||
sudo su -c "psql -d postgres -c \"ALTER TABLE devices ADD COLUMN IF NOT EXISTS calibration_version Int4 DEFAULT -1;\"" postgres
|
||||
Reference in New Issue
Block a user