This commit is contained in:
Your Name
2025-01-30 11:42:02 +01:00
parent a8ca15505e
commit 578721a9f2
6 changed files with 156 additions and 23 deletions

View File

@@ -1,5 +1,5 @@
# Script to read data from BME280 # Script to read data from BME280
# Sensor connected to i2c on address 77 (use sudo i2cdetect -y 1 to get the address ) # Sensor connected to i2c on address 76 (use sudo i2cdetect -y 1 to get the address )
# sudo python3 /var/www/nebuleair_pro_4g/BME280/read.py # sudo python3 /var/www/nebuleair_pro_4g/BME280/read.py
import board import board

View File

@@ -66,7 +66,7 @@ sudo chmod 777 /dev/ttyAMA*
## I2C ## I2C
Decibel meter and BME280 is connected via I2C. Decibel meter, BME280 and the RTC module (DS3231) is connected via I2C.
Need to activate by modifying `sudo nano /boot/firmware/config.txt` Need to activate by modifying `sudo nano /boot/firmware/config.txt`
@@ -82,14 +82,23 @@ sudo chmod 777 /dev/i2c-1
Attention: sometimes activation with config.txt do not work, you need to activate i2c with `sudo raspi-config` and go to "Interface" -> I2C -> enable. Attention: sometimes activation with config.txt do not work, you need to activate i2c with `sudo raspi-config` and go to "Interface" -> I2C -> enable.
I2C addresses: use `sudo i2cdetect -y 1` to check the connected devices.
### BME280 ### BME280
The python script is triggered by the main loop every minutes to get instant temp, hum and press values (no need to have a minute average). The python script is triggered by the main loop every minutes to get instant temp, hum and press values (no need to have a minute average).
BME280 address is 0x76.
### RTC module (DS3231)
### Noise sensor ### Noise sensor
As noise varies a lot, we keep the C program running every seconds to create a moving average for the last 60 seconds (we also gather max and min values). As noise varies a lot, we keep the C program running every seconds to create a moving average for the last 60 seconds (we also gather max and min values).
To keep the script running at boot and stay on we create a systemd service To keep the script running at boot and stay on we create a systemd service.
Nois sensor address is 0x48.
Create the service with `sudo nano /etc/systemd/system/sound_meter.service` and add: Create the service with `sudo nano /etc/systemd/system/sound_meter.service` and add:
``` ```
@@ -151,11 +160,10 @@ And set the base URL for Sara R4 communication:
### With only 1 NPM ### With only 1 NPM
Loop every minutes to get the PM values and send it to the server: Loop every minutes to get the PM values and send it to the server (we use flock to be sure the previous script is over before start the new one):
``` ```
* * * * * /usr/bin/python3 /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.py >> /var/www/nebuleair_pro_4g/logs/loop.log 2>&1 * * * * * flock -n /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.lock /usr/bin/python3 /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.py >> /var/www/nebuleair_pro_4g/logs/loop.log 2>&1
``` ```
All in one: All in one:
@@ -164,7 +172,7 @@ All in one:
@reboot chmod 777 /dev/ttyAMA* @reboot chmod 777 /dev/ttyAMA*
@reboot /var/www/nebuleair_pro_4g/boot_hotspot.sh >> /var/www/nebuleair_pro_4g/logs/app.log 2>&1 @reboot /var/www/nebuleair_pro_4g/boot_hotspot.sh >> /var/www/nebuleair_pro_4g/logs/app.log 2>&1
@reboot sleep 30 && /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_setURL.py ttyAMA2 data.nebuleair.fr >> /var/www/nebuleair_pro_4g/logs/app.log 2>&1 @reboot sleep 30 && /usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_setURL.py ttyAMA2 data.nebuleair.fr >> /var/www/nebuleair_pro_4g/logs/app.log 2>&1
* * * * * /usr/bin/python3 /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.py >> /var/www/nebuleair_pro_4g/logs/loop.log 2>&1 * * * * * flock -n /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.lock /usr/bin/python3 /var/www/nebuleair_pro_4g/loop/1_NPM/send_data.py >> /var/www/nebuleair_pro_4g/logs/loop.log 2>&1
0 0 */2 * * > /var/www/nebuleair_pro_4g/logs/loop.log 0 0 */2 * * > /var/www/nebuleair_pro_4g/logs/loop.log
``` ```

