firmware-base/vendor/sming/Sming/samples/MeteoControl/app/webserver.cpp
2026-01-28 16:42:43 +01:00

152 lines
4.5 KiB
C++

#include <SmingCore.h>
#include "configuration.h"
#include "webserver.h"
extern String StrT, StrRH; // Sensors string values
namespace
{
HttpServer server;
HttpClient downloadClient;
bool serverStarted;
void onIndex(HttpRequest& request, HttpResponse& response)
{
TemplateFileStream* tmpl = new TemplateFileStream("index.html");
auto& vars = tmpl->variables();
vars["T"] = StrT;
vars["RH"] = StrRH;
response.sendNamedStream(tmpl);
}
void onConfiguration(HttpRequest& request, HttpResponse& response)
{
MeteoConfig cfg = loadConfig();
if(request.method == HTTP_POST) {
debugf("Update config");
// Update config
if(request.getPostParameter("SSID").length() > 0) // Network
{
cfg.NetworkSSID = request.getPostParameter("SSID");
cfg.NetworkPassword = request.getPostParameter("Password");
}
if(request.getPostParameter("TZ").length() > 0) // Correction
{
cfg.AddT = request.getPostParameter("T").toFloat();
cfg.AddRH = request.getPostParameter("RH").toFloat();
cfg.AddTZ = request.getPostParameter("TZ").toFloat();
}
if(request.getPostParameter("Trigger").length() > 0) // Trigger
{
cfg.Trigger = (TriggerType)request.getPostParameter("Trigger").toInt();
cfg.RangeMin = request.getPostParameter("RMin").toFloat();
cfg.RangeMax = request.getPostParameter("RMax").toFloat();
}
saveConfig(cfg);
startWebClock(); // Apply time zone settings
response.headers[HTTP_HEADER_LOCATION] = "/";
}
debugf("Send template");
TemplateFileStream* tmpl = new TemplateFileStream("config.html");
auto& vars = tmpl->variables();
vars["SSID"] = cfg.NetworkSSID;
vars["T"] = String(cfg.AddT, 2);
vars["RH"] = String(cfg.AddRH, 2);
vars["TZ"] = String(cfg.AddTZ, 2);
vars["Trigger"] = String((int)cfg.Trigger);
vars["RMin"] = String(cfg.RangeMin, 2);
vars["RMax"] = String(cfg.RangeMax, 2);
response.sendNamedStream(tmpl);
}
void onFile(HttpRequest& request, HttpResponse& response)
{
String file = request.uri.getRelativePath();
if(file[0] == '.')
response.code = HTTP_STATUS_FORBIDDEN;
else {
response.setCache(86400, true); // It's important to use cache for better performance.
response.sendFile(file);
}
}
/// API ///
void onApiDoc(HttpRequest& request, HttpResponse& response)
{
TemplateFileStream* tmpl = new TemplateFileStream("api.html");
auto& vars = tmpl->variables();
vars["IP"] = (WifiStation.isConnected() ? WifiStation.getIP() : WifiAccessPoint.getIP()).toString();
response.sendNamedStream(tmpl);
}
void onApiSensors(HttpRequest& request, HttpResponse& response)
{
JsonObjectStream* stream = new JsonObjectStream();
JsonObject json = stream->getRoot();
json["status"] = (bool)true;
JsonObject sensors = json.createNestedObject("sensors");
sensors["temperature"] = StrT.c_str();
sensors["humidity"] = StrRH.c_str();
response.sendDataStream(stream, MIME_JSON);
}
void onApiOutput(HttpRequest& request, HttpResponse& response)
{
int val = request.getQueryParameter("control", "-1").toInt();
if(val == 0 || val == 1) {
digitalWrite(CONTROL_PIN, val == 1);
} else {
val = -1;
}
JsonObjectStream* stream = new JsonObjectStream();
JsonObject json = stream->getRoot();
json["status"] = val >= 0;
if(val < 0)
json["error"] = "Wrong control parameter value, please use: ?control=0|1";
response.sendDataStream(stream, MIME_JSON);
}
} // namespace
void downloadContentFiles()
{
debugf("DownloadContentFiles");
downloadClient.downloadFile(F("http://simple.anakod.ru/templates/MeteoControl/MeteoControl.html"), "index.html");
downloadClient.downloadFile(F("http://simple.anakod.ru/templates/MeteoControl/MeteoConfig.html"), "config.html");
downloadClient.downloadFile(F("http://simple.anakod.ru/templates/MeteoControl/MeteoAPI.html"), "api.html");
downloadClient.downloadFile(F("http://simple.anakod.ru/templates/bootstrap.css.gz"));
downloadClient.downloadFile(F("http://simple.anakod.ru/templates/jquery.js.gz"),
[](HttpConnection& connection, bool success) -> int {
if(success) {
startWebServer();
}
return 0;
});
}
void startWebServer()
{
if(serverStarted) {
return;
}
server.listen(80);
server.paths.set("/", onIndex);
server.paths.set("/api", onApiDoc);
server.paths.set("/api/sensors", onApiSensors);
server.paths.set("/api/output", onApiOutput);
server.paths.set("/config", onConfiguration);
server.paths.setDefault(onFile);
serverStarted = true;
if(WifiStation.isEnabled())
debugf("STA: %s", WifiStation.getIP().toString().c_str());
if(WifiAccessPoint.isEnabled())
debugf("AP: %s", WifiAccessPoint.getIP().toString().c_str());
}