Compare commits

..

14 Commits

Author SHA1 Message Date
LuoYiTing 034b7976cd Update README.md 2022-04-25 03:55:34 +00:00
peterlu14 f233c019fd [update] auto get eth0 mac address 2022-04-25 10:36:02 +08:00
peterlu14 13825fe9ff [update] hide print 2022-04-08 18:22:44 +08:00
peterlu14 dd2e31d01f [update] fix index problem 2022-04-08 18:16:31 +08:00
peterlu14 455fa1f86b [update] fix stop error & relative_time 2022-04-08 11:17:07 +08:00
Roy 71850b31a8 [update] fix recording error 2022-04-07 12:33:02 +08:00
peterlu14 8d52fef4c1 [update] hide print message 2022-04-07 12:29:18 +08:00
peterlu14 e091f220fa Merge branch 'test/update_data_server' into rel/v1.4.0_schedule/channel_lost_data 2022-03-28 18:19:29 +08:00
Roy 2fd05d18ed [update] fix battery value 2022-03-25 13:41:48 +08:00
Roy 03011ebd5f Merge branch 'dev/check_sum/battery' into rel/v1.4.0_schedule/channel_lost_data 2022-03-25 12:11:05 +08:00
Roy 4b9bc30e28 [update] get battery value 2022-03-25 11:46:40 +08:00
Roy 4966113393 [update] use check sum 2022-03-25 11:44:52 +08:00
Roy 3371c21bbd [update] update log message 2022-03-25 11:34:30 +08:00
Roy afc87829d9 [update] head != tailer, delete data 2022-03-24 17:12:06 +08:00
13 changed files with 402 additions and 226 deletions
+174 -38
View File
@@ -4,7 +4,7 @@ New goal on pi4 without kotlin and django, and with only one dataserver.
# Installation # Installation
### Get Raspbrain into SD card ### Get Raspbrain into SD card
###### Download Raspbian Buster Lite ###### Download Raspbian Bullseye Lite
>https://www.raspberrypi.org/downloads/raspberry-pi-os/ >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 lsblk
# copy data to sd card # 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 # enable ssh on first boot
add ssh.txt in boot folder add ssh.txt in boot folder
@@ -77,18 +77,22 @@ add ssh.txt in boot folder
###### Install dependencies ###### Install dependencies
sudo apt-get install vim git wiringpi build-essential libi2c-dev i2c-tools python-dev libffi-dev python3-pip postgresql 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 ### Setup project
###### Clone project ###### Clone data server project
``` ```
cd ~ cd ~
git clone https://gitlab.com/bioproscientific/bioprorelife.git git clone https://gitlab.com/wisetop/controller/wisetopdataserver.git
``` ```
###### Install python dependencies ###### Install python dependencies
``` ```
cd ~/bioprorelife cd ~/wisetopdataserver
pip3 install -r requirements.txt pip3 install -r requirements.txt
``` ```
##### Packages version ##### Packages version
@@ -112,14 +116,14 @@ psycopg2 2.8.5
###### Build C extension ###### Build C extension
``` ```
cd ~/bioprorelife/python/biopro/ext/ cd ~/wisetopdataserver/python/biopro/ext/
rm -rf *.so build rm -rf *.so build
python3 setup.py build_ext --inplace python3 setup.py build_ext --inplace
``` ```
###### Check setup-uart file ###### Check setup-uart file
``` ```
cd ~/bioprorelife cd ~/wisetopdataserver/
sudo vim ./run-setup-uart.sh sudo vim ./run-setup-uart.sh
``` ```
##### Modify the code as following ##### Modify the code as following
@@ -149,44 +153,72 @@ sudo raspi-config
reboot reboot
``` ```
###### Set pi password
```
$cd ~
$passwd
Current password:raspberry
New password:5k6zj454778225
Retype new password:5k6zj454778225
```
###### Auto run program when device start ###### Auto run program when device start
``` ```
sudo vim /etc/rc.local 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 ### MQTT broker install
1. Install mosquitto ###### 1.Install mosquitto
``` $sudo apt-get install mosquitto mosquitto-clients
sudo apt-get install mosquitto mosquitto-clients
```
###### 2.Enable Remote Access
$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: add the code following as:
``` ```
listener 1883 listener 1883
protocol mqtt protocol mqtt
listener 8083 listener 8083
protocol websockets protocol websockets
allow_anonymous true
``` ```
restart mqtt broker ###### 3.restart mqtt broker
``` $sudo systemctl restart mosquitto
sudo systemctl restart mosquitto
```
3. Robust MQTT ###### 4.Robust MQTT
create mosquitto_restart.sh create mosquitto_restart.sh
```
cd ~ $cd ~
sudo vim mosquitto_restart.sh $sudo vim mosquitto_restart.sh
```
add the code following as: add the code following as:
``` ```
if [ "`ps -aux | grep /usr/sbin/mosquitto | wc -l`" == "1" ] if [ "`ps -aux | grep /usr/sbin/mosquitto | wc -l`" == "1" ]
@@ -200,25 +232,129 @@ fi
echo "$SERVICE is currently running" >> /home/ubuntu/cron.log echo "$SERVICE is currently running" >> /home/ubuntu/cron.log
exit 0 exit 0
``` ```
add mosquitto_restart.sh to root routing ###### 5.add mosquitto_restart.sh to root routing
``` $sudo chmod +x mosquitto_restart.sh
sudo chmod +x mosquitto_restart.sh $sudo -i
sudo -i $crontab -e
crontab -e
```
add the code following as: add the code following as:
``` ```
*/5 * * * * /home/pi/mosquitto_restart.sh */5 * * * * /home/pi/mosquitto_restart.sh
``` ```
3. Auto run MQTT broker when when pi-start ###### 6.Auto run MQTT broker when when pi-start
``` $sudo vim /etc/rc.local
sudo vim /etc/rc.local
```
add the code following as: add the code following as:
``` ```
sudo nohup systemctl restart mosquitto 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: ##### raspberry website document:
> https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md > https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md
+2 -1
View File
@@ -536,7 +536,7 @@ class CC2650Device(Device):
self._master.log_warn('device', self.device_id, 'update_battery_info no response') self._master.log_warn('device', self.device_id, 'update_battery_info no response')
else: else:
if data is not None and len(data) == 4 : if data is not None and len(data) > 2 :
battery = struct.unpack('<H', data[1:3])[0] battery = struct.unpack('<H', data[1:3])[0]
if battery is not None: if battery is not None:
self._battery = battery self._battery = battery
@@ -2035,6 +2035,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
# print("local_name = ", local_name) # print("local_name = ", local_name)
# addr type is don't care in BMD380 # 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 = int(scan_response[index:index + 1][0])
# local_addr_type = 0xFF # local_addr_type = 0xFF
index = index + 1 index = index + 1
+23 -17
View File
@@ -882,15 +882,18 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
if len(data) < 18: if len(data) < 18:
return None return None
time_stamp: float = struct.unpack('<I', data[1:5])[0] # unit: ms 0x18030000 mem_cnt = data[1]
current = struct.unpack('<i', data[5:9])[0] # unit: nA time_stamp: float = struct.unpack('<I', data[4:8])[0] # unit: ms 0x18030000
voltage = struct.unpack('<i', data[9:13])[0] # unit: uV current = struct.unpack('<i', data[8:12])[0] # unit: nA
impedance = struct.unpack('<i', data[13:17])[0] # unit: mOm voltage = struct.unpack('<i', data[12:16])[0] # unit: uV
cycle_number = struct.unpack('<H', data[17:19])[0] impedance = struct.unpack('<i', data[16:20])[0] # unit: mOm
finish_mode_falg = data[19] cycle_number = struct.unpack('<H', data[20:22])[0]
finish_mode_falg = data[22]
battery = struct.unpack('<i', data[23:27])[0]
elite_notify_times = data[27]
mem_wrong_information = struct.unpack('<i', data[40:40+4])[0] # mem_wrong_information = green retry, green wrong, red retry, red wrong mem_wrong_information = struct.unpack('<i', data[43:47])[0] # mem_wrong_information = green retry, green wrong, red retry, red wrong
ram_num = data[44] ram_num = data[47]
broken_flag = data[-1] broken_flag = data[-1]
if (finish_mode_falg & 0b11110000 == 0b10100000): if (finish_mode_falg & 0b11110000 == 0b10100000):
@@ -942,12 +945,15 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
ret.append_data(1, voltage) ret.append_data(1, voltage)
ret.append_data(2, impedance) ret.append_data(2, impedance)
ret.append_data(3, cycle_number) ret.append_data(3, cycle_number)
ret.append_data(4, battery)
ret.append_data(5, elite_notify_times)
ret.append_data(6, mem_cnt)
# memoryboard information # memoryboard information
ret.append_data(4, ram_num) ret.append_data(7, ram_num)
ret.append_data(5, broken_flag) ret.append_data(8, broken_flag)
try: try:
ret.append_data(6, mem_wrong_information) ret.append_data(9, mem_wrong_information)
# print('append_data success, mem_wrong_information:', mem_wrong_information, hex(mem_wrong_information)) # print('append_data success, mem_wrong_information:', mem_wrong_information, hex(mem_wrong_information))
except: except:
print('append_data fail, mem_wrong_information:', mem_wrong_information, hex(mem_wrong_information)) print('append_data fail, mem_wrong_information:', mem_wrong_information, hex(mem_wrong_information))
@@ -1450,12 +1456,12 @@ class EISZeroOneDataDecoder(RecDataDecoder):
if len(data) < 18: if len(data) < 18:
return None return None
ch1 = struct.unpack('>i', data[1:5])[0] # unit: 1/1000 nA ch1 = struct.unpack('>i', data[1+3:5+3])[0] # unit: 1/1000 nA
ch2 = struct.unpack('>i', data[5:9])[0] # unit: mV ch2 = struct.unpack('>i', data[5+3:9+3])[0] # unit: mV
ch3 = struct.unpack('>i', data[9:13])[0] # unit: kOm ch3 = struct.unpack('>i', data[9+3:13+3])[0] # unit: kOm
time_stamp: float = struct.unpack('<I', data[13:17])[0] # unit: ms time_stamp: float = struct.unpack('<I', data[13+3:17+3])[0] # unit: ms
cycle_number = struct.unpack('>H', data[17:19])[0] cycle_number = struct.unpack('>H', data[17+3:19+3])[0]
d19 = data[19] d19 = data[19+3]
gain = (d19 & 0x0F) gain = (d19 & 0x0F)
finishMode = (d19 & 0x80) >> 7 finishMode = (d19 & 0x80) >> 7
+64 -41
View File
@@ -46,7 +46,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
self._elite_data_len = 40 self._elite_data_len = 40
self._mem_header_len = 3 self._mem_header_len = 3
self._mem_tailer_len = 8 self._mem_tailer_len = 6
self._single_data_len = self._elite_data_len + self._mem_header_len + self._mem_tailer_len self._single_data_len = self._elite_data_len + self._mem_header_len + self._mem_tailer_len
# buffer # buffer
@@ -167,10 +167,33 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
print("read red data times", self._read_red_times) print("read red data times", self._read_red_times)
return data return data
def _compare_green_data_addr_and_flag(self, data: Union[bytes, List[int]], device: int):
green_data_section1 = data[3:7]
green_data_section2 = data[7:11]
green_data_section3 = data[11:15]
green_data_section = []
if green_data_section1 == green_data_section2:
green_data_section = green_data_section1
elif(green_data_section2 == green_data_section3 or green_data_section1 == green_data_section3):
print("green data not equal: = ", data[3:15])
print("green data print:", data, device, datetime.now())
green_data_section = green_data_section3
else:
print("green data not equal: = ", data[3:15])
print("green data print:", data, device, datetime.now())
green_data_section = green_data_section3 # use last data
return green_data_section
def _print_ram_all_data(self): def _print_ram_all_data(self):
addr = 0 addr = 0
red_length = int(7000 / 2) red_length = int(7000 / 2)
tx_temp = [0] * red_length tx_temp = [0] * (red_length + 3)
while True: while True:
tx_temp[0] = MEM_INS_READ tx_temp[0] = MEM_INS_READ
@@ -216,7 +239,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1 self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
if (self._head_wrong_cnt[device] <= 5): # print 5 times if (self._head_wrong_cnt[device] <= 5): # print 5 times
print('data_first[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times') print('data_first[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times')
print(list(data[0:15])) print(list(data))
data[0:3] = [255, 255, 255] data[0:3] = [255, 255, 255]
# ---------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------
@@ -235,13 +258,13 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
# self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1 # self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
# if (self._head_wrong_cnt[device] < 10): # if (self._head_wrong_cnt[device] < 10):
# print('data_first[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times') # print('data_first[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times')
# print(list(data_first[0:7])) # print(list(data_first))
# if (data_second[0] != 255 or data_second[1] != 255 or data_second[2] != 255): # if (data_second[0] != 255 or data_second[1] != 255 or data_second[2] != 255):
# self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1 # self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
# if (self._head_wrong_cnt[device] < 10): # if (self._head_wrong_cnt[device] < 10):
# print('data_second[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times') # print('data_second[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times')
# print(list(data_second[0:7])) # print(list(data_second))
# if (data_first[3:] == data_second[3:]): # if (data_first[3:] == data_second[3:]):
# data = data_first # data = data_first
@@ -253,27 +276,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
# data = self.compare_green_data(data_first, data_second, data_third, len(tx_h)) # data = self.compare_green_data(data_first, data_second, data_third, len(tx_h))
# ---------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------
# debug use green_data_section = self._compare_green_data_addr_and_flag(data, device)
# green_data = []
# green_data = data
# print("_[Debug] @ spi green data = ", green_data)
green_data_section1 = data[3:7]
green_data_section2 = data[7:11]
green_data_section3 = data[11:15]
if green_data_section1 == green_data_section2:
green_data_section = green_data_section1
elif(green_data_section2 == green_data_section3 or green_data_section1 == green_data_section3):
print("green data not equal: = ", data[3:15])
print("green data print:", data, device, datetime.now())
green_data_section = green_data_section3
else:
print("green data not equal: = ", data[3:15])
print("green data print:", data, device, datetime.now())
green_data_section = green_data_section3 # use last data
length = (green_data_section[0] << 8) | green_data_section[1] length = (green_data_section[0] << 8) | green_data_section[1]
header = data[15] header = data[15]
@@ -284,8 +287,8 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
print("length < 12") print("length < 12")
print("green data print:", data, device, datetime.now()) print("green data print:", data, device, datetime.now())
if length == 0: # if length == 0:
self._print_ram_all_data() # self._print_ram_all_data()
return None return None
@@ -302,7 +305,7 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
if (header != 255): if (header != 255):
flag_print = True flag_print = True
print("green data: header is not 255: ", header) 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): if (elite_data_len != self._elite_data_len):
flag_print = True flag_print = True
@@ -311,18 +314,9 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
if (flag_print): if (flag_print):
print("green data print:", data, device, datetime.now(), '\n') print("green data print:", data, device, datetime.now(), '\n')
# neulive
# address += len(data) - 11
# tx_d = self._tx_buffer_data
# red_length = len(tx_d)
address = 12 address = 12
red_length = int(length / 2) red_length = int(length / 2)
tx_d = [0] * red_length tx_d = [0] * (red_length + 3)
# elite read len(_tx_buffer_data) byte
# address = 12
# tx_d = self._tx_buffer_data
while True: while True:
tx_d[0] = MEM_INS_READ tx_d[0] = MEM_INS_READ
@@ -377,11 +371,40 @@ class MultiExtMemSpiInterface(LowLevelHardwareInterface):
# * red data formate: # * red data formate:
# * ramHdr, ramHdr, ramHdr, (3B) # * ramHdr, ramHdr, ramHdr, (3B)
# * 255, #, data_length, (3B) # * 255, #, data_length, (3B)
# * data, (20B) # * data, (40B)
# * red_wrong, red_retry_cnt, green_wrong, green_retry_cnt, (4B) # * red_wrong, red_retry_cnt, green_wrong, green_retry_cnt, (4B)
# * 255, #, data_length, (3B) # * check_num, (1B)
# * */ # * */
# read again if check num is wrong
index = 0
check_number_print = False
for i in range(0, len(rx), self._single_data_len):
check_sum = sum(rx[i : i + self._single_data_len - 1]) & 0b11111111
# 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])
tx_d = [0] * (self._single_data_len + 3)
address = 12 + self._single_data_len * index
tx_d[0] = MEM_INS_READ
tx_d[1] = ((address >> 8) & 0xFF)
tx_d[2] = (address & 0xFF)
data = []
data = self._spi.send_byte(tx_d)
data[0:3] = [255, 255, 255]
rx[i : i + self._single_data_len] = data[3:]
print('check_sum wrong, read again:', 'check_sum =', check_sum, rx[i : i + self._single_data_len])
check_number_print = True
index = index + 1
if check_number_print:
print('check_sum wrong:', device, datetime.now())
for i in range(0, len(rx), self._single_data_len):
print(rx[i:i+self._single_data_len])
print()
# mark read # mark read
self._spi.send_byte(self.MEM_INS_MARKED1) self._spi.send_byte(self.MEM_INS_MARKED1)
self._spi.send_byte(self.MEM_INS_MARKED2) self._spi.send_byte(self.MEM_INS_MARKED2)
+5 -2
View File
@@ -9,7 +9,6 @@ class Action():
self._duration = action.get('duration', None) self._duration = action.get('duration', None)
self._goto = action.get('goto', None) self._goto = action.get('goto', None)
self._cycle = action.get('cycle', None) self._cycle = action.get('cycle', None)
self._instruction = None self._instruction = None
self.update_instruction() self.update_instruction()
@@ -19,12 +18,16 @@ class Action():
return self._type return self._type
def update_instruction(self): def update_instruction(self):
instruction_type = self._type
if instruction_type == 'stop':
instruction_type = 'interrupt'
self._instruction = { self._instruction = {
"device_instruction": { "device_instruction": {
"header": "call_instruction", "header": "call_instruction",
"device": self._target, "device": self._target,
"arguments": { "arguments": {
"instruction": self._type, "instruction": instruction_type,
} }
}, },
"device_parameter": { "device_parameter": {
+11 -3
View File
@@ -3,7 +3,6 @@ from time import time
class Condition(): class Condition():
def __init__(self, id, condition): def __init__(self, id, condition):
print('condition', id, condition)
self._id = id self._id = id
self._type = condition['type'] self._type = condition['type']
self._comparsion = condition['comparsion'] self._comparsion = condition['comparsion']
@@ -12,12 +11,15 @@ class Condition():
@property @property
def id(self): def id(self):
return self._id return self._id
@property @property
def type(self): def type(self):
return self._type return self._type
@property @property
def comparsion(self): def comparsion(self):
return self._comparsion return self._comparsion
@property @property
def value(self): def value(self):
return self._value return self._value
@@ -38,11 +40,11 @@ class Condition():
"smaller": lambda a, b: a < b, "smaller": lambda a, b: a < b,
} }
# print('x','y',x, y,type(x),type(y))
return cases[operator](x, y) return cases[operator](x, y)
def match_or_not(self, **kwargs): 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): def absolute_time(self, **kwargs):
now = time() now = time()
@@ -51,7 +53,13 @@ class Condition():
return self.compareWith(self.comparsion, int(now), int(time_condition)) return self.compareWith(self.comparsion, int(now), int(time_condition))
def relative_time(self, **kwargs): 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() 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): def device(self, **kwargs):
print('device') print('device')
+20 -16
View File
@@ -8,6 +8,7 @@ from datetime import datetime
from collections import deque from collections import deque
from biopro.device.manager import DeviceManager from biopro.device.manager import DeviceManager
from biopro.text import * from biopro.text import *
from copy import copy
class Project(threading.Thread): class Project(threading.Thread):
def __init__(self, project, device_manager: DeviceManager, mqttThread = None, name="project"): def __init__(self, project, device_manager: DeviceManager, mqttThread = None, name="project"):
@@ -19,9 +20,8 @@ class Project(threading.Thread):
self._start_time = None self._start_time = None
self._task_manager = TaskManager(self._project['taskList']) self._task_manager = TaskManager(self._project['taskList'])
self._stop = False
self._start_time = None
@property @property
def desc(self) -> str: def desc(self) -> str:
return self._project['desc'] return self._project['desc']
@@ -45,34 +45,38 @@ class Project(threading.Thread):
def run(self): def run(self):
self._start_time = time.time() self._start_time = time.time()
while True: while not self._stop:
# current task # 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>, ...]
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>, ...], ...]
match_action_list = task.get_match_action_list(match_condition_list) match_action_list = task.get_match_action_list(match_condition_list)
for action_list in match_action_list: for action_list in match_action_list:
for action in action_list: for action in action_list:
if action.type == 'start': if action.type == 'start':
task.reset_start_time()
self._task_manager.set_current_task(task) self._task_manager.set_current_task(task)
task.do_action(action) task.do_action(action)
now = time.time()
while len(task.instruction_list) > 0: while len(task.instruction_list) > 0:
instruction = task.instruction_list.pop(0) instruction = task.instruction_list.pop(0)
if instruction.get('device', None) != None: if instruction.get('device', None) != None:
device = self._device_manager.get_device(self.device[instruction['device']]['connectDevice']['device_address']) device = self._device_manager.get_device(self.device[instruction['device']]['connectDevice']['device_address'])
if device is None: if device is None:
raise RuntimeError(DEVICE_NOT_FOUND, device) raise RuntimeError(DEVICE_NOT_FOUND, device)
# print(instruction['header'], *instruction['arguments'].values())
getattr(device, instruction['header'])(*instruction['arguments'].values())
getattr(device, instruction['header'])(*instruction['arguments'].values())
delay_time += (time.time() - now)
time.sleep(self._time_interval) time.sleep(self._time_interval)
def stop(self): def stop(self):
return self._stop = True
def close(self): def close(self):
return self._stop = True
+9 -8
View File
@@ -1,3 +1,4 @@
from typing import List
from .condition import Condition from .condition import Condition
from .action import Action from .action import Action
from time import time from time import time
@@ -6,8 +7,8 @@ class Task:
def __init__(self, task): def __init__(self, task):
self._task = task self._task = task
self._condition_list = [] self._condition_list:List[Condition] = []
self._action_list = [] self._action_list:List[Action] = []
self._start_time = time() self._start_time = time()
self._idle_time = [] self._idle_time = []
@@ -16,7 +17,6 @@ class Task:
self._last_time = None self._last_time = None
self._instruction_list = [] self._instruction_list = []
self.setup() self.setup()
def setup(self) -> None: def setup(self) -> None:
@@ -105,6 +105,9 @@ class Task:
@property @property
def next(self) -> str: def next(self) -> str:
return self._task['next'] return self._task['next']
def reset_start_time(self):
self._start_time = time()
def get_parameter_set_by_device(self, device): def get_parameter_set_by_device(self, device):
return [parameter_set for parameter_set in self.parameter_set.values() if device == parameter_set['target']] 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) 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): 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(): for instruction in action.get_instruction_list():
self._instruction_list.append(instruction) self._instruction_list.append(instruction)
@@ -164,5 +164,6 @@ class Task:
} }
return statuses[status] return statuses[status]
def check_condition(self, type): def check_condition(self, **kwargs):
return [condition for condition in self._condition_list if condition.match_or_not()] kwargs['task_start_time'] = self._start_time
return [condition for condition in self._condition_list if condition.match_or_not(**kwargs)]
+2 -2
View File
@@ -1,5 +1,5 @@
from json import loads as json_parse, dumps as _json_stringify 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 from xml.dom.expatbuilder import parseString
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
from biopro.text import * from biopro.text import *
@@ -29,7 +29,7 @@ class TaskManager():
def get_task(self, task_id): def get_task(self, task_id):
return self._task_list[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 return self._need_to_check_task_list
def get_current_task(self) -> Task: def get_current_task(self) -> Task:
+1 -1
View File
@@ -1315,7 +1315,7 @@ class RecordingFileWriter:
self._time_now = int(t) self._time_now = int(t)
return return
@calculate_time(1) # @calculate_time(1)
def write(self, data: Union[bytes, RecordingData, List[bytes], List[RecordingData]], mqtt_thread) -> int: def write(self, data: Union[bytes, RecordingData, List[bytes], List[RecordingData]], mqtt_thread) -> int:
# check size # check size
ths = self.splitting_threshold_size ths = self.splitting_threshold_size
+3 -17
View File
@@ -9,23 +9,9 @@ _jwt = None
def controller_device_id() -> str: def controller_device_id() -> str:
### device ID ### device ID
return 'b8:27:eb:52:ea:97' f = open("/sys/class/net/eth0/address", "r")
ret = None mac = f.read()[:-1]
try: return mac
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
def get_api_jwt() -> str: def get_api_jwt() -> str:
global _jwt global _jwt
+3 -3
View File
@@ -160,7 +160,7 @@ class DataBaseProcess(Process):
getattr(self, do)(*args) getattr(self, do)(*args)
return None return None
@calculate_time(1) # @calculate_time(1)
def data_meta_write(self, _data: JSON_OBJECT, device_id, _uuid = None, _id = None): def data_meta_write(self, _data: JSON_OBJECT, device_id, _uuid = None, _id = None):
if _id > 0: if _id > 0:
sql_str = 'UPDATE "public"."recording_data_metas" SET ' sql_str = 'UPDATE "public"."recording_data_metas" SET '
@@ -376,7 +376,7 @@ class DataBaseProcess(Process):
print('recording error', e) print('recording error', e)
return None return None
@calculate_time(1) # @calculate_time(1)
def data_raw_recording_new(self, _id_dict, _channel_list, _data_dict, _end_time_dict, _size_dict): def data_raw_recording_new(self, _id_dict, _channel_list, _data_dict, _end_time_dict, _size_dict):
try: try:
para_list = [] para_list = []
@@ -446,7 +446,7 @@ class DataBaseProcess(Process):
return True return True
@calculate_time(1) # @calculate_time(1)
def data_mini_recording_new(self, _id_dict, _channel_list, _data_mean_dict): def data_mini_recording_new(self, _id_dict, _channel_list, _data_mean_dict):
try: try:
para_list = [] para_list = []
+85 -77
View File
@@ -98,6 +98,11 @@ class RecordingProcess(Process):
self._last_cnt = [-1, -1, -1, -1, -1, -1, -1, -1] self._last_cnt = [-1, -1, -1, -1, -1, -1, -1, -1]
self._wrong_cnt = 0 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: def ensure_data_format(self) -> DataDecodeFormat:
if isinstance(self._data_format, (str, bytes)): if isinstance(self._data_format, (str, bytes)):
@@ -160,11 +165,11 @@ class RecordingProcess(Process):
""" """
q = None q = None
try: try:
now = time() # now = time()
q = self._queue_rec.get() q = self._queue_rec.get()
get_queue_time_cost = time() - now # get_queue_time_cost = time() - now
if get_queue_time_cost > 1: # if get_queue_time_cost > 2:
print('get queue cost time', get_queue_time_cost) # print('get queue cost time', get_queue_time_cost)
except: except:
return False return False
finally: finally:
@@ -190,7 +195,7 @@ class RecordingProcess(Process):
current_time = time() current_time = time()
if self._timer is not None: if self._timer is not None:
if current_time - self._timer > 1.5: if current_time - self._timer > 1.5:
print('time, sync_data routine_time', current_time, current_time - self._timer) print('time, sync_data routine_time', 'device:', self._device, datetime.now(), current_time, current_time - self._timer)
self._isTimeOut = True self._isTimeOut = True
self._timer = current_time self._timer = current_time
@@ -290,6 +295,7 @@ class RecordingProcess(Process):
self._last_cnt[7] = head_counter - 1 self._last_cnt[7] = head_counter - 1
last_data_cnt = self._last_cnt[7] last_data_cnt = self._last_cnt[7]
# dont save to section when head or id is wrong
if (head != 255 or device_id != device): if (head != 255 or device_id != device):
save = False save = False
last_data_cnt = last_data_cnt + 1 last_data_cnt = last_data_cnt + 1
@@ -332,60 +338,57 @@ class RecordingProcess(Process):
return save return save
def _check_jump_ram(self, raw_data: bytes, colum_now: int, colum_total: int, save: bool, device: int): def _check_jump_ram(self, raw_data: bytes, colum_now: int, colum_total: int, save: bool, device: int, data_len: int):
i = colum_now col = colum_now
save = False
if (raw_data[i][0] == 255 and raw_data[i][3] == device): if raw_data[col][0] != 255 or raw_data[col][3] != device:
if colum_total < 3: return save
print('this ram data < 3 records, need to fix, colum_total = ', colum_total)
if colum_total == 1:
print('raw_data[0]', raw_data[0])
elif colum_total == 2: if colum_total == 1:
print('raw_data[0]', raw_data[0]) print('this ram data < 3 records, colum_total = ', colum_total)
print('raw_data[1]', raw_data[1]) 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 elif colum_total >= 3:
(raw_data[i][1] == 255 and raw_data[i + 1][1] == 0 and raw_data[i + 2][1] == 1) or 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[i][1] == 254 and raw_data[i + 1][1] == 255 and raw_data[i + 2][1] == 0)): (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 if save == True:
(raw_data[i][1] == 254 and raw_data[i + 1][1] == 255 and raw_data[i + 2][1] == 0)): self._skip_ram_cnt += 1
print('cnt = [254, 255, 0] or [255, 0, 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 if (device == 4):
self._skip_ram_cnt += 1 self._last_cnt[4] = last_data_cnt
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): elif (device == 5):
self._last_cnt[4] = last_data_cnt self._last_cnt[5] = last_data_cnt
elif (device == 5): elif (device == 6):
self._last_cnt[5] = last_data_cnt self._last_cnt[6] = last_data_cnt
elif (device == 6): elif (device == 7):
self._last_cnt[6] = last_data_cnt self._last_cnt[7] = last_data_cnt
elif (device == 7):
self._last_cnt[7] = last_data_cnt
return save return save
def _neu_foreach_data_section(self, data: bytes): def _neu_foreach_data_section(self, data: bytes):
@@ -500,54 +503,59 @@ class RecordingProcess(Process):
:return: :return:
""" """
raw_data = [] raw_data = []
index = 0 records = 0
elite_data_len = 40
mem_header_len = 3
mem_tailer_len = 8
single_data_len = elite_data_len + mem_header_len + mem_tailer_len
device = self._device
print_flag = False 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 # packet section data use two microarray
for i in range(0, len(data), single_data_len): for i in range(0, len(data), single_data_len):
index = index + 1 records = records + 1
for j in range(index, index + 1): raw_data.append(data[i : i + single_data_len])
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 # check cnt
for i in range(index): for i in range(records):
# if jump cnt, don't save data # if jump cnt, don't save data
save = self._check_cnt(raw_data[i], device) save = self._check_cnt(raw_data[i], device)
# # if jump Ram, also can handle data # # if jump Ram, also can handle data
if save == False: 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): if (save == True):
section = raw_data[i] section = raw_data[i]
if (section[0 : mem_header_len] == section[single_data_len - 3: single_data_len]): check_sum = sum(section[0 : single_data_len - 1]) & 0b11111111
section = section + b'\x00'
if (check_sum != section[single_data_len - 1]):
else: print('check number not match,',
section = section + b'\x01' list(section[0 : mem_header_len]), section[-1], '!=', check_sum, 'device:', device, ',', datetime.now())
print('header != tailer,',
list(section[0 : mem_header_len]),
list(section[single_data_len - 3: single_data_len]),
'device:', device, ',', datetime.now())
if (i-1 >= 0): if (i-1 >= 0):
print('header != tailer', list(raw_data[i-1]), 'raw:', i-1) print('check number not match', list(raw_data[i-1]), 'raw:', i-1)
print('header != tailer', list(section), 'raw:', i)
if (i+1 <= index): print('check number not match', list(raw_data[i]), 'raw:', i)
print('header != tailer', list(raw_data[i+1]), 'raw:', i+1, '\n')
if (i+1 <= records):
section = section[3:] print('check number not match', list(raw_data[i+1]), 'raw:', i+1, '\n')
section = section + b'\x01'
print('delete data:', list(raw_data[i][0:3]), 'raw:', i, '\n')
continue
else:
section = section + b'\x00'
# section = section[3:]
yield None, section yield None, section
else: else:
print_flag = True print_flag = True
print('delete data:', list(raw_data[i][0:3]), 'raw:', i+1, '\n') print('delete data:', list(raw_data[i][0:3]), 'raw:', i, '\n')
# if print_flag: # if print_flag:
# print('delete data context:') # print('delete data context:')