''' ____ _ ____ _ / ___| / \ | _ \ / \ \___ \ / _ \ | |_) | / _ \ ___) / ___ \| _ < / ___ \ |____/_/ \_\_| \_\/_/ \_\ 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))