mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
@@ -64,7 +64,7 @@ const CustomEntitiesDialog = ({
|
|||||||
}
|
}
|
||||||
}, [open, selectedItem]);
|
}, [open, selectedItem]);
|
||||||
|
|
||||||
const handleClose = (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => {
|
const handleClose = (event: object, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||||
if (reason !== 'backdropClick') {
|
if (reason !== 'backdropClick') {
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const CustomizationDialog = ({
|
|||||||
}
|
}
|
||||||
}, [open, selectedItem]);
|
}, [open, selectedItem]);
|
||||||
|
|
||||||
const handleClose = (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => {
|
const handleClose = (event: object, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||||
if (reason !== 'backdropClick') {
|
if (reason !== 'backdropClick') {
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ const SchedulerDialog = ({
|
|||||||
</Typography>
|
</Typography>
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleClose = (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => {
|
const handleClose = (event: object, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||||
if (reason !== 'backdropClick') {
|
if (reason !== 'backdropClick') {
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const SensorsAnalogDialog = ({
|
|||||||
}
|
}
|
||||||
}, [open, selectedItem]);
|
}, [open, selectedItem]);
|
||||||
|
|
||||||
const handleClose = (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => {
|
const handleClose = (event: object, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||||
if (reason !== 'backdropClick') {
|
if (reason !== 'backdropClick') {
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ const SensorsTemperatureDialog = ({
|
|||||||
}
|
}
|
||||||
}, [open, selectedItem]);
|
}, [open, selectedItem]);
|
||||||
|
|
||||||
const handleClose = (event: {}, reason: 'backdropClick' | 'escapeKeyDown') => {
|
const handleClose = (event: object, reason: 'backdropClick' | 'escapeKeyDown') => {
|
||||||
if (reason !== 'backdropClick') {
|
if (reason !== 'backdropClick') {
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec
|
|||||||
p.parse(path);
|
p.parse(path);
|
||||||
|
|
||||||
if (!p.paths().size()) {
|
if (!p.paths().size()) {
|
||||||
return message(CommandRet::ERROR, "invalid path", output);
|
return json_message(CommandRet::ERROR, "invalid path", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check first if it's from API, if so strip the "api/"
|
// check first if it's from API, if so strip the "api/"
|
||||||
@@ -48,7 +48,7 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec
|
|||||||
strlcpy(new_path, path, sizeof(new_path));
|
strlcpy(new_path, path, sizeof(new_path));
|
||||||
p.parse(new_path + Mqtt::base().length() + 1); // re-parse the stripped path
|
p.parse(new_path + Mqtt::base().length() + 1); // re-parse the stripped path
|
||||||
} else {
|
} else {
|
||||||
return message(CommandRet::ERROR, "unrecognized path", output); // error
|
return json_message(CommandRet::ERROR, "unrecognized path", output); // error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec
|
|||||||
// if there is only a path (URL) and no body then error!
|
// if there is only a path (URL) and no body then error!
|
||||||
size_t num_paths = p.paths().size();
|
size_t num_paths = p.paths().size();
|
||||||
if (!num_paths && !input.size()) {
|
if (!num_paths && !input.size()) {
|
||||||
return message(CommandRet::ERROR, "missing command in path", output);
|
return json_message(CommandRet::ERROR, "missing command in path", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string cmd_s;
|
std::string cmd_s;
|
||||||
@@ -78,8 +78,11 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec
|
|||||||
// validate the device, make sure it exists
|
// validate the device, make sure it exists
|
||||||
uint8_t device_type = EMSdevice::device_name_2_device_type(device_s);
|
uint8_t device_type = EMSdevice::device_name_2_device_type(device_s);
|
||||||
if (!device_has_commands(device_type)) {
|
if (!device_has_commands(device_type)) {
|
||||||
LOG_DEBUG("Command failed: unknown device '%s'", device_s);
|
char err[100];
|
||||||
return message(CommandRet::NOT_FOUND, "unknown device", output);
|
snprintf(err, sizeof(err), "unknown device %s", device_s);
|
||||||
|
LOG_WARNING("Command failed: %s", err);
|
||||||
|
output["message"] = err;
|
||||||
|
return CommandRet::NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the next value on the path should be the command or entity name
|
// the next value on the path should be the command or entity name
|
||||||
@@ -114,7 +117,7 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec
|
|||||||
if (num_paths < (id_n > 0 ? 4 : 3)) {
|
if (num_paths < (id_n > 0 ? 4 : 3)) {
|
||||||
command_p = device_type == EMSdevice::DeviceType::SYSTEM ? F_(info) : F_(values);
|
command_p = device_type == EMSdevice::DeviceType::SYSTEM ? F_(info) : F_(values);
|
||||||
} else {
|
} else {
|
||||||
return message(CommandRet::NOT_FOUND, "missing or bad command", output);
|
return json_message(CommandRet::NOT_FOUND, "missing or bad command", output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +202,7 @@ uint8_t Command::process(const char * path, const bool is_admin, const JsonObjec
|
|||||||
} else if (data.isNull()) {
|
} else if (data.isNull()) {
|
||||||
return_code = Command::call(device_type, command_p, "", is_admin, id_n, output); // empty, will do a query instead
|
return_code = Command::call(device_type, command_p, "", is_admin, id_n, output); // empty, will do a query instead
|
||||||
} else {
|
} else {
|
||||||
return message(CommandRet::ERROR, "cannot parse command", output); // can't process
|
return json_message(CommandRet::ERROR, "cannot parse command", output); // can't process
|
||||||
}
|
}
|
||||||
return return_code;
|
return return_code;
|
||||||
}
|
}
|
||||||
@@ -334,10 +337,12 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
|||||||
// first see if there is a command registered and it's valid
|
// first see if there is a command registered and it's valid
|
||||||
auto cf = find_command(device_type, device_id, cmd, flag);
|
auto cf = find_command(device_type, device_id, cmd, flag);
|
||||||
if (!cf) {
|
if (!cf) {
|
||||||
LOG_WARNING("Command failed: unknown command '%s'", cmd ? cmd : "");
|
std::string err = std::string("unknown command ") + cmd;
|
||||||
|
LOG_WARNING("Command failed: %s", err.c_str());
|
||||||
|
|
||||||
// if we don't alread have a message set, set it to invalid command
|
// if we don't alread have a message set, set it to invalid command
|
||||||
if (!output["message"]) {
|
if (!output["message"]) {
|
||||||
output["message"] = "unknown command";
|
output["message"] = err;
|
||||||
}
|
}
|
||||||
return CommandRet::ERROR;
|
return CommandRet::ERROR;
|
||||||
}
|
}
|
||||||
@@ -355,9 +360,9 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
|||||||
auto description = Helpers::translated_word(cf->description_);
|
auto description = Helpers::translated_word(cf->description_);
|
||||||
char info_s[100];
|
char info_s[100];
|
||||||
if (strlen(description)) {
|
if (strlen(description)) {
|
||||||
snprintf(info_s, sizeof(info_s), "'%s/%s' (%s)", dname, cmd, description);
|
snprintf(info_s, sizeof(info_s), "%s/%s (%s)", dname, cmd, description);
|
||||||
} else {
|
} else {
|
||||||
snprintf(info_s, sizeof(info_s), "'%s/%s'", dname, cmd);
|
snprintf(info_s, sizeof(info_s), "%s/%s", dname, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// call the function based on command function type
|
// call the function based on command function type
|
||||||
@@ -380,9 +385,9 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
|||||||
if (return_code != CommandRet::OK) {
|
if (return_code != CommandRet::OK) {
|
||||||
char error[100];
|
char error[100];
|
||||||
if (single_command) {
|
if (single_command) {
|
||||||
snprintf(error, sizeof(error), "Command '%s' failed (%s)", cmd, return_code_string(return_code));
|
snprintf(error, sizeof(error), "Command %s failed (%s)", cmd, return_code_string(return_code));
|
||||||
} else {
|
} else {
|
||||||
snprintf(error, sizeof(error), "Command '%s: %s' failed (%s)", cmd, value, return_code_string(return_code));
|
snprintf(error, sizeof(error), "Command %s: %s failed (%s)", cmd, value, return_code_string(return_code));
|
||||||
}
|
}
|
||||||
output.clear();
|
output.clear();
|
||||||
output["message"] = error;
|
output["message"] = error;
|
||||||
@@ -683,6 +688,16 @@ void Command::show_all(uuid::console::Shell & shell) {
|
|||||||
shell.println();
|
shell.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t Command::json_message(uint8_t error_code, const char * message, const JsonObject output) {
|
||||||
|
output.clear();
|
||||||
|
output["message"] = message;
|
||||||
|
return error_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// SUrlParser class
|
||||||
|
//
|
||||||
|
|
||||||
// Extract only the path component from the passed URI and normalized it
|
// Extract only the path component from the passed URI and normalized it
|
||||||
// e.g. //one/two////three/// becomes /one/two/three
|
// e.g. //one/two////three/// becomes /one/two/three
|
||||||
std::string SUrlParser::path() {
|
std::string SUrlParser::path() {
|
||||||
|
|||||||
@@ -143,11 +143,7 @@ class Command {
|
|||||||
|
|
||||||
static std::vector<CmdFunction> cmdfunctions_; // the list of commands
|
static std::vector<CmdFunction> cmdfunctions_; // the list of commands
|
||||||
|
|
||||||
inline static uint8_t message(uint8_t error_code, const char * message, const JsonObject output) {
|
static uint8_t json_message(uint8_t error_code, const char * message, const JsonObject output);
|
||||||
output.clear();
|
|
||||||
output["message"] = message;
|
|
||||||
return error_code;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SUrlParser {
|
class SUrlParser {
|
||||||
|
|||||||
@@ -1599,7 +1599,7 @@ bool EMSdevice::get_value_info(JsonObject output, const char * cmd, const int8_t
|
|||||||
// if we're filtering on an attribute, go find it
|
// if we're filtering on an attribute, go find it
|
||||||
if (attribute_s) {
|
if (attribute_s) {
|
||||||
#if defined(EMSESP_DEBUG)
|
#if defined(EMSESP_DEBUG)
|
||||||
EMSESP::logger().debug("[DEBUG] fetching single attribute '%s'", attribute_s);
|
EMSESP::logger().debug("[DEBUG] fetching single attribute %s", attribute_s);
|
||||||
#endif
|
#endif
|
||||||
if (json.containsKey(attribute_s)) {
|
if (json.containsKey(attribute_s)) {
|
||||||
std::string data = json[attribute_s].as<std::string>();
|
std::string data = json[attribute_s].as<std::string>();
|
||||||
|
|||||||
@@ -743,7 +743,7 @@ void EMSESP::publish_response(std::shared_ptr<const Telegram> telegram) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// builds json with the detail of each value, for a given EMS device
|
// builds json with the detail of each value, for a given EMS device
|
||||||
// for other types like sensors, scheduler, custom entities it will process single commands like 'info', 'values', 'commands'...
|
// for other types like sensors, scheduler, custom entities it will process single commands like 'info', 'values', 'commands', 'entities'...
|
||||||
bool EMSESP::get_device_value_info(JsonObject root, const char * cmd, const int8_t id, const uint8_t devicetype) {
|
bool EMSESP::get_device_value_info(JsonObject root, const char * cmd, const int8_t id, const uint8_t devicetype) {
|
||||||
// check first for EMS devices
|
// check first for EMS devices
|
||||||
bool found_device = false;
|
bool found_device = false;
|
||||||
@@ -755,9 +755,8 @@ bool EMSESP::get_device_value_info(JsonObject root, const char * cmd, const int8
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if the EMS device was valid, but the cmd not found show an error
|
// if the EMS device was valid, but the cmd not found exit. it will be handled upstream.
|
||||||
if (found_device) {
|
if (found_device) {
|
||||||
root["message"] = std::string("unknown command ") + cmd;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1712,14 +1711,14 @@ void EMSESP::loop() {
|
|||||||
// if we're doing an OTA upload, skip everything except from console refresh
|
// if we're doing an OTA upload, skip everything except from console refresh
|
||||||
if (!system_.upload_status()) {
|
if (!system_.upload_status()) {
|
||||||
// service loops
|
// service loops
|
||||||
webLogService.loop(); // log in Web UI
|
webLogService.loop(); // log in Web UI
|
||||||
rxservice_.loop(); // process any incoming Rx telegrams
|
rxservice_.loop(); // process any incoming Rx telegrams
|
||||||
shower_.loop(); // check for shower on/off
|
shower_.loop(); // check for shower on/off
|
||||||
temperaturesensor_.loop(); // read sensor temperatures
|
temperaturesensor_.loop(); // read sensor temperatures
|
||||||
analogsensor_.loop(); // read analog sensor values
|
analogsensor_.loop(); // read analog sensor values
|
||||||
publish_all_loop(); // with HA messages in parts to avoid flooding the mqtt queue
|
publish_all_loop(); // with HA messages in parts to avoid flooding the mqtt queue
|
||||||
mqtt_.loop(); // sends out anything in the MQTT queue
|
mqtt_.loop(); // sends out anything in the MQTT queue
|
||||||
webModulesService.loop(); // loop through the external library modules
|
webModulesService.loop(); // loop through the external library modules
|
||||||
|
|
||||||
// force a query on the EMS devices to fetch latest data at a set interval (1 min)
|
// force a query on the EMS devices to fetch latest data at a set interval (1 min)
|
||||||
scheduled_fetch_values();
|
scheduled_fetch_values();
|
||||||
|
|||||||
@@ -1053,20 +1053,17 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
// This next batch should all fail
|
// This next batch should all fail
|
||||||
//
|
//
|
||||||
|
|
||||||
Serial.printf("%s**** Testing bad urls ****\n%s", COLOR_RED, COLOR_RESET);
|
|
||||||
Serial.println();
|
Serial.println();
|
||||||
|
Serial.printf("%s**** Testing bad urls ****\n%s", COLOR_RED, COLOR_RESET);
|
||||||
|
|
||||||
|
request.url("/api/boiler2");
|
||||||
|
EMSESP::webAPIService.webAPIService(&request);
|
||||||
|
|
||||||
// boiler
|
// boiler
|
||||||
request.url("/api/boiler/bad");
|
request.url("/api/boiler/bad");
|
||||||
EMSESP::webAPIService.webAPIService(&request);
|
EMSESP::webAPIService.webAPIService(&request);
|
||||||
request.url("/api/boiler/bad/value");
|
request.url("/api/boiler/bad/value");
|
||||||
EMSESP::webAPIService.webAPIService(&request);
|
EMSESP::webAPIService.webAPIService(&request);
|
||||||
request.url("/api/boiler2/bad");
|
|
||||||
EMSESP::webAPIService.webAPIService(&request);
|
|
||||||
request.url("/api/boiler/bad");
|
|
||||||
EMSESP::webAPIService.webAPIService(&request);
|
|
||||||
request.url("/api/boiler/bad/value");
|
|
||||||
EMSESP::webAPIService.webAPIService(&request);
|
|
||||||
request.url("/api/boiler/comfort/valu");
|
request.url("/api/boiler/comfort/valu");
|
||||||
EMSESP::webAPIService.webAPIService(&request);
|
EMSESP::webAPIService.webAPIService(&request);
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace emsesp {
|
|||||||
// #define EMSESP_DEBUG_DEFAULT "310"
|
// #define EMSESP_DEBUG_DEFAULT "310"
|
||||||
// #define EMSESP_DEBUG_DEFAULT "render"
|
// #define EMSESP_DEBUG_DEFAULT "render"
|
||||||
// #define EMSESP_DEBUG_DEFAULT "api"
|
// #define EMSESP_DEBUG_DEFAULT "api"
|
||||||
// #define EMSESP_DEBUG_DEFAULT "api3"
|
#define EMSESP_DEBUG_DEFAULT "api3"
|
||||||
// #define EMSESP_DEBUG_DEFAULT "crash"
|
// #define EMSESP_DEBUG_DEFAULT "crash"
|
||||||
// #define EMSESP_DEBUG_DEFAULT "dv"
|
// #define EMSESP_DEBUG_DEFAULT "dv"
|
||||||
// #define EMSESP_DEBUG_DEFAULT "lastcode"
|
// #define EMSESP_DEBUG_DEFAULT "lastcode"
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ void WebSchedulerService::begin() {
|
|||||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||||
snprintf(topic, sizeof(topic), "%s/#", F_(scheduler));
|
snprintf(topic, sizeof(topic), "%s/#", F_(scheduler));
|
||||||
Mqtt::subscribe(EMSdevice::DeviceType::SCHEDULER, topic, nullptr); // use empty function callback
|
Mqtt::subscribe(EMSdevice::DeviceType::SCHEDULER, topic, nullptr); // use empty function callback
|
||||||
|
#ifndef EMSESP_STANDALONE
|
||||||
xTaskCreate((TaskFunction_t)scheduler_task, "scheduler_task", 4096, NULL, 3, NULL);
|
xTaskCreate((TaskFunction_t)scheduler_task, "scheduler_task", 4096, NULL, 3, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// this creates the scheduler file, saving it to the FS
|
// this creates the scheduler file, saving it to the FS
|
||||||
@@ -529,7 +531,9 @@ void WebSchedulerService::scheduler_task(void * pvParameters) {
|
|||||||
EMSESP::webSchedulerService.loop();
|
EMSESP::webSchedulerService.loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef EMSESP_STANDALONE
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// hard coded tests
|
// hard coded tests
|
||||||
@@ -600,7 +604,7 @@ void WebSchedulerService::test() {
|
|||||||
test_value = "(custom/seltemp - boiler/flowtempoffset) * 2.8 + 5";
|
test_value = "(custom/seltemp - boiler/flowtempoffset) * 2.8 + 5";
|
||||||
command("test10", test_cmd.c_str(), compute(test_value).c_str());
|
command("test10", test_cmd.c_str(), compute(test_value).c_str());
|
||||||
|
|
||||||
// TODO add some HTTP/URI tests
|
// TODO add some more HTTP/URI tests
|
||||||
test_cmd = "{\"method\":\"POST\",\"url\":\"http://192.168.1.42:8123/api/services/script/test_notify2\", \"header\":{\"authorization\":\"Bearer "
|
test_cmd = "{\"method\":\"POST\",\"url\":\"http://192.168.1.42:8123/api/services/script/test_notify2\", \"header\":{\"authorization\":\"Bearer "
|
||||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMmNlYWI5NDgzMmI0ODE2YWQ2NzU4MjkzZDE2YWMxZSIsImlhdCI6MTcyMTM5MTI0NCwiZXhwIjoyMDM2NzUxMjQ0fQ."
|
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhMmNlYWI5NDgzMmI0ODE2YWQ2NzU4MjkzZDE2YWMxZSIsImlhdCI6MTcyMTM5MTI0NCwiZXhwIjoyMDM2NzUxMjQ0fQ."
|
||||||
"S5sago1tEI6lNhrDCO0dM_WsVQHkD_laAjcks8tWAqo\"}}";
|
"S5sago1tEI6lNhrDCO0dM_WsVQHkD_laAjcks8tWAqo\"}}";
|
||||||
|
|||||||
Reference in New Issue
Block a user