Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 034b7976cd | |||
| f233c019fd | |||
| 13825fe9ff | |||
| dd2e31d01f | |||
| 455fa1f86b | |||
| 71850b31a8 | |||
| 8d52fef4c1 | |||
| e091f220fa | |||
| 6049154fae | |||
| 3502472021 | |||
| 5e48c8ae0a | |||
| cb2a4c9d56 | |||
| b253aca73f |
@@ -4,7 +4,7 @@ New goal on pi4 without kotlin and django, and with only one dataserver.
|
||||
# Installation
|
||||
### Get Raspbrain into SD card
|
||||
|
||||
###### Download Raspbian Buster Lite
|
||||
###### Download Raspbian Bullseye Lite
|
||||
|
||||
>https://www.raspberrypi.org/downloads/raspberry-pi-os/
|
||||
|
||||
@@ -14,7 +14,7 @@ New goal on pi4 without kotlin and django, and with only one dataserver.
|
||||
lsblk
|
||||
|
||||
# copy data to sd card
|
||||
sudo dd bs=4M if=yyyy-mm-dd-raspbian-buster.img of=/dev/sdX conv=fsync status=progress
|
||||
sudo dd bs=4M if=yyyy-mm-dd-raspios-bullseye-armhf-lite.img of=/dev/sdX conv=fsync status=progress
|
||||
|
||||
# enable ssh on first boot
|
||||
add ssh.txt in boot folder
|
||||
@@ -77,18 +77,22 @@ 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
|
||||
sudo apt-get install vim git wiringpi build-essential libi2c-dev i2c-tools python-dev libffi-dev python3-pip postgresql npm
|
||||
|
||||
###### wiringpi conflict
|
||||
need to install wiringpi: https://github.com/WiringPi/WiringPi
|
||||
install instructions: https://github.com/WiringPi/WiringPi/blob/master/INSTALL
|
||||
|
||||
### Setup project
|
||||
###### Clone project
|
||||
###### Clone data server project
|
||||
```
|
||||
cd ~
|
||||
git clone https://gitlab.com/bioproscientific/bioprorelife.git
|
||||
git clone https://gitlab.com/wisetop/controller/wisetopdataserver.git
|
||||
```
|
||||
|
||||
###### Install python dependencies
|
||||
```
|
||||
cd ~/bioprorelife
|
||||
cd ~/wisetopdataserver
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
##### Packages version
|
||||
@@ -112,14 +116,14 @@ psycopg2 2.8.5
|
||||
|
||||
###### Build C extension
|
||||
```
|
||||
cd ~/bioprorelife/python/biopro/ext/
|
||||
cd ~/wisetopdataserver/python/biopro/ext/
|
||||
rm -rf *.so build
|
||||
python3 setup.py build_ext --inplace
|
||||
```
|
||||
|
||||
###### Check setup-uart file
|
||||
```
|
||||
cd ~/bioprorelife
|
||||
cd ~/wisetopdataserver/
|
||||
sudo vim ./run-setup-uart.sh
|
||||
```
|
||||
##### Modify the code as following
|
||||
@@ -149,44 +153,72 @@ sudo raspi-config
|
||||
reboot
|
||||
```
|
||||
|
||||
###### Set pi password
|
||||
```
|
||||
$cd ~
|
||||
$passwd
|
||||
Current password:raspberry
|
||||
New password:5k6zj454778225
|
||||
Retype new password:5k6zj454778225
|
||||
```
|
||||
|
||||
###### Auto run program when device start
|
||||
```
|
||||
sudo vim /etc/rc.local
|
||||
```
|
||||
add the code following as:
|
||||
###### add the code following as:
|
||||
```
|
||||
sudo -H -u pi nohup /home/pi/bioprorelife/run-data-server.sh > /home/pi/.data_server.out &
|
||||
sudo -H -u pi nohup /home/pi/wisetopdataserver/run-data-server.sh > /home/pi/.data_server.out &
|
||||
#sudo -H -u pi nohup /home/pi/wisetopdataserver/run-data-server.sh > /home/pi/.wisetop_data_$now.out &
|
||||
```
|
||||
##### /etc/rc.local
|
||||
```
|
||||
_IP=$(hostname -I) || true
|
||||
if [ "$_IP" ]; then
|
||||
printf "My IP address is %s\n" "$_IP"
|
||||
fi
|
||||
|
||||
now=$(date +'%F_%T')
|
||||
|
||||
sudo nohup systemctl restart apache2
|
||||
sudo nohup systemctl restart mosquitto
|
||||
|
||||
nohup node /home/pi/wisetopapiserver/dist/app.js > /home/pi/.api_server.out &
|
||||
|
||||
sleep 5
|
||||
|
||||
sudo -H -u pi nohup /home/pi/wisetopdataserver/run-data-server.sh > /home/pi/.data_server.out &
|
||||
#sudo -H -u pi nohup /home/pi/wisetopdataserver/run-data-server.sh > /home/pi/.wisetop_data_$now.out &
|
||||
|
||||
exit 0
|
||||
```
|
||||
### MQTT broker install
|
||||
|
||||
1. Install mosquitto
|
||||
```
|
||||
sudo apt-get install mosquitto mosquitto-clients
|
||||
```
|
||||
###### 1.Install mosquitto
|
||||
$sudo apt-get install mosquitto mosquitto-clients
|
||||
|
||||
|
||||
###### 2.Enable Remote Access
|
||||
$sudo vim /etc/mosquitto/conf.d/default.conf
|
||||
|
||||
2. Enable Remote Access
|
||||
```
|
||||
sudo vim /etc/mosquitto/conf.d/default.conf
|
||||
```
|
||||
add the code following as:
|
||||
```
|
||||
listener 1883
|
||||
protocol mqtt
|
||||
listener 8083
|
||||
protocol websockets
|
||||
allow_anonymous true
|
||||
```
|
||||
restart mqtt broker
|
||||
```
|
||||
sudo systemctl restart mosquitto
|
||||
```
|
||||
###### 3.restart mqtt broker
|
||||
$sudo systemctl restart mosquitto
|
||||
|
||||
3. Robust MQTT
|
||||
###### 4.Robust MQTT
|
||||
create mosquitto_restart.sh
|
||||
```
|
||||
cd ~
|
||||
sudo vim mosquitto_restart.sh
|
||||
```
|
||||
|
||||
$cd ~
|
||||
$sudo vim mosquitto_restart.sh
|
||||
|
||||
|
||||
add the code following as:
|
||||
```
|
||||
if [ "`ps -aux | grep /usr/sbin/mosquitto | wc -l`" == "1" ]
|
||||
@@ -200,25 +232,129 @@ fi
|
||||
echo "$SERVICE is currently running" >> /home/ubuntu/cron.log
|
||||
exit 0
|
||||
```
|
||||
add mosquitto_restart.sh to root routing
|
||||
```
|
||||
sudo chmod +x mosquitto_restart.sh
|
||||
sudo -i
|
||||
crontab -e
|
||||
```
|
||||
###### 5.add mosquitto_restart.sh to root routing
|
||||
$sudo chmod +x mosquitto_restart.sh
|
||||
$sudo -i
|
||||
$crontab -e
|
||||
|
||||
add the code following as:
|
||||
```
|
||||
*/5 * * * * /home/pi/mosquitto_restart.sh
|
||||
```
|
||||
3. Auto run MQTT broker when when pi-start
|
||||
```
|
||||
sudo vim /etc/rc.local
|
||||
```
|
||||
###### 6.Auto run MQTT broker when when pi-start
|
||||
$sudo vim /etc/rc.local
|
||||
|
||||
add the code following as:
|
||||
```
|
||||
sudo nohup systemctl restart mosquitto
|
||||
```
|
||||
|
||||
### Setup routed wireless access point
|
||||
### 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
|
||||
|
||||
###### 2.Set up the Network Router
|
||||
$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
|
||||
```
|
||||
# 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 nano /etc/dnsmasq.conf
|
||||
|
||||
```
|
||||
interface=wlan0 # Listening interface
|
||||
dhcp-range=192.168.2.2,192.168.2.255,255.255.255.0,24h
|
||||
# Pool of IP addresses served via DHCP
|
||||
domain=wlan # Local wireless DNS domain
|
||||
address=/gw.wlan/192.168.2.1
|
||||
# Alias for this router
|
||||
```
|
||||
###### 3.Ensure Wireless Operation
|
||||
$sudo rfkill unblock wlan
|
||||
|
||||
###### 4.Configure the AP Software
|
||||
$sudo nano /etc/hostapd/hostapd.conf
|
||||
|
||||
```
|
||||
country_code=TW
|
||||
interface=wlan0
|
||||
ssid=WTP_NONE
|
||||
hw_mode=g
|
||||
channel=7
|
||||
macaddr_acl=0
|
||||
auth_algs=1
|
||||
ignore_broadcast_ssid=0
|
||||
wpa=2
|
||||
wpa_passphrase=00000000
|
||||
wpa_key_mgmt=WPA-PSK
|
||||
wpa_pairwise=TKIP
|
||||
rsn_pairwise=CCMP
|
||||
|
||||
# 802.11n support
|
||||
ieee80211n=1
|
||||
# make raspberry pi dongle fast
|
||||
wme_enabled=1
|
||||
# ht_capab: HT capabilities, enable 40MHz
|
||||
ht_capab=[HT40+][SHORT-GI-40]
|
||||
```
|
||||
###### 5.Running the new Wireless AP
|
||||
$sudo systemctl reboot
|
||||
|
||||
|
||||
### Set web site
|
||||
$sudo vim ./sites-available/000-default.conf
|
||||
```
|
||||
<VirtualHost *:8080> #80------>8080
|
||||
# The ServerName directive sets the request scheme, hostname and port that
|
||||
# the server uses to identify itself. This is used when creating
|
||||
# redirection URLs. In the context of virtual hosts, the ServerName
|
||||
# specifies what hostname must appear in the request's Host: header to
|
||||
# match this virtual host. For the default virtual host (this file) this
|
||||
# value is not decisive as it is used as a last resort host regardless.
|
||||
# However, you must set it for any further virtual host explicitly.
|
||||
#ServerName www.example.com
|
||||
|
||||
ServerAdmin webmaster@localhost
|
||||
DocumentRoot /var/www/html
|
||||
|
||||
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
|
||||
# error, crit, alert, emerg.
|
||||
# It is also possible to configure the loglevel for particular
|
||||
# modules, e.g.
|
||||
#LogLevel info ssl:warn
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
|
||||
# For most configuration files from conf-available/, which are
|
||||
# enabled or disabled at a global level, it is possible to
|
||||
# include a line for only one particular virtual host. For example the
|
||||
# following line enables the CGI configuration for this host only
|
||||
# after it has been globally disabled with "a2disconf".
|
||||
#Include conf-available/serve-cgi-bin.conf
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerAdmin bioprovue@localhost
|
||||
DocumentRoot /var/www/bioprovuebuild
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
##### raspberry website document:
|
||||
> https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md
|
||||
|
||||
@@ -2035,6 +2035,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
# print("local_name = ", local_name)
|
||||
|
||||
# addr type is don't care in BMD380
|
||||
print('scan_response:', list(scan_response))
|
||||
local_addr_type = int(scan_response[index:index + 1][0])
|
||||
# local_addr_type = 0xFF
|
||||
index = index + 1
|
||||
|
||||
@@ -1456,12 +1456,12 @@ class EISZeroOneDataDecoder(RecDataDecoder):
|
||||
if len(data) < 18:
|
||||
return None
|
||||
|
||||
ch1 = struct.unpack('>i', data[1:5])[0] # unit: 1/1000 nA
|
||||
ch2 = struct.unpack('>i', data[5:9])[0] # unit: mV
|
||||
ch3 = struct.unpack('>i', data[9:13])[0] # unit: kOm
|
||||
time_stamp: float = struct.unpack('<I', data[13:17])[0] # unit: ms
|
||||
cycle_number = struct.unpack('>H', data[17:19])[0]
|
||||
d19 = data[19]
|
||||
ch1 = struct.unpack('>i', data[1+3:5+3])[0] # unit: 1/1000 nA
|
||||
ch2 = struct.unpack('>i', data[5+3:9+3])[0] # unit: mV
|
||||
ch3 = struct.unpack('>i', data[9+3:13+3])[0] # unit: kOm
|
||||
time_stamp: float = struct.unpack('<I', data[13+3:17+3])[0] # unit: ms
|
||||
cycle_number = struct.unpack('>H', data[17+3:19+3])[0]
|
||||
d19 = data[19+3]
|
||||
gain = (d19 & 0x0F)
|
||||
finishMode = (d19 & 0x80) >> 7
|
||||
|
||||
|
||||
@@ -287,8 +287,8 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
|
||||
print("length < 12")
|
||||
print("green data print:", data, device, datetime.now())
|
||||
|
||||
if length == 0:
|
||||
self._print_ram_all_data()
|
||||
# if length == 0:
|
||||
# self._print_ram_all_data()
|
||||
|
||||
return None
|
||||
|
||||
@@ -305,7 +305,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
|
||||
if (header != 255):
|
||||
flag_print = True
|
||||
print("green data: header is not 255: ", header)
|
||||
self._print_ram_all_data()
|
||||
# self._print_ram_all_data()
|
||||
|
||||
if (elite_data_len != self._elite_data_len):
|
||||
flag_print = True
|
||||
@@ -384,7 +384,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
|
||||
# print(check_sum, rx[i + self._single_data_len - 1])
|
||||
|
||||
if (check_sum != rx[i + self._single_data_len - 1]):
|
||||
print('check_sum wrong, origin value:', 'check_sum =', check_sum, rx[i : i + self._single_data_len])
|
||||
# print('check_sum wrong, origin value:', 'check_sum =', check_sum, rx[i : i + self._single_data_len])
|
||||
tx_d = [0] * (self._single_data_len + 3)
|
||||
address = 12 + self._single_data_len * index
|
||||
tx_d[0] = MEM_INS_READ
|
||||
|
||||
@@ -9,7 +9,6 @@ class Action():
|
||||
self._duration = action.get('duration', None)
|
||||
self._goto = action.get('goto', None)
|
||||
self._cycle = action.get('cycle', None)
|
||||
|
||||
self._instruction = None
|
||||
|
||||
self.update_instruction()
|
||||
@@ -19,12 +18,16 @@ class Action():
|
||||
return self._type
|
||||
|
||||
def update_instruction(self):
|
||||
instruction_type = self._type
|
||||
if instruction_type == 'stop':
|
||||
instruction_type = 'interrupt'
|
||||
|
||||
self._instruction = {
|
||||
"device_instruction": {
|
||||
"header": "call_instruction",
|
||||
"device": self._target,
|
||||
"arguments": {
|
||||
"instruction": self._type,
|
||||
"instruction": instruction_type,
|
||||
}
|
||||
},
|
||||
"device_parameter": {
|
||||
|
||||
@@ -3,7 +3,6 @@ from time import time
|
||||
|
||||
class Condition():
|
||||
def __init__(self, id, condition):
|
||||
print('condition', id, condition)
|
||||
self._id = id
|
||||
self._type = condition['type']
|
||||
self._comparsion = condition['comparsion']
|
||||
@@ -12,12 +11,15 @@ class Condition():
|
||||
@property
|
||||
def id(self):
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def comparsion(self):
|
||||
return self._comparsion
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
@@ -38,11 +40,11 @@ class Condition():
|
||||
"smaller": lambda a, b: a < b,
|
||||
}
|
||||
|
||||
# print('x','y',x, y,type(x),type(y))
|
||||
return cases[operator](x, y)
|
||||
|
||||
def match_or_not(self, **kwargs):
|
||||
return self.method_mapping(self.type)()
|
||||
# print(self._type, self._comparsion, self._value)
|
||||
return getattr(self, self.type)(**kwargs)
|
||||
|
||||
def absolute_time(self, **kwargs):
|
||||
now = time()
|
||||
@@ -51,7 +53,13 @@ class Condition():
|
||||
return self.compareWith(self.comparsion, int(now), int(time_condition))
|
||||
|
||||
def relative_time(self, **kwargs):
|
||||
project_start_time = kwargs['project_start_time']
|
||||
task_start_time = kwargs['task_start_time']
|
||||
delay_time = kwargs['delay_time']
|
||||
now = time()
|
||||
|
||||
time_diff = int(now - project_start_time - delay_time)
|
||||
return self.compareWith(self.comparsion, time_diff, int(self._value))
|
||||
|
||||
def device(self, **kwargs):
|
||||
print('device')
|
||||
|
||||
@@ -8,6 +8,7 @@ from datetime import datetime
|
||||
from collections import deque
|
||||
from biopro.device.manager import DeviceManager
|
||||
from biopro.text import *
|
||||
from copy import copy
|
||||
|
||||
class Project(threading.Thread):
|
||||
def __init__(self, project, device_manager: DeviceManager, mqttThread = None, name="project"):
|
||||
@@ -19,9 +20,8 @@ class Project(threading.Thread):
|
||||
self._start_time = None
|
||||
|
||||
self._task_manager = TaskManager(self._project['taskList'])
|
||||
self._stop = False
|
||||
|
||||
self._start_time = None
|
||||
|
||||
@property
|
||||
def desc(self) -> str:
|
||||
return self._project['desc']
|
||||
@@ -45,34 +45,38 @@ class Project(threading.Thread):
|
||||
def run(self):
|
||||
self._start_time = time.time()
|
||||
|
||||
while True:
|
||||
while not self._stop:
|
||||
# current task
|
||||
for task in self._task_manager.get_check_task_list():
|
||||
task_check_list = copy(self._task_manager.get_check_task_list())
|
||||
delay_time = 0
|
||||
for task in task_check_list:
|
||||
# [<match_condition>, ...]
|
||||
match_condition_list = task.check_condition('time')
|
||||
match_condition_list = task.check_condition(project_start_time = self._start_time, delay_time = delay_time)
|
||||
# [[<match_action>, ...], ...]
|
||||
match_action_list = task.get_match_action_list(match_condition_list)
|
||||
|
||||
for action_list in match_action_list:
|
||||
for action in action_list:
|
||||
if action.type == 'start':
|
||||
task.reset_start_time()
|
||||
self._task_manager.set_current_task(task)
|
||||
task.do_action(action)
|
||||
|
||||
|
||||
now = time.time()
|
||||
while len(task.instruction_list) > 0:
|
||||
instruction = task.instruction_list.pop(0)
|
||||
if instruction.get('device', None) != None:
|
||||
device = self._device_manager.get_device(self.device[instruction['device']]['connectDevice']['device_address'])
|
||||
instruction = task.instruction_list.pop(0)
|
||||
if instruction.get('device', None) != None:
|
||||
device = self._device_manager.get_device(self.device[instruction['device']]['connectDevice']['device_address'])
|
||||
|
||||
if device is None:
|
||||
raise RuntimeError(DEVICE_NOT_FOUND, device)
|
||||
|
||||
# print(instruction['header'], *instruction['arguments'].values())
|
||||
getattr(device, instruction['header'])(*instruction['arguments'].values())
|
||||
if device is None:
|
||||
raise RuntimeError(DEVICE_NOT_FOUND, device)
|
||||
|
||||
getattr(device, instruction['header'])(*instruction['arguments'].values())
|
||||
delay_time += (time.time() - now)
|
||||
time.sleep(self._time_interval)
|
||||
|
||||
def stop(self):
|
||||
return
|
||||
self._stop = True
|
||||
|
||||
def close(self):
|
||||
return
|
||||
self._stop = True
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from typing import List
|
||||
from .condition import Condition
|
||||
from .action import Action
|
||||
from time import time
|
||||
@@ -6,8 +7,8 @@ class Task:
|
||||
def __init__(self, task):
|
||||
self._task = task
|
||||
|
||||
self._condition_list = []
|
||||
self._action_list = []
|
||||
self._condition_list:List[Condition] = []
|
||||
self._action_list:List[Action] = []
|
||||
|
||||
self._start_time = time()
|
||||
self._idle_time = []
|
||||
@@ -16,7 +17,6 @@ class Task:
|
||||
self._last_time = None
|
||||
|
||||
self._instruction_list = []
|
||||
|
||||
self.setup()
|
||||
|
||||
def setup(self) -> None:
|
||||
@@ -105,6 +105,9 @@ class Task:
|
||||
@property
|
||||
def next(self) -> str:
|
||||
return self._task['next']
|
||||
|
||||
def reset_start_time(self):
|
||||
self._start_time = time()
|
||||
|
||||
def get_parameter_set_by_device(self, device):
|
||||
return [parameter_set for parameter_set in self.parameter_set.values() if device == parameter_set['target']]
|
||||
@@ -151,9 +154,6 @@ class Task:
|
||||
return map(lambda condition: [x for x in self._action_list if condition.id in x.get_condition_list()], match_condition_list)
|
||||
|
||||
def do_action(self, action):
|
||||
# # match_action = [x for x in self._action_list if condition_id in x.get_condition_list()]
|
||||
|
||||
# for action in match_action:
|
||||
for instruction in action.get_instruction_list():
|
||||
self._instruction_list.append(instruction)
|
||||
|
||||
@@ -164,5 +164,6 @@ class Task:
|
||||
}
|
||||
return statuses[status]
|
||||
|
||||
def check_condition(self, type):
|
||||
return [condition for condition in self._condition_list if condition.match_or_not()]
|
||||
def check_condition(self, **kwargs):
|
||||
kwargs['task_start_time'] = self._start_time
|
||||
return [condition for condition in self._condition_list if condition.match_or_not(**kwargs)]
|
||||
@@ -1,5 +1,5 @@
|
||||
from json import loads as json_parse, dumps as _json_stringify
|
||||
from typing import Dict, Optional, Any
|
||||
from typing import Dict, List, Optional, Any
|
||||
from xml.dom.expatbuilder import parseString
|
||||
import paho.mqtt.client as mqtt
|
||||
from biopro.text import *
|
||||
@@ -29,7 +29,7 @@ class TaskManager():
|
||||
def get_task(self, task_id):
|
||||
return self._task_list[task_id]
|
||||
|
||||
def get_check_task_list(self):
|
||||
def get_check_task_list(self) -> List[Task]:
|
||||
return self._need_to_check_task_list
|
||||
|
||||
def get_current_task(self) -> Task:
|
||||
|
||||
+103
-21
@@ -8,6 +8,7 @@ import gc
|
||||
|
||||
from biopro.util.json import JSON
|
||||
from biopro.util.stack import print_exception
|
||||
from biopro.util.logger import calculate_time
|
||||
from .data import RecordingData
|
||||
from .loader import *
|
||||
|
||||
@@ -115,8 +116,8 @@ class RecordingMetaFile(JsonSerialize):
|
||||
__slots__ = ('_filename', '_filepath', '_id_db', '_create_time', '_file_version', '_file_uuid', '_data_format', '_last_time',
|
||||
'_device', '_configuration', '_channel_mask', '_database',
|
||||
'_dirty', '_last_modify_time', '_file_size_cache',
|
||||
'_recording_file_ch', '_size',
|
||||
'_parameter', '_parent', '_recording_file_name', '_recording_mini_ch',
|
||||
'_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')
|
||||
|
||||
def __init__(self, filepath: Union[str, Path], data_format: bytes = None, id_db = 0, database = None):
|
||||
@@ -167,6 +168,10 @@ class RecordingMetaFile(JsonSerialize):
|
||||
self._raw_serial_number = {}
|
||||
self._mini_serial_number = {}
|
||||
|
||||
self._recording_sub_file = {}
|
||||
self._recording_sub_mini = {}
|
||||
|
||||
|
||||
self._size = 0
|
||||
|
||||
self._dirty = True
|
||||
@@ -304,6 +309,7 @@ class RecordingMetaFile(JsonSerialize):
|
||||
if database is not None :
|
||||
self._database = database
|
||||
self._database.put_queue(['data_meta_write', meta_data, self._device_id, str(self._file_uuid), self._id_db])
|
||||
# database.put_queue(['data_meta_write', self, meta_data, _path, self._id_db])
|
||||
|
||||
with self._filepath.open('wb') as _f:
|
||||
f = FileEncoder(_f)
|
||||
@@ -353,15 +359,58 @@ class RecordingMetaFile(JsonSerialize):
|
||||
|
||||
def update_subfile(self, database = None):
|
||||
meta_data = {
|
||||
'raw_data': self._recording_sub_file,
|
||||
'mini_data': self._recording_sub_mini,
|
||||
'channels': str(self._channel_mask.channels()),
|
||||
'size': str(self._size),
|
||||
'time_duration': str(self._last_time),
|
||||
'uuid': str(self._file_uuid),
|
||||
}
|
||||
_path = str(self._filepath).replace('/', '^')
|
||||
|
||||
if database is not None :
|
||||
self._database = database
|
||||
self._database.put_queue(['data_meta_write', meta_data, self._device_id, str(self._file_uuid), self._id_db])
|
||||
# database.put_queue(['data_meta_write', self, meta_data, _path, self._id_db])
|
||||
return None
|
||||
|
||||
def update_subfile_time_size(self, database = None):
|
||||
meta_data = {
|
||||
'channels': str(self._channel_mask.channels()),
|
||||
'size': str(self._size),
|
||||
'time_duration': str(self._last_time),
|
||||
'uuid': str(self._file_uuid),
|
||||
}
|
||||
_path = str(self._filepath).replace('/', '^')
|
||||
|
||||
if database is not None :
|
||||
self._database = database
|
||||
self._database.put_queue(['data_meta_write', meta_data, self._device_id, str(self._file_uuid), self._id_db])
|
||||
# database.put_queue(['data_meta_write', self, meta_data, _path, self._id_db])
|
||||
return None
|
||||
|
||||
def update_subfile_raw(self, database = None):
|
||||
meta_data = {
|
||||
'raw_data': self._recording_sub_file,
|
||||
}
|
||||
_path = str(self._filepath).replace('/', '^')
|
||||
|
||||
if database is not None :
|
||||
self._database = database
|
||||
self._database.put_queue(['data_meta_write', meta_data, self._device_id, str(self._file_uuid), self._id_db])
|
||||
# database.put_queue(['data_meta_write', self, meta_data, _path, self._id_db])
|
||||
return None
|
||||
|
||||
def update_subfile_mini(self, database = None):
|
||||
meta_data = {
|
||||
'mini_data': self._recording_sub_mini,
|
||||
}
|
||||
_path = str(self._filepath).replace('/', '^')
|
||||
|
||||
if database is not None :
|
||||
self._database = database
|
||||
self._database.put_queue(['data_meta_write', meta_data, self._device_id, str(self._file_uuid), self._id_db])
|
||||
# database.put_queue(['data_meta_write', self, meta_data, _path, self._id_db])
|
||||
return None
|
||||
|
||||
@property
|
||||
@@ -965,7 +1014,8 @@ class RecordingFileWriter:
|
||||
'_data_value_ch', '_close', '_data_mini_ch',
|
||||
'_mini_scale_list', '_time_real_time', '_data_rl', '_data_db',
|
||||
'_raw_save', '_mini_save', '_data_time_ch', '_data_value_ch_for_rl',
|
||||
'_data_time_ch_for_rl', '_device_id', '_send_data', '_data_mqtt_ch', '_id_db_save')
|
||||
'_data_time_ch_for_rl', '_device_id', '_send_data', '_data_mqtt_ch', '_id_db_save', '_raw_create_not_done',
|
||||
'_mini_create_not_done')
|
||||
|
||||
def __init__(self, meta: RecordingMetaFile, device_id, database = None):
|
||||
self._meta = meta
|
||||
@@ -1046,6 +1096,9 @@ class RecordingFileWriter:
|
||||
|
||||
self._splitting_size = None
|
||||
|
||||
self._raw_create_not_done = True
|
||||
self._mini_create_not_done = True
|
||||
|
||||
|
||||
@property
|
||||
def meta_file(self) -> RecordingMetaFile:
|
||||
@@ -1066,7 +1119,6 @@ class RecordingFileWriter:
|
||||
|
||||
def channels_update(self, channels):
|
||||
channels.sort()
|
||||
self._database.put_queue(['data_meta_update_raw_empty_channel', self._meta._id_db, channels])
|
||||
self._channel_list.extend(channels)
|
||||
return self._channel_list
|
||||
|
||||
@@ -1080,6 +1132,9 @@ class RecordingFileWriter:
|
||||
return None
|
||||
|
||||
def close(self):
|
||||
# if self._recording_file is not None:
|
||||
# self._recording_file.close()
|
||||
# self._recording_file = None
|
||||
print('close1')
|
||||
self._close = True
|
||||
if len(self._recording_file_dict) > 0:
|
||||
@@ -1259,7 +1314,8 @@ class RecordingFileWriter:
|
||||
self._data_db[c].append(str(v))
|
||||
self._time_now = int(t)
|
||||
return
|
||||
|
||||
|
||||
# @calculate_time(1)
|
||||
def write(self, data: Union[bytes, RecordingData, List[bytes], List[RecordingData]], mqtt_thread) -> int:
|
||||
# check size
|
||||
ths = self.splitting_threshold_size
|
||||
@@ -1318,18 +1374,34 @@ class RecordingFileWriter:
|
||||
|
||||
self.get_data_iter(d, mqtt_thread)
|
||||
|
||||
for ch in self._recording_file_dict:
|
||||
if self._recording_file_dict[ch]._id_db == 0:
|
||||
return None
|
||||
|
||||
data_save = False
|
||||
mini_save = False
|
||||
if len(self._recording_file_dict) > 0:
|
||||
for ch in self._data_db.keys():
|
||||
if self._time_now - self._time_real_time[ch] > 1000000:
|
||||
self._send_data[ch] = True
|
||||
self._time_real_time[ch] = self._time_now
|
||||
if self._time_now - self._time[ch] > 2000000:
|
||||
|
||||
for ch in self._recording_file_dict:
|
||||
if self._recording_file_dict[ch]._id_db == 0:
|
||||
return None
|
||||
|
||||
for ch in self._data_db.keys():
|
||||
for scale in self._mini_scale_list:
|
||||
if self._recording_mini_dict[str(scale)][ch]._id_db == 0:
|
||||
return None
|
||||
|
||||
if self._raw_create_not_done :
|
||||
self._raw_create_not_done = False
|
||||
self._meta.update_subfile_raw(database = self._database)
|
||||
|
||||
if self._mini_create_not_done :
|
||||
self._mini_create_not_done = False
|
||||
self._meta.update_subfile_mini(database = self._database)
|
||||
|
||||
data_save = False
|
||||
mini_save = False
|
||||
if len(self._recording_file_dict) > 0:
|
||||
for ch in self._data_db.keys():
|
||||
if self._time_now - self._time[ch] > 5000000:
|
||||
if self._recording_file_dict[ch]._status:
|
||||
_data = ' '.join(self._data_db[ch])
|
||||
write_sz = self._recording_file_dict[ch].write(_data, self._channel_list)
|
||||
@@ -1345,9 +1417,11 @@ class RecordingFileWriter:
|
||||
if len(self._data_mini_ch[ch]['1000']['mean']) >= 10:
|
||||
mini_save = True
|
||||
for scale in self._mini_scale_list:
|
||||
str_mean = [str(int) for int in self._data_mini_ch[ch][str(scale)]['mean']]
|
||||
data_mean = str(self._data_mini_ch[ch][str(scale)]['start_time']) + ' ' + ' '.join(str_mean) + '"***"'
|
||||
self._mini_save[str(scale)]['id'][ch] = self._recording_mini_dict[str(scale)][ch]._id_db
|
||||
self._mini_save[str(scale)]['start_time'][ch] = str(self._data_mini_ch[ch][str(scale)]['start_time'])
|
||||
self._mini_save[str(scale)]['data_mean'][ch] = self._data_mini_ch[ch][str(scale)]['mean'].copy()
|
||||
self._mini_save[str(scale)]['data_mean'][ch] = data_mean
|
||||
# self._mini_save[str(scale)]['data_random'][ch] = self._data_mini_ch[ch][str(scale)]['random'].copy()
|
||||
# self._mini_save[str(scale)]['data_bar'][ch] = self._data_mini_ch[ch][str(scale)]['bar'].copy()
|
||||
self._recording_mini_dict[str(scale)][ch].write(self._mini_save[str(scale)]['data_mean'][ch])
|
||||
@@ -1360,19 +1434,20 @@ class RecordingFileWriter:
|
||||
if self._database is not None:
|
||||
recording_input = ['data_raw_recording_new', copy(self._raw_save['id']), copy(self._channel_list), copy(self._raw_save['data']), copy(self._raw_save['end_time']), copy(self._raw_save['size'])]
|
||||
self._database.put_queue(recording_input)
|
||||
self._meta.update_subfile(database = self._database)
|
||||
self._meta.update_subfile_time_size(database = self._database)
|
||||
if mini_save is True:
|
||||
if self._database is not None:
|
||||
for scale in self._mini_scale_list:
|
||||
self._database.put_queue(['data_mini_recording', self._mini_save[str(scale)]['id'], self._channel_list, self._mini_save[str(scale)]['start_time'], self._mini_save[str(scale)]['data_mean']])
|
||||
self._meta.update_subfile(database = self._database)
|
||||
|
||||
self._database.put_queue(['data_mini_recording_new', copy(self._mini_save[str(scale)]['id']), self._channel_list, copy(self._mini_save[str(scale)]['data_mean'])])
|
||||
self._meta.update_subfile_time_size(database = self._database)
|
||||
del data
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _switch_recording_file(self):
|
||||
self._raw_create_not_done = True
|
||||
|
||||
if len(self._recording_file_dict) > 0:
|
||||
for ch in self._recording_file_dict.keys():
|
||||
self._id_db_save[ch] = self._recording_file_dict[ch]._id_db
|
||||
@@ -1393,13 +1468,14 @@ class RecordingFileWriter:
|
||||
self._database.put_queue(['data_raw_create', raw_data_dict, self._channel_list, self._device_id])
|
||||
|
||||
self._meta._last_time = self._time_now
|
||||
self._meta.update_subfile(database = self._database)
|
||||
# self._meta.update_subfile(database = self._database)
|
||||
|
||||
self._splitting_size = 0
|
||||
|
||||
return None
|
||||
|
||||
def _switch_recording_mini(self, scale):
|
||||
self._mini_create_not_done = True
|
||||
|
||||
if len(self._recording_mini_dict[str(scale)]) > 0:
|
||||
for ch in self._recording_mini_dict[str(scale)].keys():
|
||||
@@ -1419,7 +1495,7 @@ class RecordingFileWriter:
|
||||
self._database.put_queue(['data_mini_create', mini_data_dict, self._channel_list, scale, self._device_id])
|
||||
|
||||
self._meta._last_time = self._time_now
|
||||
self._meta.update_subfile(database = self._database)
|
||||
# self._meta.update_subfile(database = self._database)
|
||||
return None
|
||||
|
||||
def update_meta_id(self, _id):
|
||||
@@ -1428,10 +1504,16 @@ class RecordingFileWriter:
|
||||
|
||||
def update_raw_dict_id(self, _channel, _id):
|
||||
self._recording_file_dict[int(_channel)]._id_db = _id
|
||||
self._database.put_queue(['data_meta_update_channel_raw_id', self._meta._id_db, _channel, _id])
|
||||
if int(_channel) not in self._meta._recording_sub_file:
|
||||
self._meta._recording_sub_file[int(_channel)] = []
|
||||
self._meta._recording_sub_file[int(_channel)].append(_id)
|
||||
return None
|
||||
|
||||
def update_mini_dict_id(self, _scale, _channel, _id):
|
||||
self._recording_mini_dict[str(_scale)][int(_channel)]._id_db = _id
|
||||
self._database.put_queue(['data_meta_update_channel_mini_id', self._meta._id_db, _channel, _scale, _id])
|
||||
if int(_channel) not in self._meta._recording_sub_mini:
|
||||
self._meta._recording_sub_mini[int(_channel)] = {}
|
||||
if int(_scale) not in self._meta._recording_sub_mini[int(_channel)]:
|
||||
self._meta._recording_sub_mini[int(_channel)][int(_scale)] = []
|
||||
self._meta._recording_sub_mini[int(_channel)][int(_scale)].append(_id)
|
||||
return None
|
||||
@@ -9,23 +9,9 @@ _jwt = None
|
||||
|
||||
def controller_device_id() -> str:
|
||||
### device ID
|
||||
return 'b8:27:eb:52:ea:97'
|
||||
ret = None
|
||||
try:
|
||||
with open('/etc/BPS/device_id') as f:
|
||||
for line in f:
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
|
||||
ret = line.strip()
|
||||
break
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
if ret is None or len(ret) == 0:
|
||||
return str(uuid.uuid1())
|
||||
else:
|
||||
return ret
|
||||
f = open("/sys/class/net/eth0/address", "r")
|
||||
mac = f.read()[:-1]
|
||||
return mac
|
||||
|
||||
def get_api_jwt() -> str:
|
||||
global _jwt
|
||||
|
||||
@@ -23,6 +23,7 @@ import biopro.server._identify
|
||||
from time import time
|
||||
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
from biopro.util.logger import calculate_time
|
||||
|
||||
_RUNTIME_COMPILE = False
|
||||
|
||||
@@ -69,6 +70,7 @@ class DataBaseProcess(Process):
|
||||
self._data_raw_create_sql_str = None
|
||||
self._data_raw_update_sql_str = None
|
||||
self._data_raw_recording_sql_str = 'UPDATE "public"."%s_recording_data_raws" SET data = concat(data, %s), end_time=%s, size=%s where id = %s'
|
||||
self._data_mini_recording_sql_str = 'UPDATE "public"."%s_recording_data_minis" SET data_mean = concat(data_mean, %s) where id = %s'
|
||||
|
||||
@property
|
||||
def db_host(self) -> str:
|
||||
@@ -85,13 +87,6 @@ class DataBaseProcess(Process):
|
||||
@property
|
||||
def api_token(self) -> str:
|
||||
return self._api_token
|
||||
|
||||
def calculate_time(func):
|
||||
def warp(*args, **kwargs):
|
||||
now = time()
|
||||
func(*args, **kwargs)
|
||||
print(func.__name__,'cost:', time() - now)
|
||||
return warp
|
||||
|
||||
def run(self) -> None:
|
||||
self.setup()
|
||||
@@ -165,7 +160,7 @@ class DataBaseProcess(Process):
|
||||
getattr(self, do)(*args)
|
||||
return None
|
||||
|
||||
# @calculate_time
|
||||
# @calculate_time(1)
|
||||
def data_meta_write(self, _data: JSON_OBJECT, device_id, _uuid = None, _id = None):
|
||||
if _id > 0:
|
||||
sql_str = 'UPDATE "public"."recording_data_metas" SET '
|
||||
@@ -268,6 +263,7 @@ class DataBaseProcess(Process):
|
||||
# _conn.close()
|
||||
return None
|
||||
|
||||
# @calculate_time()
|
||||
def data_meta_get(self, _path = None, _id = None):
|
||||
if _id is not None:
|
||||
sql_str = 'SELECT * FROM "public"."recording_data_metas" WHERE id = %s'
|
||||
@@ -302,6 +298,7 @@ class DataBaseProcess(Process):
|
||||
# _conn.close()
|
||||
return None
|
||||
|
||||
# @calculate_time()
|
||||
def data_meta_id_get_by_path(self, _path = None):
|
||||
ret = None
|
||||
if _path is not None:
|
||||
@@ -323,7 +320,7 @@ class DataBaseProcess(Process):
|
||||
# _conn.close()
|
||||
return None
|
||||
|
||||
# @calculate_time
|
||||
# @calculate_time()
|
||||
def data_raw_create(self, _data_dict, _channel_list, device_id):
|
||||
if self._data_raw_create_sql_str == None:
|
||||
sql_str_list = []
|
||||
@@ -345,7 +342,7 @@ class DataBaseProcess(Process):
|
||||
|
||||
return True
|
||||
|
||||
# @calculate_time
|
||||
# @calculate_time()
|
||||
def data_raw_update(self, _id, _channel, _data: JSON_OBJECT):
|
||||
sql_str = 'UPDATE "public"."' + str(_channel) + '_recording_data_raws" SET '
|
||||
sql_set = []
|
||||
@@ -365,7 +362,7 @@ class DataBaseProcess(Process):
|
||||
sql_cursor.close()
|
||||
return None
|
||||
|
||||
# @calculate_time
|
||||
# @calculate_time()
|
||||
def data_raw_recording(self, _id_dict, _channel_list, _data_dict, _id_db_save):
|
||||
try:
|
||||
with self._psql_conn as conn:
|
||||
@@ -379,19 +376,20 @@ class DataBaseProcess(Process):
|
||||
print('recording error', e)
|
||||
return None
|
||||
|
||||
# @calculate_time
|
||||
# @calculate_time(1)
|
||||
def data_raw_recording_new(self, _id_dict, _channel_list, _data_dict, _end_time_dict, _size_dict):
|
||||
try:
|
||||
para_list = []
|
||||
for _channel in _channel_list:
|
||||
para_list.append([_channel, _data_dict[_channel] + '"***"', _end_time_dict[_channel], _size_dict[_channel], _id_dict[_channel]])
|
||||
with self._psql_conn as conn:
|
||||
with conn.cursor() as sql_cursor:
|
||||
para_list = []
|
||||
for _channel in _channel_list:
|
||||
para_list.append([_channel, _data_dict[_channel] + '"***"', _end_time_dict[_channel], _size_dict[_channel], _id_dict[_channel]])
|
||||
execute_batch(sql_cursor, self._data_raw_recording_sql_str, para_list)
|
||||
except psycopg2.Error as e:
|
||||
print('recording error', e)
|
||||
return None
|
||||
|
||||
|
||||
# @calculate_time()
|
||||
def data_mini_create(self, _data_dict, _channel_list, _scale, device_id):
|
||||
for _channel in _channel_list:
|
||||
sql_str = 'INSERT INTO "public"."' + str(_channel) + '_recording_data_minis" ('
|
||||
@@ -425,6 +423,7 @@ class DataBaseProcess(Process):
|
||||
# _conn.close()
|
||||
return True
|
||||
|
||||
# @calculate_time()
|
||||
def data_mini_recording(self, _id_dict, _channel_list, _start_time_dict, _data_mean_dict):
|
||||
with self._psql_conn as conn:
|
||||
with self._psql_conn.cursor() as sql_cursor:
|
||||
@@ -444,9 +443,23 @@ class DataBaseProcess(Process):
|
||||
for _channel in _channel_list:
|
||||
del _start_time_dict[_channel], _data_mean_dict[_channel]
|
||||
gc.collect()
|
||||
|
||||
|
||||
return True
|
||||
|
||||
# @calculate_time(1)
|
||||
def data_mini_recording_new(self, _id_dict, _channel_list, _data_mean_dict):
|
||||
try:
|
||||
para_list = []
|
||||
for _channel in _channel_list:
|
||||
para_list.append([_channel, _data_mean_dict[_channel], _id_dict[_channel]])
|
||||
with self._psql_conn as conn:
|
||||
with conn.cursor() as sql_cursor:
|
||||
execute_batch(sql_cursor, self._data_mini_recording_sql_str, para_list)
|
||||
except psycopg2.Error as e:
|
||||
print('recording error', e)
|
||||
return None
|
||||
|
||||
# @calculate_time()
|
||||
def data_mini_update(self, _id, _channel, _data: JSON_OBJECT):
|
||||
sql_str = 'UPDATE "public"."' + str(_channel) + '_recording_data_minis" SET '
|
||||
sql_set = []
|
||||
@@ -481,26 +494,58 @@ class DataBaseProcess(Process):
|
||||
print('e', e)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
# @calculate_time()
|
||||
def data_meta_update_channel_raw_id(self, meta_id, channel, raw_id):
|
||||
try:
|
||||
with self._psql_conn as conn:
|
||||
with conn.cursor() as sql_cursor:
|
||||
sql_str = "UPDATE recording_data_metas SET raw_data = jsonb_insert(raw_data, '{%s, -1}', '%s', TRUE) WHERE id = %s;"
|
||||
sql_set = [channel, raw_id, 571]
|
||||
sql_cursor.execute(sql_str, sql_set)
|
||||
except psycopg2.Error as e:
|
||||
print('e', e)
|
||||
|
||||
return True
|
||||
|
||||
# @calculate_time()
|
||||
def data_meta_update_all_channel_raw_id(self, meta_id:str, raw_id_dict:dict):
|
||||
try:
|
||||
sql_str = "UPDATE recording_data_metas SET raw_data = jsonb_insert(raw_data, '{%s, -1}', '%s', TRUE) WHERE id = %s;"
|
||||
sql_set = []
|
||||
for ch in raw_id_dict.keys():
|
||||
sql_set.append([ch, raw_id_dict[ch], meta_id])
|
||||
with self._psql_conn as conn:
|
||||
with conn.cursor() as sql_cursor:
|
||||
sql_str = "UPDATE recording_data_metas SET raw_data = jsonb_insert(raw_data, '{%s, -1}', '%s', TRUE) WHERE id = %s;"
|
||||
sql_set = [channel, raw_id, meta_id]
|
||||
execute_batch(sql_cursor, sql_str, sql_set)
|
||||
except psycopg2.Error as e:
|
||||
print('e', e)
|
||||
|
||||
return True
|
||||
|
||||
def data_meta_update_channel_mini_id(self, meta_id, channel, scale, mini_id):
|
||||
try:
|
||||
with self._psql_conn as conn:
|
||||
with conn.cursor() as sql_cursor:
|
||||
sql_str = "UPDATE recording_data_metas SET mini_data = jsonb_insert(mini_data, '{%s, %s, -1}', '%s', TRUE) WHERE id = %s;"
|
||||
sql_set = [channel, scale, mini_id, meta_id]
|
||||
sql_cursor.execute(sql_str, sql_set)
|
||||
except psycopg2.Error as e:
|
||||
print('e', e)
|
||||
|
||||
return True
|
||||
|
||||
def data_meta_update_channel_mini_id(self, meta_id, channel, scale, raw_id):
|
||||
# @calculate_time()
|
||||
def data_meta_update_all_channel_mini_id(self, meta_id, mini_id_dict):
|
||||
try:
|
||||
sql_str = "UPDATE recording_data_metas SET mini_data = jsonb_insert(mini_data, '{%s, %s, -1}', '%s', TRUE) WHERE id = %s;"
|
||||
sql_set = []
|
||||
for ch in mini_id_dict.keys():
|
||||
for scale in mini_id_dict[ch].keys():
|
||||
sql_set.append([ch, scale, mini_id_dict[ch][scale], meta_id])
|
||||
with self._psql_conn as conn:
|
||||
with conn.cursor() as sql_cursor:
|
||||
sql_str = "UPDATE recording_data_metas SET mini_data = jsonb_insert(mini_data, '{%s, %s, -1}', '%s', TRUE) WHERE id = %s;"
|
||||
sql_set = [channel, scale, raw_id, meta_id]
|
||||
sql_cursor.execute(sql_str, sql_set)
|
||||
with conn.cursor() as sql_cursor:
|
||||
execute_batch(sql_cursor, sql_str, sql_set)
|
||||
except psycopg2.Error as e:
|
||||
print('e', e)
|
||||
|
||||
|
||||
@@ -98,6 +98,11 @@ class RecordingProcess(Process):
|
||||
self._last_cnt = [-1, -1, -1, -1, -1, -1, -1, -1]
|
||||
self._wrong_cnt = 0
|
||||
|
||||
# elite data length
|
||||
self._elite_data_len = 40
|
||||
self._mem_header_len = 3
|
||||
self._mem_tailer_len = 6
|
||||
self._single_data_len = self._elite_data_len + self._mem_header_len + self._mem_tailer_len
|
||||
|
||||
def ensure_data_format(self) -> DataDecodeFormat:
|
||||
if isinstance(self._data_format, (str, bytes)):
|
||||
@@ -160,7 +165,11 @@ class RecordingProcess(Process):
|
||||
"""
|
||||
q = None
|
||||
try:
|
||||
# now = time()
|
||||
q = self._queue_rec.get()
|
||||
# get_queue_time_cost = time() - now
|
||||
# if get_queue_time_cost > 2:
|
||||
# print('get queue cost time', get_queue_time_cost)
|
||||
except:
|
||||
return False
|
||||
finally:
|
||||
@@ -286,6 +295,7 @@ class RecordingProcess(Process):
|
||||
self._last_cnt[7] = head_counter - 1
|
||||
last_data_cnt = self._last_cnt[7]
|
||||
|
||||
# dont save to section when head or id is wrong
|
||||
if (head != 255 or device_id != device):
|
||||
save = False
|
||||
last_data_cnt = last_data_cnt + 1
|
||||
@@ -328,60 +338,57 @@ class RecordingProcess(Process):
|
||||
|
||||
return save
|
||||
|
||||
def _check_jump_ram(self, raw_data: bytes, colum_now: int, colum_total: int, save: bool, device: int):
|
||||
i = colum_now
|
||||
def _check_jump_ram(self, raw_data: bytes, colum_now: int, colum_total: int, save: bool, device: int, data_len: int):
|
||||
col = colum_now
|
||||
save = False
|
||||
|
||||
if (raw_data[i][0] == 255 and raw_data[i][3] == device):
|
||||
if colum_total < 3:
|
||||
print('this ram data < 3 records, need to fix, colum_total = ', colum_total)
|
||||
if colum_total == 1:
|
||||
print('raw_data[0]', raw_data[0])
|
||||
if raw_data[col][0] != 255 or raw_data[col][3] != device:
|
||||
return save
|
||||
|
||||
elif colum_total == 2:
|
||||
print('raw_data[0]', raw_data[0])
|
||||
print('raw_data[1]', raw_data[1])
|
||||
if colum_total == 1:
|
||||
print('this ram data < 3 records, colum_total = ', colum_total)
|
||||
print('raw_data[0]', raw_data[0])
|
||||
return save
|
||||
|
||||
else:
|
||||
elif colum_total == 2:
|
||||
print('this ram data < 3 records, colum_total = ', colum_total)
|
||||
print('raw_data[0]', raw_data[0])
|
||||
print('raw_data[1]', raw_data[1])
|
||||
if (raw_data[col + 1][1] - raw_data[col][1] == 1) or (raw_data[col][1] == 255 and raw_data[col + 1][1] == 0):
|
||||
save = True
|
||||
|
||||
if((raw_data[i + 1][1] - raw_data[i][1] == 1 and raw_data[i + 2][1] - raw_data[i + 1][1] == 1) or
|
||||
(raw_data[i][1] == 255 and raw_data[i + 1][1] == 0 and raw_data[i + 2][1] == 1) or
|
||||
(raw_data[i][1] == 254 and raw_data[i + 1][1] == 255 and raw_data[i + 2][1] == 0)):
|
||||
elif colum_total >= 3:
|
||||
if (raw_data[col + 1][1] - raw_data[col][1] == 1 and raw_data[col + 2][1] - raw_data[col + 1][1] == 1) or\
|
||||
(raw_data[col][1] == 255 and raw_data[col + 1][1] == 0 and raw_data[col + 2][1] == 1) or\
|
||||
(raw_data[col][1] == 254 and raw_data[col + 1][1] == 255 and raw_data[col + 2][1] == 0):
|
||||
save = True
|
||||
|
||||
if ((raw_data[i][1] == 255 and raw_data[i + 1][1] == 0 and raw_data[i + 2][1] == 1) or
|
||||
(raw_data[i][1] == 254 and raw_data[i + 1][1] == 255 and raw_data[i + 2][1] == 0)):
|
||||
print('cnt = [254, 255, 0] or [255, 0, 1]')
|
||||
if save == True:
|
||||
self._skip_ram_cnt += 1
|
||||
last_data_cnt = raw_data[col][1]
|
||||
if (device == 4):
|
||||
print('self._last_cnt[4]:', self._last_cnt[4], ', last_data_cnt:', last_data_cnt)
|
||||
if (device == 5):
|
||||
print('self._last_cnt[5]:', self._last_cnt[5], ', last_data_cnt:', last_data_cnt)
|
||||
if (device == 6):
|
||||
print('self._last_cnt[6]:', self._last_cnt[6], ', last_data_cnt:', last_data_cnt)
|
||||
if (device == 7):
|
||||
print('self._last_cnt[7]:', self._last_cnt[7], ', last_data_cnt:', last_data_cnt)
|
||||
|
||||
print('skip RAM, but data is right, solve data', list(raw_data[col][0:3]),'|', list(raw_data[colum_total-1][0:3]), 'skip Ram', self._skip_ram_cnt, 'times \n')
|
||||
|
||||
save = True
|
||||
self._skip_ram_cnt += 1
|
||||
last_data_cnt = raw_data[i][1]
|
||||
if (device == 4):
|
||||
print('self._last_cnt[4]:', self._last_cnt[4], ', last_data_cnt:', last_data_cnt)
|
||||
if (device == 5):
|
||||
print('self._last_cnt[5]:', self._last_cnt[5], ', last_data_cnt:', last_data_cnt)
|
||||
if (device == 6):
|
||||
print('self._last_cnt[6]:', self._last_cnt[6], ', last_data_cnt:', last_data_cnt)
|
||||
if (device == 7):
|
||||
print('self._last_cnt[7]:', self._last_cnt[7], ', last_data_cnt:', last_data_cnt)
|
||||
|
||||
print('skip RAM, but data is right, solve data', list(raw_data[i][0:3]),'|', list(raw_data[colum_total-1][0:3]), 'skip Ram', self._skip_ram_cnt, 'times \n')
|
||||
# print('data:')
|
||||
# print('|', list(raw_data[0]))
|
||||
# print('|', list(raw_data[1]))
|
||||
# print('| ... ... ...')
|
||||
# print('| ... ... ...')
|
||||
# print('|', list(raw_data[colum_total-1]))
|
||||
if (device == 4):
|
||||
self._last_cnt[4] = last_data_cnt
|
||||
|
||||
if (device == 4):
|
||||
self._last_cnt[4] = last_data_cnt
|
||||
elif (device == 5):
|
||||
self._last_cnt[5] = last_data_cnt
|
||||
|
||||
elif (device == 5):
|
||||
self._last_cnt[5] = last_data_cnt
|
||||
elif (device == 6):
|
||||
self._last_cnt[6] = last_data_cnt
|
||||
|
||||
elif (device == 6):
|
||||
self._last_cnt[6] = last_data_cnt
|
||||
elif (device == 7):
|
||||
self._last_cnt[7] = last_data_cnt
|
||||
|
||||
elif (device == 7):
|
||||
self._last_cnt[7] = last_data_cnt
|
||||
return save
|
||||
|
||||
def _neu_foreach_data_section(self, data: bytes):
|
||||
@@ -496,29 +503,30 @@ class RecordingProcess(Process):
|
||||
:return:
|
||||
"""
|
||||
raw_data = []
|
||||
index = 0
|
||||
elite_data_len = 40
|
||||
mem_header_len = 3
|
||||
mem_tailer_len = 6
|
||||
single_data_len = elite_data_len + mem_header_len + mem_tailer_len
|
||||
device = self._device
|
||||
records = 0
|
||||
print_flag = False
|
||||
device = self._device
|
||||
single_data_len = self._single_data_len
|
||||
mem_header_len = self._mem_header_len
|
||||
|
||||
# packet section data use two microarray
|
||||
for i in range(0, len(data), single_data_len):
|
||||
index = index + 1
|
||||
for j in range(index, index + 1):
|
||||
raw_data.append(data[i : i + single_data_len])
|
||||
|
||||
records = records + 1
|
||||
raw_data.append(data[i : i + single_data_len])
|
||||
if len(data[i : i + 10]) < 10:
|
||||
print('data dont be package:', raw_data[records - 1], 'index:', records - 1)
|
||||
del raw_data[records - 1]
|
||||
records = records - 1
|
||||
|
||||
# check cnt
|
||||
for i in range(index):
|
||||
for i in range(records):
|
||||
|
||||
# if jump cnt, don't save data
|
||||
save = self._check_cnt(raw_data[i], device)
|
||||
|
||||
# # if jump Ram, also can handle data
|
||||
if save == False:
|
||||
save = self._check_jump_ram(raw_data, i, index, save, device)
|
||||
save = self._check_jump_ram(raw_data, i, records, save, device, single_data_len)
|
||||
|
||||
if (save == True):
|
||||
section = raw_data[i]
|
||||
@@ -533,7 +541,7 @@ class RecordingProcess(Process):
|
||||
|
||||
print('check number not match', list(raw_data[i]), 'raw:', i)
|
||||
|
||||
if (i+1 <= index):
|
||||
if (i+1 <= records):
|
||||
print('check number not match', list(raw_data[i+1]), 'raw:', i+1, '\n')
|
||||
section = section + b'\x01'
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import inspect
|
||||
import os
|
||||
import sys
|
||||
import threading as _threading
|
||||
from time import time
|
||||
from datetime import datetime
|
||||
from functools import wraps
|
||||
from typing import Any, Optional, Tuple, Union
|
||||
@@ -520,3 +521,17 @@ def logging_error(f):
|
||||
return f(self, *args, **kwargs)
|
||||
|
||||
return _logger
|
||||
|
||||
|
||||
def calculate_time(time_limit=None):
|
||||
def actual_calculate_time(func):
|
||||
def warp(*args, **kwargs):
|
||||
now = time()
|
||||
func(*args, **kwargs)
|
||||
if time_limit == None:
|
||||
print(func.__name__,'cost:', time() - now)
|
||||
else:
|
||||
if time() - now > time_limit:
|
||||
print(func.__name__,'cost:', time() - now)
|
||||
return warp
|
||||
return actual_calculate_time
|
||||
|
||||
Reference in New Issue
Block a user