This commit is contained in:
PaulVua
2025-01-09 16:55:31 +01:00
parent 8619f7d3bf
commit 4df29fc157
10 changed files with 1580 additions and 1239 deletions

5
README.md Normal file → Executable file
View File

@@ -25,13 +25,14 @@ sudo mkdir /var/www/nebuleair_pro_4g/logs
sudo touch /var/www/nebuleair_pro_4g/logs/app.log /var/www/nebuleair_pro_4g/logs/loop.log sudo touch /var/www/nebuleair_pro_4g/logs/app.log /var/www/nebuleair_pro_4g/logs/loop.log
sudo cp /var/www/nebuleair_pro_4g/config.json.dist /var/www/nebuleair_pro_4g/config.json sudo cp /var/www/nebuleair_pro_4g/config.json.dist /var/www/nebuleair_pro_4g/config.json
sudo chmod -R 777 /var/www/nebuleair_pro_4g/ sudo chmod -R 777 /var/www/nebuleair_pro_4g/
git config core.fileMode false git config --global core.fileMode false
git config --global --add safe.directory /var/www/nebuleair_pro_4g
sudo crontab /var/www/nebuleair_pro_4g/cron_jobs sudo crontab /var/www/nebuleair_pro_4g/cron_jobs
``` ```
## Apache ## Apache
Configuration of Apache to redirect to the html homepage project Configuration of Apache to redirect to the html homepage project
``` ```
sudo sed -i 's|DocumentRoot /var/www/html|DocumentRoot /var/www/nebuleair_pro_4g/html|' /etc/apache2/sites-available/000-default.conf sudo sed -i 's|DocumentRoot /var/www/html|DocumentRoot /var/www/nebuleair_pro_4g|' /etc/apache2/sites-available/000-default.conf
sudo systemctl reload apache2 sudo systemctl reload apache2
``` ```

View File

@@ -2,6 +2,9 @@
Script to see if the SARA-R410 is running Script to see if the SARA-R410 is running
ex: ex:
python3 /var/www/nebuleair_pro_4g/SARA/sara.py ttyAMA2 AT+CCID? 2 python3 /var/www/nebuleair_pro_4g/SARA/sara.py ttyAMA2 AT+CCID? 2
ex 2 (turn on blue light):
python3 /var/www/nebuleair_pro_4g/SARA/sara.py ttyAMA2 AT+UGPIOC=16,2 2
''' '''
import serial import serial

68
SARA/sara_setAPN.py Executable file
View File

@@ -0,0 +1,68 @@
'''
Script to connect SARA-R410 to APN
AT+CGDCONT=1,"IP","data.mono"
/usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_setAPN.py ttyAMA2 data.mono 2
'''
import serial
import time
import sys
import json
parameter = sys.argv[1:] # Exclude the script name
port='/dev/'+parameter[0] # ex: ttyAMA2
apn_address = parameter[1] # ex: data.mono
timeout = float(parameter[2]) # ex:2
#get baudrate
def load_config(config_file):
try:
with open(config_file, 'r') as file:
config_data = json.load(file)
return config_data
except Exception as e:
print(f"Error loading config file: {e}")
return {}
# Define the config file path
config_file = '/var/www/nebuleair_pro_4g/config.json'
# Load the configuration data
config = load_config(config_file)
# Access the shared variables
baudrate = config.get('SaraR4_baudrate', 115200)
ser = serial.Serial(
port=port, #USB0 or ttyS0
baudrate=baudrate, #115200 ou 9600
parity=serial.PARITY_NONE, #PARITY_NONE, PARITY_EVEN or PARITY_ODD
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout = timeout
)
command = f'AT+CGDCONT=1,"IP","{apn_address}"\r'
ser.write((command + '\r').encode('utf-8'))
try:
# Read lines until a timeout occurs
response_lines = []
while True:
line = ser.readline().decode('utf-8').strip()
if not line:
break # Break the loop if an empty line is encountered
response_lines.append(line)
# Print the response
for line in response_lines:
print(line)
except serial.SerialException as e:
print(f"Error: {e}")
finally:
if ser.is_open:
ser.close()
#print("Serial closed")

View File

