This commit is contained in:
proddy
2025-01-04 13:41:39 +01:00
parent 4138598db2
commit eb87651c47
166 changed files with 2099 additions and 10446 deletions

View File

@@ -25,7 +25,10 @@ uint16_t WebAPIService::api_fails_ = 0;
WebAPIService::WebAPIService(AsyncWebServer * server, SecurityManager * securityManager)
: _securityManager(securityManager) {
server->on(EMSESP_API_SERVICE_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { webAPIService(request, json); });
AsyncCallbackJsonWebHandler * jsonHandler = new AsyncCallbackJsonWebHandler(EMSESP_API_SERVICE_PATH);
jsonHandler->setMethod(HTTP_POST | HTTP_GET);
jsonHandler->onRequest([this](AsyncWebServerRequest * request, JsonVariant json) { webAPIService(request, json); });
server->addHandler(jsonHandler);
}
// POST|GET api/

View File

@@ -27,7 +27,7 @@ class WebAPIService {
public:
WebAPIService(AsyncWebServer * server, SecurityManager * securityManager);
void webAPIService(AsyncWebServerRequest * request, JsonVariant json);
void webAPIService(AsyncWebServerRequest * request, JsonVariant input);
#if defined(EMSESP_TEST)
// for test.cpp and running unit tests

View File

@@ -21,9 +21,9 @@
namespace emsesp {
WebActivityService::WebActivityService(AsyncWebServer * server, SecurityManager * securityManager) {
server->on(EMSESP_ACTIVITY_SERVICE_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { webActivityService(request); }, AuthenticationPredicates::IS_AUTHENTICATED));
securityManager->addEndpoint(server, EMSESP_ACTIVITY_SERVICE_PATH, AuthenticationPredicates::IS_AUTHENTICATED, [this](AsyncWebServerRequest * request) {
webActivityService(request);
});
}
void WebActivityService::webActivityService(AsyncWebServerRequest * request) {

View File

@@ -82,7 +82,8 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web
// rebuild the list
if (root["entities"].is<JsonArray>()) {
for (const JsonObject ei : root["entities"].as<JsonArray>()) {
auto entities = root["entities"].as<JsonArray>();
for (const JsonObject ei : entities) {
auto entityItem = CustomEntityItem();
entityItem.ram = ei["ram"];
entityItem.device_id = ei["device_id"]; // send as numeric, will be converted to string in web

View File

@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../telegram.h"
#include "../core/telegram.h"
#ifndef WebCustomEntityService_h
#define WebCustomEntityService_h

View File

@@ -25,20 +25,27 @@ bool WebCustomization::_start = true;
WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
: _fsPersistence(WebCustomization::read, WebCustomization::update, this, fs, EMSESP_CUSTOMIZATION_FILE) {
// GET
server->on(EMSESP_DEVICE_ENTITIES_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { device_entities(request); }, AuthenticationPredicates::IS_AUTHENTICATED));
securityManager->addEndpoint(server, EMSESP_DEVICE_ENTITIES_PATH, AuthenticationPredicates::IS_AUTHENTICATED, [this](AsyncWebServerRequest * request) {
device_entities(request);
});
// POST
server->on(EMSESP_RESET_CUSTOMIZATION_SERVICE_PATH,
HTTP_POST,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { reset_customization(request); }, AuthenticationPredicates::IS_ADMIN));
server->on(EMSESP_WRITE_DEVICE_NAME_PATH,
securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { writeDeviceName(request, json); },
AuthenticationPredicates::IS_AUTHENTICATED));
server->on(EMSESP_CUSTOMIZATION_ENTITIES_PATH,
securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { customization_entities(request, json); },
AuthenticationPredicates::IS_AUTHENTICATED));
securityManager->addEndpoint(
server,
EMSESP_RESET_CUSTOMIZATION_SERVICE_PATH,
AuthenticationPredicates::IS_ADMIN,
[this](AsyncWebServerRequest * request) { reset_customization(request); },
HTTP_POST); // force POST
securityManager->addEndpoint(server,
EMSESP_WRITE_DEVICE_NAME_PATH,
AuthenticationPredicates::IS_AUTHENTICATED,
[this](AsyncWebServerRequest * request, JsonVariant json) { writeDeviceName(request, json); });
securityManager->addEndpoint(server,
EMSESP_CUSTOMIZATION_ENTITIES_PATH,
AuthenticationPredicates::IS_AUTHENTICATED,
[this](AsyncWebServerRequest * request, JsonVariant json) { customization_entities(request, json); });
}
// this creates the customization file, saving it to the FS
@@ -87,7 +94,8 @@ StateUpdateResult WebCustomization::update(JsonObject root, WebCustomization & c
// Temperature Sensor customization
customizations.sensorCustomizations.clear();
if (root["ts"].is<JsonArray>()) {
for (const JsonObject sensorJson : root["ts"].as<JsonArray>()) {
auto sensorsJsons = root["ts"].as<JsonArray>();
for (const JsonObject sensorJson : sensorsJsons) {
// create each of the sensor, overwriting any previous settings
auto sensor = SensorCustomization();
sensor.id = sensorJson["id"].as<std::string>();
@@ -104,7 +112,8 @@ StateUpdateResult WebCustomization::update(JsonObject root, WebCustomization & c
// Analog Sensor customization
customizations.analogCustomizations.clear();
if (root["as"].is<JsonArray>()) {
for (const JsonObject analogJson : root["as"].as<JsonArray>()) {
auto analogJsons = root["as"].as<JsonArray>();
for (const JsonObject analogJson : analogJsons) {
// create each of the sensor, overwriting any previous settings
auto analog = AnalogCustomization();
analog.gpio = analogJson["gpio"];
@@ -124,13 +133,15 @@ StateUpdateResult WebCustomization::update(JsonObject root, WebCustomization & c
// load array of entities id's with masks, building up the object class
customizations.entityCustomizations.clear();
if (root["masked_entities"].is<JsonArray>()) {
for (const JsonObject masked_entities : root["masked_entities"].as<JsonArray>()) {
auto masked_entities = root["masked_entities"].as<JsonArray>();
for (const JsonObject masked_entity : masked_entities) {
auto emsEntity = EntityCustomization();
emsEntity.product_id = masked_entities["product_id"];
emsEntity.device_id = masked_entities["device_id"];
emsEntity.custom_name = masked_entities["custom_name"] | "";
emsEntity.product_id = masked_entity["product_id"];
emsEntity.device_id = masked_entity["device_id"];
emsEntity.custom_name = masked_entity["custom_name"] | "";
for (const JsonVariant masked_entity_id : masked_entities["entity_ids"].as<JsonArray>()) {
auto masked_entity_ids = masked_entity["entity_ids"].as<JsonArray>();
for (const JsonVariant masked_entity_id : masked_entity_ids) {
if (masked_entity_id.is<std::string>()) {
emsEntity.entity_ids.push_back(masked_entity_id.as<std::string>()); // add entity list
}
@@ -172,7 +183,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request) {
id = Helpers::atoint(request->getParam(F_(id))->value().c_str()); // get id from url
#endif
auto * response = new AsyncJsonResponse(true, true); // array and msgpack
auto * response = new AsyncMessagePackResponse(true); // array and msgpack
// while (!response) {
// delete response;

View File

@@ -21,32 +21,38 @@
namespace emsesp {
WebDataService::WebDataService(AsyncWebServer * server, SecurityManager * securityManager) {
// write endpoints
server->on(EMSESP_WRITE_DEVICE_VALUE_SERVICE_PATH,
securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { write_device_value(request, json); },
AuthenticationPredicates::IS_ADMIN));
server->on(EMSESP_WRITE_TEMPERATURE_SENSOR_SERVICE_PATH,
securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { write_temperature_sensor(request, json); },
AuthenticationPredicates::IS_ADMIN));
server->on(EMSESP_WRITE_ANALOG_SENSOR_SERVICE_PATH,
securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { write_analog_sensor(request, json); },
AuthenticationPredicates::IS_ADMIN));
// write endpoints - POSTs
securityManager->addEndpoint(server,
EMSESP_WRITE_DEVICE_VALUE_SERVICE_PATH,
AuthenticationPredicates::IS_ADMIN,
[this](AsyncWebServerRequest * request, JsonVariant json) { write_device_value(request, json); });
securityManager->addEndpoint(server,
EMSESP_WRITE_TEMPERATURE_SENSOR_SERVICE_PATH,
AuthenticationPredicates::IS_ADMIN,
[this](AsyncWebServerRequest * request, JsonVariant json) { write_temperature_sensor(request, json); });
securityManager->addEndpoint(server,
EMSESP_WRITE_ANALOG_SENSOR_SERVICE_PATH,
AuthenticationPredicates::IS_ADMIN,
[this](AsyncWebServerRequest * request, JsonVariant json) { write_analog_sensor(request, json); });
// GET's
server->on(EMSESP_DEVICE_DATA_SERVICE_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { device_data(request); }, AuthenticationPredicates::IS_AUTHENTICATED));
securityManager->addEndpoint(server, EMSESP_DEVICE_DATA_SERVICE_PATH, AuthenticationPredicates::IS_AUTHENTICATED, [this](AsyncWebServerRequest * request) {
device_data(request);
});
server->on(EMSESP_CORE_DATA_SERVICE_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { core_data(request); }, AuthenticationPredicates::IS_AUTHENTICATED));
securityManager->addEndpoint(server, EMSESP_CORE_DATA_SERVICE_PATH, AuthenticationPredicates::IS_AUTHENTICATED, [this](AsyncWebServerRequest * request) {
core_data(request);
});
server->on(EMSESP_SENSOR_DATA_SERVICE_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { sensor_data(request); }, AuthenticationPredicates::IS_AUTHENTICATED));
securityManager->addEndpoint(server, EMSESP_SENSOR_DATA_SERVICE_PATH, AuthenticationPredicates::IS_AUTHENTICATED, [this](AsyncWebServerRequest * request) {
sensor_data(request);
});
server->on(EMSESP_DASHBOARD_DATA_SERVICE_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { dashboard_data(request); }, AuthenticationPredicates::IS_AUTHENTICATED));
securityManager->addEndpoint(server, EMSESP_DASHBOARD_DATA_SERVICE_PATH, AuthenticationPredicates::IS_AUTHENTICATED, [this](AsyncWebServerRequest * request) {
dashboard_data(request);
});
}
// this is used in the Devices page and contains all EMS device information
@@ -161,7 +167,7 @@ void WebDataService::device_data(AsyncWebServerRequest * request) {
if (request->hasParam(F_(id))) {
id = Helpers::atoint(request->getParam(F_(id))->value().c_str()); // get id from url
auto * response = new AsyncJsonResponse(false, true); // use msgPack
auto * response = new AsyncMessagePackResponse();
// check size
// while (!response) {
@@ -346,7 +352,7 @@ void WebDataService::write_analog_sensor(AsyncWebServerRequest * request, JsonVa
// this is used in the dashboard and contains all ems device information
// /dashboardData endpoint
void WebDataService::dashboard_data(AsyncWebServerRequest * request) {
auto * response = new AsyncJsonResponse(true, true); // its an Array and also msgpack'd
auto * response = new AsyncMessagePackResponse(true);
#if defined(EMSESP_STANDALONE)
JsonDocument doc;

View File

@@ -24,10 +24,14 @@ namespace emsesp {
WebLogService::WebLogService(AsyncWebServer * server, SecurityManager * securityManager)
: events_(EMSESP_EVENT_SOURCE_LOG_PATH) {
// get & set settings
server->on(EMSESP_LOG_SETTINGS_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { getSetValues(request, json); });
// there is a GET and a POST for LogSettings endpoint, in one function
securityManager->addEndpoint(
server,
EMSESP_LOG_SETTINGS_PATH,
AuthenticationPredicates::IS_AUTHENTICATED,
[this](AsyncWebServerRequest * request, JsonVariant json) { getSetValues(request, json); },
HTTP_ANY);
// events_.setFilter(securityManager->filterRequest(AuthenticationPredicates::IS_ADMIN));
server->addHandler(&events_);
}
@@ -121,7 +125,7 @@ void WebLogService::operator<<(std::shared_ptr<uuid::log::Message> message) {
log_messages_.emplace_back(++log_message_id_, std::move(message));
EMSESP::esp8266React.getNTPSettingsService()->read([&](NTPSettings & settings) {
EMSESP::esp32React.getNTPSettingsService()->read([&](NTPSettings & settings) {
if (!settings.enabled || (time(nullptr) < 1500000000L)) {
time_offset_ = 0;
} else {

View File

@@ -51,13 +51,14 @@ void WebModulesService::loop() {
// and also calls when the Modules web page is refreshed/loaded
void WebModules::read(WebModules & webModules, JsonObject root) {
JsonDocument doc_modules;
JsonObject root_modules = doc_modules.to<JsonObject>();
auto root_modules = doc_modules.to<JsonObject>();
moduleLibrary.list(root_modules); // get list the external library modules, put in a json object
JsonArray modules = root["modules"].to<JsonArray>();
auto modules_new = root["modules"].to<JsonArray>();
auto modules = root_modules["modules"].as<JsonArray>();
uint8_t counter = 0;
for (const JsonObject module : root_modules["modules"].as<JsonArray>()) {
JsonObject mi = modules.add<JsonObject>();
for (const JsonObject module : modules) {
JsonObject mi = modules_new.add<JsonObject>();
mi["id"] = counter++; // id is only used to render the table and must be unique
mi["key"] = module["key"].as<std::string>();
mi["name"] = module["name"].as<std::string>();
@@ -76,7 +77,8 @@ void WebModules::read(WebModules & webModules, JsonObject root) {
StateUpdateResult WebModules::update(JsonObject root, WebModules & webModules) {
bool err = false;
if (root["modules"].is<JsonArray>()) {
for (const JsonObject module : root["modules"].as<JsonArray>()) {
auto modules = root["modules"].as<JsonArray>();
for (const JsonObject module : modules) {
auto key = module["key"].as<const char *>();
auto license = module["license"].as<const char *>();
auto enable = module["enabled"].as<bool>();

View File

@@ -71,7 +71,8 @@ StateUpdateResult WebScheduler::update(JsonObject root, WebScheduler & webSchedu
EMSESP::webSchedulerService.ha_reset();
// build up the list of schedule items
for (const JsonObject schedule : root["schedule"].as<JsonArray>()) {
auto scheduleItems = root["schedule"].as<JsonArray>();
for (const JsonObject schedule : scheduleItems) {
// create each schedule item, overwriting any previous settings
// ignore the id (as this is only used in the web for table rendering)
auto si = ScheduleItem();

View File

@@ -25,9 +25,10 @@ uint8_t WebSettings::flags_ = 0;
WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
: _httpEndpoint(WebSettings::read, WebSettings::update, this, server, EMSESP_SETTINGS_SERVICE_PATH, securityManager)
, _fsPersistence(WebSettings::read, WebSettings::update, this, fs, EMSESP_SETTINGS_FILE) {
server->on(EMSESP_BOARD_PROFILE_SERVICE_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { board_profile(request); }, AuthenticationPredicates::IS_AUTHENTICATED));
securityManager->addEndpoint(server, EMSESP_BOARD_PROFILE_SERVICE_PATH, AuthenticationPredicates::IS_AUTHENTICATED, [this](AsyncWebServerRequest * request) {
board_profile(request);
});
addUpdateHandler([this] { onUpdate(); }, false);
}

View File

@@ -19,7 +19,7 @@
#ifndef WebSettingsService_h
#define WebSettingsService_h
#include "../default_settings.h"
#include "../core/default_settings.h"
#define EMSESP_SETTINGS_FILE "/config/emsespSettings.json"

View File

@@ -27,10 +27,17 @@ namespace emsesp {
WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager)
: _securityManager(securityManager) {
// GET
server->on(EMSESP_SYSTEM_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { systemStatus(request); });
securityManager->addEndpoint(server, EMSESP_SYSTEM_STATUS_SERVICE_PATH, AuthenticationPredicates::IS_AUTHENTICATED, [this](AsyncWebServerRequest * request) {
systemStatus(request);
});
// POST - generic action handler
server->on(EMSESP_ACTION_SERVICE_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { action(request, json); });
// POST - generic action handler, handles both GET and POST
securityManager->addEndpoint(
server,
EMSESP_ACTION_SERVICE_PATH,
AuthenticationPredicates::IS_AUTHENTICATED,
[this](AsyncWebServerRequest * request, JsonVariant json) { action(request, json); },
HTTP_ANY);
}
// /rest/systemStatus
@@ -58,25 +65,23 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) {
root["mqtt_status"] = EMSESP::mqtt_.connected();
#ifndef EMSESP_STANDALONE
root["ntp_status"] = [] {
if (esp_sntp_enabled()) {
if (emsesp::EMSESP::system_.ntp_connected()) {
return 2;
} else {
return 1;
}
uint8_t ntp_status = 0; // 0=disabled, 1=enabled, 2=connected
if (esp_sntp_enabled()) {
ntp_status = (emsesp::EMSESP::system_.ntp_connected()) ? 2 : 1;
}
root["ntp_status"] = ntp_status;
if (ntp_status == 2) {
// send back actual time if NTP enabled and active
time_t now = time(nullptr);
if (now > 1500000000L) {
char t[25];
strftime(t, sizeof(t), "%FT%T", localtime(&now));
root["ntp_time"] = t; // optional string
}
return 0;
}();
time_t now = time(nullptr);
if (now > 1500000000L) {
char t[25];
strftime(t, sizeof(t), "%FT%T", localtime(&now));
root["ntp_time"] = t;
}
#endif
root["ap_status"] = EMSESP::esp8266React.apStatus();
root["ap_status"] = EMSESP::esp32React.apStatus();
if (emsesp::EMSESP::system_.ethernet_connected()) {
root["network_status"] = 10; // custom code #10 - ETHERNET_STATUS_CONNECTED
@@ -217,7 +222,7 @@ bool WebStatusService::checkUpgrade(JsonObject root, std::string & versions) {
#else
// for testing only - see api3 test in test.cpp
// current_version_s = "3.6.5";
current_version_s = "3.7.1-dev.8";
current_version_s = "3.7.2-dev.1";
#endif
if (!versions.empty()) {