This commit is contained in:
Your Name
2025-05-14 17:24:01 +02:00
parent b17c996f2f
commit fd28069b0c
6 changed files with 358 additions and 20 deletions

View File

@@ -4,7 +4,10 @@
@reboot sleep 30 && /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/reboot/start.py >> /var/www/nebuleair_pro_4g/logs/app.log 2>&1
0 0 * * * > /var/www/nebuleair_pro_4g/logs/master.log
0 0 * * * > /var/www/nebuleair_pro_4g/logs/master_errors.log
0 0 * * * > /var/www/nebuleair_pro_4g/logs/app.log
#0 0 * * * > /var/www/nebuleair_pro_4g/logs/master.log
#0 0 * * * > /var/www/nebuleair_pro_4g/logs/master_errors.log
#0 0 * * * > /var/www/nebuleair_pro_4g/logs/app.log
0 0 * * * find /var/www/nebuleair_pro_4g/logs -name "*.log" -type f -exec truncate -s 0 {} \;

View File

@@ -115,14 +115,14 @@
const boot_card_content = document.getElementById('card_boot_content');
//Getting Master logs
console.log("Getting master logs");
displayLogFile('../logs/master.log', loop_card_content, true, 1000);
console.log("Getting SARA logs");
displayLogFile('../logs/sara_service.log', loop_card_content, true, 1000);
console.log("Getting app/boot logs");
displayLogFile('../logs/app.log', boot_card_content, true, 1000);
// Setup master log with refresh button
setupLogRefreshButton('refresh-master-log', '../logs/master.log', 'card_loop_content', 3000);
setupLogRefreshButton('refresh-master-log', '../logs/sara_service.log', 'card_loop_content', 3000);
// Setup boot log with refresh button
setupLogRefreshButton('refresh-boot-log', '../logs/app.log', 'card_boot_content', 300);

View File

