Files
nebuleair_pro_4g/envea/read_value_v2.py
Your Name 25c5a7a65a update
2025-07-22 15:36:36 +02:00

182 lines
6.6 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
_____ _ ___ _______ _
| ____| \ | \ \ / / ____| / \
| _| | \| |\ \ / /| _| / _ \
| |___| |\ | \ V / | |___ / ___ \
|_____|_| \_| \_/ |_____/_/ \_\
Gather data from envea Sensors and store them to the SQlite table
Use the RTC time for the timestamp
This script is run by a service nebuleair-envea-data.service
/usr/bin/python3 /var/www/nebuleair_pro_4g/envea/read_value_v2.py -d
"""
import json
import serial
import time
import traceback
import sqlite3
from datetime import datetime
import sys
# Set DEBUG to True to enable debug prints, False to disable
DEBUG = False # Change this to False to disable debug output
# You can also control debug via command line argument
if len(sys.argv) > 1 and sys.argv[1] in ['--debug', '-d']:
DEBUG = True
elif len(sys.argv) > 1 and sys.argv[1] in ['--quiet', '-q']:
DEBUG = False
def debug_print(message):
"""Print debug messages only if DEBUG is True"""
if DEBUG:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}] {message}")
debug_print("=== ENVEA Sensor Reader Started ===")
# Connect to the SQLite database
try:
conn = sqlite3.connect("/var/www/nebuleair_pro_4g/sqlite/sensors.db")
cursor = conn.cursor()
except Exception as e:
debug_print(f"✗ Failed to connect to database: {e}")
sys.exit(1)
# GET RTC TIME from SQlite
try:
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'
except Exception as e:
debug_print(f"✗ Failed to get RTC time: {e}")
rtc_time_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
debug_print(f" Using system time instead: {rtc_time_str}")
# Fetch connected ENVEA sondes from SQLite config table
try:
cursor.execute("SELECT port, name, coefficient FROM envea_sondes_table WHERE connected = 1")
connected_envea_sondes = cursor.fetchall() # List of tuples (port, name, coefficient)
debug_print(f"✓ Found {len(connected_envea_sondes)} connected ENVEA sensors")
for port, name, coefficient in connected_envea_sondes:
debug_print(f" - {name}: port={port}, coefficient={coefficient}")
except Exception as e:
debug_print(f"✗ Failed to fetch connected sensors: {e}")
connected_envea_sondes = []
serial_connections = {}
if connected_envea_sondes:
debug_print("\n--- Opening Serial Connections ---")
for port, name, coefficient in connected_envea_sondes:
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
)
debug_print(f"✓ Opened serial port for {name} on /dev/{port}")
except serial.SerialException as e:
debug_print(f"✗ Error opening serial port for {name}: {e}")
else:
debug_print("! No connected ENVEA sensors found in configuration")
# Initialize sensor data variables
global data_h2s, data_no2, data_o3, data_co, data_nh3, data_so2
data_h2s = 0
data_no2 = 0
data_o3 = 0
data_co = 0
data_nh3 = 0
data_so2 = 0
try:
if connected_envea_sondes:
debug_print("\n--- Reading Sensor Data ---")
for port, name, coefficient in connected_envea_sondes:
if name in serial_connections:
serial_connection = serial_connections[name]
try:
debug_print(f"Reading from {name}...")
# Send command to sensor
command = b"\xFF\x02\x13\x30\x01\x02\x03\x04\x05\x06\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x12\xAF\x88\x03"
serial_connection.write(command)
debug_print(f" → Sent command: {command.hex()}")
# Read response
data_envea = serial_connection.readline()
debug_print(f" ← Received {len(data_envea)} bytes: {data_envea.hex()}")
if len(data_envea) >= 20:
byte_20 = data_envea[19]
raw_value = byte_20
calculated_value = byte_20 * coefficient
debug_print(f" → Byte 20 value: {raw_value} (0x{raw_value:02X})")
debug_print(f" → Calculated value: {raw_value} × {coefficient} = {calculated_value}")
if name == "h2s":
data_h2s = calculated_value
elif name == "no2":
data_no2 = calculated_value
elif name == "o3":
data_o3 = calculated_value
elif name == "co":
data_co = calculated_value
elif name == "nh3":
data_nh3 = calculated_value
elif name == "so2":
data_so2 = calculated_value
debug_print(f"{name.upper()} = {calculated_value}")
else:
debug_print(f" ✗ Response too short (expected ≥20 bytes)")
except serial.SerialException as e:
debug_print(f"✗ Error communicating with {name}: {e}")
else:
debug_print(f"! No serial connection available for {name}")
except Exception as e:
debug_print(f"\n✗ An error occurred while gathering data: {e}")
traceback.print_exc()
# Display all collected data
debug_print(f"\n--- Collected Sensor Data ---")
debug_print(f"H2S: {data_h2s} ppb")
debug_print(f"NO2: {data_no2} ppb")
debug_print(f"O3: {data_o3} ppb")
debug_print(f"CO: {data_co} ppb")
debug_print(f"NH3: {data_nh3} ppb")
debug_print(f"SO2: {data_so2} ppb")
# Save to sqlite database
try:
cursor.execute('''
INSERT INTO data_envea (timestamp, h2s, no2, o3, co, nh3, so2) VALUES (?,?,?,?,?,?,?)'''
, (rtc_time_str, data_h2s, data_no2, data_o3, data_co, data_nh3, data_so2))
# Commit and close the connection
conn.commit()
except Exception as e:
debug_print(f"✗ Database error: {e}")
traceback.print_exc()
# Close serial connections
if serial_connections:
for name, connection in serial_connections.items():
try:
connection.close()
except:
pass
conn.close()
debug_print("\n=== ENVEA Sensor Reader Finished ===\n")