58
RTC/read.py Normal file
View File

@@ -0,0 +1,58 @@
'''
Script to read time from RTC module
I2C connection
Address 0x68
/usr/bin/python3 /var/www/nebuleair_pro_4g/RTC/read.py
'''
import smbus2
import time
import json
from datetime import datetime
# DS3231 I2C address
DS3231_ADDR = 0x68
# Registers for DS3231
REG_TIME = 0x00
def bcd_to_dec(bcd):
return (bcd // 16 * 10) + (bcd % 16)
def read_time(bus):
data = bus.read_i2c_block_data(DS3231_ADDR, REG_TIME, 7)
seconds = bcd_to_dec(data[0] & 0x7F)
minutes = bcd_to_dec(data[1])
hours = bcd_to_dec(data[2] & 0x3F)
day = bcd_to_dec(data[4])
month = bcd_to_dec(data[5])
year = bcd_to_dec(data[6]) + 2000
return (year, month, day, hours, minutes, seconds)
def main():
# Read RTC time
bus = smbus2.SMBus(1)
year, month, day, hours, minutes, seconds = read_time(bus)
rtc_time = datetime(year, month, day, hours, minutes, seconds)
# Get current system time
system_time = datetime.now() #local
utc_time = datetime.utcnow() #UTC
# Print both times
#print(f"RTC module Time: {rtc_time.strftime('%Y-%m-%d %H:%M:%S')}")
#print(f"Sys local Time: {system_time.strftime('%Y-%m-%d %H:%M:%S')}")
#print(f"Sys UTC Time: {utc_time.strftime('%Y-%m-%d %H:%M:%S')}")
# Create JSON output
time_data = {
"rtc_module_time": rtc_time.strftime('%Y-%m-%d %H:%M:%S'),
"system_local_time": system_time.strftime('%Y-%m-%d %H:%M:%S'),
"system_utc_time": utc_time.strftime('%Y-%m-%d %H:%M:%S')
}
print(json.dumps(time_data, indent=4))
if __name__ == "__main__":
main()

View File

@@ -11,6 +11,7 @@
"NextPM_5channels": false, "NextPM_5channels": false,
"i2C_sound": false, "i2C_sound": false,
"i2c_BME": false, "i2c_BME": false,
"i2c_RTC": false,
"sshTunnel_port": 59228, "sshTunnel_port": 59228,
"npm1_status": "connected", "npm1_status": "connected",
"SARA_R4_general_status": "connected", "SARA_R4_general_status": "connected",

View File

@@ -54,7 +54,7 @@
<div class="row mb-3"> <div class="row mb-3">
<div class="col-lg-4 col-12"> <div class="col-lg-3 col-12">
<h3 class="mt-4">Parameters</h3> <h3 class="mt-4">Parameters</h3>
<form> <form>
@@ -94,11 +94,41 @@
<!--<button type="submit" class="btn btn-primary">Submit</button>--> <!--<button type="submit" class="btn btn-primary">Submit</button>-->
</form> </form>
</div> </div>
<!-- CLOCK-->
<div class="col-lg-3 col-12">
<h3 class="mt-4">Clock</h3>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="check_RTC" onchange="update_config('i2c_RTC', this.checked)">
<label class="form-check-label" for="check_RTC">
RTC module (DS3231)
</label>
</div>
<div class="mb-3">
<label for="sys_local_time" class="form-label">System time (local)</label>
<input type="text" class="form-control" id="sys_local_time" disabled>
</div>
<div class="mb-3">
<label for="sys_UTC_time" class="form-label">System time (UTC)</label>
<input type="text" class="form-control" id="sys_UTC_time" disabled>
</div>
<div class="mb-3">
<label for="RTC_utc_time" class="form-label">RTC time (UTC)</label>
<input type="text" class="form-control" id="RTC_utc_time" disabled>
</div>
</div>
<!-- UPDATE-->
<div class="col-lg-4 col-12"> <div class="col-lg-4 col-12">
<h3 class="mt-4">Updates</h3> <h3 class="mt-4">Updates</h3>
<button type="submit" class="btn btn-primary" onclick="updateGitPull()">Update firmware</button> <button type="submit" class="btn btn-primary" onclick="updateGitPull()">Update firmware</button>
</div> </div>
@@ -137,6 +167,7 @@
}); });
window.onload = function() { window.onload = function() {
fetch('../config.json') // Replace 'deviceID.txt' with 'config.json' fetch('../config.json') // Replace 'deviceID.txt' with 'config.json'
.then(response => response.json()) // Parse response as JSON .then(response => response.json()) // Parse response as JSON
.then(data => { .then(data => {
@@ -156,6 +187,10 @@ window.onload = function() {
const checkbox = document.getElementById("check_bme280"); const checkbox = document.getElementById("check_bme280");
checkbox.checked = data.i2c_BME; checkbox.checked = data.i2c_BME;
//get BME check
const checkbox_RTC = document.getElementById("check_RTC");
checkbox_RTC.checked = data.i2c_RTC;
//loop activation //loop activation
const flex_loop = document.getElementById("flex_loop"); const flex_loop = document.getElementById("flex_loop");
flex_loop.checked = data.loop_activation; flex_loop.checked = data.loop_activation;
@@ -176,20 +211,37 @@ window.onload = function() {
const device_ID = document.getElementById("device_ID"); const device_ID = document.getElementById("device_ID");
device_ID.value = data.deviceID.toUpperCase(); device_ID.value = data.deviceID.toUpperCase();
//get local RTC //get system time and RTC module
$.ajax({ $.ajax({
url: 'launcher.php?type=RTC_time', url: 'launcher.php?type=sys_RTC_module_time',
dataType: 'text', // Specify that you expect a JSON response dataType: 'json', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs method: 'GET', // Use GET or POST depending on your needs
success: function(response) { success: function(response) {
console.log("Local RTC: " + response); console.log(response);
const RTC_Element = document.getElementById("RTC_time"); // Update the input fields with the received JSON data
RTC_Element.textContent = response; document.getElementById("sys_local_time").value = response.system_local_time;
}, document.getElementById("sys_UTC_time").value = response.system_utc_time;
error: function(xhr, status, error) { document.getElementById("RTC_utc_time").value = response.rtc_module_time;
console.error('AJAX request failed:', status, error); },
} error: function(xhr, status, error) {
}); console.error('AJAX request failed:', status, 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);
}
});
}) })
.catch(error => console.error('Error loading config.json:', error)); .catch(error => console.error('Error loading config.json:', error));
@@ -202,6 +254,7 @@ function update_config(param, value){
url: 'launcher.php?type=update_config&param='+param+'&value='+value, url: 'launcher.php?type=update_config&param='+param+'&value='+value,
dataType: 'text', // Specify that you expect a JSON response dataType: 'text', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs method: 'GET', // Use GET or POST depending on your needs
cache: false, // Prevent AJAX from caching
success: function(response) { success: function(response) {
console.log(response); console.log(response);
}, },
@@ -217,6 +270,8 @@ function updateGitPull(){
$.ajax({ $.ajax({
url: 'launcher.php?type=git_pull', url: 'launcher.php?type=git_pull',
method: 'GET', // Use GET or POST depending on your needs method: 'GET', // Use GET or POST depending on your needs
dataType: 'text', // Specify that you expect a JSON response
success: function(response) { success: function(response) {
// Handle success response if needed // Handle success response if needed
console.log(response); console.log(response);

View File

@@ -1,4 +1,9 @@
<?php <?php
// ✅ Prevents caching → Adds headers to ensure fresh response.
header("Content-Type: application/json");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Pragma: no-cache");
$type=$_GET['type']; $type=$_GET['type'];
if ($type == "update_config") { if ($type == "update_config") {
@@ -25,6 +30,12 @@ if ($type == "RTC_time") {
echo $time; echo $time;
} }
if ($type == "sys_RTC_module_time") {
$command = '/usr/bin/python3 /var/www/nebuleair_pro_4g/RTC/read.py';
$output = shell_exec($command);
echo $output;
}
if ($type == "git_pull") { if ($type == "git_pull") {
$command = 'sudo git pull'; $command = 'sudo git pull';
$output = shell_exec($command); $output = shell_exec($command);