diff --git a/NPM/get_data_modbus_v3.py b/NPM/get_data_modbus_v3.py
index 4e26897..0c9c141 100755
--- a/NPM/get_data_modbus_v3.py
+++ b/NPM/get_data_modbus_v3.py
@@ -52,9 +52,7 @@ def load_config(config_file):
return {}
# Load the configuration data
-config_file = '/var/www/nebuleair_pro_4g/config.json'
-config = load_config(config_file)
-npm_solo_port = config.get('NPM_solo_port', '') #port du NPM solo
+npm_solo_port = "/dev/ttyAMA5" #port du NPM solo
#GET RTC TIME from SQlite
cursor.execute("SELECT * FROM timestamp_table LIMIT 1")
diff --git a/envea/read_value_v2.py b/envea/read_value_v2.py
index 469c381..3e91f7f 100755
--- a/envea/read_value_v2.py
+++ b/envea/read_value_v2.py
@@ -28,31 +28,14 @@ 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 {}
+# Fetch connected ENVEA sondes from SQLite config table
+cursor.execute("SELECT port, name, coefficient FROM envea_sondes_table WHERE connected = 1")
+connected_envea_sondes = cursor.fetchall() # List of tuples (port, name, coefficient)
-# 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')
+ for port, name, coefficient in connected_envea_sondes:
try:
serial_connections[name] = serial.Serial(
port=f'/dev/{port}',
@@ -74,9 +57,7 @@ data_nh3 = 0
try:
if connected_envea_sondes:
- for device in connected_envea_sondes:
- name = device.get('name', 'Unknown')
- coefficient = device.get('coefficient', 1)
+ for port, name, coefficient in connected_envea_sondes:
if name in serial_connections:
serial_connection = serial_connections[name]
try:
diff --git a/html/admin.html b/html/admin.html
index a237e92..e9f6cdd 100755
--- a/html/admin.html
+++ b/html/admin.html
@@ -114,10 +114,9 @@
-
+
@@ -611,10 +610,18 @@ function add_sondeEnveaContainer() {
// Create container div if it doesn't exist
if ($('#sondes_envea_div').length === 0) {
- $('#advanced_options').append('');
+ $('#advanced_options').append('');
} else {
// Clear existing content if container exists
$('#sondes_envea_div').html('');
+ $('#envea_table').html(''+
+ '| Software | Hardware (PCB) |
'+
+ '' +
+ '| ttyAMA5 | NPM1 |
' +
+ '| ttyAMA4 | NPM2 |
' +
+ '| ttyAMA3 | NPM3 |
' +
+ '| ttyAMA2 | SARA |
' +
+ '
');
}
// Loop through each sonde and create UI elements
diff --git a/loop/SARA_send_data_v2.py b/loop/SARA_send_data_v2.py
index 3104af7..8f7c5d2 100755
--- a/loop/SARA_send_data_v2.py
+++ b/loop/SARA_send_data_v2.py
@@ -577,9 +577,9 @@ try:
payload_csv[10] = averages[1] # envea_h2s
payload_csv[11] = averages[2] # envea_nh3
- #Add data to payload JSON
+ #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_H2S", "value": str(averages[1])})
payload_json["sensordatavalues"].append({"value_type": "CAIRSENS_NH3", "value": str(averages[2])})
#Wind meter
diff --git a/master.py b/master.py
index 96305b3..0cb008a 100755
--- a/master.py
+++ b/master.py
@@ -52,17 +52,73 @@ Specific scripts can be disabled with config.json
import time
import threading
import subprocess
-import json
import os
+import sqlite3
+
# Base directory where scripts are stored
SCRIPT_DIR = "/var/www/nebuleair_pro_4g/"
-CONFIG_FILE = "/var/www/nebuleair_pro_4g/config.json"
+DB_PATH = "/var/www/nebuleair_pro_4g/sqlite/sensors.db"
+
+# Lock file path for SARA script
+SARA_LOCK_FILE = "/var/www/nebuleair_pro_4g/sara_script.lock"
+
+
+def is_script_enabled(script_name):
+ """Check if a script is enabled in the database."""
+ try:
+ conn = sqlite3.connect(DB_PATH)
+ cursor = conn.cursor()
+
+ cursor.execute(
+ "SELECT enabled FROM config_scripts_table WHERE script_path = ?",
+ (script_name,)
+ )
+
+ result = cursor.fetchone()
+ conn.close()
+
+ if result is None:
+ return True # Default to enabled if not found in database
+
+ return bool(result[0])
+ except Exception:
+ # If any database error occurs, default to enabled
+ return True
+
+
+def create_lock_file():
+ """Create a lock file for the SARA script."""
+ with open(SARA_LOCK_FILE, 'w') as f:
+ f.write(str(int(time.time())))
+
+
+def remove_lock_file():
+ """Remove the SARA script lock file."""
+ if os.path.exists(SARA_LOCK_FILE):
+ os.remove(SARA_LOCK_FILE)
+
+
+def is_script_locked():
+ """Check if the SARA script is currently locked."""
+ if not os.path.exists(SARA_LOCK_FILE):
+ return False
+
+ # Check if lock is older than 60 seconds (stale)
+ with open(SARA_LOCK_FILE, 'r') as f:
+ try:
+ lock_time = int(f.read().strip())
+ if time.time() - lock_time > 60:
+ # Lock is stale, remove it
+ remove_lock_file()
+ return False
+ except ValueError:
+ # Invalid lock file content
+ remove_lock_file()
+ return False
+
+ return True
-def load_config():
- """Load the configuration file to determine which scripts to run."""
- with open(CONFIG_FILE, "r") as f:
- return json.load(f)
def run_script(script_name, interval, delay=0):
"""Run a script in a synchronized loop with an optional start delay."""
@@ -70,33 +126,41 @@ def run_script(script_name, interval, delay=0):
next_run = time.monotonic() + delay # Apply the initial delay
while True:
- config = load_config()
- if config.get(script_name, True): # Default to True if not found
- subprocess.run(["python3", script_path])
+ if is_script_enabled(script_name):
+ # Special handling for SARA script to prevent concurrent runs
+ if script_name == "loop/SARA_send_data_v2.py":
+ if not is_script_locked():
+ create_lock_file()
+ try:
+ subprocess.run(["python3", script_path])
+ finally:
+ remove_lock_file()
+ else:
+ # Run other scripts normally
+ subprocess.run(["python3", script_path])
# Wait until the next exact interval
next_run += interval
sleep_time = max(0, next_run - time.monotonic()) # Prevent negative sleep times
time.sleep(sleep_time)
+
# Define scripts and their execution intervals (seconds)
SCRIPTS = [
- #("RTC/save_to_db.py", 1, 0), # --> will run as a separated system service (rtc_save_to_db.service)
- ("NPM/get_data_modbus_v3.py", 10, 0), # 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
- ("BME280/get_data_v2.py", 120, 0), # Get BME280 data every 120 seconds, no delay
- ("MPPT/read.py", 120, 0), # Get MPPT data every 120 seconds, no delay
- #("windMeter/read.py", 60, 2), # --> will run as a separated system service ()
- ("sqlite/flush_old_data.py", 86400, 0) # flush old data inside db every day ()
+ # Format: (script_name, interval_in_seconds, start_delay_in_seconds)
+ ("NPM/get_data_modbus_v3.py", 10, 0), # Get NPM data (modbus 5 channels) every 10s
+ ("envea/read_value_v2.py", 10, 0), # Get Envea data every 10s
+ ("loop/SARA_send_data_v2.py", 60, 1), # Send data every 60 seconds, with 1s delay
+ ("BME280/get_data_v2.py", 120, 0), # Get BME280 data every 120 seconds
+ ("MPPT/read.py", 120, 0), # Get MPPT data every 120 seconds
+ ("sqlite/flush_old_data.py", 86400, 0) # Flush old data inside db every day
]
-# Start threads for enabled scripts
+# Start threads for scripts
for script_name, interval, delay in SCRIPTS:
thread = threading.Thread(target=run_script, args=(script_name, interval, delay), daemon=True)
thread.start()
# Keep the main script running
while True:
- time.sleep(1)
-
+ time.sleep(1)
\ No newline at end of file