update
This commit is contained in:
@@ -1,4 +1,10 @@
|
|||||||
'''
|
'''
|
||||||
|
_ _ ____ __ __
|
||||||
|
| \ | | _ \| \/ |
|
||||||
|
| \| | |_) | |\/| |
|
||||||
|
| |\ | __/| | | |
|
||||||
|
|_| \_|_| |_| |_|
|
||||||
|
|
||||||
Script to get NPM values
|
Script to get NPM values
|
||||||
need parameter: port
|
need parameter: port
|
||||||
/usr/bin/python3 /var/www/nebuleair_pro_4g/NPM/get_data.py ttyAMA5
|
/usr/bin/python3 /var/www/nebuleair_pro_4g/NPM/get_data.py ttyAMA5
|
||||||
|
|||||||
52
NPM/get_data_temp_hum.py
Normal file
52
NPM/get_data_temp_hum.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
'''
|
||||||
|
_ _ ____ __ __
|
||||||
|
| \ | | _ \| \/ |
|
||||||
|
| \| | |_) | |\/| |
|
||||||
|
| |\ | __/| | | |
|
||||||
|
|_| \_|_| |_| |_|
|
||||||
|
|
||||||
|
Script to get NPM values: ONLY temp and hum
|
||||||
|
need parameter: port
|
||||||
|
/usr/bin/python3 /var/www/nebuleair_pro_4g/NPM/get_data_temp_hum.py ttyAMA5
|
||||||
|
'''
|
||||||
|
|
||||||
|
import serial
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
parameter = sys.argv[1:] # Exclude the script name
|
||||||
|
#print("Parameters received:")
|
||||||
|
port='/dev/'+parameter[0]
|
||||||
|
|
||||||
|
ser = serial.Serial(
|
||||||
|
port=port,
|
||||||
|
baudrate=115200,
|
||||||
|
parity=serial.PARITY_EVEN,
|
||||||
|
stopbits=serial.STOPBITS_ONE,
|
||||||
|
bytesize=serial.EIGHTBITS,
|
||||||
|
timeout = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
ser.write(b'\x81\x14\x6B') # Temp and humidity command
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
byte_data_temp_hum = ser.readline()
|
||||||
|
# Decode temperature and humidity values
|
||||||
|
temperature = int.from_bytes(byte_data_temp_hum[3:5], byteorder='big') / 100.0
|
||||||
|
humidity = int.from_bytes(byte_data_temp_hum[5:7], byteorder='big') / 100.0
|
||||||
|
|
||||||
|
print(f"temp: {temperature}")
|
||||||
|
print(f"hum: {humidity}")
|
||||||
|
break
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("User interrupt encountered. Exiting...")
|
||||||
|
time.sleep(3)
|
||||||
|
exit()
|
||||||
|
except:
|
||||||
|
# for all other kinds of error, but not specifying which one
|
||||||
|
print("Unknown error...")
|
||||||
|
time.sleep(3)
|
||||||
|
exit()
|
||||||
|
|
||||||
@@ -48,9 +48,11 @@ ser = serial.Serial(
|
|||||||
timeout = 0.5
|
timeout = 0.5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 1️⃣ Request PM Data (PM1, PM2.5, PM10)
|
||||||
|
|
||||||
#ser.write(b'\x81\x11\x6E') #data10s
|
#ser.write(b'\x81\x11\x6E') #data10s
|
||||||
ser.write(b'\x81\x12\x6D') #data60s
|
ser.write(b'\x81\x12\x6D') #data60s
|
||||||
|
time.sleep(0.5) # Small delay to allow the sensor to process the request
|
||||||
|
|
||||||
#print("Start get_data_v2.py script")
|
#print("Start get_data_v2.py script")
|
||||||
byte_data = ser.readline()
|
byte_data = ser.readline()
|
||||||
@@ -61,8 +63,9 @@ PM1 = int.from_bytes(byte_data[9:11], byteorder='big')/10
|
|||||||
PM25 = int.from_bytes(byte_data[11:13], byteorder='big')/10
|
PM25 = int.from_bytes(byte_data[11:13], byteorder='big')/10
|
||||||
PM10 = int.from_bytes(byte_data[13:15], byteorder='big')/10
|
PM10 = int.from_bytes(byte_data[13:15], byteorder='big')/10
|
||||||
|
|
||||||
# Write command to retrieve temperature and humidity data
|
# 2️⃣ Request Temperature & Humidity
|
||||||
ser.write(b'\x81\x14\x6B') # Temp and humidity command
|
ser.write(b'\x81\x14\x6B') # Temp and humidity command
|
||||||
|
time.sleep(0.5) # Small delay to allow the sensor to process the request
|
||||||
byte_data_temp_hum = ser.readline()
|
byte_data_temp_hum = ser.readline()
|
||||||
|
|
||||||
# Decode temperature and humidity values
|
# Decode temperature and humidity values
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
"loop/SARA_send_data_v2.py": true,
|
"loop/SARA_send_data_v2.py": true,
|
||||||
"RTC/save_to_db.py": true,
|
"RTC/save_to_db.py": true,
|
||||||
"BME280/get_data_v2.py": true,
|
"BME280/get_data_v2.py": true,
|
||||||
|
"envea/read_value_v2.py": true,
|
||||||
"deviceID": "XXXX",
|
"deviceID": "XXXX",
|
||||||
"deviceName": "NebuleAir-proXXX",
|
"deviceName": "NebuleAir-proXXX",
|
||||||
"SaraR4_baudrate": 115200,
|
"SaraR4_baudrate": 115200,
|
||||||
@@ -15,7 +16,6 @@
|
|||||||
"NextPM_ports": [
|
"NextPM_ports": [
|
||||||
"ttyAMA5"
|
"ttyAMA5"
|
||||||
],
|
],
|
||||||
"NextPM_5channels": false,
|
|
||||||
"i2C_sound": false,
|
"i2C_sound": false,
|
||||||
"i2c_BME": false,
|
"i2c_BME": false,
|
||||||
"i2c_RTC": false,
|
"i2c_RTC": false,
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
"""
|
"""
|
||||||
|
_____ _ ___ _______ _
|
||||||
|
| ____| \ | \ \ / / ____| / \
|
||||||
|
| _| | \| |\ \ / /| _| / _ \
|
||||||
|
| |___| |\ | \ V / | |___ / ___ \
|
||||||
|
|_____|_| \_| \_/ |_____/_/ \_\
|
||||||
|
|
||||||
Main loop to gather data from envea Sensors
|
Main loop to gather data from envea Sensors
|
||||||
Need to run every minutes
|
Need to run every minutes
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
"""
|
"""
|
||||||
|
_____ _ ___ _______ _
|
||||||
|
| ____| \ | \ \ / / ____| / \
|
||||||
|
| _| | \| |\ \ / /| _| / _ \
|
||||||
|
| |___| |\ | \ V / | |___ / ___ \
|
||||||
|
|_____|_| \_| \_/ |_____/_/ \_\
|
||||||
|
|
||||||
Main loop to gather data from Envea Sensors
|
Main loop to gather data from Envea Sensors
|
||||||
|
|
||||||
Runs every minute via cron:
|
Runs every minute via cron:
|
||||||
|
|||||||
121
envea/read_value_v2.py
Normal file
121
envea/read_value_v2.py
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
"""
|
||||||
|
_____ _ ___ _______ _
|
||||||
|
| ____| \ | \ \ / / ____| / \
|
||||||
|
| _| | \| |\ \ / /| _| / _ \
|
||||||
|
| |___| |\ | \ V / | |___ / ___ \
|
||||||
|
|_____|_| \_| \_/ |_____/_/ \_\
|
||||||
|
|
||||||
|
Gather data from envea Sensors and store them to the SQlite table
|
||||||
|
Use the RTC time for the timestamp
|
||||||
|
|
||||||
|
/usr/bin/python3 /var/www/nebuleair_pro_4g/envea/read_value_v2.py
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import serial
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
import sqlite3
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# Connect to the SQLite database
|
||||||
|
conn = sqlite3.connect("/var/www/nebuleair_pro_4g/sqlite/sensors.db")
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
#GET RTC TIME from SQlite
|
||||||
|
cursor.execute("SELECT * FROM timestamp_table LIMIT 1")
|
||||||
|
row = cursor.fetchone() # Get the first (and only) row
|
||||||
|
rtc_time_str = row[1] # '2025-02-07 12:30:45'
|
||||||
|
|
||||||
|
# Function to load config data
|
||||||
|
def load_config(config_file):
|
||||||
|
try:
|
||||||
|
with open(config_file, 'r') as file:
|
||||||
|
config_data = json.load(file)
|
||||||
|
return config_data
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error loading config file: {e}")
|
||||||
|
return {}
|
||||||
|
|
||||||
|
# Define the config file path
|
||||||
|
config_file = '/var/www/nebuleair_pro_4g/config.json'
|
||||||
|
|
||||||
|
# Load the configuration data
|
||||||
|
config = load_config(config_file)
|
||||||
|
|
||||||
|
# Initialize sensors and serial connections
|
||||||
|
envea_sondes = config.get('envea_sondes', [])
|
||||||
|
connected_envea_sondes = [sonde for sonde in envea_sondes if sonde.get('connected', False)]
|
||||||
|
serial_connections = {}
|
||||||
|
|
||||||
|
if connected_envea_sondes:
|
||||||
|
for device in connected_envea_sondes:
|
||||||
|
port = device.get('port', 'Unknown')
|
||||||
|
name = device.get('name', 'Unknown')
|
||||||
|
try:
|
||||||
|
serial_connections[name] = serial.Serial(
|
||||||
|
port=f'/dev/{port}',
|
||||||
|
baudrate=9600,
|
||||||
|
parity=serial.PARITY_NONE,
|
||||||
|
stopbits=serial.STOPBITS_ONE,
|
||||||
|
bytesize=serial.EIGHTBITS,
|
||||||
|
timeout=1
|
||||||
|
)
|
||||||
|
except serial.SerialException as e:
|
||||||
|
print(f"Error opening serial port for {name}: {e}")
|
||||||
|
|
||||||
|
global data_h2s, data_no2, data_o3
|
||||||
|
data_h2s = 0
|
||||||
|
data_no2 = 0
|
||||||
|
data_o3 = 0
|
||||||
|
data_co = 0
|
||||||
|
data_nh3 = 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
if connected_envea_sondes:
|
||||||
|
for device in connected_envea_sondes:
|
||||||
|
name = device.get('name', 'Unknown')
|
||||||
|
coefficient = device.get('coefficient', 1)
|
||||||
|
if name in serial_connections:
|
||||||
|
serial_connection = serial_connections[name]
|
||||||
|
try:
|
||||||
|
serial_connection.write(
|
||||||
|
b"\xFF\x02\x13\x30\x01\x02\x03\x04\x05\x06\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x12\xAF\x88\x03"
|
||||||
|
)
|
||||||
|
data_envea = serial_connection.readline()
|
||||||
|
if len(data_envea) >= 20:
|
||||||
|
byte_20 = data_envea[19] * coefficient
|
||||||
|
if name == "h2s":
|
||||||
|
data_h2s = byte_20
|
||||||
|
elif name == "no2":
|
||||||
|
data_no2 = byte_20
|
||||||
|
elif name == "o3":
|
||||||
|
data_o3 = byte_20
|
||||||
|
except serial.SerialException as e:
|
||||||
|
print(f"Error communicating with {name}: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
print("An error occurred while gathering data:", e)
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
|
||||||
|
#print(f" H2S: {data_h2s}, NO2: {data_no2}, O3: {data_o3}")
|
||||||
|
|
||||||
|
#save to sqlite database
|
||||||
|
try:
|
||||||
|
cursor.execute('''
|
||||||
|
INSERT INTO data_envea (timestamp,h2s, no2, o3, co, nh3) VALUES (?,?,?,?,?,?)'''
|
||||||
|
, (rtc_time_str,data_h2s,data_no2,data_o3,data_co,data_nh3 ))
|
||||||
|
|
||||||
|
# Commit and close the connection
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
#print("Sensor data saved successfully!")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Database error: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
@@ -67,11 +67,10 @@
|
|||||||
<option value="30">30 dernières</option>
|
<option value="30">30 dernières</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<button class="btn btn-primary" onclick="get_data_sqlite('data_NPM',getSelectedLimit(),false)">Mesures PM</button>
|
<button class="btn btn-primary" onclick="get_data_sqlite('data_NPM',getSelectedLimit(),false)">Mesures PM</button>
|
||||||
<button class="btn btn-primary" onclick="get_data_sqlite('data_BME280',getSelectedLimit(),false)">Mesures Temp/Hum</button>
|
<button class="btn btn-primary" onclick="get_data_sqlite('data_BME280',getSelectedLimit(),false)">Mesures Temp/Hum</button>
|
||||||
<button class="btn btn-primary" onclick="get_data_sqlite('data_NPM_5channels',getSelectedLimit(),false)">Mesures PM (5 canaux)</button>
|
<button class="btn btn-primary" onclick="get_data_sqlite('data_NPM_5channels',getSelectedLimit(),false)">Mesures PM (5 canaux)</button>
|
||||||
|
<button class="btn btn-primary" onclick="get_data_sqlite('data_envea',getSelectedLimit(),false)">Sonde Cairsens</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -93,6 +92,7 @@
|
|||||||
<button class="btn btn-primary" onclick="get_data_sqlite('data_NPM',10,true, getStartDate(), getEndDate())">Mesures PM</button>
|
<button class="btn btn-primary" onclick="get_data_sqlite('data_NPM',10,true, getStartDate(), getEndDate())">Mesures PM</button>
|
||||||
<button class="btn btn-primary" onclick="get_data_sqlite('data_BME280',10,true, getStartDate(), getEndDate())">Mesures Temp/Hum</button>
|
<button class="btn btn-primary" onclick="get_data_sqlite('data_BME280',10,true, getStartDate(), getEndDate())">Mesures Temp/Hum</button>
|
||||||
<button class="btn btn-primary" onclick="get_data_sqlite('data_NPM_5channels',10,true, getStartDate(), getEndDate())">Mesures PM (5 canaux)</button>
|
<button class="btn btn-primary" onclick="get_data_sqlite('data_NPM_5channels',10,true, getStartDate(), getEndDate())">Mesures PM (5 canaux)</button>
|
||||||
|
<button class="btn btn-primary" onclick="get_data_sqlite('data_envea',10,true, getStartDate(), getEndDate())">Sonde Cairsens</button>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -244,6 +244,16 @@ function get_data_sqlite(table, limit, download , startDate = "", endDate = "")
|
|||||||
<th>PM_ch4 (nb/L)</th>
|
<th>PM_ch4 (nb/L)</th>
|
||||||
<th>PM_ch5 (nb/L)</th>
|
<th>PM_ch5 (nb/L)</th>
|
||||||
|
|
||||||
|
`;
|
||||||
|
}else if (table === "data_envea") {
|
||||||
|
tableHTML += `
|
||||||
|
<th>Timestamp</th>
|
||||||
|
<th>NO2</th>
|
||||||
|
<th>H2S</th>
|
||||||
|
<th>NH3</th>
|
||||||
|
<th>CO</th>
|
||||||
|
<th>O3</th>
|
||||||
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,6 +290,16 @@ function get_data_sqlite(table, limit, download , startDate = "", endDate = "")
|
|||||||
<td>${columns[4]}</td>
|
<td>${columns[4]}</td>
|
||||||
<td>${columns[5]}</td>
|
<td>${columns[5]}</td>
|
||||||
|
|
||||||
|
`;
|
||||||
|
} else if (table === "data_envea") {
|
||||||
|
tableHTML += `
|
||||||
|
<td>${columns[0]}</td>
|
||||||
|
<td>${columns[1]}</td>
|
||||||
|
<td>${columns[2]}</td>
|
||||||
|
<td>${columns[3]}</td>
|
||||||
|
<td>${columns[4]}</td>
|
||||||
|
<td>${columns[5]}</td>
|
||||||
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ function getModem_busy_status() {
|
|||||||
if (response.running) {
|
if (response.running) {
|
||||||
// Script is running → Show the Bootstrap spinner
|
// Script is running → Show the Bootstrap spinner
|
||||||
script_is_running.innerHTML = `
|
script_is_running.innerHTML = `
|
||||||
<div class="spinner-border text-danger" role="status">
|
<div class="spinner-border spinner-border-sm text-danger" role="status">
|
||||||
<span class="visually-hidden">Modem is busy...</span>
|
<span class="visually-hidden">Modem is busy...</span>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ CSV PAYLOAD (AirCarto Servers)
|
|||||||
8 -> min_noise
|
8 -> min_noise
|
||||||
9 -> envea_no2
|
9 -> envea_no2
|
||||||
10 -> envea_h2s
|
10 -> envea_h2s
|
||||||
11 -> envea_o3
|
11 -> envea_nh3
|
||||||
12 -> 4G signal quality,
|
12 -> 4G signal quality,
|
||||||
13 -> PM 0.2μm to 0.5μm quantity (Nb/L)
|
13 -> PM 0.2μm to 0.5μm quantity (Nb/L)
|
||||||
14 -> PM 0.5μm to 1.0μm quantity (Nb/L)
|
14 -> PM 0.5μm to 1.0μm quantity (Nb/L)
|
||||||
@@ -202,10 +202,13 @@ config_file = '/var/www/nebuleair_pro_4g/config.json'
|
|||||||
config = load_config(config_file)
|
config = load_config(config_file)
|
||||||
baudrate = config.get('SaraR4_baudrate', 115200) #baudrate du sara R4
|
baudrate = config.get('SaraR4_baudrate', 115200) #baudrate du sara R4
|
||||||
device_id = config.get('deviceID', '').upper() #device ID en maj
|
device_id = config.get('deviceID', '').upper() #device ID en maj
|
||||||
need_to_log = config.get('loop_log', False) #inscription des logs
|
bme_280_config = config.get('BME280/get_data_v2.py', False) #présence du BME280
|
||||||
|
envea_cairsens= config.get('envea/read_value_v2.py', False)
|
||||||
send_aircarto = config.get('send_aircarto', True) #envoi sur AirCarto (data.nebuleair.fr)
|
send_aircarto = config.get('send_aircarto', True) #envoi sur AirCarto (data.nebuleair.fr)
|
||||||
send_uSpot = config.get('send_uSpot', False) #envoi sur MicroSpot ()
|
send_uSpot = config.get('send_uSpot', False) #envoi sur MicroSpot ()
|
||||||
selected_networkID = config.get('SARA_R4_neworkID', '')
|
selected_networkID = config.get('SARA_R4_neworkID', '')
|
||||||
|
npm_5channel = config.get('NPM/get_data_modbus.py', False) #5 canaux du NPM
|
||||||
|
|
||||||
modem_config_mode = config.get('modem_config_mode', False) #modem 4G en mode configuration
|
modem_config_mode = config.get('modem_config_mode', False) #modem 4G en mode configuration
|
||||||
|
|
||||||
#update device id in the payload json
|
#update device id in the payload json
|
||||||
@@ -279,8 +282,9 @@ try:
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
print('<h3>START LOOP</h3>')
|
print('<h3>START LOOP</h3>')
|
||||||
print("Getting NPM values")
|
|
||||||
# Retrieve the last sensor readings
|
#NEXTPM
|
||||||
|
print("➡️Getting NPM values")
|
||||||
cursor.execute("SELECT * FROM data_NPM ORDER BY timestamp DESC LIMIT 1")
|
cursor.execute("SELECT * FROM data_NPM ORDER BY timestamp DESC LIMIT 1")
|
||||||
last_row = cursor.fetchone()
|
last_row = cursor.fetchone()
|
||||||
# Display the result
|
# Display the result
|
||||||
@@ -313,6 +317,74 @@ try:
|
|||||||
else:
|
else:
|
||||||
print("No data available in the database.")
|
print("No data available in the database.")
|
||||||
|
|
||||||
|
#NextPM 5 channels
|
||||||
|
if npm_5channel:
|
||||||
|
print("➡️Getting NextPM 5 channels values")
|
||||||
|
cursor.execute("SELECT * FROM data_NPM_5channels ORDER BY timestamp DESC LIMIT 6")
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
# Exclude the timestamp column (assuming first column is timestamp)
|
||||||
|
data_values = [row[1:] for row in rows] # Exclude timestamp
|
||||||
|
# Compute column-wise average
|
||||||
|
num_columns = len(data_values[0])
|
||||||
|
averages = [round(sum(col) / len(col)) for col in zip(*data_values)]
|
||||||
|
|
||||||
|
# Store averages in specific indices
|
||||||
|
payload_csv[13] = averages[0] # Channel 1
|
||||||
|
payload_csv[14] = averages[1] # Channel 2
|
||||||
|
payload_csv[15] = averages[2] # Channel 3
|
||||||
|
payload_csv[16] = averages[3] # Channel 4
|
||||||
|
payload_csv[17] = averages[4] # Channel 5
|
||||||
|
|
||||||
|
#BME280
|
||||||
|
if bme_280_config:
|
||||||
|
print("➡️Getting BME280 values")
|
||||||
|
cursor.execute("SELECT * FROM data_BME280 ORDER BY timestamp DESC LIMIT 1")
|
||||||
|
last_row = cursor.fetchone()
|
||||||
|
if last_row:
|
||||||
|
print("SQLite DB last available row:", last_row)
|
||||||
|
BME280_temperature = last_row[1]
|
||||||
|
BME280_humidity = last_row[2]
|
||||||
|
BME280_pressure = last_row[3]
|
||||||
|
|
||||||
|
#Add data to payload CSV
|
||||||
|
payload_csv[3] = BME280_temperature
|
||||||
|
payload_csv[4] = BME280_humidity
|
||||||
|
payload_csv[5] = BME280_pressure
|
||||||
|
|
||||||
|
#Add data to payload JSON
|
||||||
|
payload_json["sensordatavalues"].append({"value_type": "BME280_temperature", "value": str(BME280_temperature)})
|
||||||
|
payload_json["sensordatavalues"].append({"value_type": "BME280_humidity", "value": str(BME280_humidity)})
|
||||||
|
payload_json["sensordatavalues"].append({"value_type": "BME280_pressure", "value": str(BME280_pressure)})
|
||||||
|
else:
|
||||||
|
print("No data available in the database.")
|
||||||
|
|
||||||
|
#envea
|
||||||
|
if envea_cairsens:
|
||||||
|
print("➡️Getting envea cairsens values")
|
||||||
|
cursor.execute("SELECT * FROM data_envea ORDER BY timestamp DESC LIMIT 6")
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
# Exclude the timestamp column (assuming first column is timestamp)
|
||||||
|
data_values = [row[1:] for row in rows] # Exclude timestamp
|
||||||
|
# Compute column-wise average, ignoring 0 values
|
||||||
|
averages = []
|
||||||
|
for col in zip(*data_values): # Iterate column-wise
|
||||||
|
filtered_values = [val for val in col if val != 0] # Remove zeros
|
||||||
|
if filtered_values:
|
||||||
|
avg = round(sum(filtered_values) / len(filtered_values)) # Compute average
|
||||||
|
else:
|
||||||
|
avg = 0 # If all values were zero, store 0
|
||||||
|
averages.append(avg)
|
||||||
|
|
||||||
|
# Store averages in specific indices
|
||||||
|
payload_csv[9] = averages[0] # envea_no2
|
||||||
|
payload_csv[10] = averages[1] # envea_h2s
|
||||||
|
payload_csv[11] = averages[2] # envea_nh3
|
||||||
|
|
||||||
|
#Add data to payload JSON
|
||||||
|
payload_json["sensordatavalues"].append({"value_type": "CAIRSENS_NO2", "value": str(averages[0])})
|
||||||
|
payload_json["sensordatavalues"].append({"value_type": "CAIRSENS_NO2", "value": str(averages[1])})
|
||||||
|
payload_json["sensordatavalues"].append({"value_type": "CAIRSENS_NH3", "value": str(averages[2])})
|
||||||
|
|
||||||
|
|
||||||
print("Verify SARA R4 connection")
|
print("Verify SARA R4 connection")
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ SCRIPTS = [
|
|||||||
("RTC/save_to_db.py", 1, 0), # SAVE RTC time every 1 second, no delay
|
("RTC/save_to_db.py", 1, 0), # SAVE RTC time every 1 second, no delay
|
||||||
("NPM/get_data_v2.py", 60, 0), # Get NPM data every 60s, no delay
|
("NPM/get_data_v2.py", 60, 0), # Get NPM data every 60s, no delay
|
||||||
("NPM/get_data_modbus.py", 10, 2), # Get NPM data (modbus 5 channels) every 10s, with 2s delay
|
("NPM/get_data_modbus.py", 10, 2), # Get NPM data (modbus 5 channels) every 10s, with 2s delay
|
||||||
|
("envea/read_value_v2.py", 10, 0), # Get NPM data (modbus 5 channels) every 10s, with 2s delay
|
||||||
("loop/SARA_send_data_v2.py", 60, 1), # Send data every 60 seconds, with 2s delay
|
("loop/SARA_send_data_v2.py", 60, 1), # Send data every 60 seconds, with 2s delay
|
||||||
("BME280/get_data_v2.py", 120, 0) # Get BME280 data every 120 seconds, no delay
|
("BME280/get_data_v2.py", 120, 0) # Get BME280 data every 120 seconds, no delay
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user