update
This commit is contained in:
@@ -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
|
||||
|
||||
41
master.py
41
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)
|
||||
|
||||
Binary file not shown.
@@ -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)
|
||||
|
||||
BIN
matrix/test_text
BIN
matrix/test_text
Binary file not shown.
@@ -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
|
||||
|
||||
BIN
matrix/welcome_screen
Executable file
BIN
matrix/welcome_screen
Executable file
Binary file not shown.
96
matrix/welcome_screen.cc
Normal file
96
matrix/welcome_screen.cc
Normal file
@@ -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 <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <atomic>
|
||||
|
||||
using rgb_matrix::RGBMatrix;
|
||||
using rgb_matrix::Canvas;
|
||||
|
||||
std::atomic<bool> 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;
|
||||
}
|
||||
@@ -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("""
|
||||
|
||||
96
sqlite/set_config.py
Normal file
96
sqlite/set_config.py
Normal file
@@ -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!")
|
||||
Reference in New Issue
Block a user