mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
Merge remote-tracking branch 'origin/v3.4' into dev
This commit is contained in:
@@ -23,69 +23,131 @@ namespace emsesp {
|
||||
using namespace std::placeholders; // for `_1` etc
|
||||
|
||||
WebDataService::WebDataService(AsyncWebServer * server, SecurityManager * securityManager)
|
||||
: _device_dataHandler(DEVICE_DATA_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::device_data, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED))
|
||||
, _writevalue_dataHandler(WRITE_VALUE_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::write_value, this, _1, _2), AuthenticationPredicates::IS_ADMIN))
|
||||
, _writesensor_dataHandler(WRITE_SENSOR_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::write_sensor, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) {
|
||||
server->on(EMSESP_DATA_SERVICE_PATH,
|
||||
: _device_data_handler(DEVICE_DATA_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::device_data, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED))
|
||||
, _write_value_handler(WRITE_VALUE_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::write_value, this, _1, _2), AuthenticationPredicates::IS_ADMIN))
|
||||
, _write_sensor_handler(WRITE_SENSOR_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::write_sensor, this, _1, _2), AuthenticationPredicates::IS_ADMIN))
|
||||
, _write_analog_handler(WRITE_ANALOG_SERVICE_PATH,
|
||||
securityManager->wrapCallback(std::bind(&WebDataService::write_analog, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) {
|
||||
server->on(CORE_DATA_SERVICE_PATH,
|
||||
HTTP_GET,
|
||||
securityManager->wrapRequest(std::bind(&WebDataService::all_devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||
securityManager->wrapRequest(std::bind(&WebDataService::core_data, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||
|
||||
server->on(SENSOR_DATA_SERVICE_PATH,
|
||||
HTTP_GET,
|
||||
securityManager->wrapRequest(std::bind(&WebDataService::sensor_data, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||
|
||||
server->on(SCAN_DEVICES_SERVICE_PATH,
|
||||
HTTP_GET,
|
||||
securityManager->wrapRequest(std::bind(&WebDataService::scan_devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||
HTTP_POST,
|
||||
securityManager->wrapRequest(std::bind(&WebDataService::scan_devices, this, _1), AuthenticationPredicates::IS_ADMIN));
|
||||
|
||||
_device_dataHandler.setMethod(HTTP_POST);
|
||||
_device_dataHandler.setMaxContentLength(256);
|
||||
server->addHandler(&_device_dataHandler);
|
||||
_device_data_handler.setMethod(HTTP_POST);
|
||||
_device_data_handler.setMaxContentLength(256);
|
||||
server->addHandler(&_device_data_handler);
|
||||
|
||||
_writevalue_dataHandler.setMethod(HTTP_POST);
|
||||
_writevalue_dataHandler.setMaxContentLength(256);
|
||||
server->addHandler(&_writevalue_dataHandler);
|
||||
_write_value_handler.setMethod(HTTP_POST);
|
||||
_write_value_handler.setMaxContentLength(256);
|
||||
server->addHandler(&_write_value_handler);
|
||||
|
||||
_writesensor_dataHandler.setMethod(HTTP_POST);
|
||||
_writesensor_dataHandler.setMaxContentLength(256);
|
||||
server->addHandler(&_writesensor_dataHandler);
|
||||
_write_sensor_handler.setMethod(HTTP_POST);
|
||||
_write_sensor_handler.setMaxContentLength(256);
|
||||
server->addHandler(&_write_sensor_handler);
|
||||
|
||||
_write_analog_handler.setMethod(HTTP_POST);
|
||||
_write_analog_handler.setMaxContentLength(256);
|
||||
server->addHandler(&_write_analog_handler);
|
||||
}
|
||||
|
||||
// scan devices service
|
||||
void WebDataService::scan_devices(AsyncWebServerRequest * request) {
|
||||
EMSESP::logger().info(F("Scanning devices..."));
|
||||
EMSESP::scan_devices();
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void WebDataService::all_devices(AsyncWebServerRequest * request) {
|
||||
// this is used in the dashboard and contains all ems device information
|
||||
// /coreData endpoint
|
||||
void WebDataService::core_data(AsyncWebServerRequest * request) {
|
||||
AsyncJsonResponse * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_XLARGE_DYN);
|
||||
JsonObject root = response->getRoot();
|
||||
|
||||
// list is already sorted by device type
|
||||
// Ignore Contoller
|
||||
JsonArray devices = root.createNestedArray("devices");
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
if (emsdevice) {
|
||||
for (auto & emsdevice : EMSESP::emsdevices) {
|
||||
if (emsdevice && emsdevice->device_type() != EMSdevice::DeviceType::CONTROLLER) {
|
||||
JsonObject obj = devices.createNestedObject();
|
||||
obj["i"] = emsdevice->unique_id(); // id
|
||||
obj["i"] = emsdevice->unique_id(); // a unique id
|
||||
obj["t"] = emsdevice->device_type_name(); // type
|
||||
obj["b"] = emsdevice->brand_to_string(); // brand
|
||||
obj["n"] = emsdevice->name(); // name
|
||||
obj["d"] = emsdevice->device_id(); // deviceid
|
||||
obj["p"] = emsdevice->product_id(); // productid
|
||||
obj["v"] = emsdevice->version(); // version
|
||||
obj["e"] = emsdevice->count_entities(); // number of entities (device values)
|
||||
}
|
||||
}
|
||||
|
||||
// sensors stuff
|
||||
root["active_sensors"] = EMSESP::dallassensor_.no_sensors() + (EMSESP::analogsensor_.analog_enabled() ? EMSESP::analogsensor_.no_sensors() : 0);
|
||||
root["analog_enabled"] = EMSESP::analogsensor_.analog_enabled();
|
||||
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
// sensor data - sends back to web
|
||||
// /sensorData endpoint
|
||||
// the "sensors" and "analogs" are arrays and must exist
|
||||
void WebDataService::sensor_data(AsyncWebServerRequest * request) {
|
||||
AsyncJsonResponse * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_XLARGE_DYN);
|
||||
JsonObject root = response->getRoot();
|
||||
|
||||
// dallas sensors
|
||||
JsonArray sensors = root.createNestedArray("sensors");
|
||||
if (EMSESP::have_sensors()) {
|
||||
uint8_t i = 1;
|
||||
for (const auto & sensor : EMSESP::sensor_devices()) {
|
||||
if (EMSESP::dallassensor_.have_sensors()) {
|
||||
for (const auto & sensor : EMSESP::dallassensor_.sensors()) {
|
||||
JsonObject obj = sensors.createNestedObject();
|
||||
obj["n"] = i++; // no
|
||||
obj["i"] = sensor.to_string(true); // id
|
||||
obj["t"] = (float)(sensor.temperature_c) / 10; // temp
|
||||
obj["o"] = (float)(sensor.offset()) / 10; // offset
|
||||
obj["is"] = sensor.id_str(); // id
|
||||
obj["n"] = sensor.name(); // name
|
||||
if (EMSESP::system_.fahrenheit()) {
|
||||
if (Helpers::hasValue(sensor.temperature_c)) {
|
||||
obj["t"] = (float)sensor.temperature_c * 0.18 + 32;
|
||||
}
|
||||
obj["u"] = DeviceValueUOM::FAHRENHEIT;
|
||||
obj["o"] = (float)sensor.offset() * 0.18;
|
||||
} else {
|
||||
if (Helpers::hasValue(sensor.temperature_c)) {
|
||||
obj["t"] = (float)sensor.temperature_c / 10;
|
||||
}
|
||||
obj["u"] = DeviceValueUOM::DEGREES;
|
||||
obj["o"] = (float)(sensor.offset()) / 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EMSESP::system_.analog_enabled()) {
|
||||
root["analog"] = EMSESP::system_.analog();
|
||||
// analog sensors
|
||||
// assume list is already sorted by id
|
||||
JsonArray analogs = root.createNestedArray("analogs");
|
||||
if (EMSESP::analog_enabled() && EMSESP::analogsensor_.have_sensors()) {
|
||||
for (const auto & sensor : EMSESP::analogsensor_.sensors()) {
|
||||
// don't send if it's marked for removal
|
||||
if (sensor.type() != AnalogSensor::AnalogType::MARK_DELETED) {
|
||||
JsonObject obj = analogs.createNestedObject();
|
||||
obj["i"] = sensor.id();
|
||||
obj["n"] = sensor.name();
|
||||
obj["u"] = sensor.uom();
|
||||
obj["o"] = sensor.offset();
|
||||
obj["f"] = sensor.factor();
|
||||
obj["t"] = sensor.type();
|
||||
|
||||
if (sensor.type() != AnalogSensor::AnalogType::NOTUSED) {
|
||||
obj["v"] = Helpers::round2(sensor.value(), 1); // is optional and is a float
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response->setLength();
|
||||
@@ -96,7 +158,7 @@ void WebDataService::all_devices(AsyncWebServerRequest * request) {
|
||||
// Compresses the JSON using MsgPack https://msgpack.org/index.html
|
||||
void WebDataService::device_data(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
if (json.is<JsonObject>()) {
|
||||
MsgpackAsyncJsonResponse * response = new MsgpackAsyncJsonResponse(false, EMSESP_JSON_SIZE_XXLARGE_DYN);
|
||||
MsgpackAsyncJsonResponse * response = new MsgpackAsyncJsonResponse(false, EMSESP_JSON_SIZE_XXXLARGE_DYN);
|
||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||
if (emsdevice) {
|
||||
if (emsdevice->unique_id() == json["id"]) {
|
||||
@@ -106,8 +168,8 @@ void WebDataService::device_data(AsyncWebServerRequest * request, JsonVariant &
|
||||
}
|
||||
EMSESP::wait_validate(0); // reset in case of timeout
|
||||
#ifndef EMSESP_STANDALONE
|
||||
JsonObject root = response->getRoot();
|
||||
emsdevice->generate_values_json_web(root);
|
||||
JsonObject output = response->getRoot();
|
||||
emsdevice->generate_values_web(output);
|
||||
#endif
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
@@ -117,12 +179,13 @@ void WebDataService::device_data(AsyncWebServerRequest * request, JsonVariant &
|
||||
}
|
||||
}
|
||||
|
||||
// invalid
|
||||
// invalid but send ok
|
||||
AsyncWebServerResponse * response = request->beginResponse(200);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
// takes a command and its data value from a specific Device, from the Web
|
||||
|
||||
// takes a command and its data value from a specific EMS Device, from the Web
|
||||
// assumes the service has been checked for admin authentication
|
||||
void WebDataService::write_value(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
if (json.is<JsonObject>()) {
|
||||
@@ -180,23 +243,42 @@ void WebDataService::write_value(AsyncWebServerRequest * request, JsonVariant &
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
// takes a sensorname and optional offset from the Web
|
||||
// takes a dallas sensor name and optional offset from the WebUI and update the customization settings
|
||||
// via the Dallas service
|
||||
void WebDataService::write_sensor(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
bool ok = false;
|
||||
if (json.is<JsonObject>()) {
|
||||
JsonObject sensor = json["sensor"];
|
||||
JsonObject sensor = json;
|
||||
|
||||
// if valid add.
|
||||
uint8_t no = sensor["no"];
|
||||
if (no > 0 && no < 100) {
|
||||
char name[20];
|
||||
std::string id = sensor["id"];
|
||||
strlcpy(name, id.c_str(), sizeof(name));
|
||||
float offset = sensor["offset"]; // this will be a float value. We'll convert it to int and * 10 it
|
||||
int16_t offset10 = offset * 10;
|
||||
char idstr[3];
|
||||
ok = EMSESP::dallassensor_.update(Helpers::itoa(idstr, no, 10), name, offset10);
|
||||
std::string id_str = sensor["id_str"]; // this is the key
|
||||
std::string name = sensor["name"];
|
||||
|
||||
// calculate offset. We'll convert it to an int and * 10
|
||||
float offset = sensor["offset"];
|
||||
int16_t offset10 = offset * 10;
|
||||
if (EMSESP::system_.fahrenheit()) {
|
||||
offset10 = offset / 0.18;
|
||||
}
|
||||
ok = EMSESP::dallassensor_.update(id_str, name, offset10);
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * response = request->beginResponse(ok ? 200 : 204);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
// update the analog record, or create a new one
|
||||
void WebDataService::write_analog(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||
bool ok = false;
|
||||
if (json.is<JsonObject>()) {
|
||||
JsonObject analog = json;
|
||||
|
||||
uint8_t id = analog["id"]; // this is the unique key
|
||||
std::string name = analog["name"];
|
||||
float factor = analog["factor"];
|
||||
int16_t offset = analog["offset"];
|
||||
uint8_t uom = analog["uom"];
|
||||
int8_t type = analog["type"];
|
||||
ok = EMSESP::analogsensor_.update(id, name, offset, factor, uom, type);
|
||||
}
|
||||
|
||||
AsyncWebServerResponse * response = request->beginResponse(ok ? 200 : 204);
|
||||
|
||||
Reference in New Issue
Block a user