update
This commit is contained in:
@@ -23,6 +23,7 @@ sudo chmod -R 777 /var/www/nebuleair_pro_4g/
|
|||||||
git config --global core.fileMode false
|
git config --global core.fileMode false
|
||||||
git config --global --add safe.directory /var/www/nebuleair_pro_4g
|
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
|
||||||
|
sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/sqlite/create_db.py
|
||||||
```
|
```
|
||||||
## Apache
|
## Apache
|
||||||
Configuration of Apache to redirect to the html homepage project
|
Configuration of Apache to redirect to the html homepage project
|
||||||
|
|||||||
109
SARA/cellLocate/get_loc.py
Normal file
109
SARA/cellLocate/get_loc.py
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
'''
|
||||||
|
____ _ ____ _
|
||||||
|
/ ___| / \ | _ \ / \
|
||||||
|
\___ \ / _ \ | |_) | / _ \
|
||||||
|
___) / ___ \| _ < / ___ \
|
||||||
|
|____/_/ \_\_| \_\/_/ \_\
|
||||||
|
|
||||||
|
Script to get Location from GSM
|
||||||
|
|
||||||
|
/usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/cellLocate/get_loc.py ttyAMA2 1
|
||||||
|
|
||||||
|
AT+ULOC=
|
||||||
|
<mode>, ->2 -> single shot position
|
||||||
|
<sensor>, ->2 -> use cellulare CellLocate
|
||||||
|
<response_type>, ->0 -> standard
|
||||||
|
<timeout>, ->2 -> seconds
|
||||||
|
<accuracy> ->1 -> in meters
|
||||||
|
[,<num_hypothesis>]
|
||||||
|
|
||||||
|
exemple: AT+ULOC=2,2,0,2,1
|
||||||
|
'''
|
||||||
|
|
||||||
|
import serial
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
|
parameter = sys.argv[1:] # Exclude the script name
|
||||||
|
port='/dev/'+parameter[0] # ex: ttyAMA2
|
||||||
|
timeout = float(parameter[1]) # 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
|
||||||
|
)
|
||||||
|
|
||||||
|
def read_complete_response(serial_connection, timeout=2, end_of_response_timeout=2, wait_for_lines=None, debug=True):
|
||||||
|
'''
|
||||||
|
Fonction très importante !!!
|
||||||
|
Reads the complete response from a serial connection and waits for specific lines.
|
||||||
|
'''
|
||||||
|
if wait_for_lines is None:
|
||||||
|
wait_for_lines = [] # Default to an empty list if not provided
|
||||||
|
|
||||||
|
response = bytearray()
|
||||||
|
serial_connection.timeout = timeout
|
||||||
|
end_time = time.time() + end_of_response_timeout
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
elapsed_time = time.time() - start_time # Time since function start
|
||||||
|
if serial_connection.in_waiting > 0:
|
||||||
|
data = serial_connection.read(serial_connection.in_waiting)
|
||||||
|
response.extend(data)
|
||||||
|
end_time = time.time() + end_of_response_timeout # Reset timeout on new data
|
||||||
|
|
||||||
|
# Decode and check for any target line
|
||||||
|
decoded_response = response.decode('utf-8', errors='replace')
|
||||||
|
for target_line in wait_for_lines:
|
||||||
|
if target_line in decoded_response:
|
||||||
|
if debug:
|
||||||
|
print(f"[DEBUG] 🔎 Found target line: {target_line} (in {elapsed_time:.2f}s)")
|
||||||
|
return decoded_response # Return response immediately if a target line is found
|
||||||
|
elif time.time() > end_time:
|
||||||
|
if debug:
|
||||||
|
print(f"[DEBUG] Timeout reached. No more data received.")
|
||||||
|
break
|
||||||
|
time.sleep(0.1) # Short sleep to prevent busy waiting
|
||||||
|
|
||||||
|
# Final response and debug output
|
||||||
|
total_elapsed_time = time.time() - start_time
|
||||||
|
if debug:
|
||||||
|
print(f"[DEBUG] ⏱️ elapsed time: {total_elapsed_time:.2f}s. ⏱️")
|
||||||
|
# Check if the elapsed time exceeded 10 seconds
|
||||||
|
if total_elapsed_time > 10 and debug:
|
||||||
|
print(f"[ALERT] 🚨 The operation took too long 🚨")
|
||||||
|
print(f'<span style="color: red;font-weight: bold;">[ALERT] ⚠️{total_elapsed_time:.2f}s⚠️</span>')
|
||||||
|
|
||||||
|
return response.decode('utf-8', errors='replace') # Return the full response if no target line is found
|
||||||
|
|
||||||
|
|
||||||
|
#command = f'ATI\r'
|
||||||
|
command = f'AT+ULOC=2,2,0,2,1\r'
|
||||||
|
ser.write((command + '\r').encode('utf-8'))
|
||||||
|
|
||||||
|
response = read_complete_response(ser, wait_for_lines=["+UULOC"])
|
||||||
|
print(response)
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
'''
|
'''
|
||||||
|
____ _ ____ _
|
||||||
|
/ ___| / \ | _ \ / \
|
||||||
|
\___ \ / _ \ | |_) | / _ \
|
||||||
|
___) / ___ \| _ < / ___ \
|
||||||
|
|____/_/ \_\_| \_\/_/ \_\
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
'''
|
'''
|
||||||
|
____ _ ____ _
|
||||||
|
/ ___| / \ | _ \ / \
|
||||||
|
\___ \ / _ \ | |_) | / _ \
|
||||||
|
___) / ___ \| _ < / ___ \
|
||||||
|
|____/_/ \_\_| \_\/_/ \_\
|
||||||
|
|
||||||
Script to connect SARA-R410 to APN
|
Script to connect SARA-R410 to APN
|
||||||
AT+CGDCONT=1,"IP","data.mono"
|
AT+CGDCONT=1,"IP","data.mono"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
'''
|
'''
|
||||||
|
____ _ ____ _
|
||||||
|
/ ___| / \ | _ \ / \
|
||||||
|
\___ \ / _ \ | |_) | / _ \
|
||||||
|
___) / ___ \| _ < / ___ \
|
||||||
|
|____/_/ \_\_| \_\/_/ \_\
|
||||||
|
|
||||||
Script to set the URL for a HTTP request
|
Script to set the URL for a HTTP request
|
||||||
Ex:
|
Ex:
|
||||||
/usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_setURL.py ttyAMA2 data.nebuleair.fr 0
|
/usr/bin/python3 /var/www/nebuleair_pro_4g/SARA/sara_setURL.py ttyAMA2 data.nebuleair.fr 0
|
||||||
|
|||||||
@@ -4,9 +4,13 @@
|
|||||||
"loop/SARA_send_data_v2.py": true,
|
"loop/SARA_send_data_v2.py": true,
|
||||||
"RTC/save_to_db.py": true,
|
"RTC/save_to_db.py": true,
|
||||||
"BME280/get_data_v2.py": true,
|
"BME280/get_data_v2.py": true,
|
||||||
"envea/read_value_v2.py": true,
|
"envea/read_value_v2.py": false,
|
||||||
"sqlite/flush_old_data.py": true,
|
"sqlite/flush_old_data.py": true,
|
||||||
"deviceID": "XXXX",
|
"deviceID": "XXXX",
|
||||||
|
"latitude_raw": 0,
|
||||||
|
"longitude_raw":0,
|
||||||
|
"latitude_precision": 0,
|
||||||
|
"longitude_precision": 0,
|
||||||
"deviceName": "NebuleAir-proXXX",
|
"deviceName": "NebuleAir-proXXX",
|
||||||
"SaraR4_baudrate": 115200,
|
"SaraR4_baudrate": 115200,
|
||||||
"NPM_solo_port": "/dev/ttyAMA5",
|
"NPM_solo_port": "/dev/ttyAMA5",
|
||||||
|
|||||||
BIN
html/assets/leaflet/images/layers-2x.png
Executable file
BIN
html/assets/leaflet/images/layers-2x.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
html/assets/leaflet/images/layers.png
Executable file
BIN
html/assets/leaflet/images/layers.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 696 B |
BIN
html/assets/leaflet/images/marker-icon-2x.png
Executable file
BIN
html/assets/leaflet/images/marker-icon-2x.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
html/assets/leaflet/images/marker-icon.png
Executable file
BIN
html/assets/leaflet/images/marker-icon.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
html/assets/leaflet/images/marker-shadow.png
Executable file
BIN
html/assets/leaflet/images/marker-shadow.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 618 B |
14419
html/assets/leaflet/leaflet-src.esm.js
Executable file
14419
html/assets/leaflet/leaflet-src.esm.js
Executable file
File diff suppressed because it is too large
Load Diff
1
html/assets/leaflet/leaflet-src.esm.js.map
Executable file
1
html/assets/leaflet/leaflet-src.esm.js.map
Executable file
File diff suppressed because one or more lines are too long
14512
html/assets/leaflet/leaflet-src.js
Executable file
14512
html/assets/leaflet/leaflet-src.js
Executable file
File diff suppressed because it is too large
Load Diff
1
html/assets/leaflet/leaflet-src.js.map
Executable file
1
html/assets/leaflet/leaflet-src.js.map
Executable file
File diff suppressed because one or more lines are too long
661
html/assets/leaflet/leaflet.css
Executable file
661
html/assets/leaflet/leaflet.css
Executable file
@@ -0,0 +1,661 @@
|
|||||||
|
/* required styles */
|
||||||
|
|
||||||
|
.leaflet-pane,
|
||||||
|
.leaflet-tile,
|
||||||
|
.leaflet-marker-icon,
|
||||||
|
.leaflet-marker-shadow,
|
||||||
|
.leaflet-tile-container,
|
||||||
|
.leaflet-pane > svg,
|
||||||
|
.leaflet-pane > canvas,
|
||||||
|
.leaflet-zoom-box,
|
||||||
|
.leaflet-image-layer,
|
||||||
|
.leaflet-layer {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.leaflet-container {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.leaflet-tile,
|
||||||
|
.leaflet-marker-icon,
|
||||||
|
.leaflet-marker-shadow {
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-drag: none;
|
||||||
|
}
|
||||||
|
/* Prevents IE11 from highlighting tiles in blue */
|
||||||
|
.leaflet-tile::selection {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
|
||||||
|
.leaflet-safari .leaflet-tile {
|
||||||
|
image-rendering: -webkit-optimize-contrast;
|
||||||
|
}
|
||||||
|
/* hack that prevents hw layers "stretching" when loading new tiles */
|
||||||
|
.leaflet-safari .leaflet-tile-container {
|
||||||
|
width: 1600px;
|
||||||
|
height: 1600px;
|
||||||
|
-webkit-transform-origin: 0 0;
|
||||||
|
}
|
||||||
|
.leaflet-marker-icon,
|
||||||
|
.leaflet-marker-shadow {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
|
||||||
|
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
|
||||||
|
.leaflet-container .leaflet-overlay-pane svg {
|
||||||
|
max-width: none !important;
|
||||||
|
max-height: none !important;
|
||||||
|
}
|
||||||
|
.leaflet-container .leaflet-marker-pane img,
|
||||||
|
.leaflet-container .leaflet-shadow-pane img,
|
||||||
|
.leaflet-container .leaflet-tile-pane img,
|
||||||
|
.leaflet-container img.leaflet-image-layer,
|
||||||
|
.leaflet-container .leaflet-tile {
|
||||||
|
max-width: none !important;
|
||||||
|
max-height: none !important;
|
||||||
|
width: auto;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-container img.leaflet-tile {
|
||||||
|
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
|
||||||
|
mix-blend-mode: plus-lighter;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-container.leaflet-touch-zoom {
|
||||||
|
-ms-touch-action: pan-x pan-y;
|
||||||
|
touch-action: pan-x pan-y;
|
||||||
|
}
|
||||||
|
.leaflet-container.leaflet-touch-drag {
|
||||||
|
-ms-touch-action: pinch-zoom;
|
||||||
|
/* Fallback for FF which doesn't support pinch-zoom */
|
||||||
|
touch-action: none;
|
||||||
|
touch-action: pinch-zoom;
|
||||||
|
}
|
||||||
|
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
|
||||||
|
-ms-touch-action: none;
|
||||||
|
touch-action: none;
|
||||||
|
}
|
||||||
|
.leaflet-container {
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
}
|
||||||
|
.leaflet-container a {
|
||||||
|
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
|
||||||
|
}
|
||||||
|
.leaflet-tile {
|
||||||
|
filter: inherit;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.leaflet-tile-loaded {
|
||||||
|
visibility: inherit;
|
||||||
|
}
|
||||||
|
.leaflet-zoom-box {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 800;
|
||||||
|
}
|
||||||
|
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||||
|
.leaflet-overlay-pane svg {
|
||||||
|
-moz-user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-pane { z-index: 400; }
|
||||||
|
|
||||||
|
.leaflet-tile-pane { z-index: 200; }
|
||||||
|
.leaflet-overlay-pane { z-index: 400; }
|
||||||
|
.leaflet-shadow-pane { z-index: 500; }
|
||||||
|
.leaflet-marker-pane { z-index: 600; }
|
||||||
|
.leaflet-tooltip-pane { z-index: 650; }
|
||||||
|
.leaflet-popup-pane { z-index: 700; }
|
||||||
|
|
||||||
|
.leaflet-map-pane canvas { z-index: 100; }
|
||||||
|
.leaflet-map-pane svg { z-index: 200; }
|
||||||
|
|
||||||
|
.leaflet-vml-shape {
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
.lvml {
|
||||||
|
behavior: url(#default#VML);
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* control positioning */
|
||||||
|
|
||||||
|
.leaflet-control {
|
||||||
|
position: relative;
|
||||||
|
z-index: 800;
|
||||||
|
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
.leaflet-top,
|
||||||
|
.leaflet-bottom {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.leaflet-top {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.leaflet-right {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.leaflet-bottom {
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
.leaflet-left {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.leaflet-control {
|
||||||
|
float: left;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.leaflet-right .leaflet-control {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.leaflet-top .leaflet-control {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.leaflet-bottom .leaflet-control {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.leaflet-left .leaflet-control {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.leaflet-right .leaflet-control {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* zoom and fade animations */
|
||||||
|
|
||||||
|
.leaflet-fade-anim .leaflet-popup {
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transition: opacity 0.2s linear;
|
||||||
|
-moz-transition: opacity 0.2s linear;
|
||||||
|
transition: opacity 0.2s linear;
|
||||||
|
}
|
||||||
|
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.leaflet-zoom-animated {
|
||||||
|
-webkit-transform-origin: 0 0;
|
||||||
|
-ms-transform-origin: 0 0;
|
||||||
|
transform-origin: 0 0;
|
||||||
|
}
|
||||||
|
svg.leaflet-zoom-animated {
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||||
|
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||||
|
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||||
|
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||||
|
}
|
||||||
|
.leaflet-zoom-anim .leaflet-tile,
|
||||||
|
.leaflet-pan-anim .leaflet-tile {
|
||||||
|
-webkit-transition: none;
|
||||||
|
-moz-transition: none;
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* cursors */
|
||||||
|
|
||||||
|
.leaflet-interactive {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.leaflet-grab {
|
||||||
|
cursor: -webkit-grab;
|
||||||
|
cursor: -moz-grab;
|
||||||
|
cursor: grab;
|
||||||
|
}
|
||||||
|
.leaflet-crosshair,
|
||||||
|
.leaflet-crosshair .leaflet-interactive {
|
||||||
|
cursor: crosshair;
|
||||||
|
}
|
||||||
|
.leaflet-popup-pane,
|
||||||
|
.leaflet-control {
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
.leaflet-dragging .leaflet-grab,
|
||||||
|
.leaflet-dragging .leaflet-grab .leaflet-interactive,
|
||||||
|
.leaflet-dragging .leaflet-marker-draggable {
|
||||||
|
cursor: move;
|
||||||
|
cursor: -webkit-grabbing;
|
||||||
|
cursor: -moz-grabbing;
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* marker & overlays interactivity */
|
||||||
|
.leaflet-marker-icon,
|
||||||
|
.leaflet-marker-shadow,
|
||||||
|
.leaflet-image-layer,
|
||||||
|
.leaflet-pane > svg path,
|
||||||
|
.leaflet-tile-container {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-marker-icon.leaflet-interactive,
|
||||||
|
.leaflet-image-layer.leaflet-interactive,
|
||||||
|
.leaflet-pane > svg path.leaflet-interactive,
|
||||||
|
svg.leaflet-image-layer.leaflet-interactive path {
|
||||||
|
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* visual tweaks */
|
||||||
|
|
||||||
|
.leaflet-container {
|
||||||
|
background: #ddd;
|
||||||
|
outline-offset: 1px;
|
||||||
|
}
|
||||||
|
.leaflet-container a {
|
||||||
|
color: #0078A8;
|
||||||
|
}
|
||||||
|
.leaflet-zoom-box {
|
||||||
|
border: 2px dotted #38f;
|
||||||
|
background: rgba(255,255,255,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* general typography */
|
||||||
|
.leaflet-container {
|
||||||
|
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* general toolbar styles */
|
||||||
|
|
||||||
|
.leaflet-bar {
|
||||||
|
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.leaflet-bar a {
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
line-height: 26px;
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.leaflet-bar a,
|
||||||
|
.leaflet-control-layers-toggle {
|
||||||
|
background-position: 50% 50%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.leaflet-bar a:hover,
|
||||||
|
.leaflet-bar a:focus {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
}
|
||||||
|
.leaflet-bar a:first-child {
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
}
|
||||||
|
.leaflet-bar a:last-child {
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.leaflet-bar a.leaflet-disabled {
|
||||||
|
cursor: default;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-touch .leaflet-bar a {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
.leaflet-touch .leaflet-bar a:first-child {
|
||||||
|
border-top-left-radius: 2px;
|
||||||
|
border-top-right-radius: 2px;
|
||||||
|
}
|
||||||
|
.leaflet-touch .leaflet-bar a:last-child {
|
||||||
|
border-bottom-left-radius: 2px;
|
||||||
|
border-bottom-right-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* zoom control */
|
||||||
|
|
||||||
|
.leaflet-control-zoom-in,
|
||||||
|
.leaflet-control-zoom-out {
|
||||||
|
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||||
|
text-indent: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* layers control */
|
||||||
|
|
||||||
|
.leaflet-control-layers {
|
||||||
|
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.leaflet-control-layers-toggle {
|
||||||
|
background-image: url(images/layers.png);
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
.leaflet-retina .leaflet-control-layers-toggle {
|
||||||
|
background-image: url(images/layers-2x.png);
|
||||||
|
background-size: 26px 26px;
|
||||||
|
}
|
||||||
|
.leaflet-touch .leaflet-control-layers-toggle {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
}
|
||||||
|
.leaflet-control-layers .leaflet-control-layers-list,
|
||||||
|
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.leaflet-control-layers-expanded {
|
||||||
|
padding: 6px 10px 6px 6px;
|
||||||
|
color: #333;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.leaflet-control-layers-scrollbar {
|
||||||
|
overflow-y: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
.leaflet-control-layers-selector {
|
||||||
|
margin-top: 2px;
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
}
|
||||||
|
.leaflet-control-layers label {
|
||||||
|
display: block;
|
||||||
|
font-size: 13px;
|
||||||
|
font-size: 1.08333em;
|
||||||
|
}
|
||||||
|
.leaflet-control-layers-separator {
|
||||||
|
height: 0;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
margin: 5px -10px 5px -6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Default icon URLs */
|
||||||
|
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
|
||||||
|
background-image: url(images/marker-icon.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* attribution and scale controls */
|
||||||
|
|
||||||
|
.leaflet-container .leaflet-control-attribution {
|
||||||
|
background: #fff;
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.leaflet-control-attribution,
|
||||||
|
.leaflet-control-scale-line {
|
||||||
|
padding: 0 5px;
|
||||||
|
color: #333;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
.leaflet-control-attribution a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.leaflet-control-attribution a:hover,
|
||||||
|
.leaflet-control-attribution a:focus {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.leaflet-attribution-flag {
|
||||||
|
display: inline !important;
|
||||||
|
vertical-align: baseline !important;
|
||||||
|
width: 1em;
|
||||||
|
height: 0.6669em;
|
||||||
|
}
|
||||||
|
.leaflet-left .leaflet-control-scale {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.leaflet-bottom .leaflet-control-scale {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.leaflet-control-scale-line {
|
||||||
|
border: 2px solid #777;
|
||||||
|
border-top: none;
|
||||||
|
line-height: 1.1;
|
||||||
|
padding: 2px 5px 1px;
|
||||||
|
white-space: nowrap;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
text-shadow: 1px 1px #fff;
|
||||||
|
}
|
||||||
|
.leaflet-control-scale-line:not(:first-child) {
|
||||||
|
border-top: 2px solid #777;
|
||||||
|
border-bottom: none;
|
||||||
|
margin-top: -2px;
|
||||||
|
}
|
||||||
|
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||||
|
border-bottom: 2px solid #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-touch .leaflet-control-attribution,
|
||||||
|
.leaflet-touch .leaflet-control-layers,
|
||||||
|
.leaflet-touch .leaflet-bar {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.leaflet-touch .leaflet-control-layers,
|
||||||
|
.leaflet-touch .leaflet-bar {
|
||||||
|
border: 2px solid rgba(0,0,0,0.2);
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* popup */
|
||||||
|
|
||||||
|
.leaflet-popup {
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.leaflet-popup-content-wrapper {
|
||||||
|
padding: 1px;
|
||||||
|
text-align: left;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
.leaflet-popup-content {
|
||||||
|
margin: 13px 24px 13px 20px;
|
||||||
|
line-height: 1.3;
|
||||||
|
font-size: 13px;
|
||||||
|
font-size: 1.08333em;
|
||||||
|
min-height: 1px;
|
||||||
|
}
|
||||||
|
.leaflet-popup-content p {
|
||||||
|
margin: 17px 0;
|
||||||
|
margin: 1.3em 0;
|
||||||
|
}
|
||||||
|
.leaflet-popup-tip-container {
|
||||||
|
width: 40px;
|
||||||
|
height: 20px;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
margin-top: -1px;
|
||||||
|
margin-left: -20px;
|
||||||
|
overflow: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.leaflet-popup-tip {
|
||||||
|
width: 17px;
|
||||||
|
height: 17px;
|
||||||
|
padding: 1px;
|
||||||
|
|
||||||
|
margin: -10px auto 0;
|
||||||
|
pointer-events: auto;
|
||||||
|
|
||||||
|
-webkit-transform: rotate(45deg);
|
||||||
|
-moz-transform: rotate(45deg);
|
||||||
|
-ms-transform: rotate(45deg);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
.leaflet-popup-content-wrapper,
|
||||||
|
.leaflet-popup-tip {
|
||||||
|
background: white;
|
||||||
|
color: #333;
|
||||||
|
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
.leaflet-container a.leaflet-popup-close-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
border: none;
|
||||||
|
text-align: center;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
font: 16px/24px Tahoma, Verdana, sans-serif;
|
||||||
|
color: #757575;
|
||||||
|
text-decoration: none;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.leaflet-container a.leaflet-popup-close-button:hover,
|
||||||
|
.leaflet-container a.leaflet-popup-close-button:focus {
|
||||||
|
color: #585858;
|
||||||
|
}
|
||||||
|
.leaflet-popup-scrolled {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||||
|
-ms-zoom: 1;
|
||||||
|
}
|
||||||
|
.leaflet-oldie .leaflet-popup-tip {
|
||||||
|
width: 24px;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||||
|
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-oldie .leaflet-control-zoom,
|
||||||
|
.leaflet-oldie .leaflet-control-layers,
|
||||||
|
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||||
|
.leaflet-oldie .leaflet-popup-tip {
|
||||||
|
border: 1px solid #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* div icon */
|
||||||
|
|
||||||
|
.leaflet-div-icon {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Tooltip */
|
||||||
|
/* Base styles for the element that has a tooltip */
|
||||||
|
.leaflet-tooltip {
|
||||||
|
position: absolute;
|
||||||
|
padding: 6px;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: #222;
|
||||||
|
white-space: nowrap;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
pointer-events: none;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
.leaflet-tooltip.leaflet-interactive {
|
||||||
|
cursor: pointer;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-top:before,
|
||||||
|
.leaflet-tooltip-bottom:before,
|
||||||
|
.leaflet-tooltip-left:before,
|
||||||
|
.leaflet-tooltip-right:before {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
border: 6px solid transparent;
|
||||||
|
background: transparent;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Directions */
|
||||||
|
|
||||||
|
.leaflet-tooltip-bottom {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-top {
|
||||||
|
margin-top: -6px;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-bottom:before,
|
||||||
|
.leaflet-tooltip-top:before {
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -6px;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-top:before {
|
||||||
|
bottom: 0;
|
||||||
|
margin-bottom: -12px;
|
||||||
|
border-top-color: #fff;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-bottom:before {
|
||||||
|
top: 0;
|
||||||
|
margin-top: -12px;
|
||||||
|
margin-left: -6px;
|
||||||
|
border-bottom-color: #fff;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-left {
|
||||||
|
margin-left: -6px;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-right {
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-left:before,
|
||||||
|
.leaflet-tooltip-right:before {
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -6px;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-left:before {
|
||||||
|
right: 0;
|
||||||
|
margin-right: -12px;
|
||||||
|
border-left-color: #fff;
|
||||||
|
}
|
||||||
|
.leaflet-tooltip-right:before {
|
||||||
|
left: 0;
|
||||||
|
margin-left: -12px;
|
||||||
|
border-right-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Printing */
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
/* Prevent printers from removing background-images of controls. */
|
||||||
|
.leaflet-control {
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
html/assets/leaflet/leaflet.js
Executable file
6
html/assets/leaflet/leaflet.js
Executable file
File diff suppressed because one or more lines are too long
1
html/assets/leaflet/leaflet.js.map
Executable file
1
html/assets/leaflet/leaflet.js.map
Executable file
File diff suppressed because one or more lines are too long
265
html/map.html
Executable file
265
html/map.html
Executable file
@@ -0,0 +1,265 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>NebuleAir</title>
|
||||||
|
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="assets/leaflet/leaflet.css" />
|
||||||
|
<script src="assets/leaflet/leaflet.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
#sidebar a.nav-link {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
#sidebar a.nav-link:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
#sidebar a.nav-link svg {
|
||||||
|
margin-right: 8px; /* Add spacing between icons and text */
|
||||||
|
}
|
||||||
|
#sidebar {
|
||||||
|
transition: transform 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
.offcanvas-backdrop {
|
||||||
|
z-index: 1040;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Topbar -->
|
||||||
|
<span id="topbar"></span>
|
||||||
|
|
||||||
|
<!-- Sidebar Offcanvas for Mobile -->
|
||||||
|
<div class="offcanvas offcanvas-start text-white bg-dark" tabindex="-1" id="sidebarOffcanvas" aria-labelledby="sidebarOffcanvasLabel">
|
||||||
|
<div class="offcanvas-header">
|
||||||
|
<h5 class="offcanvas-title" id="sidebarOffcanvasLabel">NebuleAir</h5>
|
||||||
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="offcanvas-body" id="sidebar_mobile">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container-fluid mt-5">
|
||||||
|
<div class="row">
|
||||||
|
<aside class="col-md-2 col-lg-1 d-none d-md-block vh-100 position-fixed bg-dark text-white" id="sidebar">
|
||||||
|
</aside>
|
||||||
|
<!-- Main content -->
|
||||||
|
<main class="col-md-10 ms-sm-auto col-lg-11 offset-md-2 offset-lg-1 px-md-4">
|
||||||
|
<h1 class="mt-4">Localisation</h1>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col-sm-6 mb-2">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h3 class="mt-1">Zone localisation du capteur</h3>
|
||||||
|
<p class="card-text">Mis à jour automatiquement par le capteur. </p>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 mb-3">
|
||||||
|
<label for="device_name" class="form-label">Latitude</label>
|
||||||
|
<input type="text" class="form-control" id="device_latitude_raw" disabled>
|
||||||
|
</div>
|
||||||
|
<div class="col-6 mb-3">
|
||||||
|
<label for="device_name" class="form-label">Longitude</label>
|
||||||
|
<input type="text" class="form-control" id="device_longitude_raw" disabled>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col-sm-6 mb-2">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h3 class="mt-1">Point précis</h3>
|
||||||
|
<p class="card-text">Mis à jour manuellement (sur aircarto.fr ou sur cette interface si le capteur est connecté au WIFI) </p>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 mb-3">
|
||||||
|
<label for="device_name" class="form-label">Latitude</label>
|
||||||
|
<input type="text" class="form-control" id="device_latitude_precision" onchange="update_config('latitude_precision', this.value)">
|
||||||
|
</div>
|
||||||
|
<div class="col-6 mb-3">
|
||||||
|
<label for="device_name" class="form-label">Longitude</label>
|
||||||
|
<input type="text" class="form-control" id="device_longitude_precision" onchange="update_config('longitude_precision', this.value)">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div id="map" style="height: 70vh;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- JAVASCRIPT -->
|
||||||
|
|
||||||
|
<!-- Link Ajax locally -->
|
||||||
|
<script src="assets/jquery/jquery-3.7.1.min.js"></script>
|
||||||
|
<!-- Link Bootstrap JS and Popper.js locally -->
|
||||||
|
<script src="assets/js/bootstrap.bundle.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const elementsToLoad = [
|
||||||
|
{ id: 'topbar', file: 'topbar.html' },
|
||||||
|
{ id: 'sidebar', file: 'sidebar.html' },
|
||||||
|
{ id: 'sidebar_mobile', file: 'sidebar.html' }
|
||||||
|
];
|
||||||
|
|
||||||
|
elementsToLoad.forEach(({ id, file }) => {
|
||||||
|
fetch(file)
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(data => {
|
||||||
|
const element = document.getElementById(id);
|
||||||
|
if (element) {
|
||||||
|
element.innerHTML = data;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => console.error(`Error loading ${file}:`, error));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
let map;
|
||||||
|
let marker;
|
||||||
|
|
||||||
|
// Function to load and update map
|
||||||
|
function loadConfigAndUpdateMap() {
|
||||||
|
fetch('../config.json')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
console.log("Getting config file (update)");
|
||||||
|
|
||||||
|
// Get device details
|
||||||
|
const deviceID = data.deviceID.trim().toUpperCase();
|
||||||
|
const deviceName = data.deviceName;
|
||||||
|
const device_latitude_precision = parseFloat(data.latitude_precision);
|
||||||
|
const device_longitude_precision = parseFloat(data.longitude_precision);
|
||||||
|
const device_latitude_raw = parseFloat(data.latitude_raw);
|
||||||
|
const device_longitude_raw = parseFloat(data.longitude_raw);
|
||||||
|
|
||||||
|
console.log("Latitude (precision): " + device_latitude_precision);
|
||||||
|
console.log("Longitude (precision): " + device_longitude_precision);
|
||||||
|
|
||||||
|
// Update input fields
|
||||||
|
document.getElementById("device_latitude_precision").value = device_latitude_precision;
|
||||||
|
document.getElementById("device_longitude_precision").value = device_longitude_precision;
|
||||||
|
document.getElementById("device_latitude_raw").value = device_latitude_raw;
|
||||||
|
document.getElementById("device_longitude_raw").value = device_longitude_raw;
|
||||||
|
|
||||||
|
// If map is not initialized, create it
|
||||||
|
if (!map) {
|
||||||
|
map = L.map('map').setView([device_latitude_precision, device_longitude_precision], 15);
|
||||||
|
|
||||||
|
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||||
|
maxZoom: 19,
|
||||||
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||||
|
}).addTo(map);
|
||||||
|
|
||||||
|
// Add draggable marker (point precision)
|
||||||
|
marker = L.marker([device_latitude_precision, device_longitude_precision], { draggable: true }).addTo(map);
|
||||||
|
|
||||||
|
//add a circle
|
||||||
|
var circle = L.circle([device_latitude_raw, device_longitude_raw], {
|
||||||
|
color: 'blue',
|
||||||
|
fillColor: '#f03',
|
||||||
|
fillOpacity: 0.5,
|
||||||
|
radius: 500
|
||||||
|
}).addTo(map);
|
||||||
|
|
||||||
|
// Event listener when marker is moved
|
||||||
|
marker.on('dragend', function (event) {
|
||||||
|
let newLatLng = marker.getLatLng();
|
||||||
|
console.log("Marker moved to:", newLatLng.lat, newLatLng.lng);
|
||||||
|
|
||||||
|
// Update the input fields with new values
|
||||||
|
document.getElementById("device_latitude").value = newLatLng.lat;
|
||||||
|
document.getElementById("device_longitude").value = newLatLng.lng;
|
||||||
|
|
||||||
|
// Call update function to save new values
|
||||||
|
update_config('latitude', newLatLng.lat);
|
||||||
|
|
||||||
|
setTimeout(() => { update_config('longitude', newLatLng.lng); }, 750);
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// If the map already exists, update position
|
||||||
|
map.setView([device_latitude, device_longitude], 9);
|
||||||
|
|
||||||
|
// Move marker
|
||||||
|
marker.setLatLng([device_latitude, device_longitude]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update device name in sidebar
|
||||||
|
document.querySelectorAll('.sideBar_sensorName').forEach((element) => {
|
||||||
|
element.innerText = deviceName;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get local RTC time
|
||||||
|
$.ajax({
|
||||||
|
url: 'launcher.php?type=RTC_time',
|
||||||
|
dataType: 'text',
|
||||||
|
method: 'GET',
|
||||||
|
success: function(response) {
|
||||||
|
console.log("Local RTC: " + response);
|
||||||
|
document.getElementById("RTC_time").textContent = response;
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.error('AJAX request failed:', status, error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Error loading config.json:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to update config and refresh the map
|
||||||
|
function update_config(param, value) {
|
||||||
|
console.log("Updating ", param, " : ", value);
|
||||||
|
$.ajax({
|
||||||
|
url: 'launcher.php?type=update_config¶m=' + param + '&value=' + value,
|
||||||
|
dataType: 'text',
|
||||||
|
method: 'GET',
|
||||||
|
cache: false,
|
||||||
|
success: function(response) {
|
||||||
|
console.log(response);
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.error('AJAX request failed:', status, error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load config and initialize map on page load
|
||||||
|
window.onload = function () {
|
||||||
|
loadConfigAndUpdateMap();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -41,6 +41,12 @@
|
|||||||
</svg>
|
</svg>
|
||||||
Logs
|
Logs
|
||||||
</a>
|
</a>
|
||||||
|
<a class="nav-link text-white" href="map.html">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-geo-alt-fill" viewBox="0 0 16 16">
|
||||||
|
<path d="M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10m0-7a3 3 0 1 1 0-6 3 3 0 0 1 0 6"/>
|
||||||
|
</svg>
|
||||||
|
Carte
|
||||||
|
</a>
|
||||||
<a class="nav-link text-white" href="admin.html">
|
<a class="nav-link text-white" href="admin.html">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-tools" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-tools" viewBox="0 0 16 16">
|
||||||
<path d="M1 0 0 1l2.2 3.081a1 1 0 0 0 .815.419h.07a1 1 0 0 1 .708.293l2.675 2.675-2.617 2.654A3.003 3.003 0 0 0 0 13a3 3 0 1 0 5.878-.851l2.654-2.617.968.968-.305.914a1 1 0 0 0 .242 1.023l3.27 3.27a.997.997 0 0 0 1.414 0l1.586-1.586a.997.997 0 0 0 0-1.414l-3.27-3.27a1 1 0 0 0-1.023-.242L10.5 9.5l-.96-.96 2.68-2.643A3.005 3.005 0 0 0 16 3q0-.405-.102-.777l-2.14 2.141L12 4l-.364-1.757L13.777.102a3 3 0 0 0-3.675 3.68L7.462 6.46 4.793 3.793a1 1 0 0 1-.293-.707v-.071a1 1 0 0 0-.419-.814zm9.646 10.646a.5.5 0 0 1 .708 0l2.914 2.915a.5.5 0 0 1-.707.707l-2.915-2.914a.5.5 0 0 1 0-.708M3 11l.471.242.529.026.287.445.445.287.026.529L5 13l-.242.471-.026.529-.445.287-.287.445-.529.026L3 15l-.471-.242L2 14.732l-.287-.445L1.268 14l-.026-.529L1 13l.242-.471.026-.529.445-.287.287-.445.529-.026z"/>
|
<path d="M1 0 0 1l2.2 3.081a1 1 0 0 0 .815.419h.07a1 1 0 0 1 .708.293l2.675 2.675-2.617 2.654A3.003 3.003 0 0 0 0 13a3 3 0 1 0 5.878-.851l2.654-2.617.968.968-.305.914a1 1 0 0 0 .242 1.023l3.27 3.27a.997.997 0 0 0 1.414 0l1.586-1.586a.997.997 0 0 0 0-1.414l-3.27-3.27a1 1 0 0 0-1.023-.242L10.5 9.5l-.96-.96 2.68-2.643A3.005 3.005 0 0 0 16 3q0-.405-.102-.777l-2.14 2.141L12 4l-.364-1.757L13.777.102a3 3 0 0 0-3.675 3.68L7.462 6.46 4.793 3.793a1 1 0 0 1-.293-.707v-.071a1 1 0 0 0-.419-.814zm9.646 10.646a.5.5 0 0 1 .708 0l2.914 2.915a.5.5 0 0 1-.707.707l-2.915-2.914a.5.5 0 0 1 0-.708M3 11l.471.242.529.026.287.445.445.287.026.529L5 13l-.242.471-.026.529-.445.287-.287.445-.529.026L3 15l-.471-.242L2 14.732l-.287-.445L1.268 14l-.026-.529L1 13l.242-.471.026-.529.445-.287.287-.445.529-.026z"/>
|
||||||
|
|||||||
@@ -6,17 +6,40 @@ set -e
|
|||||||
# Update and install necessary packages
|
# Update and install necessary packages
|
||||||
echo "Updating package list and installing necessary packages..."
|
echo "Updating package list and installing necessary packages..."
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install -y git gh apache2 php python3 python3-pip jq autossh i2c-tools python3-smbus
|
sudo apt install git gh apache2 php php-sqlite3 python3 python3-pip jq autossh i2c-tools python3-smbus -y
|
||||||
|
|
||||||
# Install Python libraries
|
# Install Python libraries
|
||||||
echo "Installing Python libraries..."
|
echo "Installing Python libraries..."
|
||||||
sudo pip3 install pyserial requests RPi.GPIO adafruit-circuitpython-bme280 --break-system-packages
|
sudo pip3 install pyserial requests RPi.GPIO adafruit-circuitpython-bme280 crcmod psutil --break-system-packages
|
||||||
|
|
||||||
# Set up SSH for /var/www
|
# Ask user if they want to set up SSH keys
|
||||||
echo "Setting up SSH keys..."
|
read -p "Do you want to set up an SSH key for /var/www? (y/n): " answer
|
||||||
sudo mkdir -p /var/www/.ssh
|
|
||||||
sudo ssh-keygen -t rsa -b 4096 -f /var/www/.ssh/id_rsa -N ""
|
# Convert input to lowercase to accept 'Y' or 'y'
|
||||||
sudo ssh-copy-id -i /var/www/.ssh/id_rsa.pub -p 50221 airlab_server1@aircarto.fr
|
answer=${answer,,}
|
||||||
|
|
||||||
|
if [[ "$answer" == "y" ]]; then
|
||||||
|
echo "Setting up SSH keys..."
|
||||||
|
|
||||||
|
# Create SSH directory if it doesn't exist
|
||||||
|
sudo mkdir -p /var/www/.ssh
|
||||||
|
sudo chmod 700 /var/www/.ssh
|
||||||
|
|
||||||
|
# Generate SSH key if it does not already exist
|
||||||
|
if [[ ! -f /var/www/.ssh/id_rsa ]]; then
|
||||||
|
sudo ssh-keygen -t rsa -b 4096 -f /var/www/.ssh/id_rsa -N ""
|
||||||
|
echo "SSH key generated successfully."
|
||||||
|
else
|
||||||
|
echo "SSH key already exists. Skipping key generation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy SSH key to remote server
|
||||||
|
sudo ssh-copy-id -i /var/www/.ssh/id_rsa.pub -p 50221 airlab_server1@aircarto.fr
|
||||||
|
|
||||||
|
echo "SSH setup complete!"
|
||||||
|
else
|
||||||
|
echo "Skipping SSH key setup."
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Clone the repository
|
# Clone the repository
|
||||||
@@ -25,14 +48,24 @@ sudo git clone http://gitea.aircarto.fr/PaulVua/nebuleair_pro_4g.git /var/www/ne
|
|||||||
|
|
||||||
# Set up repository files and permissions
|
# Set up repository files and permissions
|
||||||
echo "Setting up repository files and permissions..."
|
echo "Setting up repository files and permissions..."
|
||||||
sudo mkdir -p /var/www/nebuleair_pro_4g/logs
|
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 /var/www/nebuleair_pro_4g/wifi_list.csv
|
||||||
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
|
||||||
|
|
||||||
# Set up cron jobs
|
# Set up cron jobs
|
||||||
echo "Setting up cron jobs..."
|
echo "Setting up cron jobs..."
|
||||||
sudo crontab /var/www/nebuleair_pro_4g/cron_jobs
|
sudo crontab /var/www/nebuleair_pro_4g/cron_jobs
|
||||||
|
|
||||||
|
#Creates databases
|
||||||
|
echo "Creating databases."
|
||||||
|
sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/sqlite/create_db.py
|
||||||
|
|
||||||
|
#Apache
|
||||||
|
echo "Set Up Apache"
|
||||||
|
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
|
||||||
|
|
||||||
echo "Setup completed successfully!"
|
echo "Setup completed successfully!"
|
||||||
|
|||||||
Reference in New Issue
Block a user