This commit is contained in:
Your Name
2025-03-26 10:30:24 +01:00
parent e75caff929
commit 970a36598c
6 changed files with 119 additions and 45 deletions

View File

@@ -81,7 +81,7 @@
<div class="form-check mb-3"> <div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="check_NPM_5channels" onchange="update_config_sqlite('npm_5channel', this.checked)"> <input class="form-check-input" type="checkbox" value="" id="check_NPM_5channels" onchange="update_config_sqlite('npm_5channel', this.checked)">
<label class="form-check-label" for="check_NPM_5channels"> <label class="form-check-label" for="check_NPM_5channels">
Next PM send 5 channels Next PM send 5 channels (no script)
</label> </label>
</div> </div>
@@ -107,9 +107,9 @@
</div> </div>
<div class="form-check mb-3"> <div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="check_WindMeter" onchange="update_config_scripts_sqlite('windMeter/read.py', this.checked)"> <input class="form-check-input" type="checkbox" value="" id="check_WindMeter" onchange="update_config_sqlite('windMeter', this.checked)">
<label class="form-check-label" for="check_WindMeter"> <label class="form-check-label" for="check_WindMeter">
Wind Meter Wind Meter (no script -> systemd service)
</label> </label>
</div> </div>
@@ -251,6 +251,10 @@ window.onload = function() {
//nextPM send 5 channels //nextPM send 5 channels
const checkbox_nmp5channels = document.getElementById("check_NPM_5channels"); const checkbox_nmp5channels = document.getElementById("check_NPM_5channels");
checkbox_nmp5channels.checked = response.npm_5channel; checkbox_nmp5channels.checked = response.npm_5channel;
//windMeter (as a config not a script -> it's running with a systemd service)
const checkbox_wind = document.getElementById("check_WindMeter");
checkbox_wind.checked = response["windMeter"];
}, },
@@ -273,13 +277,11 @@ window.onload = function() {
const checkbox_bme = document.getElementById("check_bme280"); const checkbox_bme = document.getElementById("check_bme280");
const checkbox_envea = document.getElementById("check_envea"); const checkbox_envea = document.getElementById("check_envea");
const checkbox_solar = document.getElementById("check_solarBattery"); const checkbox_solar = document.getElementById("check_solarBattery");
const checkbox_wind = document.getElementById("check_WindMeter");
checkbox_NPM.checked = response["NPM/get_data_modbus_v3.py"]; checkbox_NPM.checked = response["NPM/get_data_modbus_v3.py"];
checkbox_bme.checked = response["BME280/get_data_v2.py"]; checkbox_bme.checked = response["BME280/get_data_v2.py"];
checkbox_envea.checked = response["envea/read_value_v2.py"]; checkbox_envea.checked = response["envea/read_value_v2.py"];
checkbox_solar.checked = response["MPPT/read.py"]; checkbox_solar.checked = response["MPPT/read.py"];
checkbox_wind.checked = response["windMeter/read.py"];
//si sonde envea is true //si sonde envea is true
if (response["envea/read_value_v2.py"]) { if (response["envea/read_value_v2.py"]) {

View File

@@ -71,6 +71,8 @@
<button class="btn btn-primary" onclick="get_data_sqlite('data_BME280',getSelectedLimit(),false)">Mesures Temp/Hum</button> <button class="btn btn-primary" onclick="get_data_sqlite('data_BME280',getSelectedLimit(),false)">Mesures Temp/Hum</button>
<button class="btn btn-primary" onclick="get_data_sqlite('data_NPM_5channels',getSelectedLimit(),false)">Mesures PM (5 canaux)</button> <button class="btn btn-primary" onclick="get_data_sqlite('data_NPM_5channels',getSelectedLimit(),false)">Mesures PM (5 canaux)</button>
<button class="btn btn-primary" onclick="get_data_sqlite('data_envea',getSelectedLimit(),false)">Sonde Cairsens</button> <button class="btn btn-primary" onclick="get_data_sqlite('data_envea',getSelectedLimit(),false)">Sonde Cairsens</button>
<button class="btn btn-primary" onclick="get_data_sqlite('data_WIND',getSelectedLimit(),false)">Sonde Vent</button>
<button class="btn btn-warning" onclick="get_data_sqlite('timestamp_table',getSelectedLimit(),false)">Timestamp Table</button> <button class="btn btn-warning" onclick="get_data_sqlite('timestamp_table',getSelectedLimit(),false)">Timestamp Table</button>
</div> </div>
@@ -147,42 +149,50 @@
window.onload = function() { window.onload = function() {
fetch('../config.json') // Replace 'deviceID.txt' with 'config.json'
.then(response => response.json()) // Parse response as JSON
.then(data => {
console.log("Getting config file (onload)");
//get device ID
const deviceID = data.deviceID.trim().toUpperCase();
//document.getElementById('pageTitle_plus_ID').innerText = 'token: ' + deviceID;
//get device Name
const deviceName = data.deviceName;
const elements = document.querySelectorAll('.sideBar_sensorName');
elements.forEach((element) => {
element.innerText = deviceName;
});
//get local RTC //NEW way to get data from SQLITE
$.ajax({ $.ajax({
url: 'launcher.php?type=RTC_time', url: 'launcher.php?type=get_config_sqlite',
dataType: 'text', // Specify that you expect a JSON response dataType:'json',
method: 'GET', // Use GET or POST depending on your needs //dataType: 'json', // Specify that you expect a JSON response
success: function(response) { method: 'GET', // Use GET or POST depending on your needs
console.log("Local RTC: " + response); success: function(response) {
const RTC_Element = document.getElementById("RTC_time"); console.log("Getting SQLite config table:");
RTC_Element.textContent = response; console.log(response);
},
error: function(xhr, status, error) { //get device Name (for the side bar)
console.error('AJAX request failed:', status, error); const deviceName = response.deviceName;
} const elements = document.querySelectorAll('.sideBar_sensorName');
elements.forEach((element) => {
element.innerText = deviceName;
}); });
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
}); //end ajax
})
.catch(error => console.error('Error loading config.json:', error)); //get local RTC
} $.ajax({
url: 'launcher.php?type=RTC_time',
dataType: 'text', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
success: function(response) {
console.log("Local RTC: " + response);
const RTC_Element = document.getElementById("RTC_time");
RTC_Element.textContent = response;
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
}); //end AJAX
}
@@ -199,7 +209,6 @@ function get_data_sqlite(table, limit, download , startDate = "", endDate = "")
console.log(url); console.log(url);
$.ajax({ $.ajax({
url: url, url: url,
dataType: 'text', // Specify that you expect a JSON response dataType: 'text', // Specify that you expect a JSON response
@@ -260,6 +269,12 @@ function get_data_sqlite(table, limit, download , startDate = "", endDate = "")
tableHTML += ` tableHTML += `
<th>Timestamp</th> <th>Timestamp</th>
`; `;
}else if (table === "data_WIND") {
tableHTML += `
<th>Timestamp</th>
<th>speed (km/h)</th>
<th>Direction (V)</th>
`;
} }
tableHTML += `</tr></thead><tbody>`; tableHTML += `</tr></thead><tbody>`;
@@ -310,6 +325,12 @@ function get_data_sqlite(table, limit, download , startDate = "", endDate = "")
tableHTML += ` tableHTML += `
<td>${columns[1]}</td> <td>${columns[1]}</td>
`; `;
}else if (table === "data_WIND") {
tableHTML += `
<td>${columns[0]}</td>
<td>${columns[1]}</td>
<td>${columns[2]}</td>
`;
} }
tableHTML += "</tr>"; tableHTML += "</tr>";

View File

@@ -156,7 +156,7 @@ window.onload = function() {
error: function(xhr, status, error) { error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error); console.error('AJAX request failed:', status, error);
} }
}); }); //end ajax
/* OLD way of getting config data /* OLD way of getting config data
fetch('../config.json') // Replace 'deviceID.txt' with 'config.json' fetch('../config.json') // Replace 'deviceID.txt' with 'config.json'

View File

@@ -54,6 +54,8 @@ CSV PAYLOAD (AirCarto Servers)
22 -> solar_voltage 22 -> solar_voltage
23 -> solar_power 23 -> solar_power
24 -> charger_status 24 -> charger_status
25 -> Wind speed
26 -> Wind direction
JSON PAYLOAD (Micro-Spot Servers) JSON PAYLOAD (Micro-Spot Servers)
Same as NebuleAir wifi Same as NebuleAir wifi
@@ -235,6 +237,8 @@ Sara_baudrate = config.get('SaraR4_baudrate', 115200)
npm_5channel = config.get('npm_5channel', False) #5 canaux du NPM npm_5channel = config.get('npm_5channel', False) #5 canaux du NPM
selected_networkID = int(config.get('SARA_R4_neworkID', 0)) selected_networkID = int(config.get('SARA_R4_neworkID', 0))
send_uSpot = config.get('send_uSpot', False) #envoi sur MicroSpot () send_uSpot = config.get('send_uSpot', False) #envoi sur MicroSpot ()
wind_meter= config.get('windMeter', False)
reset_uSpot_url = False reset_uSpot_url = False
#config_scripts #config_scripts
@@ -242,7 +246,6 @@ config_scripts = load_config_scripts_sqlite()
bme_280_config = config_scripts.get('BME280/get_data_v2.py', False) bme_280_config = config_scripts.get('BME280/get_data_v2.py', False)
envea_cairsens= config_scripts.get('envea/read_value_v2.py', False) envea_cairsens= config_scripts.get('envea/read_value_v2.py', False)
mppt_charger= config_scripts.get('MPPT/read.py', False) mppt_charger= config_scripts.get('MPPT/read.py', False)
wind_meter= config_scripts.get('windMeter/read.py', False)
#update device id in the payload json #update device id in the payload json
payload_json["nebuleairid"] = device_id payload_json["nebuleairid"] = device_id
@@ -628,6 +631,20 @@ try:
#Wind meter #Wind meter
if wind_meter: if wind_meter:
print("Getting wind meter values") print("Getting wind meter values")
cursor.execute("SELECT * FROM data_WIND ORDER BY rowid DESC LIMIT 1")
last_row = cursor.fetchone()
if last_row:
print("SQLite DB last available row:", last_row)
wind_speed = last_row[1]
wind_direction = last_row[2]
#Add data to payload CSV
payload_csv[25] = wind_speed
payload_csv[26] = wind_direction
else:
print("No data available in the database.")
#MPPT charger #MPPT charger
if mppt_charger: if mppt_charger:
@@ -750,14 +767,15 @@ try:
#3. Send to endpoint (with device ID) #3. Send to endpoint (with device ID)
print("Send data (POST REQUEST):") 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' 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'
print("sending:") #print("sending:")
print('<p class="text-danger-emphasis">') #print('<p class="text-danger-emphasis">')
print(command) #print(command)
print("</p>", end="") #print("</p>", end="")
ser_sara.write(command.encode('utf-8')) 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", "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("receiving:") #print("receiving:")
print('<p class="text-danger-emphasis">') print('<p class="text-danger-emphasis">')
print(response_SARA_3) print(response_SARA_3)
print("</p>", end="") print("</p>", end="")

View File

@@ -65,6 +65,7 @@ config_entries = [
("SARA_R4_neworkID", "20810", "int"), ("SARA_R4_neworkID", "20810", "int"),
("WIFI_status", "connected", "str"), ("WIFI_status", "connected", "str"),
("send_uSpot", "0", "bool"), ("send_uSpot", "0", "bool"),
("windMeter", "0", "bool"),
("modem_version", "XXX", "str") ("modem_version", "XXX", "str")
] ]

View File

@@ -18,6 +18,38 @@ Attention: The Raspberry Pi doesn't have analog inputs, so we need an analog-to
sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/windMeter/read.py sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/windMeter/read.py
this need to run as a service
--> sudo nano /etc/systemd/system/windMeter.service
⬇️
[Unit]
Description=Master manager for the Python wind meter scripts
After=network.target
[Service]
ExecStart=/usr/bin/python3 /var/www/nebuleair_pro_4g/windMeter/read.py
Restart=always
User=root
WorkingDirectory=/var/www/nebuleair_pro_4g
StandardOutput=append:/var/www/nebuleair_pro_4g/logs/wind.log
StandardError=append:/var/www/nebuleair_pro_4g/logs/wind_errors.log
[Install]
WantedBy=multi-user.target
⬆️
Reload systemd (first time after creating the service):
sudo systemctl daemon-reload
Enable (once), start (once and after stopping) and restart (after modification)systemd:
sudo systemctl enable windMeter.service
sudo systemctl start windMeter.service
sudo systemctl restart windMeter.service
Check the service status:
sudo systemctl status windMeter.service
''' '''
#!/usr/bin/python3 #!/usr/bin/python3
import time import time