diff --git a/MH-Z19/write_data.py b/MH-Z19/write_data.py index cd2789d..f669560 100755 --- a/MH-Z19/write_data.py +++ b/MH-Z19/write_data.py @@ -74,11 +74,11 @@ def read_co2(): response = ser.read(9) # Print the response to debug - print(f"Response: {response}") + #print(f"Response: {response}") # Check if the response is valid (the first byte should be 0xFF) if len(response) < 9: - print("Error: No data or incomplete data received.") + print("Error: No data or incomplete data received from co2 sensor.") return None if response[0] == 0xFF: @@ -86,7 +86,7 @@ def read_co2(): co2_concentration = response[2] * 256 + response[3] return co2_concentration else: - print("Error reading data from sensor.") + print("Error reading data from co2 sensor.") return None @@ -95,12 +95,12 @@ def main(): try: co2 = read_co2() if co2 is not None: - print(f"CO2 Concentration: {co2} ppm") + #print(f"CO2 Concentration: {co2} ppm") #save to file output_file = "/var/www/moduleair_pro_4g/matrix/input_MHZ16.txt" with open(output_file, "w") as file: file.write(f"{co2} \n") - print(f"Data written to {output_file}") + #print(f"Data written to {output_file}") #GET RTC TIME from SQlite cursor.execute("SELECT * FROM timestamp_table LIMIT 1") row = cursor.fetchone() # Get the first (and only) row diff --git a/master.py b/master.py index 4b0f317..72763f0 100755 --- a/master.py +++ b/master.py @@ -66,7 +66,7 @@ def load_config(): return json.load(f) def run_script(script_name, interval, delay=0): - """Run a script in a synchronized loop with an optional start delay.""" + """Run a PYTHON script in a synchronized loop with an optional start delay.""" script_path = os.path.join(SCRIPT_DIR, script_name) # Build full path next_run = time.monotonic() + delay # Apply the initial delay @@ -80,22 +80,39 @@ def run_script(script_name, interval, delay=0): 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), # SAVE RTC time every 1 second, no delay - ("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, - ("MH-Z19/write_data.py", 10, 0), # Get CO2 values every 10s, - ("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 - ("sqlite/flush_old_data.py", 86400, 0) # flush old data inside db every day () + +# ✅ **Scripts that should start immediately** +IMMEDIATE_SCRIPTS = [ + ("RTC/save_to_db.py", 1, 0), + ("NPM/get_data_modbus_v3.py", 10, 0), + ("envea/read_value_v2.py", 10, 0), + ("MH-Z19/write_data.py", 10, 0), + ("loop/SARA_send_data_v2.py", 60, 1), + ("BME280/get_data_v2.py", 120, 0), + ("sqlite/flush_old_data.py", 86400, 0) ] -# Start threads for enabled scripts -for script_name, interval, delay in SCRIPTS: +# ✅ **The compiled binary that must wait for welcome_screen** +WAIT_BINARY = "/var/www/moduleair_pro_4g/matrix/test_forms" # Adjust path if needed + +# 🚀 **Start all scripts that can run immediately** +for script_name, interval, delay in IMMEDIATE_SCRIPTS: thread = threading.Thread(target=run_script, args=(script_name, interval, delay), daemon=True) thread.start() +# 🚀 **Run welcome_screen in parallel** +print("🚀 Running welcome screen...") +welcome_process = subprocess.Popen(["sudo", "/var/www/moduleair_pro_4g/matrix/welcome_screen"]) +print("✅ Welcome screen started in parallel with other scripts.") + +# 🕒 **Wait for welcome_screen to finish before running WAIT_BINARY** +welcome_process.wait() +print("✅ Welcome screen finished. Starting another_screen...") + +# 🚀 **Now run the compiled binary `another_screen`** +subprocess.run(["sudo", WAIT_BINARY]) +print("✅ another_screen execution completed.") + # Keep the main script running while True: time.sleep(1) diff --git a/matrix/test_forms b/matrix/test_forms index 19da2fc..9295ddd 100755 Binary files a/matrix/test_forms and b/matrix/test_forms differ diff --git a/matrix/test_forms.cc b/matrix/test_forms.cc index 11d0347..f9d0317 100755 --- a/matrix/test_forms.cc +++ b/matrix/test_forms.cc @@ -1,4 +1,12 @@ /* + + __ __ _ _____ ____ _____ __ + | \/ | / \|_ _| _ \|_ _\ \/ / + | |\/| | / _ \ | | | |_) || | \ / + | | | |/ ___ \| | | _ < | | / \ + |_| |_/_/ \_\_| |_| \_\___/_/\_\ + + Script to display a simple square on the matrix LED sudo /var/www/moduleair_pro_4g/matrix/test_forms --led-no-hardware-pulse @@ -25,7 +33,10 @@ int main(int argc, char *argv[]) { defaults.row_address_type = 3; defaults.show_refresh_rate = true; defaults.brightness = 100; + defaults.pwm_bits = 1; defaults.panel_type = "FM6126A"; + defaults.disable_hardware_pulsing = false; + rgb_matrix::Color red(255, 0, 0); // Red color rgb_matrix::Color bg_color(0, 0, 0); // Background color (black) diff --git a/matrix/test_text b/matrix/test_text index b790772..2492f92 100755 Binary files a/matrix/test_text and b/matrix/test_text differ diff --git a/matrix/test_text.cc b/matrix/test_text.cc index ef7048c..83f2dd3 100755 --- a/matrix/test_text.cc +++ b/matrix/test_text.cc @@ -1,6 +1,13 @@ /* + + __ __ _ _____ ____ _____ __ + | \/ | / \|_ _| _ \|_ _\ \/ / + | |\/| | / _ \ | | | |_) || | \ / + | | | |/ ___ \| | | _ < | | / \ + |_| |_/_/ \_\_| |_| \_\___/_/\_\ + Script to display a simple text on the matrix LED -sudo /var/www/moduleair_pro_4g/matrix/test_text --led-no-hardware-pulse +sudo /var/www/moduleair_pro_4g/matrix/test_text Pour compiler: g++ -Iinclude -Llib test_text.cc -o test_text -lrgbmatrix @@ -25,7 +32,9 @@ int main(int argc, char *argv[]) { defaults.row_address_type=3; defaults.show_refresh_rate = true; defaults.brightness = 100; + defaults.pwm_bits = 1; defaults.panel_type = "FM6126A"; + defaults.disable_hardware_pulsing = false; rgb_matrix::Color color1(255, 0, 0); // Red color for the first line rgb_matrix::Color color2(0, 0, 255); // Blue color for the second line diff --git a/matrix/welcome_screen b/matrix/welcome_screen new file mode 100755 index 0000000..1d0173d Binary files /dev/null and b/matrix/welcome_screen differ diff --git a/matrix/welcome_screen.cc b/matrix/welcome_screen.cc new file mode 100644 index 0000000..03b516d --- /dev/null +++ b/matrix/welcome_screen.cc @@ -0,0 +1,96 @@ +/* + __ __ _ _____ ____ _____ __ + | \/ | / \|_ _| _ \|_ _\ \/ / + | |\/| | / _ \ | | | |_) || | \ / + | | | |/ ___ \| | | _ < | | / \ + |_| |_/_/ \_\_| |_| \_\___/_/\_\ + +Script to launch the welcome screen + + +Pour compiler: +g++ -Iinclude -Llib welcome_screen.cc -o welcome_screen -lrgbmatrix +g++ -I /var/www/moduleair_pro_4g/matrix/include -L /var/www/moduleair_pro_4g/matrix/lib /var/www/moduleair_pro_4g/matrix/welcome_screen.cc -o /var/www/moduleair_pro_4g/matrix/welcome_screen -lrgbmatrix + + +Pour lancer: +sudo /var/www/moduleair_pro_4g/matrix/welcome_screen + +*/ + +#include "led-matrix.h" +#include "graphics.h" +#include +#include +#include +#include +#include +#include + +using rgb_matrix::RGBMatrix; +using rgb_matrix::Canvas; + +std::atomic running(true); + +void signal_handler(int signum) { + running = false; +} + + +//message d'accueil +void draw_welcome_screen(Canvas *canvas) { + canvas->Clear(); + + rgb_matrix::Color myCYAN(0, 255, 255); + rgb_matrix::Color myWHITE(255, 255, 255); + rgb_matrix::Color bg_color(0, 0, 0); + + rgb_matrix::Font font1; + rgb_matrix::Font font2; + + if (!font1.LoadFont("/var/www/moduleair_pro_4g/matrix/fonts/6x9.bdf")) return; + if (!font2.LoadFont("/var/www/moduleair_pro_4g/matrix/fonts/9x18B.bdf")) return; + + int letter_spacing = 0; + int x = 10, y1 = 20, y2 = 50; + + rgb_matrix::DrawText(canvas, font2, x, y1, myCYAN, &bg_color, "Welcome to", letter_spacing); + rgb_matrix::DrawText(canvas, font2, x, y2, myWHITE, &bg_color, "ModuleAir", letter_spacing); + + usleep(2000000); // Display the welcome screen for 2 seconds +} + + +int main(int argc, char *argv[]) { + // Handle signals for graceful exit + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + + RGBMatrix::Options defaults; + defaults.hardware_mapping = "moduleair_pinout"; + defaults.rows = 64; + defaults.cols = 128; + defaults.chain_length = 1; + defaults.parallel = 1; + defaults.row_address_type = 3; + defaults.show_refresh_rate = true; + defaults.brightness = 100; + defaults.pwm_bits = 1; + defaults.panel_type = "FM6126A"; + defaults.disable_hardware_pulsing = false; + + Canvas *canvas = RGBMatrix::CreateFromFlags(&argc, &argv, &defaults); + if (canvas == NULL) + return 1; + + // Display welcome screen once + draw_welcome_screen(canvas); + + // Sleep briefly to allow for updates + usleep(10000000); // 10 s + + // Clean up + canvas->Clear(); + delete canvas; + return 0; +} diff --git a/sqlite/create_db.py b/sqlite/create_db.py index 6080a72..f9fab2d 100755 --- a/sqlite/create_db.py +++ b/sqlite/create_db.py @@ -18,6 +18,34 @@ import sqlite3 conn = sqlite3.connect("/var/www/moduleair_pro_4g/sqlite/sensors.db") cursor = conn.cursor() +#create a config table +cursor.execute(""" +CREATE TABLE IF NOT EXISTS config_table ( + key TEXT PRIMARY KEY, + value TEXT NOT NULL, + type TEXT NOT NULL +) +""") + +#creates a config_scripts table +cursor.execute(''' +CREATE TABLE IF NOT EXISTS config_scripts_table ( + script_path TEXT PRIMARY KEY, + enabled INTEGER NOT NULL +) +''') + +#creates a config table for envea sondes +cursor.execute(""" +CREATE TABLE IF NOT EXISTS envea_sondes_table ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + connected INTEGER NOT NULL, + port TEXT NOT NULL, + name TEXT NOT NULL, + coefficient REAL NOT NULL +) +""") + # Create a table timer cursor.execute(""" CREATE TABLE IF NOT EXISTS timestamp_table ( @@ -30,6 +58,14 @@ cursor.execute(""" VALUES (1, CURRENT_TIMESTAMP); """) +#create a modem status table +cursor.execute(""" +CREATE TABLE IF NOT EXISTS modem_status ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp TEXT, + status TEXT +) +""") # Create a table NPM cursor.execute(""" diff --git a/sqlite/set_config.py b/sqlite/set_config.py new file mode 100644 index 0000000..7ecb030 --- /dev/null +++ b/sqlite/set_config.py @@ -0,0 +1,96 @@ +''' + ____ ___ _ _ _ + / ___| / _ \| | (_) |_ ___ + \___ \| | | | | | | __/ _ \ + ___) | |_| | |___| | || __/ + |____/ \__\_\_____|_|\__\___| + +Script to set the config +/usr/bin/python3 /var/www/moduleair_pro_4g/sqlite/set_config.py + +in case of readonly error: +sudo chmod 777 /var/www/moduleair_pro_4g/sqlite/sensors.db +''' + +import sqlite3 + +# Connect to (or create if not existent) the database +conn = sqlite3.connect("/var/www/moduleair_pro_4g/sqlite/sensors.db") +cursor = conn.cursor() + +print(f"Connected to database") + +# Clear existing data (if any) +cursor.execute("DELETE FROM config_table") +cursor.execute("DELETE FROM config_scripts_table") +cursor.execute("DELETE FROM envea_sondes_table") +print("Existing data cleared") + +#add values + +# Insert script configurations +script_configs = [ + ("NPM/get_data_modbus_v3.py", True), + ("loop/SARA_send_data_v2.py", True), + ("RTC/save_to_db.py", True), + ("BME280/get_data_v2.py", True), + ("envea/read_value_v2.py", False), + ("MPPT/read.py", False), + ("windMeter/read.py", False), + ("sqlite/flush_old_data.py", True) +] + +for script_path, enabled in script_configs: + cursor.execute( + "INSERT INTO config_scripts_table (script_path, enabled) VALUES (?, ?)", + (script_path, 1 if enabled else 0) + ) + +# Insert general configurations +config_entries = [ + ("modem_config_mode", "0", "bool"), + ("deviceID", "XXXX", "str"), + ("npm_5channel", "0", "bool"), + ("latitude_raw", "0", "int"), + ("longitude_raw", "0", "int"), + ("latitude_precision", "0", "int"), + ("longitude_precision", "0", "int"), + ("deviceName", "NebuleAir-proXXX", "str"), + ("SaraR4_baudrate", "115200", "int"), + ("NPM_solo_port", "/dev/ttyAMA5", "str"), + ("sshTunnel_port", "59228", "int"), + ("SARA_R4_general_status", "connected", "str"), + ("SARA_R4_SIM_status", "connected", "str"), + ("SARA_R4_network_status", "connected", "str"), + ("SARA_R4_neworkID", "20810", "int"), + ("WIFI_status", "connected", "str"), + ("send_uSpot", "0", "bool"), + ("windMeter", "0", "bool"), + ("modem_version", "XXX", "str") +] + +for key, value, value_type in config_entries: + cursor.execute( + "INSERT INTO config_table (key, value, type) VALUES (?, ?, ?)", + (key, value, value_type) + ) + +# Insert envea sondes +envea_sondes = [ + (False, "ttyAMA4", "h2s", 4), + (False, "ttyAMA3", "no2", 1), + (False, "ttyAMA2", "o3", 1) +] + +for connected, port, name, coefficient in envea_sondes: + cursor.execute( + "INSERT INTO envea_sondes_table (connected, port, name, coefficient) VALUES (?, ?, ?, ?)", + (1 if connected else 0, port, name, coefficient) + ) + + +# Commit and close the connection +conn.commit() +conn.close() + +print("Database updated successfully!")