@@ -370,6 +370,45 @@ def send_error_notification(device_id, error_type, additional_info=None):
return False
def modem_hardware_reboot():
"""
Performs a hardware reboot using transistors connected to pin 16 and 20:
pin 16 set to SARA GND
pin 20 set to SARA ON (not used)
LOW -> cut the current
HIGH -> current flow
"""
print('<span style="color: orange;font-weight: bold;">🔄 Hardware SARA reboot 🔄</span>')
SARA_power_GPIO = 16
SARA_ON_GPIO = 20
GPIO.setmode(GPIO.BCM) # Use BCM numbering
GPIO.setup(SARA_power_GPIO, GPIO.OUT) # Set GPIO17 as an output
GPIO.output(SARA_power_GPIO, GPIO.LOW)
time.sleep(2)
GPIO.output(SARA_power_GPIO, GPIO.HIGH)
time.sleep(2)
print("Checking if modem is responsive...")
for attempt in range(5):
ser_sara.write(b'AT\r')
response_check = read_complete_response(ser_sara, wait_for_lines=["OK"], debug=True)
if response_check and "OK" in response_check:
print("✅ Modem is responsive after reboot.")
return True
print(f"⏳ Waiting for modem... attempt {attempt + 1}")
time.sleep(2)
else:
print("❌ Modem not responding after reboot.")
return False
def modem_complete_reboot_and_reinitialize(modem_version, aircarto_profile_id):
"""
Performs a complete modem restart sequence:
@@ -433,15 +472,22 @@ def modem_complete_reboot_and_reinitialize(modem_version, aircarto_profile_id):
# Step 4: Reset AirCarto HTTP Profile
print('<span style="color: orange;font-weight: bold;">🔧 Resetting AirCarto HTTP Profile</span>')
command = f'AT+UHTTP={aircarto_profile_id},1,"data.nebuleair.fr"\r'
ser_sara.write(command.encode('utf-8'))
responseResetHTTP = read_complete_response(ser_sara, timeout=5, end_of_response_timeout=5,
wait_for_lines=["OK", "+CME ERROR"], debug=True)
print('<p class="text-danger-emphasis">')
print(responseResetHTTP)
print("</p>", end="")
#command = f'AT+UHTTP={aircarto_profile_id},1,"data.nebuleair.fr"\r'
#ser_sara.write(command.encode('utf-8'))
#responseResetHTTP = read_complete_response(ser_sara, timeout=5, end_of_response_timeout=5,wait_for_lines=["OK", "+CME ERROR"], debug=True)
#print('<p class="text-danger-emphasis">')
#print(responseResetHTTP)
#print("</p>", end="")
http_reset_success = responseResetHTTP is not None and "OK" in responseResetHTTP
print("SET URL")
command = f'AT+UHTTP={aircarto_profile_id},1,"data.nebuleair.fr"\r'
ser_sara.write((command + '\r').encode('utf-8'))
response_SARA_5 = read_complete_response(ser_sara, wait_for_lines=["OK"])
print(response_SARA_5)
time.sleep(1)
http_reset_success = response_SARA_5 is not None and "OK" in response_SARA_5
if not http_reset_success:
print("⚠️ AirCarto HTTP profile reset failed")
# Continue anyway, don't return False here
@@ -784,7 +830,8 @@ try:
# Getting the LTE Signal
print("Getting LTE signal")
ser_sara.write(b'AT+CSQ\r')
command = f'AT+CSQ\r'
ser_sara.write((command + '\r').encode('utf-8'))
response2 = read_complete_response(ser_sara, wait_for_lines=["OK", "ERROR", "+CME ERROR","Socket:bind"])
print('<p class="text-danger-emphasis">')
print(response2)
@@ -827,6 +874,12 @@ try:
print("<hr>")
#Send notification (WIFI)
send_error_notification(device_id, "SERIAL ISSUE -> Treck TCP/IP stack error")
#Software Reboot
hardware_reboot_success = modem_hardware_reboot()
if hardware_reboot_success:
print("✅Modem successfully rebooted and reinitialized")
else:
print("⛔There were issues with the modem reboot/reinitialize process")
#end loop
sys.exit()
@@ -1032,7 +1085,8 @@ try:
#4. Read reply from server
print("Reply from server:")
ser_sara.write(b'AT+URDFILE="aircarto_server_response.txt"\r')
command = f'AT+URDFILE="aircarto_server_response.txt""\r'
ser_sara.write((command + '\r').encode('utf-8'))
response_SARA_4 = read_complete_response(ser_sara, wait_for_lines=["OK"], debug=False)
print('<p class="text-success">')
print(response_SARA_4)
@@ -1169,7 +1223,8 @@ try:
#5. empty json
print("Empty SARA memory:")
ser_sara.write(b'AT+UDELFILE="sensordata_csv.json"\r')
command = f'AT+UDELFILE="sensordata_csv.json"\r'
ser_sara.write((command + '\r').encode('utf-8'))
response_SARA_5 = read_complete_response(ser_sara, wait_for_lines=["OK","+CME ERROR"], debug=True)
print('<p class="text-danger-emphasis">')
print(response_SARA_5)
@@ -1310,7 +1365,8 @@ try:
#4. Read reply from server
print("Reply from server:")
ser_sara.write(b'AT+URDFILE="uSpot_server_response.txt"\r')
command = f'AT+URDFILE="uSpot_server_response.txt"\r'
ser_sara.write((command + '\r').encode('utf-8'))
response_SARA_4b = read_complete_response(ser_sara, wait_for_lines=["OK"], debug=False)
print('<p class="text-success">')
print(response_SARA_4b)
@@ -1349,7 +1405,8 @@ try:
#5. empty json
print("Empty SARA memory:")
ser_sara.write(b'AT+UDELFILE="sensordata_json.json"\r')
command = f'AT+UDELFILE="sensordata_json.json"\r'
ser_sara.write((command + '\r').encode('utf-8'))
response_SARA_9t = read_complete_response(ser_sara, wait_for_lines=["OK"], debug=False)
print(response_SARA_9t)

11
services/README.md Normal file
View File

@@ -0,0 +1,11 @@
# NebuleAir Pro Services
Les scripts importants tournent à l'aide d'un service et d'un timer associé.
Pour les installer:
sudo chmod +x /var/www/nebuleair_pro_4g/services/setup_services.sh
sudo /var/www/nebuleair_pro_4g/services/setup_services.sh
Supprimer l'ancien master:
sudo systemctl disable master_nebuleair.service

View File

@@ -0,0 +1,39 @@
#!/bin/bash
# File: /var/www/nebuleair_pro_4g/services/check_services.sh
# Purpose: Check status of all NebuleAir services and logs
# Install:
# sudo chmod +x /var/www/nebuleair_pro_4g/services/check_services.sh
# sudo /var/www/nebuleair_pro_4g/services/check_services.sh
echo "=== NebuleAir Services Status ==="
echo ""
# Check status of all timers
echo "--- TIMER STATUS ---"
systemctl list-timers | grep nebuleair
echo ""
# Check status of all services
echo "--- SERVICE STATUS ---"
for service in npm envea sara bme280 mppt db-cleanup; do
status=$(systemctl is-active nebuleair-$service-data.service)
timer_status=$(systemctl is-active nebuleair-$service-data.timer)
echo "nebuleair-$service-data: Service=$status, Timer=$timer_status"
done
echo ""
# Show recent logs for each service
echo "--- RECENT LOGS (last 5 entries per service) ---"
for service in npm envea sara bme280 mppt db-cleanup; do
echo "[$service service logs]"
journalctl -u nebuleair-$service-data.service -n 5 --no-pager
echo ""
done
echo "=== End of Report ==="
echo ""
echo "For detailed logs use:"
echo " sudo journalctl -u nebuleair-[service]-data.service -f"
echo "To restart a specific service timer:"
echo " sudo systemctl restart nebuleair-[service]-data.timer"

228
services/setup_services.sh Normal file
View File

@@ -0,0 +1,228 @@
#!/bin/bash
# File: /var/www/nebuleair_pro_4g/services/setup_services.sh
# Purpose: Set up all systemd services for NebuleAir data collection
# to install:
# sudo chmod +x /var/www/nebuleair_pro_4g/services/setup_services.sh
# sudo /var/www/nebuleair_pro_4g/services/setup_services.sh
echo "Setting up NebuleAir systemd services and timers..."
# Create directory for logs if it doesn't exist
mkdir -p /var/www/nebuleair_pro_4g/logs
# Create service and timer files for NPM Data
cat > /etc/systemd/system/nebuleair-npm-data.service << 'EOL'
[Unit]
Description=NebuleAir NPM Data Collection Service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /var/www/nebuleair_pro_4g/NPM/get_data_modbus_v3.py
User=root
WorkingDirectory=/var/www/nebuleair_pro_4g
StandardOutput=append:/var/www/nebuleair_pro_4g/logs/npm_service.log
StandardError=append:/var/www/nebuleair_pro_4g/logs/npm_service_errors.log
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/nebuleair-npm-data.timer << 'EOL'
[Unit]
Description=Run NebuleAir NPM Data Collection every 10 seconds
Requires=nebuleair-npm-data.service
[Timer]
OnBootSec=10s
OnUnitActiveSec=10s
AccuracySec=1s
[Install]
WantedBy=timers.target
EOL
# Create service and timer files for Envea Data
cat > /etc/systemd/system/nebuleair-envea-data.service << 'EOL'
[Unit]
Description=NebuleAir Envea Data Collection Service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /var/www/nebuleair_pro_4g/envea/read_value_v2.py
User=root
WorkingDirectory=/var/www/nebuleair_pro_4g
StandardOutput=append:/var/www/nebuleair_pro_4g/logs/envea_service.log
StandardError=append:/var/www/nebuleair_pro_4g/logs/envea_service_errors.log
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/nebuleair-envea-data.timer << 'EOL'
[Unit]
Description=Run NebuleAir Envea Data Collection every 10 seconds
Requires=nebuleair-envea-data.service
[Timer]
OnBootSec=10s
OnUnitActiveSec=10s
AccuracySec=1s
[Install]
WantedBy=timers.target
EOL
# Create service and timer files for SARA Data (No Lock File Needed)
cat > /etc/systemd/system/nebuleair-sara-data.service << 'EOL'
[Unit]
Description=NebuleAir SARA Data Transmission Service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /var/www/nebuleair_pro_4g/loop/SARA_send_data_v2.py
User=root
WorkingDirectory=/var/www/nebuleair_pro_4g
StandardOutput=append:/var/www/nebuleair_pro_4g/logs/sara_service.log
StandardError=append:/var/www/nebuleair_pro_4g/logs/sara_service_errors.log
RuntimeMaxSec=200s
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/nebuleair-sara-data.timer << 'EOL'
[Unit]
Description=Run NebuleAir SARA Data Transmission every 60 seconds
Requires=nebuleair-sara-data.service
[Timer]
OnBootSec=60s
OnUnitActiveSec=60s
AccuracySec=1s
# This is the key setting that prevents overlap
Persistent=true
[Install]
WantedBy=timers.target
EOL
# Create service and timer files for BME280 Data
cat > /etc/systemd/system/nebuleair-bme280-data.service << 'EOL'
[Unit]
Description=NebuleAir BME280 Data Collection Service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /var/www/nebuleair_pro_4g/BME280/get_data_v2.py
User=root
WorkingDirectory=/var/www/nebuleair_pro_4g
StandardOutput=append:/var/www/nebuleair_pro_4g/logs/bme280_service.log
StandardError=append:/var/www/nebuleair_pro_4g/logs/bme280_service_errors.log
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/nebuleair-bme280-data.timer << 'EOL'
[Unit]
Description=Run NebuleAir BME280 Data Collection every 120 seconds
Requires=nebuleair-bme280-data.service
[Timer]
OnBootSec=120s
OnUnitActiveSec=120s
AccuracySec=1s
[Install]
WantedBy=timers.target
EOL
# Create service and timer files for MPPT Data
cat > /etc/systemd/system/nebuleair-mppt-data.service << 'EOL'
[Unit]
Description=NebuleAir MPPT Data Collection Service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /var/www/nebuleair_pro_4g/MPPT/read.py
User=root
WorkingDirectory=/var/www/nebuleair_pro_4g
StandardOutput=append:/var/www/nebuleair_pro_4g/logs/mppt_service.log
StandardError=append:/var/www/nebuleair_pro_4g/logs/mppt_service_errors.log
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/nebuleair-mppt-data.timer << 'EOL'
[Unit]
Description=Run NebuleAir MPPT Data Collection every 120 seconds
Requires=nebuleair-mppt-data.service
[Timer]
OnBootSec=120s
OnUnitActiveSec=120s
AccuracySec=1s
[Install]
WantedBy=timers.target
EOL
# Create service and timer files for Database Cleanup
cat > /etc/systemd/system/nebuleair-db-cleanup-data.service << 'EOL'
[Unit]
Description=NebuleAir Database Cleanup Service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /var/www/nebuleair_pro_4g/sqlite/flush_old_data.py
User=root
WorkingDirectory=/var/www/nebuleair_pro_4g
StandardOutput=append:/var/www/nebuleair_pro_4g/logs/db_cleanup_service.log
StandardError=append:/var/www/nebuleair_pro_4g/logs/db_cleanup_service_errors.log
[Install]
WantedBy=multi-user.target
EOL
cat > /etc/systemd/system/nebuleair-db-cleanup-data.timer << 'EOL'
[Unit]
Description=Run NebuleAir Database Cleanup daily
Requires=nebuleair-db-cleanup-data.service
[Timer]
OnBootSec=1h
OnUnitActiveSec=24h
AccuracySec=1h
[Install]
WantedBy=timers.target
EOL
# Reload systemd to recognize new services
systemctl daemon-reload
# Enable and start all timers
echo "Enabling and starting all services..."
for service in npm envea sara bme280 mppt db-cleanup; do
systemctl enable nebuleair-$service-data.timer
systemctl start nebuleair-$service-data.timer
echo "Started nebuleair-$service-data timer"
done
echo "Checking status of all timers..."
systemctl list-timers | grep nebuleair
echo "Setup complete. All NebuleAir services are now running."
echo "To check the status of a specific service:"
echo " sudo systemctl status nebuleair-npm-data.service"
echo "To view logs for a specific service:"
echo " sudo journalctl -u nebuleair-npm-data.service"
echo "To restart a specific timer:"
echo " sudo systemctl restart nebuleair-npm-data.timer"