Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
co2ampel
ampel-firmware
Commits
208eadd3
Commit
208eadd3
authored
Apr 23, 2021
by
Eric Duminil
Browse files
Merge branch 'develop'
parents
b48d4d18
a9b0db5d
Pipeline
#3221
passed with stage
in 1 minute and 40 seconds
Changes
24
Pipelines
1
Show whitespace changes
Inline
Side-by-side
ampel-firmware/web_server.cpp
View file @
208eadd3
...
...
@@ -22,6 +22,7 @@ namespace web_server {
const
char
*
script_template
;
void
handleWebServerRoot
();
void
handlePageNotFound
();
void
handleWebServerCommand
();
#ifdef AMPEL_CSV
void
handleDeleteCSV
();
...
...
@@ -64,7 +65,7 @@ namespace web_server {
#ifdef AMPEL_CSV
"<li class='pure-menu-item'><a href='#graph' class='pure-menu-link'>Graph</a></li>
\n
"
"<li class='pure-menu-item'><a href='#log' class='pure-menu-link'>Log</a></li>
\n
"
"<li class='pure-menu-item'><a href='
./
%s' class='pure-menu-link'>Download CSV</a></li>
\n
"
"<li class='pure-menu-item'><a href='%s' class='pure-menu-link'>Download CSV</a></li>
\n
"
#endif
"<li class='pure-menu-item' id='led'>⬤</li>
\n
"
// LED
"</ul></div></div>
\n
"
...
...
@@ -72,16 +73,15 @@ namespace web_server {
// Show a colored dot on the webpage, with a similar color than on LED Ring.
"hue=(1-(Math.min(Math.max(parseInt(document.title),500),1600)-500)/1100)*120;
\n
"
"document.getElementById('led').style.color=['hsl(',hue,',100%%,50%%)'].join('');
\n
"
"</script>
\n
"
);
body_template
=
PSTR
(
"<div class='pure-g'>
\n
"
"<div class='pure-u-1' id='graph'></div>
\n
"
// Graph placeholder
"</script>
\n
"
"<div class='pure-g'>
\n
"
"<div class='pure-u-1' id='graph'></div>
\n
"
// Graph placeholder
"</div>
\n
"
"<div class='pure-g'>
\n
"
//Sensor table
"<table id='table' class='pure-table-striped pure-u-1 pure-u-md-1-2'>
\n
"
"<tr><th colspan='2'>%s</th></tr>
\n
"
"<table id='table' class='pure-table-striped pure-u-1 pure-u-md-1-2'>
\n
"
);
body_template
=
PSTR
(
"<tr><th colspan='2'>%s</th></tr>
\n
"
"<tr><td>CO<sub>2</sub> concentration</td><td>%5d ppm</td></tr>
\n
"
"<tr><td>Temperature</td><td>%.1f℃</td></tr>
\n
"
"<tr><td>Humidity</td><td>%.1f%%</td></tr>
\n
"
...
...
@@ -108,14 +108,17 @@ namespace web_server {
#endif
"<tr><th colspan='2'>Sensor</th></tr>
\n
"
"<tr><td>Temperature offset</td><td>%.1fK</td></tr>
\n
"
//TODO: Read it from sensor?
"<tr><td>Auto-calibration?</td><td>%s</td></tr>
\n
"
"<tr><td>Local address</td><td><a href='http://%s.local/'>%s.local</a></td></tr>
\n
"
"<tr><td>Local IP</td><td><a href='http://%s'>%s</a></td></tr>
\n
"
"<tr><td>Free heap space</td><td>%6d bytes</td></tr>
\n
"
"<tr><td>Largest heap block</td><td>%6d bytes</td></tr>
\n
"
"<tr><td>Max loop duration</td><td>%5d ms</td></tr>
\n
"
"<tr><td>Board</td><td>%s</td></tr>
\n
"
"<tr><td>Uptime</td><td>%2d d %4d h %02d min %02d s</td></tr>
\n
"
"</table>
\n
"
"<div id='log' class='pure-u-1 pure-u-md-1-2'></div>
\n
"
"<form action='/command'><input type='text' id='send' name='send'><input type='submit' value='Send'></form>
\n
"
#ifdef AMPEL_CSV
"<form action='/delete_csv' method='POST' onsubmit=
\"
return confirm('Are you really sure you want to delete all data?') && (document.body.style.cursor = 'wait');
\"
>"
"<input type='submit' value='Delete CSV'/>"
...
...
@@ -130,7 +133,7 @@ namespace web_server {
#ifdef AMPEL_CSV
"<script>
\n
"
"document.body.style.cursor = 'default';
\n
"
"fetch('
./
%s',{credentials:'include'})
\n
"
"fetch('%s',{credentials:'include'})
\n
"
".then(response=>response.text())
\n
"
".then(csvText=>csvToTable(csvText))
\n
"
".then(htmlTable=>addLogTableToPage(htmlTable))
\n
"
...
...
@@ -173,15 +176,16 @@ namespace web_server {
// Web-server
http
.
on
(
"/"
,
handleWebServerRoot
);
http
.
on
(
"/command"
,
handleWebServerCommand
);
#ifdef AMPEL_CSV
http
.
on
(
"/"
+
csv_writer
::
filename
,
handleWebServerCSV
);
http
.
on
(
csv_writer
::
filename
,
handleWebServerCSV
);
//NOTE: csv_writer should have been initialized first.
http
.
on
(
"/delete_csv"
,
HTTP_POST
,
handleDeleteCSV
);
#endif
http
.
onNotFound
(
handlePageNotFound
);
http
.
begin
();
Serial
.
print
(
F
(
"You can access this sensor via http://"
));
Serial
.
print
(
SENSOR_ID
);
Serial
.
print
(
ampel
.
sensorId
);
Serial
.
print
(
F
(
".local (might be unstable) or http://"
));
Serial
.
println
(
WiFi
.
localIP
());
}
...
...
@@ -207,44 +211,49 @@ namespace web_server {
//NOTE: Splitting in multiple parts in order to use less RAM
char
content
[
2000
];
// Update if needed
// Header size : 1
611
- Body size : 18
00
- Script size : 19
2
0
//
INFO -
Header size : 1
767
- Body size : 18
12
- Script size : 190
9
// Header
snprintf_P
(
content
,
sizeof
(
content
),
header_template
,
sensor
::
co2
,
SENSOR_ID
.
c_str
(),
WiFi
.
localIP
().
toString
().
c_str
()
snprintf_P
(
content
,
sizeof
(
content
),
header_template
,
sensor
::
co2
,
ampel
.
sensorId
,
wifi
::
local_ip
#ifdef AMPEL_CSV
,
csv_writer
::
filename
.
c_str
()
,
csv_writer
::
filename
#endif
);
Serial
.
print
(
F
(
"INFO - Header size : "
));
Serial
.
print
(
strlen
(
content
));
http
.
setContentLength
(
CONTENT_LENGTH_UNKNOWN
);
http
.
send_P
(
200
,
PSTR
(
"text/html"
),
content
);
// Body
snprintf_P
(
content
,
sizeof
(
content
),
body_template
,
SENSOR_ID
.
c_str
()
,
sensor
::
co2
,
sensor
::
temperature
,
sensor
::
humidity
,
sensor
::
timestamp
.
c_str
()
,
config
::
measurement_timestep
,
snprintf_P
(
content
,
sizeof
(
content
),
body_template
,
ampel
.
sensorId
,
sensor
::
co2
,
sensor
::
temperature
,
sensor
::
humidity
,
sensor
::
timestamp
,
config
::
measurement_timestep
,
#ifdef AMPEL_CSV
csv_writer
::
last_successful_write
.
c_str
()
,
config
::
csv_interval
,
csv_writer
::
getAvailableSpace
()
/
1024
,
csv_writer
::
last_successful_write
,
config
::
csv_interval
,
csv_writer
::
getAvailableSpace
()
/
1024
,
#endif
#ifdef AMPEL_MQTT
mqtt
::
connected
?
"Yes"
:
"No"
,
mqtt
::
last_successful_publish
.
c_str
()
,
config
::
sending_interval
,
mqtt
::
connected
?
"Yes"
:
"No"
,
mqtt
::
last_successful_publish
,
config
::
mqtt_
sending_interval
,
#endif
#if defined(AMPEL_LORAWAN) && defined(ESP32)
lorawan
::
connected
?
"Yes"
:
"No"
,
LMIC_FREQUENCY_PLAN
,
lorawan
::
last_transmission
.
c_str
()
,
lorawan
::
connected
?
"Yes"
:
"No"
,
LMIC_FREQUENCY_PLAN
,
lorawan
::
last_transmission
,
config
::
lorawan_sending_interval
,
#endif
config
::
temperature_offset
,
SENSOR_ID
.
c_str
(),
SENSOR_ID
.
c_str
(),
WiFi
.
localIP
().
toString
().
c_str
(),
WiFi
.
localIP
().
toString
().
c_str
(),
get_free_heap_size
(),
max_loop_duration
,
BOARD
,
dd
,
hh
,
mm
,
ss
);
config
::
temperature_offset
,
config
::
auto_calibrate_sensor
?
"Yes"
:
"No"
,
ampel
.
sensorId
,
ampel
.
sensorId
,
wifi
::
local_ip
,
wifi
::
local_ip
,
ESP
.
getFreeHeap
(),
esp_get_max_free_block_size
(),
ampel
.
max_loop_duration
,
ampel
.
board
,
dd
,
hh
,
mm
,
ss
);
Serial
.
print
(
F
(
" - Body size : "
));
http
.
sendContent
(
content
);
Serial
.
print
(
strlen
(
content
));
// Script
snprintf_P
(
content
,
sizeof
(
content
),
script_template
#ifdef AMPEL_CSV
,
csv_writer
::
filename
.
c_str
(),
SENSOR_ID
.
c_str
()
,
csv_writer
::
filename
,
ampel
.
sensorId
#endif
);
Serial
.
print
(
F
(
" - Script size : "
));
Serial
.
println
(
strlen
(
content
));
http
.
sendContent
(
content
);
}
...
...
@@ -255,7 +264,9 @@ namespace web_server {
}
if
(
FS_LIB
.
exists
(
csv_writer
::
filename
))
{
fs
::
File
csv_file
=
FS_LIB
.
open
(
csv_writer
::
filename
,
"r"
);
http
.
sendHeader
(
"Content-Length"
,
String
(
csv_file
.
size
()));
char
csv_size
[
10
];
snprintf
(
csv_size
,
sizeof
(
csv_size
),
"%d"
,
csv_file
.
size
());
http
.
sendHeader
(
"Content-Length"
,
csv_size
);
http
.
streamFile
(
csv_file
,
F
(
"text/csv"
));
csv_file
.
close
();
}
else
{
...
...
@@ -267,14 +278,23 @@ namespace web_server {
if
(
!
shouldBeAllowed
())
{
return
http
.
requestAuthentication
(
DIGEST_AUTH
);
}
Serial
.
print
(
"Removing CSV file..."
);
Serial
.
print
(
F
(
"Removing CSV file..."
)
)
;
FS_LIB
.
remove
(
csv_writer
::
filename
);
Serial
.
println
(
" Done!"
);
Serial
.
println
(
F
(
" Done!"
)
)
;
http
.
sendHeader
(
"Location"
,
"/"
);
http
.
send
(
303
);
}
#endif
void
handleWebServerCommand
()
{
if
(
!
shouldBeAllowed
())
{
return
http
.
requestAuthentication
(
DIGEST_AUTH
);
}
http
.
sendHeader
(
"Location"
,
"/"
);
http
.
send
(
303
);
sensor_console
::
runCommand
(
http
.
arg
(
"send"
).
c_str
());
}
void
handlePageNotFound
()
{
http
.
send
(
404
,
F
(
"text/plain"
),
F
(
"404: Not found"
));
}
...
...
ampel-firmware/web_server.h
View file @
208eadd3
#ifndef WEB_SERVER_H_
#define WEB_SERVER_H_
#if defined(ESP8266)
# include <ESP8266WebServer.h>
#elif defined(ESP32)
...
...
@@ -8,7 +9,9 @@
#include
"config.h"
#include
"util.h"
#include
"wifi_util.h"
#include
"co2_sensor.h"
#include
"sensor_console.h"
#ifdef AMPEL_CSV
# include "csv_writer.h"
#endif
...
...
ampel-firmware/wifi_util.cpp
View file @
208eadd3
...
...
@@ -12,15 +12,17 @@ namespace config {
#endif
}
// Initialize Wi-Fi
void
WiFiConnect
(
const
String
&
hostname
)
{
namespace
wifi
{
char
local_ip
[
16
];
// "255.255.255.255\0"
// Initialize Wi-Fi
void
connect
(
const
char
*
hostname
)
{
//NOTE: WiFi Multi could allow multiple SSID and passwords.
WiFi
.
persistent
(
false
);
// Don't write user & password to Flash.
WiFi
.
mode
(
WIFI_STA
);
// Set ESP to be a WiFi-client only
#if defined(ESP8266)
WiFi
.
hostname
(
hostname
);
#elif defined(ESP32)
WiFi
.
setHostname
(
hostname
.
c_str
()
);
WiFi
.
setHostname
(
hostname
);
#endif
Serial
.
print
(
F
(
"WiFi - Connecting to "
));
...
...
@@ -36,10 +38,13 @@ void WiFiConnect(const String &hostname) {
led_effects
::
showKITTWheel
(
color
::
green
);
Serial
.
println
();
Serial
.
print
(
F
(
"WiFi - Connected! IP address: "
));
Serial
.
println
(
WiFi
.
localIP
());
IPAddress
address
=
WiFi
.
localIP
();
snprintf
(
local_ip
,
sizeof
(
local_ip
),
"%d.%d.%d.%d"
,
address
[
0
],
address
[
1
],
address
[
2
],
address
[
3
]);
Serial
.
println
(
local_ip
);
}
else
{
//TODO: Allow sensor to work as an Access Point, in order to define SSID & password?
led_effects
::
showKITTWheel
(
color
::
red
);
Serial
.
println
(
F
(
"Connection to WiFi failed"
));
}
}
}
ampel-firmware/wifi_util.h
View file @
208eadd3
...
...
@@ -5,6 +5,9 @@
#include
"util.h"
#include
"led_effects.h"
void
WiFiConnect
(
const
String
&
hostname
);
namespace
wifi
{
extern
char
local_ip
[];
void
connect
(
const
char
*
hostname
);
}
#endif
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment