Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
co2ampel
ampel-firmware
Commits
56f99df8
Commit
56f99df8
authored
May 15, 2021
by
Eric Duminil
Browse files
Web server refactor
parent
077b4e74
Changes
3
Hide whitespace changes
Inline
Side-by-side
ampel-firmware/web_config.h
View file @
56f99df8
...
...
@@ -20,5 +20,11 @@ namespace web_config {
void
setWifiConnectionCallback
(
void
(
*
function
)());
void
setWifiConnectionFailedCallback
(
void
(
*
function
)());
void
update
();
#if defined(ESP8266)
extern
ESP8266WebServer
http
;
#elif defined(ESP32)
extern
WebServer
http
;
#endif
}
#endif
ampel-firmware/web_server.cpp
View file @
56f99df8
...
...
@@ -8,6 +8,7 @@
# include <ESPmDNS.h>
#endif
#include "web_config.h"
#include "config.h"
#include "util.h"
#include "ntp.h"
...
...
@@ -56,135 +57,7 @@ namespace web_server {
void
handleWebServerCSV
();
#endif
#if defined(ESP8266)
ESP8266WebServer
http
(
80
);
// Create a webserver object that listens for HTTP request on port 80
#elif defined(ESP32)
WebServer
http
(
80
);
#endif
DNSServer
dnsServer
;
IotWebConf
*
iotWebConf
;
#define STRING_LEN 64
// -- Configuration specific key. The value should be modified if config structure was changed.
const
char
config_version
[]
=
"ampel_test_v3"
;
static
const
char
chooserValues
[][
STRING_LEN
]
=
{
"red"
,
"blue"
,
"darkYellow"
};
static
const
char
chooserNames
[][
STRING_LEN
]
=
{
"Red"
,
"Blue"
,
"Dark yellow"
};
iotwebconf
::
TextTParameter
<
STRING_LEN
>
stringParam
=
iotwebconf
::
Builder
<
iotwebconf
::
TextTParameter
<
STRING_LEN
>>
(
"stringParam"
).
label
(
"String param"
).
build
();
iotwebconf
::
ParameterGroup
group1
=
iotwebconf
::
ParameterGroup
(
"group1"
,
""
);
iotwebconf
::
IntTParameter
<
int16_t
>
intParam
=
iotwebconf
::
Builder
<
iotwebconf
::
IntTParameter
<
int16_t
>>
(
"intParam"
).
label
(
"Int param"
).
defaultValue
(
30
).
min
(
1
).
max
(
100
).
step
(
1
).
placeholder
(
"1..100"
).
build
();
// -- We can add a legend to the separator
iotwebconf
::
ParameterGroup
group2
=
iotwebconf
::
ParameterGroup
(
"c_factor"
,
"Calibration factor"
);
iotwebconf
::
FloatTParameter
floatParam
=
iotwebconf
::
Builder
<
iotwebconf
::
FloatTParameter
>
(
"floatParam"
).
label
(
"Float param"
).
defaultValue
(
0.0
).
step
(
0.1
).
placeholder
(
"e.g. 23.4"
).
build
();
iotwebconf
::
CheckboxTParameter
checkboxParam
=
iotwebconf
::
Builder
<
iotwebconf
::
CheckboxTParameter
>
(
"checkParam"
).
label
(
"Check param"
).
defaultValue
(
true
).
build
();
iotwebconf
::
SelectTParameter
<
STRING_LEN
>
chooserParam
=
iotwebconf
::
Builder
<
iotwebconf
::
SelectTParameter
<
STRING_LEN
>>
(
"chooseParam"
).
label
(
"Choose param"
).
optionValues
(
(
const
char
*
)
chooserValues
).
optionNames
((
const
char
*
)
chooserNames
).
optionCount
(
sizeof
(
chooserValues
)
/
STRING_LEN
).
nameLength
(
STRING_LEN
).
build
();
void
update
()
{
iotWebConf
->
doLoop
();
// Listen for HTTP requests from clients
}
void
initialize
()
{
iotWebConf
=
new
IotWebConf
(
ampel
.
sensorId
,
&
dnsServer
,
&
http
,
HTTP_PASSWORD
,
config_version
);
const
int
ONBOARD_LED_PIN
=
2
;
# ifdef ESP8266
iotWebConf
->
setStatusPin
(
ONBOARD_LED_PIN
,
LOW
);
# else
iotWebConf
->
setStatusPin
(
ONBOARD_LED_PIN
,
HIGH
);
# endif
iotWebConf
->
setWifiConnectionTimeoutMs
(
1000UL
*
WIFI_TIMEOUT
);
#if defined(ESP8266)
WiFi
.
hostname
(
ampel
.
sensorId
);
#elif defined(ESP32)
WiFi
.
setHostname
(
ampel
.
sensorId
);
#endif
group1
.
addItem
(
&
intParam
);
group2
.
addItem
(
&
floatParam
);
group2
.
addItem
(
&
checkboxParam
);
group2
.
addItem
(
&
chooserParam
);
iotWebConf
->
addSystemParameter
(
&
stringParam
);
iotWebConf
->
addParameterGroup
(
&
group1
);
iotWebConf
->
addParameterGroup
(
&
group2
);
iotWebConf
->
setWifiConnectionCallback
([]()
{
led_effects
::
showKITTWheel
(
color
::
green
);
Serial
.
println
();
Serial
.
print
(
F
(
"WiFi - Connected! IP address: "
));
IPAddress
address
=
WiFi
.
localIP
();
snprintf
(
wifi
::
local_ip
,
sizeof
(
wifi
::
local_ip
),
"%d.%d.%d.%d"
,
address
[
0
],
address
[
1
],
address
[
2
],
address
[
3
]);
ntp
::
initialize
();
//FIXME: Somehow already started
// if (MDNS.begin(ampel.sensorId)) { // Start the mDNS responder for SENSOR_ID.local
// MDNS.addService("http", "tcp", 80);
// Serial.println(F("mDNS responder started"));
// } else {
// Serial.println(F("Error setting up MDNS responder!"));
// }
# ifdef AMPEL_MQTT
mqtt
::
initialize
(
ampel
.
sensorId
);
# endif
Serial
.
println
(
wifi
::
local_ip
);
Serial
.
print
(
F
(
"You can access this sensor via http://"
));
Serial
.
print
(
ampel
.
sensorId
);
Serial
.
print
(
F
(
".local (might be unstable) or http://"
));
Serial
.
println
(
WiFi
.
localIP
());
});
iotWebConf
->
setWifiConnectionFailedHandler
([]()
->
iotwebconf
::
WifiAuthInfo
*
{
led_effects
::
showKITTWheel
(
color
::
red
);
Serial
.
println
(
F
(
"Connection to WiFi failed"
));
return
NULL
;
});
iotWebConf
->
skipApStartup
();
//TODO: Add callbacks
//TODO: Add LED effects
//TODO: Allow offline config loading
//TODO: Add default values for SSID/password
//TODO: Add other params
//TODO: Use HTTP_USER / HTTP_PASSWORD for config
//TODO: Move to own class
//TODO: Remove AP Password config?
//TODO: Save LoRaWAN key if possible?
//FIXME: Why does MQTT fail? (on ESP32)
// iotWebConf->loadConfig();
Serial
.
println
(
"<<<<<<<<<<<<<<<"
);
Serial
.
println
(
stringParam
.
value
());
Serial
.
println
(
intParam
.
value
());
Serial
.
println
(
floatParam
.
value
());
iotWebConf
->
init
();
Serial
.
println
(
stringParam
.
value
());
Serial
.
println
(
intParam
.
value
());
Serial
.
println
(
floatParam
.
value
());
Serial
.
println
(
">>>>>>>>>>>>>>>"
);
sensor_console
::
defineCommand
(
"reset_config"
,
[]()
{
Serial
.
println
(
F
(
"Resetting config..."
));
iotWebConf
->
getSystemParameterGroup
()
->
applyDefaultValue
();
iotWebConf
->
saveConfig
();
Serial
.
println
(
F
(
"Done!"
));
},
F
(
"(resets the complete IotWeb config)"
));
void
definePages
()
{
header_template
=
PSTR
(
"<!doctype html><html lang=en>"
"<head>
\n
"
...
...
@@ -323,36 +196,27 @@ namespace web_server {
"</html>"
);
// Web-server
http
.
on
(
"/"
,
handleWebServerRoot
);
http
.
on
(
"/command"
,
handleWebServerCommand
);
web_config
::
http
.
on
(
"/"
,
handleWebServerRoot
);
web_config
::
http
.
on
(
"/command"
,
handleWebServerCommand
);
#ifdef AMPEL_CSV
http
.
on
(
csv_writer
::
filename
,
handleWebServerCSV
);
//NOTE: csv_writer should have been initialized first.
http
.
on
(
"/delete_csv"
,
HTTP_POST
,
handleDeleteCSV
);
web_config
::
http
.
on
(
csv_writer
::
filename
,
handleWebServerCSV
);
//NOTE: csv_writer should have been initialized first.
web_config
::
http
.
on
(
"/delete_csv"
,
HTTP_POST
,
handleDeleteCSV
);
#endif
http
.
on
(
"/config"
,
[]
{
iotWebConf
->
handleConfig
();
});
http
.
onNotFound
([]()
{
iotWebConf
->
handleNotFound
();
});
//TODO: Only once wifi connected
}
// Allow access if http_user or http_password are empty, or if provided credentials match
bool
shouldBeAllowed
()
{
return
strcmp
(
config
::
http_user
,
""
)
==
0
||
strcmp
(
config
::
http_password
,
""
)
==
0
||
http
.
authenticate
(
config
::
http_user
,
config
::
http_password
);
||
web_config
::
http
.
authenticate
(
config
::
http_user
,
config
::
http_password
);
}
void
handleWebServerRoot
()
{
if
(
iotWebConf
->
handleCaptivePortal
())
{
// -- Captive portal requests were already served.
return
;
}
//
if (
web_config::
handleCaptivePortal()) {
//
// -- Captive portal requests were already served.
//
return;
//
}
if
(
!
shouldBeAllowed
())
{
return
http
.
requestAuthentication
(
DIGEST_AUTH
);
return
web_config
::
http
.
requestAuthentication
(
DIGEST_AUTH
);
}
unsigned
long
ss
=
seconds
();
...
...
@@ -375,8 +239,8 @@ namespace web_server {
// Serial.print(F("INFO - Header size : "));
// Serial.print(strlen(content));
http
.
setContentLength
(
CONTENT_LENGTH_UNKNOWN
);
http
.
send_P
(
200
,
PSTR
(
"text/html"
),
content
);
web_config
::
http
.
setContentLength
(
CONTENT_LENGTH_UNKNOWN
);
web_config
::
http
.
send_P
(
200
,
PSTR
(
"text/html"
),
content
);
// Body
snprintf_P
(
content
,
sizeof
(
content
),
body_template
,
ampel
.
sensorId
,
sensor
::
co2
,
sensor
::
temperature
,
...
...
@@ -397,7 +261,7 @@ namespace web_server {
// Serial.print(F(" - Body size : "));
// Serial.print(strlen(content));
http
.
sendContent
(
content
);
web_config
::
http
.
sendContent
(
content
);
// Script
snprintf_P
(
content
,
sizeof
(
content
),
script_template
...
...
@@ -408,48 +272,48 @@ namespace web_server {
// Serial.print(F(" - Script size : "));
// Serial.println(strlen(content));
http
.
sendContent
(
content
);
web_config
::
http
.
sendContent
(
content
);
}
#ifdef AMPEL_CSV
void
handleWebServerCSV
()
{
if
(
!
shouldBeAllowed
())
{
return
http
.
requestAuthentication
(
DIGEST_AUTH
);
return
web_config
::
http
.
requestAuthentication
(
DIGEST_AUTH
);
}
if
(
FS_LIB
.
exists
(
csv_writer
::
filename
))
{
fs
::
File
csv_file
=
FS_LIB
.
open
(
csv_writer
::
filename
,
"r"
);
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"
));
web_config
::
http
.
sendHeader
(
"Content-Length"
,
csv_size
);
web_config
::
http
.
streamFile
(
csv_file
,
F
(
"text/csv"
));
csv_file
.
close
();
}
else
{
http
.
send
(
204
,
F
(
"text/html"
),
F
(
"No data available."
));
web_config
::
http
.
send
(
204
,
F
(
"text/html"
),
F
(
"No data available."
));
}
}
void
handleDeleteCSV
()
{
if
(
!
shouldBeAllowed
())
{
return
http
.
requestAuthentication
(
DIGEST_AUTH
);
return
web_config
::
http
.
requestAuthentication
(
DIGEST_AUTH
);
}
Serial
.
print
(
F
(
"Removing CSV file..."
));
FS_LIB
.
remove
(
csv_writer
::
filename
);
Serial
.
println
(
F
(
" Done!"
));
http
.
sendHeader
(
"Location"
,
"/"
);
http
.
send
(
303
);
web_config
::
http
.
sendHeader
(
"Location"
,
"/"
);
web_config
::
http
.
send
(
303
);
}
#endif
void
handleWebServerCommand
()
{
if
(
!
shouldBeAllowed
())
{
return
http
.
requestAuthentication
(
DIGEST_AUTH
);
return
web_config
::
http
.
requestAuthentication
(
DIGEST_AUTH
);
}
http
.
sendHeader
(
"Location"
,
"/"
);
http
.
send
(
303
);
sensor_console
::
execute
(
http
.
arg
(
"send"
).
c_str
());
web_config
::
http
.
sendHeader
(
"Location"
,
"/"
);
web_config
::
http
.
send
(
303
);
sensor_console
::
execute
(
web_config
::
http
.
arg
(
"send"
).
c_str
());
}
void
handlePageNotFound
()
{
http
.
send
(
404
,
F
(
"text/plain"
),
F
(
"404: Not found"
));
web_config
::
http
.
send
(
404
,
F
(
"text/plain"
),
F
(
"404: Not found"
));
}
}
ampel-firmware/web_server.h
View file @
56f99df8
...
...
@@ -2,7 +2,6 @@
#define WEB_SERVER_H_
namespace
web_server
{
void
initialize
();
void
update
();
void
definePages
();
}
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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