Page modem: reset hardware GPIO 16 + alerte mode configuration + reset au boot
- Bouton Reset Hardware (GPIO 16) avec verification ATI apres redemarrage - Bandeau d'alerte rouge quand mode configuration actif (transmission desactivee) - Reset automatique de modem_config_mode a 0 au boot (SARA/reboot/start.py) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
72
SARA/reboot/hardware_reboot.py
Normal file
72
SARA/reboot/hardware_reboot.py
Normal file
@@ -0,0 +1,72 @@
|
||||
'''
|
||||
____ _ ____ _
|
||||
/ ___| / \ | _ \ / \
|
||||
\___ \ / _ \ | |_) | / _ \
|
||||
___) / ___ \| _ < / ___ \
|
||||
|____/_/ \_\_| \_\/_/ \_\
|
||||
|
||||
sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/reboot/hardware_reboot.py
|
||||
|
||||
Hardware reboot of the SARA R5 modem using GPIO 16 (GND control via transistor).
|
||||
Cuts power for 3 seconds, then verifies modem is responsive with ATI command.
|
||||
Returns JSON result for web interface.
|
||||
'''
|
||||
|
||||
import RPi.GPIO as GPIO
|
||||
import serial
|
||||
import time
|
||||
import json
|
||||
import sqlite3
|
||||
|
||||
SARA_GND_GPIO = 16
|
||||
|
||||
# Load baudrate from config
|
||||
conn = sqlite3.connect("/var/www/nebuleair_pro_4g/sqlite/sensors.db")
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT value FROM config_table WHERE key='SaraR4_baudrate'")
|
||||
row = cursor.fetchone()
|
||||
baudrate = int(row[0]) if row else 115200
|
||||
conn.close()
|
||||
|
||||
result = {
|
||||
"reboot": False,
|
||||
"modem_response": None,
|
||||
"error": None
|
||||
}
|
||||
|
||||
try:
|
||||
# Step 1: Cut GND (modem off)
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setup(SARA_GND_GPIO, GPIO.OUT)
|
||||
GPIO.output(SARA_GND_GPIO, GPIO.LOW)
|
||||
time.sleep(3)
|
||||
|
||||
# Step 2: Restore GND (modem on)
|
||||
GPIO.output(SARA_GND_GPIO, GPIO.HIGH)
|
||||
time.sleep(5) # wait for modem boot
|
||||
|
||||
# Step 3: Check modem with ATI
|
||||
ser = serial.Serial('/dev/ttyAMA2', baudrate=baudrate, timeout=3)
|
||||
ser.reset_input_buffer()
|
||||
|
||||
for attempt in range(5):
|
||||
ser.write(b'ATI\r')
|
||||
time.sleep(1)
|
||||
response = ser.read(ser.in_waiting or 1).decode('utf-8', errors='replace')
|
||||
if "OK" in response:
|
||||
result["reboot"] = True
|
||||
result["modem_response"] = response.strip()
|
||||
break
|
||||
time.sleep(2)
|
||||
else:
|
||||
result["error"] = "Modem ne repond pas apres le redemarrage"
|
||||
|
||||
ser.close()
|
||||
|
||||
except Exception as e:
|
||||
result["error"] = str(e)
|
||||
|
||||
finally:
|
||||
GPIO.cleanup(SARA_GND_GPIO)
|
||||
|
||||
print(json.dumps(result))
|
||||
@@ -175,6 +175,11 @@ def read_complete_response(serial_connection, timeout=2, end_of_response_timeout
|
||||
try:
|
||||
print('<h3>Start reboot python script</h3>')
|
||||
|
||||
# Reset modem_config_mode at boot to prevent capteur from staying stuck in config mode
|
||||
cursor.execute("UPDATE config_table SET value = '0' WHERE key = 'modem_config_mode'")
|
||||
conn.commit()
|
||||
print("modem_config_mode reset to 0 (boot safety)")
|
||||
|
||||
#First we need to power on the module (if connected to mosfet via gpio16)
|
||||
GPIO.output(SARA_power_GPIO, GPIO.HIGH)
|
||||
time.sleep(5)
|
||||
|
||||
@@ -880,6 +880,13 @@ if ($type == "sara") {
|
||||
echo $output;
|
||||
}
|
||||
|
||||
# SARA HARDWARE REBOOT (GPIO 16)
|
||||
if ($type == "sara_hardware_reboot") {
|
||||
$command = 'sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/reboot/hardware_reboot.py';
|
||||
$output = shell_exec($command);
|
||||
echo $output;
|
||||
}
|
||||
|
||||
# SARA R4 COMMANDS (MQTT)
|
||||
if ($type == "sara_getMQTT_config") {
|
||||
$port=$_GET['port'];
|
||||
|
||||
@@ -58,6 +58,16 @@
|
||||
<label class="form-check-label" for="check_modem_configMode">Mode configuration</label>
|
||||
</div>
|
||||
|
||||
<div id="configmode_alert" class="alert alert-danger d-flex align-items-center py-3 mb-3" role="alert" style="display:none;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-exclamation-triangle-fill me-3 flex-shrink-0" viewBox="0 0 16 16">
|
||||
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5m.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2"/>
|
||||
</svg>
|
||||
<div>
|
||||
<strong>Mode configuration actif — le capteur n'envoie aucune donnée !</strong><br>
|
||||
<small>Le script de transmission (SARA) est désactivé tant que ce mode est actif. Pensez à le désactiver une fois la configuration terminée. Ce mode sera automatiquement désactivé au prochain redémarrage du capteur.</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-success mb-3 btn_selfTest" onclick="runSelfTest()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check2-circle me-1" viewBox="0 0 16 16">
|
||||
<path d="M2.5 8a5.5 5.5 0 1 1 11 0 5.5 5.5 0 0 1-11 0z"/>
|
||||
@@ -151,14 +161,22 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2">
|
||||
<div class="col-sm-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<p class="card-text">Modem Reset </p>
|
||||
<button class="btn btn-danger" onclick="getData_saraR4('ttyAMA2', 'AT+CFUN=15', 1)">Reset</button>
|
||||
<p class="card-text"><strong>Modem Reset</strong></p>
|
||||
|
||||
<p class="text-muted small mb-2">Reset software (AT+CFUN=15) : redémarre le firmware du modem.</p>
|
||||
<button class="btn btn-warning mb-2" onclick="getData_saraR4('ttyAMA2', 'AT+CFUN=15', 1)">Reset Software</button>
|
||||
<div id="loading_ttyAMA2_AT_CFUN_15" class="spinner-border spinner-border-sm" style="display: none;" role="status"></div>
|
||||
<div id="response_ttyAMA2_AT_CFUN_15"></div>
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="text-muted small mb-2">Reset hardware (GPIO 16) : coupe et rétablit l'alimentation du modem.</p>
|
||||
<button class="btn btn-danger mb-2" onclick="hardwareRebootSara()">Reset Hardware</button>
|
||||
<div id="loading_hw_reboot" class="spinner-border spinner-border-sm" style="display: none;" role="status"></div>
|
||||
<div id="response_hw_reboot"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -446,6 +464,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
if (check_modem_configMode) {
|
||||
check_modem_configMode.checked = response.modem_config_mode;
|
||||
console.log("Modem configuration: " + response.modem_config_mode);
|
||||
// Show/hide config mode alert banner
|
||||
const alertEl = document.getElementById("configmode_alert");
|
||||
if (alertEl) alertEl.style.display = response.modem_config_mode ? "flex" : "none";
|
||||
} else {
|
||||
console.error("Checkbox element not found");
|
||||
}
|
||||
@@ -1024,6 +1045,48 @@ function getSignalInfo(port, timeout) {
|
||||
});
|
||||
}
|
||||
|
||||
function hardwareRebootSara() {
|
||||
if (!confirm("Couper l'alimentation du modem SARA via GPIO 16 ?\nLe modem sera éteint pendant ~3 secondes puis redémarré.")) return;
|
||||
|
||||
console.log("Hardware reboot SARA via GPIO 16");
|
||||
$("#loading_hw_reboot").show();
|
||||
$("#response_hw_reboot").empty();
|
||||
|
||||
$.ajax({
|
||||
url: 'launcher.php?type=sara_hardware_reboot',
|
||||
dataType: 'json',
|
||||
method: 'GET',
|
||||
timeout: 30000,
|
||||
success: function(response) {
|
||||
console.log(response);
|
||||
$("#loading_hw_reboot").hide();
|
||||
|
||||
if (response.reboot) {
|
||||
$("#response_hw_reboot").html(`
|
||||
<div class="alert alert-success py-2 mt-2">
|
||||
<strong>Modem redémarré</strong><br>
|
||||
<small><code>${response.modem_response}</code></small>
|
||||
</div>`);
|
||||
} else {
|
||||
$("#response_hw_reboot").html(`
|
||||
<div class="alert alert-danger py-2 mt-2">
|
||||
<strong>Echec</strong><br>
|
||||
<small>${response.error || 'Modem ne répond pas'}</small>
|
||||
</div>`);
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('Hardware reboot failed:', status, error);
|
||||
$("#loading_hw_reboot").hide();
|
||||
$("#response_hw_reboot").html(`
|
||||
<div class="alert alert-danger py-2 mt-2">
|
||||
<strong>Erreur de communication</strong><br>
|
||||
<small>${error}</small>
|
||||
</div>`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getData_saraR4(port, command, timeout){
|
||||
console.log("Data from SaraR4");
|
||||
console.log("Port: " + port );
|
||||
@@ -1429,6 +1492,10 @@ function update_modem_configMode(param, checked){
|
||||
const toastBody = toastLiveExample.querySelector('.toast-body');
|
||||
|
||||
console.log("updating modem config mode to :" + checked);
|
||||
// Toggle alert banner immediately
|
||||
const alertEl = document.getElementById("configmode_alert");
|
||||
if (alertEl) alertEl.style.display = checked ? "flex" : "none";
|
||||
|
||||
$.ajax({
|
||||
url: 'launcher.php?type=update_config_sqlite¶m='+param+'&value='+checked,
|
||||
dataType: 'json', // Specify that you expect a JSON response
|
||||
|
||||
Reference in New Issue
Block a user