Merge remote-tracking branch 'refs/remotes/origin/main'
This commit is contained in:
@@ -12,6 +12,8 @@ echo "-------------------"
|
||||
|
||||
echo "NebuleAir pro started at $(date)"
|
||||
|
||||
chmod -R 777 /var/www/nebuleair_pro_4g/
|
||||
|
||||
# Blink GPIO 23 and 24 five times
|
||||
for i in {1..5}; do
|
||||
# Turn GPIO 23 and 24 ON
|
||||
|
||||
@@ -5,3 +5,6 @@
|
||||
@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
|
||||
|
||||
|
||||
@@ -304,6 +304,121 @@ def extract_error_code(response):
|
||||
# Return None if we couldn't find the error code
|
||||
return None
|
||||
|
||||
def modem_complete_reboot_and_reinitialize(modem_version, aircarto_profile_id):
|
||||
"""
|
||||
Performs a complete modem restart sequence:
|
||||
1. Reboots the modem using the appropriate command for its version
|
||||
2. Waits for the modem to restart
|
||||
3. Resets the HTTP profile
|
||||
4. For SARA-R5, resets the PDP connection
|
||||
|
||||
Args:
|
||||
modem_version (str): The modem version, e.g., 'SARA-R500' or 'SARA-R410'
|
||||
aircarto_profile_id (int): The HTTP profile ID to reset
|
||||
|
||||
Returns:
|
||||
bool: True if the complete sequence was successful, False otherwise
|
||||
"""
|
||||
print('<span style="color: orange;font-weight: bold;">🔄 Complete SARA reboot and reinitialize sequence 🔄</span>')
|
||||
|
||||
# Step 1: Reboot the modem - Integrated modem_software_reboot logic
|
||||
print('<span style="color: orange;font-weight: bold;">🔄 Software SARA reboot! 🔄</span>')
|
||||
|
||||
# Use different commands based on modem version
|
||||
if 'R5' in modem_version: # For SARA-R5 series
|
||||
command = 'AT+CFUN=16\r' # Normal restart for R5
|
||||
else: # For SARA-R4 series
|
||||
command = 'AT+CFUN=15\r' # Factory reset for R4
|
||||
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
response = read_complete_response(ser_sara, wait_for_lines=["OK", "ERROR"], debug=True)
|
||||
|
||||
print('<p class="text-danger-emphasis">')
|
||||
print(response)
|
||||
print("</p>", end="")
|
||||
|
||||
# Check if reboot command was acknowledged
|
||||
reboot_success = response is not None and "OK" in response
|
||||
if not reboot_success:
|
||||
print("⚠️ Modem reboot command failed")
|
||||
return False
|
||||
|
||||
# Step 2: Wait for the modem to restart (adjust time as needed)
|
||||
print("Waiting for modem to restart...")
|
||||
time.sleep(15) # 15 seconds should be enough for most modems to restart
|
||||
|
||||
# Step 3: Check if modem is responsive after reboot
|
||||
print("Checking if modem is responsive...")
|
||||
ser_sara.write(b'AT\r')
|
||||
response_check = read_complete_response(ser_sara, wait_for_lines=["OK"], debug=True)
|
||||
if response_check is None or "OK" not in response_check:
|
||||
print("⚠️ Modem not responding after reboot")
|
||||
return False
|
||||
|
||||
print("✅ Modem restarted successfully")
|
||||
|
||||
# Step 4: Reset the HTTP Profile
|
||||
print('<span style="color: orange;font-weight: bold;">🔧 Resetting the 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="")
|
||||
|
||||
http_reset_success = responseResetHTTP is not None and "OK" in responseResetHTTP
|
||||
if not http_reset_success:
|
||||
print("⚠️ HTTP profile reset failed")
|
||||
# Continue anyway, don't return False here
|
||||
|
||||
# Step 5: For SARA-R5, reset the PDP connection
|
||||
pdp_reset_success = True
|
||||
if modem_version == "SARA-R500":
|
||||
print("⚠️ Need to reset PDP connection for SARA-R500")
|
||||
|
||||
# Activate PDP context 1
|
||||
print('➡️ Activate PDP context 1')
|
||||
command = f'AT+CGACT=1,1\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
response_pdp1 = read_complete_response(ser_sara, wait_for_lines=["OK"])
|
||||
print(response_pdp1, end="")
|
||||
pdp_reset_success = pdp_reset_success and (response_pdp1 is not None and "OK" in response_pdp1)
|
||||
time.sleep(1)
|
||||
|
||||
# Set the PDP type
|
||||
print('➡️ Set the PDP type to IPv4 referring to the output of the +CGDCONT read command')
|
||||
command = f'AT+UPSD=0,0,0\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
response_pdp2 = read_complete_response(ser_sara, wait_for_lines=["OK"])
|
||||
print(response_pdp2, end="")
|
||||
pdp_reset_success = pdp_reset_success and (response_pdp2 is not None and "OK" in response_pdp2)
|
||||
time.sleep(1)
|
||||
|
||||
# Profile #0 is mapped on CID=1
|
||||
print('➡️ Profile #0 is mapped on CID=1.')
|
||||
command = f'AT+UPSD=0,100,1\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
response_pdp3 = read_complete_response(ser_sara, wait_for_lines=["OK"])
|
||||
print(response_pdp3, end="")
|
||||
pdp_reset_success = pdp_reset_success and (response_pdp3 is not None and "OK" in response_pdp3)
|
||||
time.sleep(1)
|
||||
|
||||
# Activate the PSD profile
|
||||
print('➡️ Activate the PSD profile #0: the IPv4 address is already assigned by the network.')
|
||||
command = f'AT+UPSDA=0,3\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
response_pdp4 = read_complete_response(ser_sara, wait_for_lines=["OK", "+UUPSDA"])
|
||||
print(response_pdp4, end="")
|
||||
pdp_reset_success = pdp_reset_success and (response_pdp4 is not None and ("OK" in response_pdp4 or "+UUPSDA" in response_pdp4))
|
||||
time.sleep(1)
|
||||
|
||||
if not pdp_reset_success:
|
||||
print("⚠️ PDP connection reset had some issues")
|
||||
|
||||
# Return overall success
|
||||
return http_reset_success and pdp_reset_success
|
||||
|
||||
try:
|
||||
'''
|
||||
_ ___ ___ ____
|
||||
@@ -479,43 +594,50 @@ try:
|
||||
# Getting the LTE Signal
|
||||
print("➡️Getting LTE signal")
|
||||
ser_sara.write(b'AT+CSQ\r')
|
||||
response2 = read_complete_response(ser_sara, wait_for_lines=["OK"])
|
||||
response2 = read_complete_response(ser_sara, wait_for_lines=["OK", "ERROR", "+CME ERROR"])
|
||||
print('<p class="text-danger-emphasis">')
|
||||
print(response2)
|
||||
print("</p>", end="")
|
||||
|
||||
#Here it's possible that the SARA do not repond at all
|
||||
|
||||
#Here it's possible that the SARA do not repond at all or send a error message
|
||||
#-> TO DO : harware reboot
|
||||
#-> send notification
|
||||
#-> end loop, no need to continue
|
||||
if response2 is None or response2 == "" or not any(expected in response2 for expected in ["OK", "ERROR", "+", "AT"]):
|
||||
|
||||
#1. No answer at all form SARA
|
||||
if response2 is None or response2 == "":
|
||||
print("No answer from SARA module")
|
||||
print('🛑STOP LOOP🛑')
|
||||
print("<hr>")
|
||||
|
||||
# Send notification
|
||||
try:
|
||||
# Format the URL with the device_id
|
||||
alert_url = f'http://data.nebuleair.fr/pro_4G/alert.php?capteur_id={device_id}&error_type=serial_error'
|
||||
|
||||
# Send POST request with short timeout
|
||||
response = requests.post(alert_url, timeout=3)
|
||||
|
||||
if response.status_code == 200:
|
||||
print(f"Alert notification sent successfully")
|
||||
else:
|
||||
print(f"Alert notification failed with status code: {response.status_code}")
|
||||
|
||||
except Exception as e:
|
||||
# Catch any exception and continue
|
||||
print(f"Alert notification failed: {e}")
|
||||
|
||||
#end loop
|
||||
sys.exit()
|
||||
|
||||
#2. si on a une erreur
|
||||
elif "+CME ERROR" in response2:
|
||||
print(f"SARA module returned error: {response2}")
|
||||
print("The CSQ command is not supported by this module or in its current state")
|
||||
print("⚠️ATTENTION: SARA is connected over serial but CSQ command not supported")
|
||||
print('🛑STOP LOOP🛑')
|
||||
#end loop
|
||||
sys.exit()
|
||||
|
||||
else :
|
||||
print("✅SARA is connected over serial")
|
||||
|
||||
print('<p class="text-danger-emphasis">')
|
||||
print(response2)
|
||||
print("</p>", end="")
|
||||
|
||||
match = re.search(r'\+CSQ:\s*(\d+),', response2)
|
||||
if match:
|
||||
signal_quality = int(match.group(1))
|
||||
@@ -556,22 +678,27 @@ try:
|
||||
print("Open JSON:")
|
||||
command = f'AT+UDWNFILE="sensordata_csv.json",{size_of_string}\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
response_SARA_1 = read_complete_response(ser_sara, wait_for_lines=[">"], debug=False)
|
||||
response_SARA_1 = read_complete_response(ser_sara, wait_for_lines=[">"], debug=True)
|
||||
print('<p class="text-danger-emphasis">')
|
||||
print(response_SARA_1)
|
||||
print("</p>", end="")
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
#2. Write to shell
|
||||
print("Write data to memory:")
|
||||
ser_sara.write(csv_string.encode())
|
||||
response_SARA_2 = read_complete_response(ser_sara, wait_for_lines=["OK"], debug=False)
|
||||
response_SARA_2 = read_complete_response(ser_sara, wait_for_lines=["OK"], debug=True)
|
||||
print('<p class="text-danger-emphasis">')
|
||||
print(response_SARA_2)
|
||||
print("</p>", end="")
|
||||
|
||||
#3. Send to endpoint (with device ID)
|
||||
print("Send data (POST REQUEST):")
|
||||
command= f'AT+UHTTPC={aircarto_profile_id},4,"/pro_4G/data.php?sensor_id={device_id}&lat{device_latitude_raw}=&long={device_longitude_raw}&datetime={influx_timestamp}","aircarto_server_response.txt","sensordata_csv.json",4\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
|
||||
response_SARA_3 = read_complete_response(ser_sara, timeout=5, end_of_response_timeout=120, wait_for_lines=["+UUHTTPCR", "+CME ERROR"], debug=True)
|
||||
response_SARA_3 = read_complete_response(ser_sara, timeout=5, end_of_response_timeout=120, wait_for_lines=["+UUHTTPCR", "+CME ERROR", "ERROR"], debug=True)
|
||||
|
||||
print('<p class="text-danger-emphasis">')
|
||||
print(response_SARA_3)
|
||||
@@ -678,64 +805,12 @@ try:
|
||||
print('<p class="text-danger">Could not extract error code from response</p>')
|
||||
|
||||
|
||||
#Reboot du SARA R4
|
||||
#ATTENTION: sur le SARA R5 la commande renvoie une erreur
|
||||
print('<span style="color: orange;font-weight: bold;">🔄SARA reboot!🔄</span>')
|
||||
command = f'AT+CFUN=15\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
response_SARA_9r = read_complete_response(ser_sara, wait_for_lines=["OK"], debug=True)
|
||||
print('<p class="text-danger-emphasis">')
|
||||
print(response_SARA_9r)
|
||||
print("</p>", end="")
|
||||
|
||||
reset_uSpot_url = True
|
||||
|
||||
print("Sleep 10 secs before continuing")
|
||||
time.sleep(10)
|
||||
|
||||
#reset l'url AirCarto
|
||||
print('<span style="color: orange;font-weight: bold;">🔧Resetting the HTTP Profile</span>')
|
||||
command = f'AT+UHTTP={aircarto_profile_id},1,"data.nebuleair.fr"\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
responseResetHTTP2_profile = 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(responseResetHTTP2_profile)
|
||||
print("</p>", end="")
|
||||
|
||||
#si on a un sara r5 il faut également reset la connection PDP
|
||||
if modem_version == "SARA-R500":
|
||||
print("⚠️Need to reset PDP connection")
|
||||
# 2. Activate PDP context 1
|
||||
print('➡️Activate PDP context 1')
|
||||
command = f'AT+CGACT=1,1\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
response_SARA_2dpd = read_complete_response(ser_sara, wait_for_lines=["OK"])
|
||||
print(response_SARA_2dpd, end="")
|
||||
time.sleep(1)
|
||||
|
||||
# 2. Set the PDP type
|
||||
print('➡️Set the PDP type to IPv4 referring to the outputof the +CGDCONT read command')
|
||||
command = f'AT+UPSD=0,0,0\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
response_SARA_31dpd = read_complete_response(ser_sara, wait_for_lines=["OK"])
|
||||
print(response_SARA_31dpd, end="")
|
||||
time.sleep(1)
|
||||
|
||||
# 2. Profile #0 is mapped on CID=1.
|
||||
print('➡️Profile #0 is mapped on CID=1.')
|
||||
command = f'AT+UPSD=0,100,1\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
response_SARA_32dpd = read_complete_response(ser_sara, wait_for_lines=["OK"])
|
||||
print(response_SARA_32dpd, end="")
|
||||
time.sleep(1)
|
||||
|
||||
# 2. Set the PDP type
|
||||
print('➡️Activate the PSD profile #0: the IPv4 address is already assigned by the network.')
|
||||
command = f'AT+UPSDA=0,3\r'
|
||||
ser_sara.write(command.encode('utf-8'))
|
||||
response_SARA_33dpd = read_complete_response(ser_sara, wait_for_lines=["OK","+UUPSDA"])
|
||||
print(response_SARA_33dpd, end="")
|
||||
time.sleep(1)
|
||||
#Software Reboot
|
||||
software_reboot_success = modem_complete_reboot_and_reinitialize(modem_version, aircarto_profile_id)
|
||||
if software_reboot_success:
|
||||
print("Modem successfully rebooted and reinitialized")
|
||||
else:
|
||||
print("There were issues with the modem reboot/reinitialize process")
|
||||
|
||||
|
||||
# 2.2 code 1 (✅✅HHTP / UUHTTPCR succeded✅✅)
|
||||
@@ -867,14 +942,30 @@ try:
|
||||
if "+CME ERROR: Operation not allowed" in line:
|
||||
print('<span style="color: red;font-weight: bold;">⚠️ATTENTION: CME ERROR⚠️</span>')
|
||||
print('<span style="color: orange;font-weight: bold;">❓Try Reboot the module❓</span>')
|
||||
#Software Reboot
|
||||
|
||||
if "ERROR" in line:
|
||||
print("⛔Attention ERROR!⛔")
|
||||
#Software Reboot
|
||||
software_reboot_success = modem_complete_reboot_and_reinitialize(modem_version, aircarto_profile_id)
|
||||
if software_reboot_success:
|
||||
print("Modem successfully rebooted and reinitialized")
|
||||
else:
|
||||
print("There were issues with the modem reboot/reinitialize process")
|
||||
|
||||
|
||||
#5. empty json
|
||||
print("Empty SARA memory:")
|
||||
ser_sara.write(b'AT+UDELFILE="sensordata_csv.json"\r')
|
||||
response_SARA_5 = read_complete_response(ser_sara, wait_for_lines=["OK"], debug=False)
|
||||
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)
|
||||
print("</p>", end="")
|
||||
|
||||
if "+CME ERROR" in response_SARA_5:
|
||||
print("⛔ Attention CME ERROR ⛔")
|
||||
|
||||
|
||||
|
||||
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user