update
This commit is contained in:
104
master.py
104
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)
|
||||
Reference in New Issue
Block a user