@@ -6,7 +6,7 @@
"NextPM_ports": [ "NextPM_ports": [
"ttyAMA5" "ttyAMA5"
], ],
"i2C_sound": true, "i2C_sound": false,
"i2c_BME": false, "i2c_BME": false,
"sshTunnel_port": 59228, "sshTunnel_port": 59228,
"npm1_status": "connected", "npm1_status": "connected",
@@ -14,10 +14,10 @@
"SARA_R4_SIM_status": "connected", "SARA_R4_SIM_status": "connected",
"SARA_R4_network_status": "connected", "SARA_R4_network_status": "connected",
"WIFI_status": "connected", "WIFI_status": "connected",
"MQTT_GUI": true, "MQTT_GUI": false,
"envea_sondes": [ "envea_sondes": [
{ {
"connected": true, "connected": false,
"port": "ttyAMA4", "port": "ttyAMA4",
"name": "h2s", "name": "h2s",
"coefficient" : 4 "coefficient" : 4

View File

@@ -115,7 +115,7 @@ if ($type == "sara_APN") {
$port=$_GET['port']; $port=$_GET['port'];
$timeout=$_GET['timeout']; $timeout=$_GET['timeout'];
$APN_address=$_GET['APN_address']; $APN_address=$_GET['APN_address'];
$command = '/usr/bin/python3 /var/www/moduleair_pro_4g/SARA/sara_setAPN.py ' . $port . ' ' . $APN_address . ' ' . $timeout; $command = '/usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_setAPN.py ' . $port . ' ' . $APN_address . ' ' . $timeout;
$output = shell_exec($command); $output = shell_exec($command);
echo $output; echo $output;
} }

View File

@@ -55,6 +55,7 @@
Status Status
<span id="modem-status" class="badge">Loading...</span> <span id="modem-status" class="badge">Loading...</span>
</h3> </h3>
<div class="row mb-3"> <div class="row mb-3">
<div class="col-sm-3"> <div class="col-sm-3">
@@ -111,6 +112,7 @@
</div> </div>
<h3>Connexion 4G Network</h3> <h3>Connexion 4G Network</h3>
<div class="row mb-3"> <div class="row mb-3">
<div class="col-sm-6"> <div class="col-sm-6">
@@ -118,6 +120,8 @@
<div class="card-body"> <div class="card-body">
<p class="card-text">Network scan. Attention: 2 min scan.</p> <p class="card-text">Network scan. Attention: 2 min scan.</p>
<p class="card-text">Orange FR (20801), SFR (20810), Bouygues (20820)</p>
<button class="btn btn-primary" onclick="getData_saraR4('ttyAMA2', 'AT+COPS=?', 120)">Scan</button> <button class="btn btn-primary" onclick="getData_saraR4('ttyAMA2', 'AT+COPS=?', 120)">Scan</button>
<div id="loading_ttyAMA2_AT_COPS__" class="spinner-border spinner-border-sm" style="display: none;" role="status"></div> <div id="loading_ttyAMA2_AT_COPS__" class="spinner-border spinner-border-sm" style="display: none;" role="status"></div>
<div id="response_ttyAMA2_AT_COPS__"></div> <div id="response_ttyAMA2_AT_COPS__"></div>
@@ -152,7 +156,8 @@
<span class="input-group-text" id="inputGroup-sizing-sm">Address</span> <span class="input-group-text" id="inputGroup-sizing-sm">Address</span>
<input type="text" id="messageInput_APN" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm"> <input type="text" id="messageInput_APN" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm">
</div> </div>
<button class="btn btn-primary" onclick="connectAPN_saraR4('ttyAMA2', document.getElementById('messageInput_APN').value, 5)">Connect</button> <button class="btn btn-primary" onclick="connectAPN_saraR4('ttyAMA2', document.getElementById('messageInput_APN').value, 5)">Set APN</button>
<button class="btn btn-secondary" onclick="getData_saraR4('ttyAMA2','AT+CGDCONT?', 5)">Get APN</button> <button class="btn btn-secondary" onclick="getData_saraR4('ttyAMA2','AT+CGDCONT?', 5)">Get APN</button>
<div id="loading_ttyAMA2_APN" class="spinner-border spinner-border-sm" style="display: none;" role="status"></div> <div id="loading_ttyAMA2_APN" class="spinner-border spinner-border-sm" style="display: none;" role="status"></div>
@@ -536,6 +541,7 @@ function getData_saraR4(port, command, timeout){
} }
function sendMessage_saraR4(port, endpoint){ function sendMessage_saraR4(port, endpoint){
console.log("Send message from SaraR4 (port "+port+" and endpoint "+endpoint+"):"); console.log("Send message from SaraR4 (port "+port+" and endpoint "+endpoint+"):");
$("#loading_"+port+"_message_send").show(); $("#loading_"+port+"_message_send").show();
@@ -558,8 +564,11 @@ function getData_saraR4(port, command, timeout){
} }
function connectAPN_saraR4(port, APN_address, timeout){ function connectAPN_saraR4(port, APN_address, timeout){
console.log(" Set APN (port "+port+" and adress "+APN_address+"):"); console.log(" Set APN (port "+port+" and adress "+APN_address+"):");
$("#loading_"+port+"_APN").show(); $("#loading_"+port+"_APN").show();
$.ajax({ $.ajax({
url: 'launcher.php?type=sara_APN&port='+port+'&APN_address='+encodeURIComponent(APN_address)+'&timeout='+timeout, url: 'launcher.php?type=sara_APN&port='+port+'&APN_address='+encodeURIComponent(APN_address)+'&timeout='+timeout,
//dataType: 'json', // Specify that you expect a JSON response //dataType: 'json', // Specify that you expect a JSON response

View File

@@ -48,9 +48,65 @@
<aside class="col-md-2 col-lg-1 d-none d-md-block vh-100 position-fixed bg-dark text-white" id="sidebar"> <aside class="col-md-2 col-lg-1 d-none d-md-block vh-100 position-fixed bg-dark text-white" id="sidebar">
</aside> </aside>
<!-- Main content --> <!-- Main content -->
<main class="col-md-9 ms-sm-auto col-lg-10 offset-md-3 offset-lg-2 px-md-4"> <main class="col-md-10 ms-sm-auto col-lg-11 offset-md-2 offset-lg-1 px-md-4">
<h1 class="mt-4">Connection WIFI</h1> <h1 class="mt-4">Connection WIFI</h1>
<p>La connexion WIFI n'est pas obligatoire mais elle vous permet d'effectuer des mises à jour et d'activer le contrôle à distance.</p> <p>La connexion WIFI n'est pas obligatoire mais elle vous permet d'effectuer des mises à jour et d'activer le contrôle à distance.</p>
<h3>Status
<span id="wifi-status" class="badge">Loading...</span>
</h3>
<div class="row mb-3">
<div class="col-sm-4">
<div class="card text-dark bg-light">
<div class="card-body">
<h5 class="card-title">WIFI / Ethernet</h5>
<p class="card-text">General information.</p>
<button class="btn btn-primary" onclick="get_internet()">Get Data</button>
<table class="table table-striped-columns">
<tbody id="data-table-body_internet_general"></tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-8">
<div class="card text-dark bg-light">
<div class="card-body">
<h5 class="card-title">Wifi Scan</h5>
<p class="card-text">Scan des réseaux WIFI disponibles.</p>
<button class="btn btn-primary" onclick="wifi_scan()">Scan</button>
<table class="table">
<tbody id="data-table-body_wifi_scan"></tbody>
</table>
</table>
</div>
</div>
</div>
<!-- Modal WIFI PASSWORD -->
<!-- filled with JS -->
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="myModalLabel">Modal title</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="myModalBody">
...
</div>
<div class="modal-footer" id="myModalFooter">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
<div>
</main> </main>
</div> </div>
</div> </div>
@@ -64,6 +120,8 @@
<script> <script>
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {
console.log("DOMContentLoaded");
const elementsToLoad = [ const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' }, { id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' }, { id: 'sidebar', file: 'sidebar.html' },
@@ -81,7 +139,151 @@
}) })
.catch(error => console.error(`Error loading ${file}:`, error)); .catch(error => console.error(`Error loading ${file}:`, error));
}); });
}); });
function get_internet(){
console.log("Getting internet general infos");
$.ajax({
url: 'launcher.php?type=internet',
dataType: 'json', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
success: function(response) {
console.log(response);
let tableBody = document.getElementById('data-table-body_internet_general');
tableBody.innerHTML = ''; // Clear existing table content
// Iterate through the data and create rows
for (let key in response) {
let row = `
<tr>
<td>${key}</td>
<td>${response[key].connection}</td>
<td>${response[key].IP ? response[key].IP : "No IP"}</td>
</tr>
`;
tableBody.innerHTML += row; // Append row to table body
}
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
function wifi_connect(SSID, PASS){
console.log("Connecting to wifi");
console.log(SSID);
console.log(PASS);
if (typeof PASS === 'undefined') {
console.log("Need to add password");
//open bootstrap modal to ask for password
var myModal = new bootstrap.Modal(document.getElementById('myModal'));
//modifiy modal title
document.getElementById('myModalLabel').innerHTML = "Enter password for "+SSID;
//add input field to modal body
document.getElementById('myModalBody').innerHTML = "<input type='text' id='wifi_pass' class='form-control' placeholder='Password'>";
//add button to modal footer
document.getElementById('myModalFooter').innerHTML = "<button type='button' class='btn btn-secondary' data-bs-dismiss='modal'>Close</button><button type='button' class='btn btn-primary' onclick='wifi_connect(\""+SSID+"\", document.getElementById(\"wifi_pass\").value)'>Se connecter</button>";
myModal.show();
} else {
console.log("Will try to connect to "+SSID+" with password "+PASS);
console.log("Start PHP script:");
$.ajax({
url: 'launcher.php?type=wifi_connect&SSID='+SSID+'&pass='+PASS,
dataType: 'text', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
success: function(response) {
console.log(response);
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
}
function wifi_scan(){
console.log("Scanning Wifi");
$.ajax({
url: 'launcher.php?type=wifi_scan',
dataType: 'json', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
success: function(response) {
console.log(response);
const tableBody = document.getElementById("data-table-body_wifi_scan");
// Clear the existing table body
tableBody.innerHTML = "";
// Loop through the wifiNetworks array and create rows
response.forEach(network => {
const row = document.createElement("tr");
// Create and append cells for SSID, BARS, and SIGNAL
const ssidCell = document.createElement("td");
// Truncate SSID to 25 characters
const truncatedSSID = network.SSID.length > 20 ? network.SSID.substring(0, 20) + '...' : network.SSID;
ssidCell.textContent = truncatedSSID;
row.appendChild(ssidCell);
/*
const signalCell = document.createElement("td");
signalCell.textContent = network.SIGNAL;
row.appendChild(signalCell);
*/
// Create a button
const buttonCell = document.createElement("td");
const button = document.createElement("button");
button.textContent = "Connect"; // Button text
button.classList.add("btn", "btn-primary"); // Bootstrap button classes
// Determine button color based on SIGNAL value
const signalValue = parseInt(network.SIGNAL, 10); // Assuming SIGNAL is a numeric value
// Calculate color based on the signal strength
let buttonColor;
if (signalValue >= 100) {
buttonColor = "success"; // Green for strong signal
} else if (signalValue >= 50) {
buttonColor = "warning"; // Yellow for moderate signal
} else {
buttonColor = "danger"; // Red for weak signal
}
// Add Bootstrap button classes along with color
button.classList.add("btn", `btn-${buttonColor}`);
//Trigger function as soon as the button is clicked
button.addEventListener("click", () => wifi_connect(network.SSID));
// Append the button to the button cell
buttonCell.appendChild(button);
row.appendChild(buttonCell);
// Append the row to the table body
tableBody.appendChild(row);
});
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
function confirmSubmit() {
// You can display a simple confirmation message or customize the behavior
return confirm("Are you sure you want to connect to this Wi-Fi network?");
}
</script> </script>
</body> </body>

1269
index.html

File diff suppressed because it is too large Load Diff

1235
index_old.html Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -368,7 +368,7 @@ try:
# 2.2 code 1 (HHTP succeded) # 2.2 code 1 (HHTP succeded)
else: else:
# Si la commande HTTP a réussi # Si la commande HTTP a réussi
print('<span style="color: green; font-weight: bold;">HTTP operation successful.</span>') print('<span class="badge text-bg-success">HTTP operation successful.</span>')
update_json_key(config_file, "SARA_R4_network_status", "connected") update_json_key(config_file, "SARA_R4_network_status", "connected")
print("Turning on the blue LED...") print("Turning on the blue LED...")
for _ in range(4): # Faire clignoter 4 fois for _ in range(4): # Faire clignoter 4 fois
@@ -382,7 +382,9 @@ try:
response_SARA_4 = read_complete_response(ser_sara) response_SARA_4 = read_complete_response(ser_sara)
if need_to_log: if need_to_log:
print("Reply from server:") print("Reply from server:")
print('<p class="text-success">')
print(response_SARA_4) print(response_SARA_4)
print('</p>')
#5. empty json #5. empty json
ser_sara.write(b'AT+UDELFILE="sensordata.json"\r') ser_sara.write(b'AT+UDELFILE="sensordata.json"\r')