From 6c41c49866d7e9a4bedfa560ac6904adeacd2a5f Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 6 Apr 2021 11:21:01 +0200 Subject: [PATCH 001/114] remove asyncjson.h --- lib/framework/APStatus.h | 1 - lib/framework/AuthenticationService.h | 1 - lib/framework/FactoryResetService.h | 1 - lib/framework/FeaturesService.h | 3 +-- lib/framework/HttpEndpoint.h | 1 - lib/framework/MqttStatus.h | 2 -- lib/framework/NTPStatus.h | 3 --- lib/framework/NetworkStatus.h | 1 - lib/framework/SecurityManager.h | 2 +- lib/framework/SystemStatus.h | 1 - lib/framework/UploadFirmwareService.h | 1 - lib/framework/WiFiScanner.h | 1 - 12 files changed, 2 insertions(+), 16 deletions(-) diff --git a/lib/framework/APStatus.h b/lib/framework/APStatus.h index defe5f530..e5d78ac8b 100644 --- a/lib/framework/APStatus.h +++ b/lib/framework/APStatus.h @@ -5,7 +5,6 @@ #include #include -#include #include #include #include diff --git a/lib/framework/AuthenticationService.h b/lib/framework/AuthenticationService.h index 520170063..904410676 100644 --- a/lib/framework/AuthenticationService.h +++ b/lib/framework/AuthenticationService.h @@ -2,7 +2,6 @@ #define AuthenticationService_H_ #include -#include #include #include diff --git a/lib/framework/FactoryResetService.h b/lib/framework/FactoryResetService.h index b30ca1c6c..31cf06152 100644 --- a/lib/framework/FactoryResetService.h +++ b/lib/framework/FactoryResetService.h @@ -2,7 +2,6 @@ #define FactoryResetService_h #include -#include #include #include #include diff --git a/lib/framework/FeaturesService.h b/lib/framework/FeaturesService.h index 9c446fd47..1c632a4a7 100644 --- a/lib/framework/FeaturesService.h +++ b/lib/framework/FeaturesService.h @@ -4,9 +4,8 @@ #include #include -#include #include -#include +#include // TODO needed for AsyncJsonResponse #include #define MAX_FEATURES_SIZE 256 diff --git a/lib/framework/HttpEndpoint.h b/lib/framework/HttpEndpoint.h index 3951c459f..ed1e1169b 100644 --- a/lib/framework/HttpEndpoint.h +++ b/lib/framework/HttpEndpoint.h @@ -3,7 +3,6 @@ #include -#include #include #include diff --git a/lib/framework/MqttStatus.h b/lib/framework/MqttStatus.h index 04ef6f1d3..88df0aaee 100644 --- a/lib/framework/MqttStatus.h +++ b/lib/framework/MqttStatus.h @@ -2,10 +2,8 @@ #define MqttStatus_h #include -#include #include #include -#include #include #include diff --git a/lib/framework/NTPStatus.h b/lib/framework/NTPStatus.h index 757d5a239..b3a84a3da 100644 --- a/lib/framework/NTPStatus.h +++ b/lib/framework/NTPStatus.h @@ -4,16 +4,13 @@ #include #include -#include #include #include -#include #include #include #include - #define MAX_NTP_STATUS_SIZE 1024 #define NTP_STATUS_SERVICE_PATH "/rest/ntpStatus" diff --git a/lib/framework/NetworkStatus.h b/lib/framework/NetworkStatus.h index dd7d5402c..1e73439e9 100644 --- a/lib/framework/NetworkStatus.h +++ b/lib/framework/NetworkStatus.h @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/lib/framework/SecurityManager.h b/lib/framework/SecurityManager.h index 82eb516b1..89c93e737 100644 --- a/lib/framework/SecurityManager.h +++ b/lib/framework/SecurityManager.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include // TODO neede for AsyncJsonResponse #include #ifndef FACTORY_JWT_SECRET diff --git a/lib/framework/SystemStatus.h b/lib/framework/SystemStatus.h index bd911befb..5ac388590 100644 --- a/lib/framework/SystemStatus.h +++ b/lib/framework/SystemStatus.h @@ -7,7 +7,6 @@ #include #include -#include #include #include diff --git a/lib/framework/UploadFirmwareService.h b/lib/framework/UploadFirmwareService.h index 1753f37d3..f953f5a2d 100644 --- a/lib/framework/UploadFirmwareService.h +++ b/lib/framework/UploadFirmwareService.h @@ -5,7 +5,6 @@ #include #include -#include #include #include diff --git a/lib/framework/WiFiScanner.h b/lib/framework/WiFiScanner.h index 99098e6ea..ee496c1a2 100644 --- a/lib/framework/WiFiScanner.h +++ b/lib/framework/WiFiScanner.h @@ -5,7 +5,6 @@ #include #include -#include #include #include From c43fe4f9ae0bdef4464851b51a8943b663ea823e Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 1 May 2021 13:19:57 +0200 Subject: [PATCH 002/114] add doc on API spec --- doc/EMS-ESP32 API.md | 106 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 doc/EMS-ESP32 API.md diff --git a/doc/EMS-ESP32 API.md b/doc/EMS-ESP32 API.md new file mode 100644 index 000000000..90d51b0f2 --- /dev/null +++ b/doc/EMS-ESP32 API.md @@ -0,0 +1,106 @@ +# EMS-ESP REST API + +OpenAPI is an open standard specification for describing REST APIs. From the [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification): + +> The OpenAPI Specification (OAS) defines a standard, programming language-agnostic interface description for HTTP APIs, which allows both humans and computers to discover and understand the capabilities of a service without requiring access to source code, additional documentation, or inspection of network traffic. When properly defined via OpenAPI, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interface descriptions have done for lower-level programming, the OpenAPI Specification removes guesswork in calling a service. + +## Specification + +- All data is sent and received as JSON. +- The URL is `http:///api` with the default `` being `ems-esp`. Note that it may also be ems-esp.local on some environments depending on your domain and dns setup. +- Only HTTP for now. HTTPS will be supported soon, with self-signed certificates or user's own. +- The EMS-ESP REST API will eventually be fully described in an OpenAPI 3.0 compliant document, available via [postman](https://www.postman.com/collections/479af3935991ac030130). +- Read instructions to fetch data use HTTP `GET` and operations that change data use HTTP `POST`, `PUT` or `PATCH`. +- To keep backwards compatibility with earlier versions, parameters can also be provided as HTML query parameters (name-value pairs) as opposed to URI path parameters. For example `POST http://ems-esp/api/boiler/wwtemp` with a JSON body of `{value: 50}` is the same as the URL `http://ems-esp/api?device=boiler?cmd=wwtemp?data=50`. +- Unless explicitly bypassed in the WebUI some operations required admin privileges in the form of an Access Token which can be generated from the Web UI's Security tab. An Access Token is a string 152 characters long. Token's do not expire. The token needs to be either embedded into the HTTP Header as `"Authorization: Bearer {ACCESS_TOKEN}"` or as query parameter `?access_token={ACCESS_TOKEN}`. To test you can use a command line instruction like + + ```bash + curl -i -H "Authorization: Bearer {ACCESS_TOKEN}" -X POST http://ems-esp/api/system/settings + curl -i -H "Authorization: Bearer {ACCESS_TOKEN}" -d '{ "name": "wwtemp", "value":60}' http://ems-esp/api/boiler + ``` + +## Error handling + +- Requests that require authentication will return `403 Forbidden` +- Authenticating with invalid credentials will return `401 Unauthorized` + + ```html + HTTP/1.1 401 Unauthorized + {"message": "Bad credentials"} + ``` + +- Sending invalid JSON will result in a `400 Bad Request` response. + + ```html + HTTP/1.1 400 Bad Request + {"message":"Problems parsing JSON"} + ``` + +- Sending the wrong type of JSON values will result in a `400 Bad Request` response. + + ```html + HTTP/1.1 400 Bad Request + {"message":"Body should be a JSON object"} + ``` + +- Sending invalid fields will result in a `422 Unprocessable Entity` response. `code` can be missing, missing_field, invalid or unprocessable. For example when selecting an invalid heating circuit number. + + ```html + HTTP/1.1 422 Unprocessable Entity + { + "message": "Validation Failed", + "errors": [ + { + "field": "title", + "code": "missing_field" + } + ] + } + ``` + +## Endpoints + +### types + +- `` is a character string +- `` is a positive integer value +- `` is an integer or floating point number +- `` is either 1, 0, "1", "0", "on", "off", "true" or "false" + +### descriptions + +- `{device}` is boiler, thermostat, mixer, solar, heatpump, dallassensor +- `{name}` is the short name of the parameter, e.g. **curflowtemp** +- `{hc}` is the heating circuit number as a string, like **hc1**, **hc2** etc +- `{value}` is either a ``, ``, `` or `` + +## Device Endpoints + +| Method | Endpoint | Description | Access Token required | JSON body data | +| - | - | - | - | - | +| GET | `/{device}` | return all device details and values | | | +| GET | `/{device}/{name}` | return a specific parameter and all its properties (name, fullname, value, type, min, max, unit, writeable) | | | +| GET | `/device={device}?cmd={name}?data={value}[?id={hc}` | to keep compatibility with v2. Unless bypassed in the EMS-ESP settings make sure you include `access_token={ACCESS_TOKEN}` | x | +| POST/PUT | `/{device}[/{hc}][/{name}]` | sets a specific value to a parameter name. If no hc is selected and one is required for the device, the default will be used | x | `{ "value": [, "hc": {hc}] }` | + +## System Endpoints + +| Method | Endpoint | Description | Access Token required | JSON body data | +| - | - | - | - | - | +| GET | `/system/info` | list system information | | | | +| GET | `/system/settings` | list all settings, except passwords | x | +| POST/PUT | `/system/pin` | switch a GPIO state to HIGH or LOW | x | `{ "pin":, "value": }` | +| POST/PUT | `/system/send` | send a telegram to the EMS bus | x | `{ "telegram" : }` | +| POST/PUT | `/system/publish` | force an MQTT publish | x | `[{ "name" : \| "ha" }]` | +| POST/PUT | `/system/fetch` | fetch all EMS data from all devices | x | | +| POST/PUT | `/system/restart` | restarts the EMS-ESP | x | | + +## To Do + +- add restart command +- update EMS-ESP wiki/documentation for v3 +- make adjustments to the command line +- change the URLs in the web UI help page to call system commands directly instead of via URLs +- add long name to value query (only shortname is shown) +- create Postman schema +- rename setting "Enable API write commands" to something like "Use non-authenticated API" with a disclaimer that its insecure and not recommended From 7d0ed2246a2aa556ad9210c2a2293b069ad62b85 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 2 May 2021 08:32:52 +0200 Subject: [PATCH 003/114] auto formatting --- .clang-format | 2 +- src/WebDevicesService.cpp | 14 +- src/WebSettingsService.cpp | 3 +- src/WebStatusService.cpp | 4 +- src/command.cpp | 6 +- src/console.cpp | 493 +++++++++++++++++++++---------------- src/dallassensor.cpp | 18 +- src/devices/boiler.cpp | 93 ++++--- src/devices/solar.cpp | 3 +- src/devices/thermostat.cpp | 109 ++++++-- src/devices/thermostat.h | 4 +- src/emsdevice.cpp | 39 ++- src/emsdevice.h | 25 +- src/emsesp.h | 7 +- src/helpers.cpp | 3 +- src/locale_EN.h | 11 +- src/mqtt.cpp | 45 +++- src/mqtt.h | 7 +- src/system.cpp | 1 - src/telegram.cpp | 51 ++-- src/telegram.h | 17 +- src/uart/emsuart_esp32.cpp | 9 +- 22 files changed, 646 insertions(+), 318 deletions(-) diff --git a/.clang-format b/.clang-format index 2f5e3b42b..e84ce1c3c 100644 --- a/.clang-format +++ b/.clang-format @@ -2,7 +2,7 @@ Language: Cpp BasedOnStyle: LLVM UseTab: Never IndentWidth: 4 -ColumnLimit: 220 +ColumnLimit: 160 TabWidth: 4 #BreakBeforeBraces: Custom BraceWrapping: diff --git a/src/WebDevicesService.cpp b/src/WebDevicesService.cpp index 5db6fcd50..e16d50b8d 100644 --- a/src/WebDevicesService.cpp +++ b/src/WebDevicesService.cpp @@ -23,10 +23,16 @@ namespace emsesp { using namespace std::placeholders; // for `_1` etc WebDevicesService::WebDevicesService(AsyncWebServer * server, SecurityManager * securityManager) - : _device_dataHandler(DEVICE_DATA_SERVICE_PATH, securityManager->wrapCallback(std::bind(&WebDevicesService::device_data, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED)) - , _writevalue_dataHandler(WRITE_VALUE_SERVICE_PATH, securityManager->wrapCallback(std::bind(&WebDevicesService::write_value, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED)) { - server->on(EMSESP_DEVICES_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WebDevicesService::all_devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); - server->on(SCAN_DEVICES_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WebDevicesService::scan_devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + : _device_dataHandler(DEVICE_DATA_SERVICE_PATH, + securityManager->wrapCallback(std::bind(&WebDevicesService::device_data, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED)) + , _writevalue_dataHandler(WRITE_VALUE_SERVICE_PATH, + securityManager->wrapCallback(std::bind(&WebDevicesService::write_value, this, _1, _2), AuthenticationPredicates::IS_AUTHENTICATED)) { + server->on(EMSESP_DEVICES_SERVICE_PATH, + HTTP_GET, + securityManager->wrapRequest(std::bind(&WebDevicesService::all_devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + server->on(SCAN_DEVICES_SERVICE_PATH, + HTTP_GET, + securityManager->wrapRequest(std::bind(&WebDevicesService::scan_devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); _device_dataHandler.setMethod(HTTP_POST); _device_dataHandler.setMaxContentLength(256); diff --git a/src/WebSettingsService.cpp b/src/WebSettingsService.cpp index 8836c3740..f1a4d2396 100644 --- a/src/WebSettingsService.cpp +++ b/src/WebSettingsService.cpp @@ -27,7 +27,8 @@ using namespace std::placeholders; // for `_1` etc 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) - , _boardProfileHandler(EMSESP_BOARD_PROFILE_SERVICE_PATH, securityManager->wrapCallback(std::bind(&WebSettingsService::board_profile, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) { + , _boardProfileHandler(EMSESP_BOARD_PROFILE_SERVICE_PATH, + securityManager->wrapCallback(std::bind(&WebSettingsService::board_profile, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) { _boardProfileHandler.setMethod(HTTP_POST); _boardProfileHandler.setMaxContentLength(256); server->addHandler(&_boardProfileHandler); diff --git a/src/WebStatusService.cpp b/src/WebStatusService.cpp index f0d418c2e..c7e972582 100644 --- a/src/WebStatusService.cpp +++ b/src/WebStatusService.cpp @@ -24,7 +24,9 @@ namespace emsesp { WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) { // rest endpoint for web page - server->on(EMSESP_STATUS_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WebStatusService::webStatusService, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + server->on(EMSESP_STATUS_SERVICE_PATH, + HTTP_GET, + securityManager->wrapRequest(std::bind(&WebStatusService::webStatusService, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); WiFi.onEvent(std::bind(&WebStatusService::WiFiEvent, this, _1, _2)); } diff --git a/src/command.cpp b/src/command.cpp index 4abdd4d64..ca0c376d4 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -95,6 +95,7 @@ bool Command::call(const uint8_t device_type, const char * cmd, const char * val } } +// set the id if there are prefixes char * Command::check_command(char * out, const char * cmd, int8_t & id) { // convert cmd to lowercase strlcpy(out, cmd, 20); @@ -102,7 +103,7 @@ char * Command::check_command(char * out, const char * cmd, int8_t & id) { *p = tolower(*p); } - //scan for prefix hc. + // scan for prefix hc. for (uint8_t i = DeviceValueTAG::TAG_HC1; i <= DeviceValueTAG::TAG_HC4; i++) { if ((strncmp(out, EMSdevice::tag_to_string(i).c_str(), 3) == 0) && (strlen(out) > 4)) { strcpy(out, &out[4]); @@ -111,7 +112,7 @@ char * Command::check_command(char * out, const char * cmd, int8_t & id) { } } - //scan for prefix wwc. + // scan for prefix wwc. for (uint8_t i = DeviceValueTAG::TAG_WWC1; i <= DeviceValueTAG::TAG_WWC4; i++) { if ((strncmp(out, EMSdevice::tag_to_string(i).c_str(), 4) == 0) && (strlen(out) > 5)) { strcpy(out, &out[5]); @@ -123,7 +124,6 @@ char * Command::check_command(char * out, const char * cmd, int8_t & id) { return out; } - // add a command to the list, which does not return json void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cb, uint8_t flag) { // if the command already exists for that device type don't add it diff --git a/src/console.cpp b/src/console.cpp index 033cf49e3..0df126eb2 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -36,7 +36,9 @@ static std::shared_ptr shell; std::vector EMSESPStreamConsole::ptys_; #ifndef EMSESP_STANDALONE -uuid::telnet::TelnetService telnet_([](Stream & stream, const IPAddress & addr, uint16_t port) -> std::shared_ptr { return std::make_shared(stream, addr, port); }); +uuid::telnet::TelnetService telnet_([](Stream & stream, const IPAddress & addr, uint16_t port) -> std::shared_ptr { + return std::make_shared(stream, addr, port); +}); #endif EMSESPShell::EMSESPShell() @@ -102,30 +104,42 @@ void EMSESPShell::add_console_commands() { // just in case, remove everything commands->remove_all_commands(); - commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(show)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - shell.printfln(F("%s%sEMS-ESP version %s%s"), COLOR_BRIGHT_GREEN, COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_RESET); - shell.println(); - EMSESP::show_device_values(shell); - EMSESP::show_sensor_values(shell); - }); + commands->add_command(ShellContext::MAIN, + CommandFlags::USER, + flash_string_vector{F_(show)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { + shell.printfln(F("%s%sEMS-ESP version %s%s"), COLOR_BRIGHT_GREEN, COLOR_BOLD_ON, EMSESP_APP_VERSION, COLOR_RESET); + shell.println(); + EMSESP::show_device_values(shell); + EMSESP::show_sensor_values(shell); + }); - commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(show), F_(devices)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - EMSESP::show_devices(shell); - }); + commands->add_command(ShellContext::MAIN, + CommandFlags::USER, + flash_string_vector{F_(show), F_(devices)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { EMSESP::show_devices(shell); }); - commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(show), F_(ems)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { EMSESP::show_ems(shell); }); + commands->add_command(ShellContext::MAIN, + CommandFlags::USER, + flash_string_vector{F_(show), F_(ems)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { EMSESP::show_ems(shell); }); - commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(show), F_(values)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - EMSESP::show_device_values(shell); - }); + commands->add_command(ShellContext::MAIN, + CommandFlags::USER, + flash_string_vector{F_(show), F_(values)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { EMSESP::show_device_values(shell); }); - commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(show), F_(mqtt)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { Mqtt::show_mqtt(shell); }); + commands->add_command(ShellContext::MAIN, + CommandFlags::USER, + flash_string_vector{F_(show), F_(mqtt)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { Mqtt::show_mqtt(shell); }); - commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(show), F_(commands)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - Command::show_all(shell); - }); + commands->add_command(ShellContext::MAIN, + CommandFlags::USER, + flash_string_vector{F_(show), F_(commands)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { Command::show_all(shell); }); commands->add_command( ShellContext::MAIN, @@ -157,62 +171,75 @@ void EMSESPShell::add_console_commands() { }; }); - commands->add_command(ShellContext::MAIN, CommandFlags::ADMIN, flash_string_vector{F_(set), F_(tx_mode)}, flash_string_vector{F_(n_mandatory)}, [](Shell & shell, const std::vector & arguments) { - uint8_t tx_mode = std::strtol(arguments[0].c_str(), nullptr, 10); - // save the tx_mode - EMSESP::webSettingsService.update( - [&](WebSettings & settings) { - settings.tx_mode = tx_mode; - shell.printfln(F_(tx_mode_fmt), settings.tx_mode); - return StateUpdateResult::CHANGED; - }, - "local"); - }); + commands->add_command(ShellContext::MAIN, + CommandFlags::ADMIN, + flash_string_vector{F_(set), F_(tx_mode)}, + flash_string_vector{F_(n_mandatory)}, + [](Shell & shell, const std::vector & arguments) { + uint8_t tx_mode = std::strtol(arguments[0].c_str(), nullptr, 10); + // save the tx_mode + EMSESP::webSettingsService.update( + [&](WebSettings & settings) { + settings.tx_mode = tx_mode; + shell.printfln(F_(tx_mode_fmt), settings.tx_mode); + return StateUpdateResult::CHANGED; + }, + "local"); + }); - commands->add_command(ShellContext::MAIN, CommandFlags::ADMIN, flash_string_vector{F_(scan), F_(devices)}, flash_string_vector{F_(deep_optional)}, [](Shell & shell, const std::vector & arguments) { - if (arguments.size() == 0) { - EMSESP::scan_devices(); - } else { - shell.printfln(F("Performing a deep scan...")); - EMSESP::clear_all_devices(); - std::vector Device_Ids; + commands->add_command(ShellContext::MAIN, + CommandFlags::ADMIN, + flash_string_vector{F_(scan), F_(devices)}, + flash_string_vector{F_(deep_optional)}, + [](Shell & shell, const std::vector & arguments) { + if (arguments.size() == 0) { + EMSESP::scan_devices(); + } else { + shell.printfln(F("Performing a deep scan...")); + EMSESP::clear_all_devices(); + std::vector Device_Ids; - Device_Ids.push_back(0x08); // Boilers - 0x08 - Device_Ids.push_back(0x38); // HeatPump - 0x38 - Device_Ids.push_back(0x30); // Solar Module - 0x30 - Device_Ids.push_back(0x09); // Controllers - 0x09 - Device_Ids.push_back(0x02); // Connect - 0x02 - Device_Ids.push_back(0x48); // Gateway - 0x48 - Device_Ids.push_back(0x20); // Mixer Devices - 0x20 - Device_Ids.push_back(0x21); // Mixer Devices - 0x21 - Device_Ids.push_back(0x22); // Mixer Devices - 0x22 - Device_Ids.push_back(0x23); // Mixer Devices - 0x23 - Device_Ids.push_back(0x28); // Mixer Devices WW- 0x28 - Device_Ids.push_back(0x29); // Mixer Devices WW- 0x29 - Device_Ids.push_back(0x10); // Thermostats - 0x10 - Device_Ids.push_back(0x17); // Thermostats - 0x17 - Device_Ids.push_back(0x18); // Thermostat remote - 0x18 - Device_Ids.push_back(0x19); // Thermostat remote - 0x19 - Device_Ids.push_back(0x1A); // Thermostat remote - 0x1A - Device_Ids.push_back(0x1B); // Thermostat remote - 0x1B - Device_Ids.push_back(0x11); // Switches - 0x11 + Device_Ids.push_back(0x08); // Boilers - 0x08 + Device_Ids.push_back(0x38); // HeatPump - 0x38 + Device_Ids.push_back(0x30); // Solar Module - 0x30 + Device_Ids.push_back(0x09); // Controllers - 0x09 + Device_Ids.push_back(0x02); // Connect - 0x02 + Device_Ids.push_back(0x48); // Gateway - 0x48 + Device_Ids.push_back(0x20); // Mixer Devices - 0x20 + Device_Ids.push_back(0x21); // Mixer Devices - 0x21 + Device_Ids.push_back(0x22); // Mixer Devices - 0x22 + Device_Ids.push_back(0x23); // Mixer Devices - 0x23 + Device_Ids.push_back(0x28); // Mixer Devices WW- 0x28 + Device_Ids.push_back(0x29); // Mixer Devices WW- 0x29 + Device_Ids.push_back(0x10); // Thermostats - 0x10 + Device_Ids.push_back(0x17); // Thermostats - 0x17 + Device_Ids.push_back(0x18); // Thermostat remote - 0x18 + Device_Ids.push_back(0x19); // Thermostat remote - 0x19 + Device_Ids.push_back(0x1A); // Thermostat remote - 0x1A + Device_Ids.push_back(0x1B); // Thermostat remote - 0x1B + Device_Ids.push_back(0x11); // Switches - 0x11 - // send the read command with Version command - for (const uint8_t device_id : Device_Ids) { - EMSESP::send_read_request(EMSdevice::EMS_TYPE_VERSION, device_id); - } - } - }); + // send the read command with Version command + for (const uint8_t device_id : Device_Ids) { + EMSESP::send_read_request(EMSdevice::EMS_TYPE_VERSION, device_id); + } + } + }); - commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(set)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - EMSESP::webSettingsService.read([&](WebSettings & settings) { - shell.printfln(F_(tx_mode_fmt), settings.tx_mode); - shell.printfln(F_(bus_id_fmt), settings.ems_bus_id); - char buffer[4]; - shell.printfln(F_(master_thermostat_fmt), settings.master_thermostat == 0 ? uuid::read_flash_string(F_(auto)).c_str() : Helpers::hextoa(buffer, settings.master_thermostat)); - shell.printfln(F_(board_profile_fmt), settings.board_profile.c_str()); - }); - }); + commands->add_command(ShellContext::MAIN, + CommandFlags::USER, + flash_string_vector{F_(set)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { + EMSESP::webSettingsService.read([&](WebSettings & settings) { + shell.printfln(F_(tx_mode_fmt), settings.tx_mode); + shell.printfln(F_(bus_id_fmt), settings.ems_bus_id); + char buffer[4]; + shell.printfln(F_(master_thermostat_fmt), + settings.master_thermostat == 0 ? uuid::read_flash_string(F_(auto)).c_str() + : Helpers::hextoa(buffer, settings.master_thermostat)); + shell.printfln(F_(board_profile_fmt), settings.board_profile.c_str()); + }); + }); commands->add_command(ShellContext::MAIN, CommandFlags::ADMIN, @@ -245,18 +272,23 @@ void EMSESPShell::add_console_commands() { settings.master_thermostat = value; EMSESP::actual_master_thermostat(value); // set the internal value too char buffer[5]; - shell.printfln(F_(master_thermostat_fmt), !value ? uuid::read_flash_string(F_(auto)).c_str() : Helpers::hextoa(buffer, value)); + shell.printfln(F_(master_thermostat_fmt), + !value ? uuid::read_flash_string(F_(auto)).c_str() : Helpers::hextoa(buffer, value)); return StateUpdateResult::CHANGED; }, "local"); }); #ifndef EMSESP_STANDALONE - commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(set), F_(timeout)}, flash_string_vector{F_(n_mandatory)}, [](Shell & shell, const std::vector & arguments) { - uint16_t value = Helpers::atoint(arguments.front().c_str()); - telnet_.initial_idle_timeout(value * 60); - shell.printfln(F("Telnet timeout set to %d minutes"), value); - }); + commands->add_command(ShellContext::MAIN, + CommandFlags::USER, + flash_string_vector{F_(set), F_(timeout)}, + flash_string_vector{F_(n_mandatory)}, + [](Shell & shell, const std::vector & arguments) { + uint16_t value = Helpers::atoint(arguments.front().c_str()); + telnet_.initial_idle_timeout(value * 60); + shell.printfln(F("Telnet timeout set to %d minutes"), value); + }); #endif commands->add_command(ShellContext::MAIN, @@ -444,27 +476,37 @@ void Console::enter_custom_context(Shell & shell, unsigned int context) { // each custom context has the common commands like log, help, exit, su etc void Console::load_standard_commands(unsigned int context) { #if defined(EMSESP_DEBUG) - EMSESPShell::commands->add_command(context, CommandFlags::USER, flash_string_vector{F("test")}, flash_string_vector{F_(name_optional)}, [](Shell & shell, const std::vector & arguments) { - if (arguments.size() == 0) { - Test::run_test(shell, "default"); - } else { - Test::run_test(shell, arguments.front()); - } - }); + EMSESPShell::commands->add_command(context, + CommandFlags::USER, + flash_string_vector{F("test")}, + flash_string_vector{F_(name_optional)}, + [](Shell & shell, const std::vector & arguments) { + if (arguments.size() == 0) { + Test::run_test(shell, "default"); + } else { + Test::run_test(shell, arguments.front()); + } + }); #endif #if defined(EMSESP_STANDALONE) - EMSESPShell::commands->add_command(context, CommandFlags::USER, flash_string_vector{F("t")}, [](Shell & shell, const std::vector & arguments) { Test::run_test(shell, "default"); }); + EMSESPShell::commands->add_command(context, CommandFlags::USER, flash_string_vector{F("t")}, [](Shell & shell, const std::vector & arguments) { + Test::run_test(shell, "default"); + }); #endif #if defined(EMSESP_DEBUG) - EMSESPShell::commands->add_command(context, CommandFlags::USER, flash_string_vector{F_(debug)}, flash_string_vector{F_(name_optional)}, [](Shell & shell, const std::vector & arguments) { - if (arguments.size() == 0) { - Test::debug(shell, "default"); - } else { - Test::debug(shell, arguments.front()); - } - }); + EMSESPShell::commands->add_command(context, + CommandFlags::USER, + flash_string_vector{F_(debug)}, + flash_string_vector{F_(name_optional)}, + [](Shell & shell, const std::vector & arguments) { + if (arguments.size() == 0) { + Test::debug(shell, "default"); + } else { + Test::debug(shell, arguments.front()); + } + }); #endif EMSESPShell::commands->add_command( @@ -493,44 +535,55 @@ void Console::load_standard_commands(unsigned int context) { } shell.printfln(F_(log_level_fmt), uuid::log::format_level_lowercase(shell.log_level())); }, - [](Shell & shell __attribute__((unused)), const std::vector & arguments __attribute__((unused))) -> std::vector { return uuid::log::levels_lowercase(); }); + [](Shell & shell __attribute__((unused)), const std::vector & arguments __attribute__((unused))) -> std::vector { + return uuid::log::levels_lowercase(); + }); - EMSESPShell::commands->add_command(context, CommandFlags::USER, flash_string_vector{F_(help)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - shell.print_all_available_commands(); - }); + EMSESPShell::commands->add_command(context, + CommandFlags::USER, + flash_string_vector{F_(help)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { + shell.print_all_available_commands(); + }); - EMSESPShell::commands->add_command(context, CommandFlags::USER, flash_string_vector{F_(exit)}, [=](Shell & shell, const std::vector & arguments __attribute__((unused))) { - shell.stop(); - // shell.exit_context(); - }); + EMSESPShell::commands->add_command(context, + CommandFlags::USER, + flash_string_vector{F_(exit)}, + [=](Shell & shell, const std::vector & arguments __attribute__((unused))) { + shell.stop(); + // shell.exit_context(); + }); - EMSESPShell::commands->add_command(context, CommandFlags::USER, flash_string_vector{F_(su)}, [=](Shell & shell, const std::vector & arguments __attribute__((unused))) { - auto become_admin = [](Shell & shell) { - shell.logger().log(LogLevel::NOTICE, LogFacility::AUTH, F("su session opened on console")); - shell.add_flags(CommandFlags::ADMIN); - }; + EMSESPShell::commands->add_command(context, + CommandFlags::USER, + flash_string_vector{F_(su)}, + [=](Shell & shell, const std::vector & arguments __attribute__((unused))) { + auto become_admin = [](Shell & shell) { + shell.logger().log(LogLevel::NOTICE, LogFacility::AUTH, F("su session opened on console")); + shell.add_flags(CommandFlags::ADMIN); + }; - if (shell.has_flags(CommandFlags::LOCAL)) { - become_admin(shell); - } else { - shell.enter_password(F_(password_prompt), [=](Shell & shell, bool completed, const std::string & password) { - if (completed) { - uint64_t now = uuid::get_uptime_ms(); + if (shell.has_flags(CommandFlags::LOCAL)) { + become_admin(shell); + } else { + shell.enter_password(F_(password_prompt), [=](Shell & shell, bool completed, const std::string & password) { + if (completed) { + uint64_t now = uuid::get_uptime_ms(); - EMSESP::esp8266React.getSecuritySettingsService()->read([&](SecuritySettings & securitySettings) { - if (securitySettings.jwtSecret.equals(password.c_str())) { - become_admin(shell); - } else { - shell.delay_until(now + INVALID_PASSWORD_DELAY_MS, [](Shell & shell) { - shell.logger().log(LogLevel::NOTICE, LogFacility::AUTH, F("Invalid su password on console")); - shell.println(F("su: incorrect password")); - }); - } - }); - } - }); - } - }); + EMSESP::esp8266React.getSecuritySettingsService()->read([&](SecuritySettings & securitySettings) { + if (securitySettings.jwtSecret.equals(password.c_str())) { + become_admin(shell); + } else { + shell.delay_until(now + INVALID_PASSWORD_DELAY_MS, [](Shell & shell) { + shell.logger().log(LogLevel::NOTICE, LogFacility::AUTH, F("Invalid su password on console")); + shell.println(F("su: incorrect password")); + }); + } + }); + } + }); + } + }); } // console commands to add @@ -538,53 +591,67 @@ void Console::load_system_commands(unsigned int context) { EMSESPShell::commands->add_command(context, CommandFlags::ADMIN, flash_string_vector{F_(restart)}, - [](Shell & shell __attribute__((unused)), const std::vector & arguments __attribute__((unused))) { EMSESP::system_.restart(); }); + [](Shell & shell __attribute__((unused)), const std::vector & arguments __attribute__((unused))) { + EMSESP::system_.restart(); + }); EMSESPShell::commands->add_command(context, CommandFlags::ADMIN, flash_string_vector{F_(wifi), F_(reconnect)}, - [](Shell & shell __attribute__((unused)), const std::vector & arguments __attribute__((unused))) { EMSESP::system_.wifi_reconnect(); }); + [](Shell & shell __attribute__((unused)), const std::vector & arguments __attribute__((unused))) { + EMSESP::system_.wifi_reconnect(); + }); - EMSESPShell::commands->add_command(ShellContext::MAIN, CommandFlags::ADMIN, flash_string_vector{F_(format)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - shell.enter_password(F_(password_prompt), [=](Shell & shell, bool completed, const std::string & password) { - if (completed) { - EMSESP::esp8266React.getSecuritySettingsService()->read([&](SecuritySettings & securitySettings) { - if (securitySettings.jwtSecret.equals(password.c_str())) { - EMSESP::system_.format(shell); - } else { - shell.println(F("incorrect password")); - } - }); - } - }); - }); + EMSESPShell::commands->add_command(ShellContext::MAIN, + CommandFlags::ADMIN, + flash_string_vector{F_(format)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { + shell.enter_password(F_(password_prompt), [=](Shell & shell, bool completed, const std::string & password) { + if (completed) { + EMSESP::esp8266React.getSecuritySettingsService()->read([&](SecuritySettings & securitySettings) { + if (securitySettings.jwtSecret.equals(password.c_str())) { + EMSESP::system_.format(shell); + } else { + shell.println(F("incorrect password")); + } + }); + } + }); + }); - EMSESPShell::commands->add_command(context, CommandFlags::ADMIN, flash_string_vector{F_(passwd)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - shell.enter_password(F_(new_password_prompt1), [](Shell & shell, bool completed, const std::string & password1) { - if (completed) { - shell.enter_password(F_(new_password_prompt2), [password1](Shell & shell, bool completed, const std::string & password2) { - if (completed) { - if (password1 == password2) { - EMSESP::esp8266React.getSecuritySettingsService()->update( - [&](SecuritySettings & securitySettings) { - securitySettings.jwtSecret = password2.c_str(); - return StateUpdateResult::CHANGED; - }, - "local"); - shell.println(F("su password updated")); - } else { - shell.println(F("Passwords do not match")); - } - } - }); - } - }); - }); + EMSESPShell::commands->add_command(context, + CommandFlags::ADMIN, + flash_string_vector{F_(passwd)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { + shell.enter_password(F_(new_password_prompt1), [](Shell & shell, bool completed, const std::string & password1) { + if (completed) { + shell.enter_password(F_(new_password_prompt2), + [password1](Shell & shell, bool completed, const std::string & password2) { + if (completed) { + if (password1 == password2) { + EMSESP::esp8266React.getSecuritySettingsService()->update( + [&](SecuritySettings & securitySettings) { + securitySettings.jwtSecret = password2.c_str(); + return StateUpdateResult::CHANGED; + }, + "local"); + shell.println(F("su password updated")); + } else { + shell.println(F("Passwords do not match")); + } + } + }); + } + }); + }); - EMSESPShell::commands->add_command(context, CommandFlags::USER, flash_string_vector{F_(show), F_(system)}, [=](Shell & shell, const std::vector & arguments __attribute__((unused))) { - EMSESP::system_.show_system(shell); - shell.println(); - }); + EMSESPShell::commands->add_command(context, + CommandFlags::USER, + flash_string_vector{F_(show), F_(system)}, + [=](Shell & shell, const std::vector & arguments __attribute__((unused))) { + EMSESP::system_.show_system(shell); + shell.println(); + }); EMSESPShell::commands->add_command(context, CommandFlags::ADMIN, @@ -614,55 +681,63 @@ void Console::load_system_commands(unsigned int context) { shell.println("Use `wifi reconnect` to save and apply the new settings"); }); - EMSESPShell::commands->add_command(context, CommandFlags::ADMIN, flash_string_vector{F_(set), F_(wifi), F_(password)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - shell.enter_password(F_(new_password_prompt1), [](Shell & shell, bool completed, const std::string & password1) { - if (completed) { - shell.enter_password(F_(new_password_prompt2), [password1](Shell & shell, bool completed, const std::string & password2) { - if (completed) { - if (password1 == password2) { - EMSESP::esp8266React.getNetworkSettingsService()->updateWithoutPropagation([&](NetworkSettings & networkSettings) { - networkSettings.password = password2.c_str(); - return StateUpdateResult::CHANGED; - }); - shell.println("Use `wifi reconnect` to save and apply the new settings"); - } else { - shell.println(F("Passwords do not match")); - } - } - }); - } - }); - }); - EMSESPShell::commands->add_command(context, CommandFlags::ADMIN, - flash_string_vector{F_(set), F_(board_profile)}, - flash_string_vector{F_(name_mandatory)}, - [](Shell & shell, const std::vector & arguments) { - std::vector data; // led, dallas, rx, tx, button - std::string board_profile = Helpers::toUpper(arguments.front()); - if (!EMSESP::system_.load_board_profile(data, board_profile)) { - shell.println(F("Invalid board profile (S32, E32, MH-ET, NODEMCU, OLIMEX, TLK110, LAN8720, CUSTOM)")); - return; - } - EMSESP::webSettingsService.update( - [&](WebSettings & settings) { - settings.board_profile = board_profile.c_str(); - settings.led_gpio = data[0]; - settings.dallas_gpio = data[1]; - settings.rx_gpio = data[2]; - settings.tx_gpio = data[3]; - settings.pbutton_gpio = data[4]; - return StateUpdateResult::CHANGED; - }, - "local"); - shell.printfln("Loaded board profile %s (%d,%d,%d,%d,%d)", board_profile.c_str(), data[0], data[1], data[2], data[3], data[4]); - EMSESP::system_.network_init(true); + flash_string_vector{F_(set), F_(wifi), F_(password)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { + shell.enter_password(F_(new_password_prompt1), [](Shell & shell, bool completed, const std::string & password1) { + if (completed) { + shell.enter_password(F_(new_password_prompt2), + [password1](Shell & shell, bool completed, const std::string & password2) { + if (completed) { + if (password1 == password2) { + EMSESP::esp8266React.getNetworkSettingsService()->updateWithoutPropagation( + [&](NetworkSettings & networkSettings) { + networkSettings.password = password2.c_str(); + return StateUpdateResult::CHANGED; + }); + shell.println("Use `wifi reconnect` to save and apply the new settings"); + } else { + shell.println(F("Passwords do not match")); + } + } + }); + } + }); }); - EMSESPShell::commands->add_command(context, CommandFlags::ADMIN, flash_string_vector{F_(show), F_(users)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - EMSESP::system_.show_users(shell); - }); + EMSESPShell::commands + ->add_command(context, + CommandFlags::ADMIN, + flash_string_vector{F_(set), F_(board_profile)}, + flash_string_vector{F_(name_mandatory)}, + [](Shell & shell, const std::vector & arguments) { + std::vector data; // led, dallas, rx, tx, button + std::string board_profile = Helpers::toUpper(arguments.front()); + if (!EMSESP::system_.load_board_profile(data, board_profile)) { + shell.println(F("Invalid board profile (S32, E32, MH-ET, NODEMCU, OLIMEX, TLK110, LAN8720, CUSTOM)")); + return; + } + EMSESP::webSettingsService.update( + [&](WebSettings & settings) { + settings.board_profile = board_profile.c_str(); + settings.led_gpio = data[0]; + settings.dallas_gpio = data[1]; + settings.rx_gpio = data[2]; + settings.tx_gpio = data[3]; + settings.pbutton_gpio = data[4]; + return StateUpdateResult::CHANGED; + }, + "local"); + shell.printfln("Loaded board profile %s (%d,%d,%d,%d,%d)", board_profile.c_str(), data[0], data[1], data[2], data[3], data[4]); + EMSESP::system_.network_init(true); + }); + EMSESPShell::commands->add_command(context, + CommandFlags::ADMIN, + flash_string_vector{F_(show), F_(users)}, + [](Shell & shell, const std::vector & arguments __attribute__((unused))) { + EMSESP::system_.show_users(shell); + }); } /* diff --git a/src/dallassensor.cpp b/src/dallassensor.cpp index a1dd07fb9..76d8e571f 100644 --- a/src/dallassensor.cpp +++ b/src/dallassensor.cpp @@ -41,7 +41,9 @@ void DallasSensor::start() { bus_.begin(dallas_gpio_); #endif // API call - Command::add_with_json(EMSdevice::DeviceType::DALLASSENSOR, F_(info), [&](const char * value, const int8_t id, JsonObject & json) { return command_info(value, id, json); }); + Command::add_with_json(EMSdevice::DeviceType::DALLASSENSOR, F_(info), [&](const char * value, const int8_t id, JsonObject & json) { + return command_info(value, id, json); + }); } } @@ -270,11 +272,13 @@ const std::vector DallasSensor::sensors() const { // skip crc from id. DallasSensor::Sensor::Sensor(const uint8_t addr[]) - : id_(((uint64_t)addr[0] << 48) | ((uint64_t)addr[1] << 40) | ((uint64_t)addr[2] << 32) | ((uint64_t)addr[3] << 24) | ((uint64_t)addr[4] << 16) | ((uint64_t)addr[5] << 8) | ((uint64_t)addr[6])) { + : id_(((uint64_t)addr[0] << 48) | ((uint64_t)addr[1] << 40) | ((uint64_t)addr[2] << 32) | ((uint64_t)addr[3] << 24) | ((uint64_t)addr[4] << 16) + | ((uint64_t)addr[5] << 8) | ((uint64_t)addr[6])) { } uint64_t DallasSensor::get_id(const uint8_t addr[]) { - return (((uint64_t)addr[0] << 48) | ((uint64_t)addr[1] << 40) | ((uint64_t)addr[2] << 32) | ((uint64_t)addr[3] << 24) | ((uint64_t)addr[4] << 16) | ((uint64_t)addr[5] << 8) | ((uint64_t)addr[6])); + return (((uint64_t)addr[0] << 48) | ((uint64_t)addr[1] << 40) | ((uint64_t)addr[2] << 32) | ((uint64_t)addr[3] << 24) | ((uint64_t)addr[4] << 16) + | ((uint64_t)addr[5] << 8) | ((uint64_t)addr[6])); } uint64_t DallasSensor::Sensor::id() const { @@ -283,7 +287,13 @@ uint64_t DallasSensor::Sensor::id() const { std::string DallasSensor::Sensor::to_string() const { std::string str(20, '\0'); - snprintf_P(&str[0], str.capacity() + 1, PSTR("%02X-%04X-%04X-%04X"), (unsigned int)(id_ >> 48) & 0xFF, (unsigned int)(id_ >> 32) & 0xFFFF, (unsigned int)(id_ >> 16) & 0xFFFF, (unsigned int)(id_)&0xFFFF); + snprintf_P(&str[0], + str.capacity() + 1, + PSTR("%02X-%04X-%04X-%04X"), + (unsigned int)(id_ >> 48) & 0xFF, + (unsigned int)(id_ >> 32) & 0xFFFF, + (unsigned int)(id_ >> 16) & 0xFFFF, + (unsigned int)(id_)&0xFFFF); return str; } diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index eb637977e..5eb577a3a 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -85,7 +85,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_telegram_type(0x48F, F("HpOutdoor"), false, MAKE_PF_CB(process_HpOutdoor)); } // MQTT commands for boiler topic - register_device_value(TAG_BOILER_DATA, &dummybool_, DeviceValueType::BOOL, nullptr, FL_(wwtapactivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_tapwarmwater_activated)); + register_device_value( + TAG_BOILER_DATA, &dummybool_, DeviceValueType::BOOL, nullptr, FL_(wwtapactivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_tapwarmwater_activated)); register_device_value(TAG_BOILER_DATA, &dummy8u_, DeviceValueType::ENUM, FL_(enum_reset), FL_(reset), DeviceValueUOM::NONE, MAKE_CF_CB(set_reset)); // add values @@ -113,7 +114,8 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(TAG_BOILER_DATA, &heatingPump_, DeviceValueType::BOOL, nullptr, FL_(heatingPump), DeviceValueUOM::PUMP); register_device_value(TAG_BOILER_DATA, &fanWork_, DeviceValueType::BOOL, nullptr, FL_(fanWork), DeviceValueUOM::NONE); register_device_value(TAG_BOILER_DATA, &ignWork_, DeviceValueType::BOOL, nullptr, FL_(ignWork), DeviceValueUOM::NONE); - register_device_value(TAG_BOILER_DATA, &heatingActivated_, DeviceValueType::BOOL, nullptr, FL_(heatingActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_heating_activated)); + register_device_value( + TAG_BOILER_DATA, &heatingActivated_, DeviceValueType::BOOL, nullptr, FL_(heatingActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_heating_activated)); register_device_value(TAG_BOILER_DATA, &heatingTemp_, DeviceValueType::UINT, nullptr, FL_(heatingTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_heating_temp)); register_device_value(TAG_BOILER_DATA, &pumpModMax_, DeviceValueType::UINT, nullptr, FL_(pumpModMax), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_max_pump)); register_device_value(TAG_BOILER_DATA, &pumpModMin_, DeviceValueType::UINT, nullptr, FL_(pumpModMin), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_min_pump)); @@ -135,7 +137,13 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(TAG_BOILER_DATA, &serviceCodeNumber_, DeviceValueType::USHORT, nullptr, FL_(serviceCodeNumber), DeviceValueUOM::NONE); register_device_value(TAG_BOILER_DATA, &maintenanceMessage_, DeviceValueType::TEXT, nullptr, FL_(maintenanceMessage), DeviceValueUOM::NONE); register_device_value(TAG_BOILER_DATA, &maintenanceDate_, DeviceValueType::TEXT, nullptr, FL_(maintenanceDate), DeviceValueUOM::NONE); - register_device_value(TAG_BOILER_DATA, &maintenanceType_, DeviceValueType::ENUM, FL_(enum_off_time_date), FL_(maintenanceType), DeviceValueUOM::NONE, MAKE_CF_CB(set_maintenance)); + register_device_value(TAG_BOILER_DATA, + &maintenanceType_, + DeviceValueType::ENUM, + FL_(enum_off_time_date), + FL_(maintenanceType), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_maintenance)); register_device_value(TAG_BOILER_DATA, &maintenanceTime_, DeviceValueType::USHORT, nullptr, FL_(maintenanceTime), DeviceValueUOM::HOURS); // heatpump info if (model() == EMS_DEVICE_FLAG_HEATPUMP) { @@ -175,20 +183,37 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(TAG_DEVICE_DATA_WW, &wWSelTemp_, DeviceValueType::UINT, nullptr, FL_(wWSelTemp), DeviceValueUOM::DEGREES); register_device_value(TAG_DEVICE_DATA_WW, &wWSetTemp_, DeviceValueType::UINT, nullptr, FL_(wWSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_warmwater_temp)); register_device_value(TAG_DEVICE_DATA_WW, &wWType_, DeviceValueType::ENUM, FL_(enum_flow), FL_(wWType), DeviceValueUOM::NONE); - register_device_value(TAG_DEVICE_DATA_WW, &wWComfort_, DeviceValueType::ENUM, FL_(enum_comfort), FL_(wWComfort), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_mode)); - register_device_value(TAG_DEVICE_DATA_WW, &wWFlowTempOffset_, DeviceValueType::UINT, nullptr, FL_(wWFlowTempOffset), DeviceValueUOM::NONE, MAKE_CF_CB(set_wWFlowTempOffset)); - register_device_value(TAG_DEVICE_DATA_WW, &wWMaxPower_, DeviceValueType::UINT, nullptr, FL_(wWMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_warmwater_maxpower)); - register_device_value(TAG_DEVICE_DATA_WW, &wWCircPump_, DeviceValueType::BOOL, nullptr, FL_(wWCircPump), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_circulation_pump)); + register_device_value( + TAG_DEVICE_DATA_WW, &wWComfort_, DeviceValueType::ENUM, FL_(enum_comfort), FL_(wWComfort), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_mode)); + register_device_value( + TAG_DEVICE_DATA_WW, &wWFlowTempOffset_, DeviceValueType::UINT, nullptr, FL_(wWFlowTempOffset), DeviceValueUOM::NONE, MAKE_CF_CB(set_wWFlowTempOffset)); + register_device_value( + TAG_DEVICE_DATA_WW, &wWMaxPower_, DeviceValueType::UINT, nullptr, FL_(wWMaxPower), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_warmwater_maxpower)); + register_device_value( + TAG_DEVICE_DATA_WW, &wWCircPump_, DeviceValueType::BOOL, nullptr, FL_(wWCircPump), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_circulation_pump)); register_device_value(TAG_DEVICE_DATA_WW, &wWChargeType_, DeviceValueType::BOOL, FL_(enum_charge), FL_(wWChargeType), DeviceValueUOM::NONE); - register_device_value(TAG_DEVICE_DATA_WW, &wWDisinfectionTemp_, DeviceValueType::UINT, nullptr, FL_(wWDisinfectionTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_disinfect_temp)); - register_device_value(TAG_DEVICE_DATA_WW, &wWCircMode_, DeviceValueType::ENUM, FL_(enum_freq), FL_(wWCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_circulation_mode)); + register_device_value(TAG_DEVICE_DATA_WW, + &wWDisinfectionTemp_, + DeviceValueType::UINT, + nullptr, + FL_(wWDisinfectionTemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_disinfect_temp)); + register_device_value(TAG_DEVICE_DATA_WW, + &wWCircMode_, + DeviceValueType::ENUM, + FL_(enum_freq), + FL_(wWCircMode), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_warmwater_circulation_mode)); register_device_value(TAG_DEVICE_DATA_WW, &wWCirc_, DeviceValueType::BOOL, nullptr, FL_(wWCirc), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_circulation)); register_device_value(TAG_DEVICE_DATA_WW, &wWCurTemp_, DeviceValueType::USHORT, FL_(div10), FL_(wWCurTemp), DeviceValueUOM::DEGREES); register_device_value(TAG_DEVICE_DATA_WW, &wWCurTemp2_, DeviceValueType::USHORT, FL_(div10), FL_(wWCurTemp2), DeviceValueUOM::DEGREES); register_device_value(TAG_DEVICE_DATA_WW, &wWCurFlow_, DeviceValueType::UINT, FL_(div10), FL_(wWCurFlow), DeviceValueUOM::LMIN); register_device_value(TAG_DEVICE_DATA_WW, &wWStorageTemp1_, DeviceValueType::USHORT, FL_(div10), FL_(wWStorageTemp1), DeviceValueUOM::DEGREES); register_device_value(TAG_DEVICE_DATA_WW, &wWStorageTemp2_, DeviceValueType::USHORT, FL_(div10), FL_(wWStorageTemp2), DeviceValueUOM::DEGREES); - register_device_value(TAG_DEVICE_DATA_WW, &wWActivated_, DeviceValueType::BOOL, nullptr, FL_(wWActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_activated)); + register_device_value( + TAG_DEVICE_DATA_WW, &wWActivated_, DeviceValueType::BOOL, nullptr, FL_(wWActivated), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_activated)); register_device_value(TAG_DEVICE_DATA_WW, &wWOneTime_, DeviceValueType::BOOL, nullptr, FL_(wWOneTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_warmwater_onetime)); register_device_value(TAG_DEVICE_DATA_WW, &wWDisinfecting_, DeviceValueType::BOOL, nullptr, FL_(wWDisinfecting), DeviceValueUOM::NONE); register_device_value(TAG_DEVICE_DATA_WW, &wWCharging_, DeviceValueType::BOOL, nullptr, FL_(wWCharging), DeviceValueUOM::NONE); @@ -204,10 +229,14 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_device_value(TAG_DEVICE_DATA_WW, &wWWorkM_, DeviceValueType::TIME, nullptr, FL_(wWWorkM), DeviceValueUOM::MINUTES); // fetch some initial data - EMSESP::send_read_request(0x10, device_id); // read last errorcode on start (only published on errors) - EMSESP::send_read_request(0x11, device_id); // read last errorcode on start (only published on errors) - EMSESP::send_read_request(0x15, device_id); // read maintenace data on start (only published on change) - EMSESP::send_read_request(0x1C, device_id); // read maintenace status on start (only published on change) + EMSESP::send_read_request(0x10, + device_id); // read last errorcode on start (only published on errors) + EMSESP::send_read_request(0x11, + device_id); // read last errorcode on start (only published on errors) + EMSESP::send_read_request(0x15, + device_id); // read maintenace data on start (only published on change) + EMSESP::send_read_request(0x1C, + device_id); // read maintenace status on start (only published on change) } // publish HA config @@ -231,7 +260,8 @@ bool Boiler::publish_ha_config() { char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; snprintf_P(topic, sizeof(topic), PSTR("sensor/%s/boiler/config"), Mqtt::base().c_str()); - Mqtt::publish_ha(topic, doc.as()); // publish the config payload with retain flag + Mqtt::publish_ha(topic, + doc.as()); // publish the config payload with retain flag return true; } @@ -288,7 +318,8 @@ void Boiler::process_UBAParameterWW(std::shared_ptr telegram) { has_update(telegram->read_value(wWCircPump_, 6)); // 0xFF means on has_update(telegram->read_value(wWCircMode_, 7)); // 1=1x3min 6=6x3min 7=continuous has_update(telegram->read_value(wWDisinfectionTemp_, 8)); - has_update(telegram->read_value(wWChargeType_, 10)); // 0 = charge pump, 0xff = 3-way valve + has_update(telegram->read_value(wWChargeType_, + 10)); // 0 = charge pump, 0xff = 3-way valve telegram->read_value(wWComfort_, 9); if (wWComfort_ == 0x00) { @@ -319,8 +350,9 @@ void Boiler::process_UBAMonitorFast(std::shared_ptr telegram) { // warm water storage sensors (if present) // wWStorageTemp2 is also used by some brands as the boiler temperature - see https://github.com/emsesp/EMS-ESP/issues/206 - has_update(telegram->read_value(wWStorageTemp1_, 9)); // 0x8300 if not available - has_update(telegram->read_value(wWStorageTemp2_, 11)); // 0x8000 if not available - this is boiler temp + has_update(telegram->read_value(wWStorageTemp1_, 9)); // 0x8300 if not available + has_update(telegram->read_value(wWStorageTemp2_, + 11)); // 0x8000 if not available - this is boiler temp has_update(telegram->read_value(retTemp_, 13)); has_update(telegram->read_value(flameCurr_, 15)); @@ -456,7 +488,8 @@ void Boiler::process_UBAMonitorSlow(std::shared_ptr telegram) { has_update(telegram->read_value(outdoorTemp_, 0)); has_update(telegram->read_value(boilTemp_, 2)); has_update(telegram->read_value(exhaustTemp_, 4)); - has_update(telegram->read_value(switchTemp_, 25)); // only if there is a mixer module present + has_update(telegram->read_value(switchTemp_, + 25)); // only if there is a mixer module present has_update(telegram->read_value(heatingPumpMod_, 9)); has_update(telegram->read_value(burnStarts_, 10, 3)); // force to 3 bytes has_update(telegram->read_value(burnWorkMin_, 13, 3)); // force to 3 bytes @@ -515,7 +548,8 @@ void Boiler::process_UBAParametersPlus(std::shared_ptr telegram) void Boiler::process_UBAParameterWWPlus(std::shared_ptr telegram) { has_update(telegram->read_value(wWActivated_, 5)); // 0x01 means on has_update(telegram->read_value(wWCircPump_, 10)); // 0x01 means yes - has_update(telegram->read_value(wWCircMode_, 11)); // 1=1x3min... 6=6x3min, 7=continuous + has_update(telegram->read_value(wWCircMode_, + 11)); // 1=1x3min... 6=6x3min, 7=continuous // has_update(telegram->read_value(wWDisinfectTemp_, 12)); // settings, status in E9 // has_update(telegram->read_value(wWSelTemp_, 6)); // settings, status in E9 } @@ -588,13 +622,12 @@ void Boiler::process_UBAEnergySupplied(std::shared_ptr telegram) } // Heatpump power - type 0x48D -void Boiler::process_HpPower(std::shared_ptr telegram){ +void Boiler::process_HpPower(std::shared_ptr telegram) { has_update(telegram->read_value(hpPower_, 11)); - } // Heatpump outdoor unit - type 0x48F -void Boiler::process_HpOutdoor(std::shared_ptr telegram){ +void Boiler::process_HpOutdoor(std::shared_ptr telegram) { has_update(telegram->read_value(hpTc0_, 6)); has_update(telegram->read_value(hpTc1_, 4)); has_update(telegram->read_value(hpTc3_, 2)); @@ -625,7 +658,8 @@ void Boiler::process_UBAOutdoorTemp(std::shared_ptr telegram) { // UBASetPoint 0x1A void Boiler::process_UBASetPoints(std::shared_ptr telegram) { - has_update(telegram->read_value(setFlowTemp_, 0)); // boiler set temp from thermostat + has_update(telegram->read_value(setFlowTemp_, + 0)); // boiler set temp from thermostat has_update(telegram->read_value(setBurnPow_, 1)); // max json power in % has_update(telegram->read_value(wWSetPumpPower_, 2)); // ww pump speed/power? } @@ -727,8 +761,9 @@ bool Boiler::set_warmwater_temp(const char * value, const int8_t id) { write_command(EMS_TYPE_UBAParameterWWPlus, 6, v, EMS_TYPE_UBAParameterWWPlus); } else { // some boiler have it in 0x33, some in 0x35 - write_command(EMS_TYPE_UBAFlags, 3, v, 0x34); // for i9000, see #397 - write_command(EMS_TYPE_UBAParameterWW, 2, v, EMS_TYPE_UBAParameterWW); // read seltemp back + write_command(EMS_TYPE_UBAFlags, 3, v, 0x34); // for i9000, see #397 + write_command(EMS_TYPE_UBAParameterWW, 2, v, + EMS_TYPE_UBAParameterWW); // read seltemp back } return true; @@ -1074,7 +1109,8 @@ bool Boiler::set_warmwater_onetime(const char * value, const int8_t id) { LOG_INFO(F("Setting warm water OneTime loading %s"), v ? "on" : "off"); if (get_toggle_fetch(EMS_TYPE_UBAParameterWWPlus)) { - write_command(EMS_TYPE_UBAFlags, 0, (v ? 0x22 : 0x02), 0xE9); // not sure if this is in flags + write_command(EMS_TYPE_UBAFlags, 0, (v ? 0x22 : 0x02), + 0xE9); // not sure if this is in flags } else { write_command(EMS_TYPE_UBAFlags, 0, (v ? 0x22 : 0x02), 0x34); } @@ -1093,7 +1129,8 @@ bool Boiler::set_warmwater_circulation(const char * value, const int8_t id) { LOG_INFO(F("Setting warm water circulation %s"), v ? "on" : "off"); if (get_toggle_fetch(EMS_TYPE_UBAParameterWWPlus)) { - write_command(EMS_TYPE_UBAFlags, 1, (v ? 0x22 : 0x02), 0xE9); // not sure if this is in flags + write_command(EMS_TYPE_UBAFlags, 1, (v ? 0x22 : 0x02), + 0xE9); // not sure if this is in flags } else { write_command(EMS_TYPE_UBAFlags, 1, (v ? 0x22 : 0x02), 0x34); } diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index ce0fe1284..c724b8c54 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -81,7 +81,8 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s register_device_value(TAG_NONE, &tankBottomTemp2_, DeviceValueType::SHORT, FL_(div10), FL_(tank2BottomTemp), DeviceValueUOM::DEGREES); register_device_value(TAG_NONE, &heatExchangerTemp_, DeviceValueType::SHORT, FL_(div10), FL_(heatExchangerTemp), DeviceValueUOM::DEGREES); - register_device_value(TAG_NONE, &tankBottomMaxTemp_, DeviceValueType::UINT, nullptr, FL_(tankMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_SM100TankBottomMaxTemp)); + register_device_value( + TAG_NONE, &tankBottomMaxTemp_, DeviceValueType::UINT, nullptr, FL_(tankMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_SM100TankBottomMaxTemp)); register_device_value(TAG_NONE, &solarPumpModulation_, DeviceValueType::UINT, nullptr, FL_(solarPumpModulation), DeviceValueUOM::PERCENT); register_device_value(TAG_NONE, &cylinderPumpModulation_, DeviceValueType::UINT, nullptr, FL_(cylinderPumpModulation), DeviceValueUOM::PERCENT); diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 44ed9246e..80fe8af51 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -38,7 +38,8 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // or if its the master thermostat we defined // see https://github.com/emsesp/EMS-ESP/issues/362#issuecomment-629628161 if ((master_thermostat == device_id) - || ((master_thermostat == EMSESP_DEFAULT_MASTER_THERMOSTAT) && (device_id < 0x19) && ((actual_master_thermostat == EMSESP_DEFAULT_MASTER_THERMOSTAT) || (device_id < actual_master_thermostat)))) { + || ((master_thermostat == EMSESP_DEFAULT_MASTER_THERMOSTAT) && (device_id < 0x19) + && ((actual_master_thermostat == EMSESP_DEFAULT_MASTER_THERMOSTAT) || (device_id < actual_master_thermostat)))) { EMSESP::actual_master_thermostat(device_id); actual_master_thermostat = device_id; reserve_telgram_functions(25); // reserve some space for the telegram registries, to avoid memory fragmentation @@ -960,7 +961,7 @@ void Thermostat::process_RC35Set(std::shared_ptr telegram) { has_update(telegram->read_value(hc->control, 26)); // 0-off, 1-RC20 (remote), 2-RC35 has_update(telegram->read_value(hc->controlmode, 33)); // 0-outdoortemp, 1-roomtemp has_update(telegram->read_value(hc->tempautotemp, 37)); - has_update(telegram->read_value(hc->noreducetemp, 38)); // outdoor temperature for no reduce + has_update(telegram->read_value(hc->noreducetemp, 38)); // outdoor temperature for no reduce has_update(telegram->read_value(hc->minflowtemp, 16)); if (hc->heatingtype == 3) { has_update(telegram->read_value(hc->designtemp, 36)); // is * 1 @@ -1970,7 +1971,10 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co // if we know what to send and to where, go and do it if (offset != -1) { char s[10]; - LOG_INFO(F("Setting thermostat temperature to %s for heating circuit %d, mode %s"), Helpers::render_value(s, temperature, 2), hc->hc_num(), mode_tostring(mode).c_str()); + LOG_INFO(F("Setting thermostat temperature to %s for heating circuit %d, mode %s"), + Helpers::render_value(s, temperature, 2), + hc->hc_num(), + mode_tostring(mode).c_str()); // add the write command to the Tx queue. value is *2 // post validate is the corresponding monitor or set type IDs as they can differ per model @@ -2084,11 +2088,19 @@ void Thermostat::register_device_values() { register_device_value(TAG_THERMOSTAT_DATA, &floordrystatus_, DeviceValueType::ENUM, FL_(enum_floordrystatus), FL_(floordrystatus), DeviceValueUOM::NONE); register_device_value(TAG_THERMOSTAT_DATA, &dampedoutdoortemp2_, DeviceValueType::SHORT, FL_(div10), FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES); register_device_value(TAG_THERMOSTAT_DATA, &floordrytemp_, DeviceValueType::UINT, nullptr, FL_(floordrytemp), DeviceValueUOM::DEGREES); - register_device_value(TAG_THERMOSTAT_DATA, &ibaBuildingType_, DeviceValueType::ENUM, FL_(enum_ibaBuildingType), FL_(ibaBuildingType), DeviceValueUOM::NONE, MAKE_CF_CB(set_building)); + register_device_value(TAG_THERMOSTAT_DATA, + &ibaBuildingType_, + DeviceValueType::ENUM, + FL_(enum_ibaBuildingType), + FL_(ibaBuildingType), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_building)); register_device_value(TAG_DEVICE_DATA_WW, &wwSetTemp_, DeviceValueType::UINT, nullptr, FL_(wwSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemp)); register_device_value(TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - register_device_value(TAG_DEVICE_DATA_WW, &wwSetTempLow_, DeviceValueType::UINT, nullptr, FL_(wwSetTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemplow)); - register_device_value(TAG_DEVICE_DATA_WW, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wWCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); + register_device_value( + TAG_DEVICE_DATA_WW, &wwSetTempLow_, DeviceValueType::UINT, nullptr, FL_(wwSetTempLow), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwtemplow)); + register_device_value( + TAG_DEVICE_DATA_WW, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wWCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); register_device_value(TAG_DEVICE_DATA_WW, &wwExtra1_, DeviceValueType::UINT, nullptr, FL_(wwExtra1), DeviceValueUOM::DEGREES); register_device_value(TAG_DEVICE_DATA_WW, &wwExtra2_, DeviceValueType::UINT, nullptr, FL_(wwExtra2), DeviceValueUOM::DEGREES); break; @@ -2100,24 +2112,67 @@ void Thermostat::register_device_values() { register_device_value(TAG_THERMOSTAT_DATA, &dateTime_, DeviceValueType::TEXT, nullptr, FL_(dateTime), DeviceValueUOM::NONE); // can't set datetime register_device_value(TAG_THERMOSTAT_DATA, &ibaMainDisplay_, DeviceValueType::ENUM, FL_(enum_ibaMainDisplay), FL_(ibaMainDisplay), DeviceValueUOM::NONE); register_device_value(TAG_THERMOSTAT_DATA, &ibaLanguage_, DeviceValueType::ENUM, FL_(enum_ibaLanguage), FL_(ibaLanguage), DeviceValueUOM::NONE); - register_device_value(TAG_THERMOSTAT_DATA, &ibaClockOffset_, DeviceValueType::UINT, nullptr, FL_(ibaClockOffset), DeviceValueUOM::NONE); // offset (in sec) to clock, 0xff=-1s, 0x02=2s - register_device_value(TAG_THERMOSTAT_DATA, &ibaCalIntTemperature_, DeviceValueType::INT, FL_(div2), FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_calinttemp)); - register_device_value(TAG_THERMOSTAT_DATA, &ibaMinExtTemperature_, DeviceValueType::INT, nullptr, FL_(ibaMinExtTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp)); + register_device_value(TAG_THERMOSTAT_DATA, + &ibaClockOffset_, + DeviceValueType::UINT, + nullptr, + FL_(ibaClockOffset), + DeviceValueUOM::NONE); // offset (in sec) to clock, 0xff=-1s, 0x02=2s + register_device_value(TAG_THERMOSTAT_DATA, + &ibaCalIntTemperature_, + DeviceValueType::INT, + FL_(div2), + FL_(ibaCalIntTemperature), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_calinttemp)); + register_device_value(TAG_THERMOSTAT_DATA, + &ibaMinExtTemperature_, + DeviceValueType::INT, + nullptr, + FL_(ibaMinExtTemperature), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_minexttemp)); register_device_value(TAG_THERMOSTAT_DATA, &dampedoutdoortemp_, DeviceValueType::INT, nullptr, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES); - register_device_value(TAG_THERMOSTAT_DATA, &ibaBuildingType_, DeviceValueType::ENUM, FL_(enum_ibaBuildingType2), FL_(ibaBuildingType), DeviceValueUOM::NONE, MAKE_CF_CB(set_building)); + register_device_value(TAG_THERMOSTAT_DATA, + &ibaBuildingType_, + DeviceValueType::ENUM, + FL_(enum_ibaBuildingType2), + FL_(ibaBuildingType), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_building)); register_device_value(TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - register_device_value(TAG_DEVICE_DATA_WW, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode2), FL_(wWCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); + register_device_value( + TAG_DEVICE_DATA_WW, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode2), FL_(wWCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); break; case EMS_DEVICE_FLAG_RC35: register_device_value(TAG_THERMOSTAT_DATA, &dateTime_, DeviceValueType::TEXT, nullptr, FL_(dateTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_datetime)); - register_device_value(TAG_THERMOSTAT_DATA, &ibaCalIntTemperature_, DeviceValueType::INT, FL_(div2), FL_(ibaCalIntTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_calinttemp)); - register_device_value(TAG_THERMOSTAT_DATA, &ibaMinExtTemperature_, DeviceValueType::INT, nullptr, FL_(ibaMinExtTemperature), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_minexttemp)); + register_device_value(TAG_THERMOSTAT_DATA, + &ibaCalIntTemperature_, + DeviceValueType::INT, + FL_(div2), + FL_(ibaCalIntTemperature), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_calinttemp)); + register_device_value(TAG_THERMOSTAT_DATA, + &ibaMinExtTemperature_, + DeviceValueType::INT, + nullptr, + FL_(ibaMinExtTemperature), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_minexttemp)); register_device_value(TAG_THERMOSTAT_DATA, &tempsensor1_, DeviceValueType::USHORT, FL_(div10), FL_(tempsensor1), DeviceValueUOM::DEGREES); register_device_value(TAG_THERMOSTAT_DATA, &tempsensor2_, DeviceValueType::USHORT, FL_(div10), FL_(tempsensor2), DeviceValueUOM::DEGREES); register_device_value(TAG_THERMOSTAT_DATA, &dampedoutdoortemp_, DeviceValueType::INT, nullptr, FL_(dampedoutdoortemp), DeviceValueUOM::DEGREES); - register_device_value(TAG_THERMOSTAT_DATA, &ibaBuildingType_, DeviceValueType::ENUM, FL_(enum_ibaBuildingType2), FL_(ibaBuildingType), DeviceValueUOM::NONE, MAKE_CF_CB(set_building)); + register_device_value(TAG_THERMOSTAT_DATA, + &ibaBuildingType_, + DeviceValueType::ENUM, + FL_(enum_ibaBuildingType2), + FL_(ibaBuildingType), + DeviceValueUOM::NONE, + MAKE_CF_CB(set_building)); register_device_value(TAG_DEVICE_DATA_WW, &wwMode_, DeviceValueType::ENUM, FL_(enum_wwMode2), FL_(wwMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwmode)); - register_device_value(TAG_DEVICE_DATA_WW, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode2), FL_(wWCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); + register_device_value( + TAG_DEVICE_DATA_WW, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode2), FL_(wWCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwcircmode)); break; case EMS_DEVICE_FLAG_JUNKERS: register_device_value(TAG_THERMOSTAT_DATA, &dateTime_, DeviceValueType::TEXT, nullptr, FL_(dateTime), DeviceValueUOM::NONE, MAKE_CF_CB(set_datetime)); @@ -2128,7 +2183,7 @@ void Thermostat::register_device_values() { } // registers the values for a heating circuit -void Thermostat::register_device_values_hc(std::shared_ptr hc) { +void Thermostat::register_device_values_hc(std::shared_ptr hc) { uint8_t model = hc->get_model(); // heating circuit @@ -2151,8 +2206,17 @@ void Thermostat::register_device_values_hc(std::shared_ptrsetpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, FL_(setpoint_roomTemp), DeviceValueUOM::DEGREES); } else { - register_device_value(tag, &hc->setpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, FL_(setpoint_roomTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp), 5, 29); - register_device_value(tag, &hc->setpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, FL_(temp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp), 5, 29); + register_device_value(tag, + &hc->setpoint_roomTemp, + DeviceValueType::SHORT, + setpoint_temp_divider, + FL_(setpoint_roomTemp), + DeviceValueUOM::DEGREES, + MAKE_CF_CB(set_temp), + 5, + 29); + register_device_value( + tag, &hc->setpoint_roomTemp, DeviceValueType::SHORT, setpoint_temp_divider, FL_(temp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_temp), 5, 29); } register_device_value(tag, &hc->curr_roomTemp, DeviceValueType::SHORT, curr_temp_divider, FL_(curr_roomTemp), DeviceValueUOM::DEGREES); @@ -2195,9 +2259,11 @@ void Thermostat::register_device_values_hc(std::shared_ptrnofrosttemp, DeviceValueType::INT, nullptr, FL_(nofrosttemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_nofrosttemp)); register_device_value(tag, &hc->targetflowtemp, DeviceValueType::UINT, nullptr, FL_(targetflowtemp), DeviceValueUOM::DEGREES); register_device_value(tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE); - register_device_value(tag, &hc->summer_setmode, DeviceValueType::ENUM, FL_(enum_summermode), FL_(summermode), DeviceValueUOM::NONE, MAKE_CF_CB(set_summermode)); + register_device_value( + tag, &hc->summer_setmode, DeviceValueType::ENUM, FL_(enum_summermode), FL_(summermode), DeviceValueUOM::NONE, MAKE_CF_CB(set_summermode)); register_device_value(tag, &hc->summermode, DeviceValueType::BOOL, nullptr, FL_(summermode), DeviceValueUOM::NONE); - register_device_value(tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode)); + register_device_value( + tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode)); register_device_value(tag, &hc->program, DeviceValueType::UINT, nullptr, FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->tempautotemp, DeviceValueType::UINT, FL_(div2), FL_(tempautotemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_tempautotemp)); break; @@ -2231,7 +2297,8 @@ void Thermostat::register_device_values_hc(std::shared_ptrflowtempoffset, DeviceValueType::UINT, nullptr, FL_(flowtempoffset), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowtempoffset)); register_device_value(tag, &hc->heatingtype, DeviceValueType::ENUM, FL_(enum_heatingtype), FL_(heatingtype), DeviceValueUOM::NONE); register_device_value(tag, &hc->reducemode, DeviceValueType::ENUM, FL_(enum_reducemode), FL_(reducemode), DeviceValueUOM::NONE, MAKE_CF_CB(set_reducemode)); - register_device_value(tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode2), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode)); + register_device_value( + tag, &hc->controlmode, DeviceValueType::ENUM, FL_(enum_controlmode2), FL_(controlmode), DeviceValueUOM::NONE, MAKE_CF_CB(set_controlmode)); register_device_value(tag, &hc->control, DeviceValueType::ENUM, FL_(enum_control), FL_(control), DeviceValueUOM::NONE, MAKE_CF_CB(set_control)); register_device_value(tag, &hc->program, DeviceValueType::UINT, nullptr, FL_(program), DeviceValueUOM::NONE, MAKE_CF_CB(set_program)); register_device_value(tag, &hc->pause, DeviceValueType::UINT, nullptr, FL_(pause), DeviceValueUOM::HOURS, MAKE_CF_CB(set_pause)); diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index c8ef0bd0b..b3059decf 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -147,7 +147,7 @@ class Thermostat : public EMSdevice { char dummychar_[5]; // for commands with no output // Installation parameters - uint8_t ibaMainDisplay_; // display on Thermostat: 0 int temp, 1 int setpoint, 2 ext temp, 3 burner temp, 4 ww temp, 5 functioning mode, 6 time, 7 data, 9 smoke temp + uint8_t ibaMainDisplay_; // display on Thermostat: 0 int temp, 1 int setpoint, 2 ext temp, 3 burner temp, 4 ww temp, 5 functioning mode, 6 time, 7 data, 9 smoke temp uint8_t ibaLanguage_; // language on Thermostat: 0 german, 1 dutch, 2 french, 3 italian int8_t ibaCalIntTemperature_; // offset int. temperature sensor, by * 0.1 Kelvin (-5.0 to 5.0K) int8_t ibaMinExtTemperature_; // min ext temp for heating curve, in deg., 0xF6=-10, 0x0 = 0, 0xFF=-1 @@ -254,7 +254,7 @@ class Thermostat : public EMSdevice { std::shared_ptr heating_circuit(const uint8_t hc_num); void register_mqtt_ha_config_hc(uint8_t hc_num); - void register_device_values_hc(std::shared_ptr hc); + void register_device_values_hc(std::shared_ptr hc); bool thermostat_ha_cmd(const char * message, uint8_t hc_num); diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 40b0bd627..eb7f1fa9b 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -298,7 +298,14 @@ std::string EMSdevice::to_string() const { if (brand_ == Brand::NO_BRAND) { snprintf_P(&str[0], str.capacity() + 1, PSTR("%s (DeviceID:0x%02X, ProductID:%d, Version:%s)"), name_.c_str(), device_id_, product_id_, version_.c_str()); } else { - snprintf_P(&str[0], str.capacity() + 1, PSTR("%s %s (DeviceID:0x%02X ProductID:%d, Version:%s)"), brand_to_string().c_str(), name_.c_str(), device_id_, product_id_, version_.c_str()); + snprintf_P(&str[0], + str.capacity() + 1, + PSTR("%s %s (DeviceID:0x%02X ProductID:%d, Version:%s)"), + brand_to_string().c_str(), + name_.c_str(), + device_id_, + product_id_, + version_.c_str()); } return str; @@ -470,7 +477,15 @@ void EMSdevice::register_device_value(uint8_t tag, devicevalues_.emplace_back(device_type_, tag, value_p, type, options, options_size, short_name, full_name, uom, 0, has_cmd, min, max); } -void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * const * name, uint8_t uom, cmdfunction_p f, int32_t min, uint32_t max) { +void EMSdevice::register_device_value(uint8_t tag, + void * value_p, + uint8_t type, + const __FlashStringHelper * const * options, + const __FlashStringHelper * const * name, + uint8_t uom, + cmdfunction_p f, + int32_t min, + uint32_t max) { register_device_value(tag, value_p, type, options, name[0], name[1], uom, (f != nullptr), min, max); if (f != nullptr) { if (tag >= TAG_HC1 && tag <= TAG_HC4) { @@ -481,7 +496,13 @@ void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, } } -void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * const * name, uint8_t uom, cmdfunction_p f) { +void EMSdevice::register_device_value(uint8_t tag, + void * value_p, + uint8_t type, + const __FlashStringHelper * const * options, + const __FlashStringHelper * const * name, + uint8_t uom, + cmdfunction_p f) { register_device_value(tag, value_p, type, options, name, uom, f, 0, 0); } @@ -489,7 +510,12 @@ void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, // register_device_value(tag, value_p, type, options, name, uom, nullptr, min, max); // } -void EMSdevice::register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * const * name, uint8_t uom) { +void EMSdevice::register_device_value(uint8_t tag, + void * value_p, + uint8_t type, + const __FlashStringHelper * const * options, + const __FlashStringHelper * const * name, + uint8_t uom) { register_device_value(tag, value_p, type, options, name, uom, nullptr, 0, 0); } @@ -657,7 +683,7 @@ bool EMSdevice::get_value_info(JsonObject & root, const char * cmd, const int8_t const char * max = "max"; const char * value = "value"; - json["name"] = dv.short_name; + json["name"] = dv.short_name; if (!tag_to_mqtt(dv.tag).empty()) { json["circuit"] = tag_to_mqtt(dv.tag); } @@ -811,7 +837,8 @@ bool EMSdevice::generate_values_json(JsonObject & root, const uint8_t tag_filter // only show if tag is either empty (TAG_NONE) or matches a value // and don't show if full_name is empty unless we're outputing for mqtt payloads // for nested we use all values, dont show command only (have_cmd and no fulname) - if (((nested) || tag_filter == DeviceValueTAG::TAG_NONE || (tag_filter == dv.tag)) && (dv.full_name != nullptr || !console) && !(dv.full_name == nullptr && dv.has_cmd)) { + if (((nested) || tag_filter == DeviceValueTAG::TAG_NONE || (tag_filter == dv.tag)) && (dv.full_name != nullptr || !console) + && !(dv.full_name == nullptr && dv.has_cmd)) { // we have a tag if it matches the filter given, and that the tag name is not empty/"" bool have_tag = ((dv.tag != tag_filter) && !tag_to_string(dv.tag).empty()); diff --git a/src/emsdevice.h b/src/emsdevice.h index 06d54d7fd..06ffc2c80 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -232,9 +232,28 @@ class EMSdevice { bool has_cmd, int32_t min, uint32_t max); - void register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * const * name, uint8_t uom, cmdfunction_p f, int32_t min, uint32_t max); - void register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * const * name, uint8_t uom, cmdfunction_p f); - void register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * const * name, uint8_t uom); + void register_device_value(uint8_t tag, + void * value_p, + uint8_t type, + const __FlashStringHelper * const * options, + const __FlashStringHelper * const * name, + uint8_t uom, + cmdfunction_p f, + int32_t min, + uint32_t max); + void register_device_value(uint8_t tag, + void * value_p, + uint8_t type, + const __FlashStringHelper * const * options, + const __FlashStringHelper * const * name, + uint8_t uom, + cmdfunction_p f); + void register_device_value(uint8_t tag, + void * value_p, + uint8_t type, + const __FlashStringHelper * const * options, + const __FlashStringHelper * const * name, + uint8_t uom); // void register_device_value(uint8_t tag, void * value_p, uint8_t type, const __FlashStringHelper * const * options, const __FlashStringHelper * const * name, uint8_t uom, int32_t min, uint32_t max); void write_command(const uint16_t type_id, const uint8_t offset, uint8_t * message_data, const uint8_t message_length, const uint16_t validate_typeid); diff --git a/src/emsesp.h b/src/emsesp.h index b49872c4d..6d1e4ac05 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -93,7 +93,12 @@ class EMSESP { static std::string pretty_telegram(std::shared_ptr telegram); static void send_read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset = 0, const uint8_t length = 0); - static void send_write_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, uint8_t * message_data, const uint8_t message_length, const uint16_t validate_typeid); + static void send_write_request(const uint16_t type_id, + const uint8_t dest, + const uint8_t offset, + uint8_t * message_data, + const uint8_t message_length, + const uint16_t validate_typeid); static void send_write_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t value); static void send_write_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, const uint8_t value, const uint16_t validate_typeid); diff --git a/src/helpers.cpp b/src/helpers.cpp index 24dc075bc..1474fe9a3 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -478,7 +478,8 @@ bool Helpers::value2enum(const char * v, uint8_t & value, const __FlashStringHel std::string str = toLower(v); for (value = 0; strs[value]; value++) { std::string str1 = toLower(uuid::read_flash_string(strs[value])); - if ((str1 == uuid::read_flash_string(F_(off)) && str == "false") || (str1 == uuid::read_flash_string(F_(on)) && str == "true") || (str == str1) || (v[0] == ('0' + value) && v[1] == '\0')) { + if ((str1 == uuid::read_flash_string(F_(off)) && str == "false") || (str1 == uuid::read_flash_string(F_(on)) && str == "true") || (str == str1) + || (v[0] == ('0' + value) && v[1] == '\0')) { return true; } } diff --git a/src/locale_EN.h b/src/locale_EN.h index 7b6a36eda..f6ec5713e 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -283,7 +283,16 @@ MAKE_PSTR(functioning_mode, "functioning mode") MAKE_PSTR(smoke_temperature, "smoke temperature") // thermostat lists -MAKE_PSTR_LIST(enum_ibaMainDisplay, F_(internal_temperature), F_(internal_setpoint), F_(external_temperature), F_(burner_temperature), F_(ww_temperature), F_(functioning_mode), F_(time), F_(date), F_(smoke_temperature)) +MAKE_PSTR_LIST(enum_ibaMainDisplay, + F_(internal_temperature), + F_(internal_setpoint), + F_(external_temperature), + F_(burner_temperature), + F_(ww_temperature), + F_(functioning_mode), + F_(time), + F_(date), + F_(smoke_temperature)) MAKE_PSTR_LIST(enum_ibaLanguage, F_(german), F_(dutch), F_(french), F_(italian)) MAKE_PSTR_LIST(enum_floordrystatus, F_(off), F_(start), F_(heat), F_(hold), F_(cool), F_(end)) MAKE_PSTR_LIST(enum_ibaBuildingType, F_(blank), F_(light), F_(medium), F_(heavy)) // RC300 diff --git a/src/mqtt.cpp b/src/mqtt.cpp index b701929b1..3b0df514e 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -228,12 +228,27 @@ void Mqtt::show_mqtt(uuid::console::Shell & shell) { } for (const auto & cf : Command::commands()) { if (subscribe_format_ == 2 && cf.flag_ == MqttSubFlag::FLAG_HC) { - shell.printfln(F(" %s/%s/hc1/%s"), mqtt_base_.c_str(), EMSdevice::device_type_2_device_name(cf.device_type_).c_str(), uuid::read_flash_string(cf.cmd_).c_str()); - shell.printfln(F(" %s/%s/hc2/%s"), mqtt_base_.c_str(), EMSdevice::device_type_2_device_name(cf.device_type_).c_str(), uuid::read_flash_string(cf.cmd_).c_str()); - shell.printfln(F(" %s/%s/hc3/%s"), mqtt_base_.c_str(), EMSdevice::device_type_2_device_name(cf.device_type_).c_str(), uuid::read_flash_string(cf.cmd_).c_str()); - shell.printfln(F(" %s/%s/hc4/%s"), mqtt_base_.c_str(), EMSdevice::device_type_2_device_name(cf.device_type_).c_str(), uuid::read_flash_string(cf.cmd_).c_str()); + shell.printfln(F(" %s/%s/hc1/%s"), + mqtt_base_.c_str(), + EMSdevice::device_type_2_device_name(cf.device_type_).c_str(), + uuid::read_flash_string(cf.cmd_).c_str()); + shell.printfln(F(" %s/%s/hc2/%s"), + mqtt_base_.c_str(), + EMSdevice::device_type_2_device_name(cf.device_type_).c_str(), + uuid::read_flash_string(cf.cmd_).c_str()); + shell.printfln(F(" %s/%s/hc3/%s"), + mqtt_base_.c_str(), + EMSdevice::device_type_2_device_name(cf.device_type_).c_str(), + uuid::read_flash_string(cf.cmd_).c_str()); + shell.printfln(F(" %s/%s/hc4/%s"), + mqtt_base_.c_str(), + EMSdevice::device_type_2_device_name(cf.device_type_).c_str(), + uuid::read_flash_string(cf.cmd_).c_str()); } else if (subscribe_format_ && cf.flag_ != MqttSubFlag::FLAG_NOSUB) { - shell.printfln(F(" %s/%s/%s"), mqtt_base_.c_str(), EMSdevice::device_type_2_device_name(cf.device_type_).c_str(), uuid::read_flash_string(cf.cmd_).c_str()); + shell.printfln(F(" %s/%s/%s"), + mqtt_base_.c_str(), + EMSdevice::device_type_2_device_name(cf.device_type_).c_str(), + uuid::read_flash_string(cf.cmd_).c_str()); } } shell.println(); @@ -265,7 +280,12 @@ void Mqtt::show_mqtt(uuid::console::Shell & shell) { shell.printfln(F(" [%02d] (Pub) topic=%s payload=%s (pid %d)"), message.id_, topic, content->payload.c_str(), message.packet_id_); } } else { - shell.printfln(F(" [%02d] (Pub) topic=%s payload=%s (pid %d, retry #%d)"), message.id_, topic, content->payload.c_str(), message.packet_id_, message.retry_count_); + shell.printfln(F(" [%02d] (Pub) topic=%s payload=%s (pid %d, retry #%d)"), + message.id_, + topic, + content->payload.c_str(), + message.packet_id_, + message.retry_count_); } } else { // Subscribe messages @@ -400,7 +420,10 @@ void Mqtt::on_message(const char * fulltopic, const char * payload, size_t len) // print all the topics related to a specific device type void Mqtt::show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type) { - if (std::count_if(mqtt_subfunctions_.cbegin(), mqtt_subfunctions_.cend(), [=](MQTTSubFunction const & mqtt_subfunction) { return device_type == mqtt_subfunction.device_type_; }) == 0) { + if (std::count_if(mqtt_subfunctions_.cbegin(), + mqtt_subfunctions_.cend(), + [=](MQTTSubFunction const & mqtt_subfunction) { return device_type == mqtt_subfunction.device_type_; }) + == 0) { return; } @@ -851,7 +874,13 @@ void Mqtt::process_queue() { // else try and publish it uint16_t packet_id = mqttClient_->publish(topic, mqtt_qos_, message->retain, message->payload.c_str(), message->payload.size(), false, mqtt_message.id_); - LOG_DEBUG(F("Publishing topic %s (#%02d, retain=%d, try#%d, size %d, pid %d)"), topic, mqtt_message.id_, message->retain, mqtt_message.retry_count_ + 1, message->payload.size(), packet_id); + LOG_DEBUG(F("Publishing topic %s (#%02d, retain=%d, try#%d, size %d, pid %d)"), + topic, + mqtt_message.id_, + message->retain, + mqtt_message.retry_count_ + 1, + message->payload.size(), + packet_id); if (packet_id == 0) { // it failed. if we retried n times, give up. remove from queue diff --git a/src/mqtt.h b/src/mqtt.h index c45aded12..fde421eab 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -106,7 +106,12 @@ class Mqtt { static void publish_ha(const std::string & topic, const JsonObject & payload); static void publish_ha(const __FlashStringHelper * topic, const JsonObject & payload); - static void publish_mqtt_ha_sensor(uint8_t type, uint8_t tag, const __FlashStringHelper * name, const uint8_t device_type, const __FlashStringHelper * entity, const uint8_t uom = 0); + static void publish_mqtt_ha_sensor(uint8_t type, + uint8_t tag, + const __FlashStringHelper * name, + const uint8_t device_type, + const __FlashStringHelper * entity, + const uint8_t uom = 0); static void register_command(const uint8_t device_type, const __FlashStringHelper * cmd, cmdfunction_p cb, uint8_t tag = 0); static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type); diff --git a/src/system.cpp b/src/system.cpp index c0ea30677..8a6aa203b 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -860,7 +860,6 @@ bool System::command_settings(const char * value, const int8_t id, JsonObject & // export status information including some basic settings // e.g. http://ems-esp/api?device=system&cmd=info bool System::command_info(const char * value, const int8_t id, JsonObject & json) { - if (id == 0) { return EMSESP::system_.heartbeat_json(json); } diff --git a/src/telegram.cpp b/src/telegram.cpp index 113cbdfd0..97e61284e 100644 --- a/src/telegram.cpp +++ b/src/telegram.cpp @@ -22,15 +22,19 @@ namespace emsesp { // CRC lookup table with poly 12 for faster checking -const uint8_t ems_crc_table[] = {0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, - 0x3A, 0x3C, 0x3E, 0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 0x60, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72, - 0x74, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xAA, 0xAC, - 0xAE, 0xB0, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0xBE, 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, - 0xE8, 0xEA, 0xEC, 0xEE, 0xF0, 0xF2, 0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFE, 0x19, 0x1B, 0x1D, 0x1F, 0x11, 0x13, 0x15, 0x17, 0x09, 0x0B, 0x0D, 0x0F, 0x01, 0x03, 0x05, 0x07, 0x39, - 0x3B, 0x3D, 0x3F, 0x31, 0x33, 0x35, 0x37, 0x29, 0x2B, 0x2D, 0x2F, 0x21, 0x23, 0x25, 0x27, 0x59, 0x5B, 0x5D, 0x5F, 0x51, 0x53, 0x55, 0x57, 0x49, 0x4B, 0x4D, 0x4F, 0x41, 0x43, - 0x45, 0x47, 0x79, 0x7B, 0x7D, 0x7F, 0x71, 0x73, 0x75, 0x77, 0x69, 0x6B, 0x6D, 0x6F, 0x61, 0x63, 0x65, 0x67, 0x99, 0x9B, 0x9D, 0x9F, 0x91, 0x93, 0x95, 0x97, 0x89, 0x8B, 0x8D, - 0x8F, 0x81, 0x83, 0x85, 0x87, 0xB9, 0xBB, 0xBD, 0xBF, 0xB1, 0xB3, 0xB5, 0xB7, 0xA9, 0xAB, 0xAD, 0xAF, 0xA1, 0xA3, 0xA5, 0xA7, 0xD9, 0xDB, 0xDD, 0xDF, 0xD1, 0xD3, 0xD5, 0xD7, - 0xC9, 0xCB, 0xCD, 0xCF, 0xC1, 0xC3, 0xC5, 0xC7, 0xF9, 0xFB, 0xFD, 0xFF, 0xF1, 0xF3, 0xF5, 0xF7, 0xE9, 0xEB, 0xED, 0xEF, 0xE1, 0xE3, 0xE5, 0xE7}; +const uint8_t ems_crc_table[] = {0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26, + 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E, 0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, + 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E, 0x60, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72, 0x74, 0x76, + 0x78, 0x7A, 0x7C, 0x7E, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, + 0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xAA, 0xAC, 0xAE, 0xB0, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0xBE, 0xC0, 0xC2, 0xC4, 0xC6, + 0xC8, 0xCA, 0xCC, 0xCE, 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, + 0xF0, 0xF2, 0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFE, 0x19, 0x1B, 0x1D, 0x1F, 0x11, 0x13, 0x15, 0x17, 0x09, 0x0B, 0x0D, 0x0F, + 0x01, 0x03, 0x05, 0x07, 0x39, 0x3B, 0x3D, 0x3F, 0x31, 0x33, 0x35, 0x37, 0x29, 0x2B, 0x2D, 0x2F, 0x21, 0x23, 0x25, 0x27, + 0x59, 0x5B, 0x5D, 0x5F, 0x51, 0x53, 0x55, 0x57, 0x49, 0x4B, 0x4D, 0x4F, 0x41, 0x43, 0x45, 0x47, 0x79, 0x7B, 0x7D, 0x7F, + 0x71, 0x73, 0x75, 0x77, 0x69, 0x6B, 0x6D, 0x6F, 0x61, 0x63, 0x65, 0x67, 0x99, 0x9B, 0x9D, 0x9F, 0x91, 0x93, 0x95, 0x97, + 0x89, 0x8B, 0x8D, 0x8F, 0x81, 0x83, 0x85, 0x87, 0xB9, 0xBB, 0xBD, 0xBF, 0xB1, 0xB3, 0xB5, 0xB7, 0xA9, 0xAB, 0xAD, 0xAF, + 0xA1, 0xA3, 0xA5, 0xA7, 0xD9, 0xDB, 0xDD, 0xDF, 0xD1, 0xD3, 0xD5, 0xD7, 0xC9, 0xCB, 0xCD, 0xCF, 0xC1, 0xC3, 0xC5, 0xC7, + 0xF9, 0xFB, 0xFD, 0xFF, 0xF1, 0xF3, 0xF5, 0xF7, 0xE9, 0xEB, 0xED, 0xEF, 0xE1, 0xE3, 0xE5, 0xE7}; uint32_t EMSbus::last_bus_activity_ = 0; // timestamp of last time a valid Rx came in bool EMSbus::bus_connected_ = false; // start assuming the bus hasn't been connected @@ -55,7 +59,13 @@ uint8_t EMSbus::calculate_crc(const uint8_t * data, const uint8_t length) { // creates a telegram object // stores header in separate member objects and the rest in the message_data block -Telegram::Telegram(const uint8_t operation, const uint8_t src, const uint8_t dest, const uint16_t type_id, const uint8_t offset, const uint8_t * data, const uint8_t message_length) +Telegram::Telegram(const uint8_t operation, + const uint8_t src, + const uint8_t dest, + const uint16_t type_id, + const uint8_t offset, + const uint8_t * data, + const uint8_t message_length) : operation(operation) , src(src) , dest(dest) @@ -192,7 +202,8 @@ void RxService::add(uint8_t * data, uint8_t length) { // if we're watching and "raw" print out actual telegram as bytes to the console if (EMSESP::watch() == EMSESP::Watch::WATCH_RAW) { uint16_t trace_watch_id = EMSESP::watch_id(); - if ((trace_watch_id == WATCH_ID_NONE) || (type_id == trace_watch_id) || ((trace_watch_id < 0x80) && ((src == trace_watch_id) || (dest == trace_watch_id)))) { + if ((trace_watch_id == WATCH_ID_NONE) || (type_id == trace_watch_id) + || ((trace_watch_id < 0x80) && ((src == trace_watch_id) || (dest == trace_watch_id)))) { LOG_NOTICE(F("Rx: %s"), Helpers::data_to_hex(data, length).c_str()); } else if (EMSESP::trace_raw()) { LOG_TRACE(F("Rx: %s"), Helpers::data_to_hex(data, length).c_str()); @@ -349,7 +360,10 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) { length++; // add one since we want to now include the CRC - LOG_DEBUG(F("Sending %s Tx [#%d], telegram: %s"), (telegram->operation == Telegram::Operation::TX_WRITE) ? F("write") : F("read"), tx_telegram.id_, Helpers::data_to_hex(telegram_raw, length).c_str()); + LOG_DEBUG(F("Sending %s Tx [#%d], telegram: %s"), + (telegram->operation == Telegram::Operation::TX_WRITE) ? F("write") : F("read"), + tx_telegram.id_, + Helpers::data_to_hex(telegram_raw, length).c_str()); set_post_send_query(tx_telegram.validateid_); // send the telegram to the UART Tx @@ -389,7 +403,14 @@ void TxService::send_telegram(const uint8_t * data, const uint8_t length) { } */ -void TxService::add(const uint8_t operation, const uint8_t dest, const uint16_t type_id, const uint8_t offset, uint8_t * message_data, const uint8_t message_length, const uint16_t validateid, const bool front) { +void TxService::add(const uint8_t operation, + const uint8_t dest, + const uint16_t type_id, + const uint8_t offset, + uint8_t * message_data, + const uint8_t message_length, + const uint16_t validateid, + const bool front) { auto telegram = std::make_shared(operation, ems_bus_id(), dest, type_id, offset, message_data, message_length); #ifdef EMSESP_DEBUG @@ -546,7 +567,9 @@ void TxService::retry_tx(const uint8_t operation, const uint8_t * data, const ui reset_retry_count(); // give up increment_telegram_fail_count(); // another Tx fail - LOG_ERROR(F("Last Tx %s operation failed after %d retries. Ignoring request."), (operation == Telegram::Operation::TX_WRITE) ? F("Write") : F("Read"), MAXIMUM_TX_RETRIES); + LOG_ERROR(F("Last Tx %s operation failed after %d retries. Ignoring request."), + (operation == Telegram::Operation::TX_WRITE) ? F("Write") : F("Read"), + MAXIMUM_TX_RETRIES); return; } diff --git a/src/telegram.h b/src/telegram.h index b10f52a2e..7891a1090 100644 --- a/src/telegram.h +++ b/src/telegram.h @@ -55,7 +55,13 @@ namespace emsesp { class Telegram { public: - Telegram(const uint8_t operation, const uint8_t src, const uint8_t dest, const uint16_t type_id, const uint8_t offset, const uint8_t * message_data, const uint8_t message_length); + Telegram(const uint8_t operation, + const uint8_t src, + const uint8_t dest, + const uint16_t type_id, + const uint8_t offset, + const uint8_t * message_data, + const uint8_t message_length); ~Telegram() = default; const uint8_t operation; // is Operation mode @@ -262,7 +268,14 @@ class TxService : public EMSbus { void start(); void send(); - void add(const uint8_t operation, const uint8_t dest, const uint16_t type_id, const uint8_t offset, uint8_t * message_data, const uint8_t message_length, const uint16_t validateid, const bool front = false); + void add(const uint8_t operation, + const uint8_t dest, + const uint16_t type_id, + const uint8_t offset, + uint8_t * message_data, + const uint8_t message_length, + const uint16_t validateid, + const bool front = false); void add(const uint8_t operation, const uint8_t * data, const uint8_t length, const uint16_t validateid, const bool front = false); void read_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset = 0, const uint8_t length = 0); void send_raw(const char * telegram_data); diff --git a/src/uart/emsuart_esp32.cpp b/src/uart/emsuart_esp32.cpp index 63cc8a9fa..df80308d9 100644 --- a/src/uart/emsuart_esp32.cpp +++ b/src/uart/emsuart_esp32.cpp @@ -102,10 +102,10 @@ void EMSuart::start(const uint8_t tx_mode, const uint8_t rx_gpio, const uint8_t uart_param_config(EMSUART_UART, &uart_config); uart_set_pin(EMSUART_UART, tx_gpio, rx_gpio, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); - EMS_UART.int_ena.val = 0; // disable all intr. - EMS_UART.int_clr.val = 0xFFFFFFFF; // clear all intr. flags - EMS_UART.idle_conf.tx_brk_num = 10; // breaklength 10 bit - drop_next_rx_ = true; + EMS_UART.int_ena.val = 0; // disable all intr. + EMS_UART.int_clr.val = 0xFFFFFFFF; // clear all intr. flags + EMS_UART.idle_conf.tx_brk_num = 10; // breaklength 10 bit + drop_next_rx_ = true; // EMS_UART.idle_conf.rx_idle_thrhd = 256; // EMS_UART.auto_baud.glitch_filt = 192; #if (EMSUART_UART != UART_NUM_2) @@ -140,7 +140,6 @@ void EMSuart::restart() { EMS_UART.int_ena.brk_det = 1; // activate only break EMS_UART.conf0.txd_brk = (tx_mode_ == EMS_TXMODE_HW) ? 1 : 0; portEXIT_CRITICAL(&mux_); - } /* From 23218bca7ddcac082ef97eea9c06e05cc559834d Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 2 May 2021 22:07:22 +0200 Subject: [PATCH 004/114] some minor formatting --- interface/src/project/EMSESPHelp.tsx | 4 +- lib/framework/AuthenticationService.cpp | 2 +- lib/framework/ESP8266React.cpp | 5 +++ lib/framework/FeaturesService.h | 2 +- lib/framework/SecurityManager.h | 2 +- src/test/test.cpp | 59 ++++++++++++++++--------- src/test/test.h | 6 +-- 7 files changed, 52 insertions(+), 28 deletions(-) diff --git a/interface/src/project/EMSESPHelp.tsx b/interface/src/project/EMSESPHelp.tsx index 52f890122..afd1a5a5e 100644 --- a/interface/src/project/EMSESPHelp.tsx +++ b/interface/src/project/EMSESPHelp.tsx @@ -52,7 +52,7 @@ class EMSESPHelp extends Component { - To list your system settings {'click here'} + To export your system settings {'click here'} @@ -62,7 +62,7 @@ class EMSESPHelp extends Component { - To create a report of the current EMS-ESP status {'click here'} + To export the current status of EMS-ESP {'click here'} diff --git a/lib/framework/AuthenticationService.cpp b/lib/framework/AuthenticationService.cpp index 3886e1c58..21cedc5ae 100644 --- a/lib/framework/AuthenticationService.cpp +++ b/lib/framework/AuthenticationService.cpp @@ -14,7 +14,7 @@ AuthenticationService::AuthenticationService(AsyncWebServer * server, SecurityMa } /** - * Verifys that the request supplied a valid JWT. + * Verifies that the request supplied a valid JWT. */ void AuthenticationService::verifyAuthorization(AsyncWebServerRequest * request) { Authentication authentication = _securityManager->authenticateRequest(request); diff --git a/lib/framework/ESP8266React.cpp b/lib/framework/ESP8266React.cpp index 56ab52c13..df598805c 100644 --- a/lib/framework/ESP8266React.cpp +++ b/lib/framework/ESP8266React.cpp @@ -40,6 +40,11 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) }); } }); + + // only added for local testing (CORS) + // DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization"); + // DefaultHeaders::Instance().addHeader("Access-Control-Allow-Credentials", "true"); + // DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); } void ESP8266React::begin() { diff --git a/lib/framework/FeaturesService.h b/lib/framework/FeaturesService.h index 1c632a4a7..257d0e1cf 100644 --- a/lib/framework/FeaturesService.h +++ b/lib/framework/FeaturesService.h @@ -5,7 +5,7 @@ #include #include -#include // TODO needed for AsyncJsonResponse +#include #include #define MAX_FEATURES_SIZE 256 diff --git a/lib/framework/SecurityManager.h b/lib/framework/SecurityManager.h index 89c93e737..82eb516b1 100644 --- a/lib/framework/SecurityManager.h +++ b/lib/framework/SecurityManager.h @@ -5,7 +5,7 @@ #include #include #include -#include // TODO neede for AsyncJsonResponse +#include #include #ifndef FACTORY_JWT_SECRET diff --git a/src/test/test.cpp b/src/test/test.cpp index 2134daaec..dbe55ae24 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -37,7 +37,8 @@ bool Test::run_test(const char * command, int8_t id) { // add some data // Boiler -> Me, UBAMonitorFast(0x18), telegram: 08 00 18 00 00 02 5A 73 3D 0A 10 65 40 02 1A 80 00 01 E1 01 76 0E 3D 48 00 C9 44 02 00 (#data=25) - uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A, 0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00}); + uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A, + 0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00}); // Boiler -> Thermostat, UBAParameterWW(0x33), telegram: 08 97 33 00 23 24 (#data=2) uart_telegram({0x08, 0x98, 0x33, 0x00, 0x23, 0x24}); @@ -46,7 +47,8 @@ bool Test::run_test(const char * command, int8_t id) { uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00}); // Thermostat RCPLUSStatusMessage_HC1(0x01A5) - uart_telegram({0x98, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xCF, 0x21, 0x2E, 0x00, 0x00, 0x2E, 0x24, 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); + uart_telegram({0x98, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xCF, 0x21, 0x2E, 0x00, 0x00, 0x2E, 0x24, + 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); return true; } @@ -59,7 +61,8 @@ bool Test::run_test(const char * command, int8_t id) { // add some data // Boiler -> Me, UBAMonitorFast(0x18), telegram: 08 00 18 00 00 02 5A 73 3D 0A 10 65 40 02 1A 80 00 01 E1 01 76 0E 3D 48 00 C9 44 02 00 (#data=25) - uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A, 0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00}); + uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A, + 0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00}); // Boiler -> Thermostat, UBAParameterWW(0x33), telegram: 08 97 33 00 23 24 (#data=2) uart_telegram({0x08, 0x90, 0x33, 0x00, 0x23, 0x24}); @@ -68,7 +71,8 @@ bool Test::run_test(const char * command, int8_t id) { uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00}); // Thermostat 0x2A5 for HC1 - uart_telegram({0x10, 00, 0xFF, 00, 01, 0xA5, 0x80, 00, 01, 0x30, 0x28, 00, 0x30, 0x28, 01, 0x54, 03, 03, 01, 01, 0x54, 02, 0xA8, 00, 00, 0x11, 01, 03, 0xFF, 0xFF, 00}); + uart_telegram({0x10, 00, 0xFF, 00, 01, 0xA5, 0x80, 00, 01, 0x30, 0x28, 00, 0x30, 0x28, 01, 0x54, + 03, 03, 01, 01, 0x54, 02, 0xA8, 00, 00, 0x11, 01, 03, 0xFF, 0xFF, 00}); return true; } @@ -123,7 +127,8 @@ bool Test::run_test(const char * command, int8_t id) { uart_telegram({0x08, 0x0B, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70}); // Boiler -> Me, UBAMonitorFast(0x18), telegram: 08 00 18 00 00 02 5A 73 3D 0A 10 65 40 02 1A 80 00 01 E1 01 76 0E 3D 48 00 C9 44 02 00 (#data=25) - uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A, 0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00}); + uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A, + 0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00}); // Boiler -> Me, UBAParameterWW(0x33), telegram: 08 0B 33 00 08 FF 34 FB 00 28 00 00 46 00 FF FF 00 (#data=13) uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00}); @@ -150,9 +155,11 @@ bool Test::run_test(const char * command, int8_t id) { add_device(0x30, 163); // SM100 // SM100Monitor - type 0x0362 EMS+ - for SM100 and SM200 - uart_telegram({0xB0, 0x0B, 0xFF, 00, 0x02, 0x62, 00, 0x44, 0x02, 0x7A, 0x80, 00, 0x80, 0x00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 00, 0x7C, 0x80, 00, 0x80, 00, 0x80, 00, 0x80}); + uart_telegram({0xB0, 0x0B, 0xFF, 00, 0x02, 0x62, 00, 0x44, 0x02, 0x7A, 0x80, 00, 0x80, 0x00, 0x80, 00, + 0x80, 00, 0x80, 00, 0x80, 00, 00, 0x7C, 0x80, 00, 0x80, 00, 0x80, 00, 0x80}); - uart_telegram({0xB0, 0x0B, 0xFF, 0x00, 0x02, 0x62, 0x01, 0x44, 0x03, 0x30, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 0x33}); + uart_telegram({0xB0, 0x0B, 0xFF, 0x00, 0x02, 0x62, 0x01, 0x44, 0x03, 0x30, 0x80, 00, 0x80, 00, 0x80, 00, + 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 0x33}); uart_telegram({0xB0, 00, 0xFF, 0x18, 02, 0x62, 0x80, 00, 0xB8}); @@ -329,7 +336,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { // test call DynamicJsonDocument doc(EMSESP_JSON_SIZE_XLARGE_DYN); JsonObject json = doc.to(); - (void)emsesp::Command::call(EMSdevice::DeviceType::BOILER, "info", nullptr, -1, json); + Command::call(EMSdevice::DeviceType::BOILER, "info", nullptr, -1, json); #if defined(EMSESP_STANDALONE) Serial.print(COLOR_YELLOW); if (json.size() != 0) { @@ -477,7 +484,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { add_device(0x18, 202); // Bosch TC100 - https://github.com/emsesp/EMS-ESP/issues/474 // 0x0A - uart_telegram({0x98, 0x0B, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + uart_telegram({0x98, 0x0B, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); } if (command == "solar") { @@ -507,9 +515,11 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { // SM100Monitor - type 0x0362 EMS+ - for SM100 and SM200 // B0 0B FF 00 02 62 00 44 02 7A 80 00 80 00 80 00 80 00 80 00 80 00 00 7C 80 00 80 00 80 00 80 - rx_telegram({0xB0, 0x0B, 0xFF, 00, 0x02, 0x62, 00, 0x44, 0x02, 0x7A, 0x80, 00, 0x80, 0x00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 00, 0x7C, 0x80, 00, 0x80, 00, 0x80, 00, 0x80}); + rx_telegram({0xB0, 0x0B, 0xFF, 00, 0x02, 0x62, 00, 0x44, 0x02, 0x7A, 0x80, 00, 0x80, 0x00, 0x80, 00, + 0x80, 00, 0x80, 00, 0x80, 00, 00, 0x7C, 0x80, 00, 0x80, 00, 0x80, 00, 0x80}); - rx_telegram({0xB0, 0x0B, 0xFF, 0x00, 0x02, 0x62, 0x01, 0x44, 0x03, 0x30, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 0x33}); + rx_telegram({0xB0, 0x0B, 0xFF, 0x00, 0x02, 0x62, 0x01, 0x44, 0x03, 0x30, 0x80, 00, 0x80, 00, 0x80, 00, + 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 00, 0x80, 0x33}); rx_telegram({0xB0, 00, 0xFF, 0x18, 02, 0x62, 0x80, 00, 0xB8}); @@ -588,7 +598,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { // RCPLUSStatusMessage_HC1(0x01A5) // 98 00 FF 00 01 A5 00 CF 21 2E 00 00 2E 24 03 25 03 03 01 03 25 00 C8 00 00 11 01 03 (no CRC) - uart_telegram({0x98, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xCF, 0x21, 0x2E, 0x00, 0x00, 0x2E, 0x24, 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); + uart_telegram({0x98, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xCF, 0x21, 0x2E, 0x00, 0x00, 0x2E, 0x24, + 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); uart_telegram("98 00 FF 00 01 A5 00 CF 21 2E 00 00 2E 24 03 25 03 03 01 03 25 00 C8 00 00 11 01 03"); // without CRC uart_telegram_withCRC("98 00 FF 00 01 A6 00 CF 21 2E 00 00 2E 24 03 25 03 03 01 03 25 00 C8 00 00 11 01 03 6B"); // with CRC @@ -617,7 +628,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { // fake telegrams. length includes CRC // Boiler -> Me, UBAMonitorFast(0x18), telegram: 08 00 18 00 00 02 5A 73 3D 0A 10 65 40 02 1A 80 00 01 E1 01 76 0E 3D 48 00 C9 44 02 00 (#data=25) - uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A, 0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00}); + uart_telegram({0x08, 0x00, 0x18, 0x00, 0x00, 0x02, 0x5A, 0x73, 0x3D, 0x0A, 0x10, 0x65, 0x40, 0x02, 0x1A, + 0x80, 0x00, 0x01, 0xE1, 0x01, 0x76, 0x0E, 0x3D, 0x48, 0x00, 0xC9, 0x44, 0x02, 0x00}); // Boiler -> Thermostat, UBAParameterWW(0x33), telegram: 08 97 33 00 23 24 (#data=2) uart_telegram({0x08, 0x97, 0x33, 0x00, 0x23, 0x24}); @@ -643,10 +655,12 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { // Thermostat -> all, telegram: 10 00 FF 00 01 A5 00 D7 21 00 00 00 00 30 01 84 01 01 03 01 84 01 F1 00 00 11 01 00 08 63 00 // 0x1A5 test ems+ - uart_telegram({0x10, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xD7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x84, 0x01, 0x01, 0x03, 0x01, 0x84, 0x01, 0xF1, 0x00, 0x00, 0x11, 0x01, 0x00, 0x08, 0x63, 0x00}); + uart_telegram({0x10, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xD7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x84, + 0x01, 0x01, 0x03, 0x01, 0x84, 0x01, 0xF1, 0x00, 0x00, 0x11, 0x01, 0x00, 0x08, 0x63, 0x00}); // setting temp from 21.5 to 19.9C - uart_telegram({0x10, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xC7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x84, 0x01, 0x01, 0x03, 0x01, 0x84, 0x01, 0xF1, 0x00, 0x00, 0x11, 0x01, 0x00, 0x08, 0x63, 0x00}); + uart_telegram({0x10, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xC7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x84, + 0x01, 0x01, 0x03, 0x01, 0x84, 0x01, 0xF1, 0x00, 0x00, 0x11, 0x01, 0x00, 0x08, 0x63, 0x00}); // Thermostat -> Boiler, UBAFlags(0x35), telegram: 17 08 35 00 11 00 (#data=2) uart_telegram({0x17, 0x08, 0x35, 0x00, 0x11, 0x00}); @@ -655,10 +669,12 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { uart_telegram({0x17, 0x08, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00}); // Thermostat -> Me, RC20Set(0xA8), telegram: 17 0B A8 00 01 00 FF F6 01 06 00 01 0D 01 00 FF FF 01 02 02 02 00 00 05 1F 05 1F 02 0E 00 FF (#data=27) - uart_telegram({0x17, 0x0B, 0xA8, 0x00, 0x01, 0x00, 0xFF, 0xF6, 0x01, 0x06, 0x00, 0x01, 0x0D, 0x01, 0x00, 0xFF, 0xFF, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x05, 0x1F, 0x05, 0x1F, 0x02, 0x0E, 0x00, 0xFF}); + uart_telegram({0x17, 0x0B, 0xA8, 0x00, 0x01, 0x00, 0xFF, 0xF6, 0x01, 0x06, 0x00, 0x01, 0x0D, 0x01, 0x00, 0xFF, + 0xFF, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x05, 0x1F, 0x05, 0x1F, 0x02, 0x0E, 0x00, 0xFF}); // Boiler(0x08) -> All(0x00), UBAMonitorWW(0x34), data: 36 01 A5 80 00 21 00 00 01 00 01 3E 8D 03 77 91 00 80 00 - uart_telegram({0x08, 0x00, 0x34, 0x00, 0x36, 0x01, 0xA5, 0x80, 0x00, 0x21, 0x00, 0x00, 0x01, 0x00, 0x01, 0x3E, 0x8D, 0x03, 0x77, 0x91, 0x00, 0x80, 0x00}); + uart_telegram( + {0x08, 0x00, 0x34, 0x00, 0x36, 0x01, 0xA5, 0x80, 0x00, 0x21, 0x00, 0x00, 0x01, 0x00, 0x01, 0x3E, 0x8D, 0x03, 0x77, 0x91, 0x00, 0x80, 0x00}); // test 0x2A - DHWStatus3 uart_telegram({0x88, 00, 0x2A, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0xD2, 00, 00, 0x80, 00, 00, 01, 0x9D, 0x80, 0x00, 0x02, 0x79, 00}); @@ -686,7 +702,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { EMSESP::send_write_request(0x91, 0x17, 0x00, t18, sizeof(t18), 0x00); // TX - send EMS+ - const uint8_t t13[] = {0x90, 0x0B, 0xFF, 00, 01, 0xBA, 00, 0x2E, 0x2A, 0x26, 0x1E, 0x03, 00, 0xFF, 0xFF, 05, 0x2A, 01, 0xE1, 0x20, 0x01, 0x0F, 05, 0x2A}; + const uint8_t t13[] = {0x90, 0x0B, 0xFF, 00, 01, 0xBA, 00, 0x2E, 0x2A, 0x26, 0x1E, 0x03, + 00, 0xFF, 0xFF, 05, 0x2A, 01, 0xE1, 0x20, 0x01, 0x0F, 05, 0x2A}; EMSESP::txservice_.add(Telegram::Operation::TX_RAW, t13, sizeof(t13), 0); // EMS+ Junkers read request @@ -791,7 +808,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { add_device(0x18, 157); // Bosch CR100 - https://github.com/emsesp/EMS-ESP/issues/355 // RCPLUSStatusMessage_HC1(0x01A5) - HC1 - uart_telegram({0x98, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xCF, 0x21, 0x2E, 0x00, 0x00, 0x2E, 0x24, 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); + uart_telegram({0x98, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xCF, 0x21, 0x2E, 0x00, 0x00, 0x2E, 0x24, + 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); uart_telegram("98 00 FF 00 01 A5 00 CF 21 2E 00 00 2E 24 03 25 03 03 01 03 25 00 C8 00 00 11 01 03"); // without CRC uart_telegram_withCRC("98 00 FF 00 01 A5 00 CF 21 2E 00 00 2E 24 03 25 03 03 01 03 25 00 C8 00 00 11 01 03 13"); // with CRC @@ -858,7 +876,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd) { if (command == "rx2") { shell.printfln(F("Testing rx2...")); - uart_telegram({0x1B, 0x5B, 0xFD, 0x2D, 0x9E, 0x3A, 0xB6, 0xE5, 0x02, 0x20, 0x33, 0x30, 0x32, 0x3A, 0x20, 0x5B, 0x73, 0xFF, 0xFF, 0xCB, 0xDF, 0xB7, 0xA7, 0xB5, 0x67, 0x77, 0x77, 0xE4, 0xFF, 0xFD, 0x77, 0xFF}); + uart_telegram({0x1B, 0x5B, 0xFD, 0x2D, 0x9E, 0x3A, 0xB6, 0xE5, 0x02, 0x20, 0x33, 0x30, 0x32, 0x3A, 0x20, 0x5B, + 0x73, 0xFF, 0xFF, 0xCB, 0xDF, 0xB7, 0xA7, 0xB5, 0x67, 0x77, 0x77, 0xE4, 0xFF, 0xFD, 0x77, 0xFF}); } // https://github.com/emsesp/EMS-ESP/issues/380#issuecomment-633663007 diff --git a/src/test/test.h b/src/test/test.h index d023c5c6e..4c0b1edea 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -22,6 +22,7 @@ #define EMSESP_TEST_H #include "emsesp.h" +#include namespace emsesp { @@ -29,14 +30,13 @@ namespace emsesp { // #define EMSESP_DEBUG_DEFAULT "solar" // #define EMSESP_DEBUG_DEFAULT "mixer" // #define EMSESP_DEBUG_DEFAULT "web" -// #define EMSESP_DEBUG_DEFAULT "general" +#define EMSESP_DEBUG_DEFAULT "general" // #define EMSESP_DEBUG_DEFAULT "boiler" // #define EMSESP_DEBUG_DEFAULT "mqtt2" // #define EMSESP_DEBUG_DEFAULT "mqtt_nested" // #define EMSESP_DEBUG_DEFAULT "ha" // #define EMSESP_DEBUG_DEFAULT "board_profile" -#define EMSESP_DEBUG_DEFAULT "shower_alert" - +// #define EMSESP_DEBUG_DEFAULT "shower_alert" class Test { public: From 101978f713a901efda8e2105bb67224cae548693 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 2 May 2021 22:07:49 +0200 Subject: [PATCH 005/114] include fullname in info command --- src/emsdevice.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index eb7f1fa9b..abb7574e0 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -684,6 +684,9 @@ bool EMSdevice::get_value_info(JsonObject & root, const char * cmd, const int8_t const char * value = "value"; json["name"] = dv.short_name; + if (dv.full_name != nullptr) { + json["fullname"] = dv.full_name; + } if (!tag_to_mqtt(dv.tag).empty()) { json["circuit"] = tag_to_mqtt(dv.tag); } From 5339e0876e7c094b07e87f5fadad37ea92ba2b74 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 2 May 2021 22:08:53 +0200 Subject: [PATCH 006/114] feat: Adopt the OpenAPI 3.0 standard for the REST API #50 --- CHANGELOG_LATEST.md | 1 + doc/EMS-ESP32 API.md | 48 +-- interface/src/project/EMSESPSettingsForm.tsx | 8 +- interface/src/project/EMSESPtypes.ts | 2 +- lib_standalone/AsyncJson.h | 54 +++ lib_standalone/ESP8266React.h | 2 +- lib_standalone/ESPAsyncWebServer.h | 28 +- mock-api/server.js | 4 +- src/WebAPIService.cpp | 338 ++++++++++++++++--- src/WebAPIService.h | 40 ++- src/WebDevicesService.cpp | 2 +- src/WebSettingsService.cpp | 4 +- src/WebSettingsService.h | 2 +- src/default_settings.h | 4 +- src/emsesp.cpp | 40 ++- src/emsesp.h | 1 + src/version.h | 2 +- 17 files changed, 460 insertions(+), 120 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 0581d30d0..63fff129d 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -21,5 +21,6 @@ - Re-enabled Shower Alert (still experimental) - lowercased Flow temp in commands - system console commands to main +- new secure API ([#50](https://github.com/emsesp/EMS-ESP32/issues/50)) ## Removed diff --git a/doc/EMS-ESP32 API.md b/doc/EMS-ESP32 API.md index 90d51b0f2..1a8e6a6f6 100644 --- a/doc/EMS-ESP32 API.md +++ b/doc/EMS-ESP32 API.md @@ -15,8 +15,8 @@ OpenAPI is an open standard specification for describing REST APIs. From the [Op - Unless explicitly bypassed in the WebUI some operations required admin privileges in the form of an Access Token which can be generated from the Web UI's Security tab. An Access Token is a string 152 characters long. Token's do not expire. The token needs to be either embedded into the HTTP Header as `"Authorization: Bearer {ACCESS_TOKEN}"` or as query parameter `?access_token={ACCESS_TOKEN}`. To test you can use a command line instruction like ```bash - curl -i -H "Authorization: Bearer {ACCESS_TOKEN}" -X POST http://ems-esp/api/system/settings - curl -i -H "Authorization: Bearer {ACCESS_TOKEN}" -d '{ "name": "wwtemp", "value":60}' http://ems-esp/api/boiler + curl -i -H "Authorization: Bearer {ACCESS_TOKEN}" -X GET http://ems-esp/api/system/settings + curl -i -H "Authorization: Bearer {ACCESS_TOKEN}" -H "Content-Type: application/json" -d '{ "name": "wwtemp", "value":60}' http://ems-esp/api/boiler ``` ## Error handling @@ -36,26 +36,11 @@ OpenAPI is an open standard specification for describing REST APIs. From the [Op {"message":"Problems parsing JSON"} ``` -- Sending the wrong type of JSON values will result in a `400 Bad Request` response. - - ```html - HTTP/1.1 400 Bad Request - {"message":"Body should be a JSON object"} - ``` - -- Sending invalid fields will result in a `422 Unprocessable Entity` response. `code` can be missing, missing_field, invalid or unprocessable. For example when selecting an invalid heating circuit number. +- Sending invalid fields will result in a `422 Unprocessable Entity` response. ```html HTTP/1.1 422 Unprocessable Entity - { - "message": "Validation Failed", - "errors": [ - { - "field": "title", - "code": "missing_field" - } - ] - } + {"message":"Invalid command"} ``` ## Endpoints @@ -80,27 +65,16 @@ OpenAPI is an open standard specification for describing REST APIs. From the [Op | - | - | - | - | - | | GET | `/{device}` | return all device details and values | | | | GET | `/{device}/{name}` | return a specific parameter and all its properties (name, fullname, value, type, min, max, unit, writeable) | | | -| GET | `/device={device}?cmd={name}?data={value}[?id={hc}` | to keep compatibility with v2. Unless bypassed in the EMS-ESP settings make sure you include `access_token={ACCESS_TOKEN}` | x | -| POST/PUT | `/{device}[/{hc}][/{name}]` | sets a specific value to a parameter name. If no hc is selected and one is required for the device, the default will be used | x | `{ "value": [, "hc": {hc}] }` | +| GET | `/device={device}?cmd={name}?data={value}[?hc=` | Using HTTP query parameters. This is to keep compatibility with v2. Unless bypassed in the EMS-ESP settings make sure you include `access_token={ACCESS_TOKEN}` | x | +| POST/PUT | `/{device}[/{hc}][/{name}]` | sets a specific value to a parameter name. If no hc is selected and one is required for the device, the default will be used | x | `{ ["name" : ] , ["hc": ], "value": }` | ## System Endpoints | Method | Endpoint | Description | Access Token required | JSON body data | | - | - | - | - | - | | GET | `/system/info` | list system information | | | | -| GET | `/system/settings` | list all settings, except passwords | x | -| POST/PUT | `/system/pin` | switch a GPIO state to HIGH or LOW | x | `{ "pin":, "value": }` | -| POST/PUT | `/system/send` | send a telegram to the EMS bus | x | `{ "telegram" : }` | -| POST/PUT | `/system/publish` | force an MQTT publish | x | `[{ "name" : \| "ha" }]` | -| POST/PUT | `/system/fetch` | fetch all EMS data from all devices | x | | -| POST/PUT | `/system/restart` | restarts the EMS-ESP | x | | - -## To Do - -- add restart command -- update EMS-ESP wiki/documentation for v3 -- make adjustments to the command line -- change the URLs in the web UI help page to call system commands directly instead of via URLs -- add long name to value query (only shortname is shown) -- create Postman schema -- rename setting "Enable API write commands" to something like "Use non-authenticated API" with a disclaimer that its insecure and not recommended +| GET | `/system/settings` | list all settings, except passwords | | +| POST/PUT | `/system/pin` | switch a GPIO state to HIGH or LOW | x | `{ "id":, "value": }` | +| POST/PUT | `/system/send` | send a telegram to the EMS bus | x | `{ "value" : }` | +| POST/PUT | `/system/publish` | force an MQTT publish | x | `{ "value" : \| "ha" }` | +| POST/PUT | `/system/fetch` | fetch all EMS data from all devices | x | `{ "value" : \| "all" }` | diff --git a/interface/src/project/EMSESPSettingsForm.tsx b/interface/src/project/EMSESPSettingsForm.tsx index 03dace618..d5306e1d3 100644 --- a/interface/src/project/EMSESPSettingsForm.tsx +++ b/interface/src/project/EMSESPSettingsForm.tsx @@ -396,12 +396,12 @@ class EMSESPSettingsForm extends React.Component { } - label="Enable API write commands" + label="Bypass Access Token authorization on API calls" /> ArJsonRequestHandlerFunction; diff --git a/lib_standalone/ESP8266React.h b/lib_standalone/ESP8266React.h index e452a3b1b..d6913e319 100644 --- a/lib_standalone/ESP8266React.h +++ b/lib_standalone/ESP8266React.h @@ -25,7 +25,7 @@ class DummySettings { bool shower_timer = true; bool shower_alert = false; bool hide_led = false; - bool api_enabled = true; + bool notoken_api = false; // MQTT uint16_t publish_time = 10; // seconds diff --git a/lib_standalone/ESPAsyncWebServer.h b/lib_standalone/ESPAsyncWebServer.h index b5472799e..8237c44f3 100644 --- a/lib_standalone/ESPAsyncWebServer.h +++ b/lib_standalone/ESPAsyncWebServer.h @@ -11,6 +11,7 @@ class AsyncWebServer; class AsyncWebServerRequest; class AsyncWebServerResponse; class AsyncJsonResponse; +class PrettyAsyncJsonResponse; class AsyncWebParameter { private: @@ -68,11 +69,13 @@ class AsyncWebServerRequest { AsyncWebServer * _server; WebRequestMethodComposite _method; + String _url; + public: void * _tempObject; - AsyncWebServerRequest(AsyncWebServer *, AsyncClient *); - ~AsyncWebServerRequest(); + AsyncWebServerRequest(AsyncWebServer *, AsyncClient *){}; + ~AsyncWebServerRequest(){}; AsyncClient * client() { return _client; @@ -82,13 +85,30 @@ class AsyncWebServerRequest { return _method; } + void method(WebRequestMethodComposite method_s) { + _method = method_s; + } + void addInterestingHeader(const String & name){}; + size_t args() const { + return 0; + } + void send(AsyncWebServerResponse * response){}; void send(AsyncJsonResponse * response){}; + void send(PrettyAsyncJsonResponse * response){}; void send(int code, const String & contentType = String(), const String & content = String()){}; void send(int code, const String & contentType, const __FlashStringHelper *){}; + const String & url() const { + return _url; + } + + void url(const String & url_s) { + _url = url_s; + } + bool hasParam(const String & name, bool post, bool file) const { return false; } @@ -174,9 +194,9 @@ class AsyncWebServerResponse { virtual ~AsyncWebServerResponse(); }; -typedef std::function ArRequestHandlerFunction; +typedef std::function ArRequestHandlerFunction; typedef std::function ArUploadHandlerFunction; -typedef std::function ArBodyHandlerFunction; +typedef std::function ArBodyHandlerFunction; class AsyncWebServer { protected: diff --git a/mock-api/server.js b/mock-api/server.js index 3403d362b..07e77e26e 100644 --- a/mock-api/server.js +++ b/mock-api/server.js @@ -103,7 +103,7 @@ const verify_authentication = { access_token: '1234' }; const signin = { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWUsInZlcnNpb24iOiIzLjAuMmIwIn0.MsHSgoJKI1lyYz77EiT5ZN3ECMrb4mPv9FNy3udq0TU" }; -const generate_token = { token: '1234' }; +const generate_token = { token: '1234' }; // EMS-ESP Project specific const EMSESP_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "emsespSettings"; @@ -117,7 +117,7 @@ const emsesp_settings = { "tx_mode": 1, "tx_delay": 0, "ems_bus_id": 11, "syslog_enabled": false, "syslog_level": 3, "trace_raw": false, "syslog_mark_interval": 0, "syslog_host": "192.168.1.4", "syslog_port": 514, "master_thermostat": 0, "shower_timer": true, "shower_alert": false, "rx_gpio": 23, "tx_gpio": 5, - "dallas_gpio": 3, "dallas_parasite": false, "led_gpio": 2, "hide_led": false, "api_enabled": true, + "dallas_gpio": 3, "dallas_parasite": false, "led_gpio": 2, "hide_led": false, "notoken_api": false, "analog_enabled": false, "pbutton_gpio": 0, "board_profile": "S32" }; const emsesp_alldevices = { diff --git a/src/WebAPIService.cpp b/src/WebAPIService.cpp index b98e98db9..035059d24 100644 --- a/src/WebAPIService.cpp +++ b/src/WebAPIService.cpp @@ -16,76 +16,308 @@ * along with this program. If not, see . */ +// SUrlParser from https://github.com/Mad-ness/simple-url-parser + #include "emsesp.h" using namespace std::placeholders; // for `_1` etc namespace emsesp { -WebAPIService::WebAPIService(AsyncWebServer * server) { - server->on(EMSESP_API_SERVICE_PATH, HTTP_GET, std::bind(&WebAPIService::webAPIService, this, _1)); +WebAPIService::WebAPIService(AsyncWebServer * server, SecurityManager * securityManager) + : _securityManager(securityManager) + , _apiHandler("/api", std::bind(&WebAPIService::webAPIService_post, this, _1, _2), 256) { // for POSTS + server->on("/api", HTTP_GET, std::bind(&WebAPIService::webAPIService_get, this, _1)); // for GETS + server->addHandler(&_apiHandler); } -// e.g. http://ems-esp/api?device=boiler&cmd=wwtemp&data=20&id=1 -void WebAPIService::webAPIService(AsyncWebServerRequest * request) { - // must have device and cmd parameters - if ((!request->hasParam(F_(device))) || (!request->hasParam(F_(cmd)))) { - request->send(400, "text/plain", F("Invalid syntax")); +// GET /{device} +// GET /{device}/{name} +// GET /device={device}?cmd={name}?data={value}[?id={hc} +void WebAPIService::webAPIService_get(AsyncWebServerRequest * request) { + std::string device(""); + std::string cmd(""); + int id = -1; + std::string value(""); + + parse(request, device, cmd, id, value); // pass it defaults +} + +// For POSTS with an optional JSON body +// HTTP_POST | HTTP_PUT | HTTP_PATCH +// POST/PUT /{device}[/{hc}][/{name}] +void WebAPIService::webAPIService_post(AsyncWebServerRequest * request, JsonVariant & json) { + // extra the params from the json body + if (not json.is()) { + webAPIService_get(request); return; } - // get device - String device = request->getParam(F_(device))->value(); - uint8_t device_type = EMSdevice::device_name_2_device_type(device.c_str()); - if (device_type == emsesp::EMSdevice::DeviceType::UNKNOWN) { - request->send(400, "text/plain", F("Invalid device")); - return; - } + // extract values from the json + // these will be used as default values + auto && body = json.as(); - // get cmd, we know we have one - String cmd = request->getParam(F_(cmd))->value(); - - String data; - if (request->hasParam(F_(data))) { - data = request->getParam(F_(data))->value(); - } - - String id; - if (request->hasParam(F_(id))) { - id = request->getParam(F_(id))->value(); - } - - if (id.isEmpty()) { - id = "-1"; - } - - DynamicJsonDocument doc(EMSESP_JSON_SIZE_XLARGE_DYN); - JsonObject json = doc.to(); - bool ok = false; - - // execute the command - if (data.isEmpty()) { - ok = Command::call(device_type, cmd.c_str(), nullptr, id.toInt(), json); // command only + std::string device = body["name"].as(); // note this was called device in the v2 + std::string cmd = body["cmd"].as(); + int id = -1; + if (body.containsKey("id")) { + id = body["id"]; + } else if (body.containsKey("hc")) { + id = body["hc"]; } else { - // we only allow commands with parameters if the API is enabled - bool api_enabled; - EMSESP::webSettingsService.read([&](WebSettings & settings) { api_enabled = settings.api_enabled; }); - if (api_enabled) { - ok = Command::call(device_type, cmd.c_str(), data.c_str(), id.toInt(), json); // has cmd, data and id - } else { - request->send(401, "text/plain", F("Unauthorized")); + id = -1; + } + + // make sure we have a value. There must always be a value + if (!body.containsKey("value")) { + send_message_response(request, 400, "Problems parsing JSON"); // Bad Request + return; + } + std::string value = body["value"].as(); // always convert value to string + + // now parse the URL. The URL is always leading and will overwrite anything provided in the json body + parse(request, device, cmd, id, value); // pass it defaults +} + +// parse the URL looking for query or path parameters +// reporting back any errors +void WebAPIService::parse(AsyncWebServerRequest * request, std::string & device_s, std::string & cmd_s, int id, std::string & value_s) { +#ifndef EMSESP_STANDALONE + // parse URL for the path names + SUrlParser p; + p.parse(request->url().c_str()); + + // remove the /api from the path + if (p.paths().front() == "api") { + p.paths().erase(p.paths().begin()); + } else { + return; // bad URL + } + + uint8_t device_type; + int8_t id_n = -1; // default hc + + // check for query parameters first + // /device={device}?cmd={name}?data={value}[?id={hc} + if (p.paths().size() == 0) { + // get the device + if (request->hasParam(F_(device))) { + device_s = request->getParam(F_(device))->value().c_str(); + } + + // get cmd + if (request->hasParam(F_(cmd))) { + cmd_s = request->getParam(F_(cmd))->value().c_str(); + } + + // get data, which is optional. This is now replaced with the name 'value' in JSON body + if (request->hasParam(F_(data))) { + value_s = request->getParam(F_(data))->value().c_str(); + } + if (request->hasParam("value")) { + value_s = request->getParam("value")->value().c_str(); + } + + // get id (or hc), which is optional + if (request->hasParam(F_(id))) { + id_n = Helpers::atoint(request->getParam(F_(id))->value().c_str()); + } + if (request->hasParam("hc")) { + id_n = Helpers::atoint(request->getParam("hc")->value().c_str()); + } + } else { + // parse paths and json data + // /{device}[/{hc}][/{name}] + // first param must be a valid device, which includes "system" + device_s = p.paths().front(); + device_type = EMSdevice::device_name_2_device_type(device_s.c_str()); + + // if there are no more paths parameters, default to 'info' + auto num_paths = p.paths().size(); + if (num_paths > 1) { + auto path2 = p.paths()[1]; // get next path + // if it's a system, the next path must be a command (info, settings,...) + if (device_type == EMSdevice::DeviceType::SYSTEM) { + cmd_s = path2; + } else { + // it's an EMS device + // path2 could be a hc which is optional or a name. first check if it's a hc + if (path2.substr(0, 2) == "hc") { + id_n = (byte)path2[2] - '0'; // bit of a hack + // there must be a name following + if (num_paths > 2) { + cmd_s = p.paths()[2]; + } + } else { + cmd_s = path2; + } + } + } + } + + // now go and validate everything + + // device check + if (device_s.empty()) { + send_message_response(request, 422, "Missing device"); // Unprocessable Entity + return; + } + device_type = EMSdevice::device_name_2_device_type(device_s.c_str()); + if (device_type == EMSdevice::DeviceType::UNKNOWN) { + send_message_response(request, 422, "Invalid device"); // Unprocessable Entity + return; + } + + // cmd check + // if the cmd is empty, default it 'info' + if (cmd_s.empty()) { + cmd_s = "info"; + } + if (Command::find_command(device_type, cmd_s.c_str()) == nullptr) { + send_message_response(request, 422, "Invalid cmd"); // Unprocessable Entity + return; + } + + // check that we have permissions first. We require authenticating on 1 or more of these conditions: + // 1. any HTTP POSTs or PUTs + // 2. a HTTP GET which has a 'data' parameter which is not empty (to keep v2 compatibility) + auto method = request->method(); + bool have_data = !value_s.empty(); + bool admin_allowed; + EMSESP::webSettingsService.read([&](WebSettings & settings) { + Authentication authentication = _securityManager->authenticateRequest(request); + admin_allowed = settings.notoken_api | AuthenticationPredicates::IS_ADMIN(authentication); + }); + + if ((method != HTTP_GET) || ((method == HTTP_GET) && have_data)) { + if (!admin_allowed) { + send_message_response(request, 401, "Bad credentials"); // Unauthorized return; } } - if (ok && json.size()) { - // send json output back to web - doc.shrinkToFit(); - std::string buffer; - serializeJsonPretty(doc, buffer); - request->send(200, "text/plain;charset=utf-8", buffer.c_str()); + + // now we have all the parameters go and execute the command + PrettyAsyncJsonResponse * response = new PrettyAsyncJsonResponse(false, EMSESP_JSON_SIZE_XLARGE_DYN); + JsonObject json = response->getRoot(); + + // EMSESP::logger().notice("Calling device=%s, cmd=%s, data=%s, id/hc=%d", device_s.c_str(), cmd_s.c_str(), value_s.c_str(), id_n); + bool ok = Command::call(device_type, cmd_s.c_str(), (have_data ? value_s.c_str() : nullptr), id_n, json); + + // check for errors + if (!ok) { + send_message_response(request, 400, "Problems parsing elements"); // Bad Request return; } - request->send(200, "text/plain", ok ? F("OK") : F("Invalid")); + + if (!json.size()) { + send_message_response(request, 200, "OK"); // OK + return; + } + + // send the json that came back from the command call + response->setLength(); + request->send(response); // send json response + +#endif } -} // namespace emsesp \ No newline at end of file +// send a HTTP error back, with optional JSON body data +void WebAPIService::send_message_response(AsyncWebServerRequest * request, uint16_t error_code, const char * error_message) { + if (error_message == nullptr) { + AsyncWebServerResponse * response = request->beginResponse(error_code); // just send the code + request->send(response); + } else { + // build a return message and send it + PrettyAsyncJsonResponse * response = new PrettyAsyncJsonResponse(false, EMSESP_JSON_SIZE_SMALL); + JsonObject json = response->getRoot(); + json["message"] = error_message; + response->setCode(error_code); + response->setLength(); + response->setContentType("application/json"); + request->send(response); + } +} + +/** + * Extract only the path component from the passed URI + * and normalized it. + * Ex. //one/two////three/// + * becomes + * /one/two/three + */ +std::string SUrlParser::path() { + std::string s = "/"; // set up the beginning slash + for (std::string & f : m_folders) { + s += f; + s += "/"; + } + s.pop_back(); // deleting last letter, that is slash '/' + return std::string(s); +} + +SUrlParser::SUrlParser(const char * uri) { + parse(uri); +} + +bool SUrlParser::parse(const char * uri) { + m_folders.clear(); + m_keysvalues.clear(); + enum Type { begin, folder, param, value }; + std::string s; + + const char * c = uri; + enum Type t = Type::begin; + std::string last_param; + + if (c != NULL || *c != '\0') { + do { + if (*c == '/') { + if (s.length() > 0) { + m_folders.push_back(s); + s.clear(); + } + t = Type::folder; + } else if (*c == '?' && (t == Type::folder || t == Type::begin)) { + if (s.length() > 0) { + m_folders.push_back(s); + s.clear(); + } + t = Type::param; + } else if (*c == '=' && (t == Type::param || t == Type::begin)) { + m_keysvalues[s] = ""; + last_param = s; + s.clear(); + t = Type::value; + } else if (*c == '&' && (t == Type::value || t == Type::param || t == Type::begin)) { + if (t == Type::value) { + m_keysvalues[last_param] = s; + } else if ((t == Type::param || t == Type::begin) && (s.length() > 0)) { + m_keysvalues[s] = ""; + last_param = s; + } + t = Type::param; + s.clear(); + } else if (*c == '\0' && s.length() > 0) { + if (t == Type::value) { + m_keysvalues[last_param] = s; + } else if (t == Type::folder || t == Type::begin) { + m_folders.push_back(s); + } else if (t == Type::param) { + m_keysvalues[s] = ""; + last_param = s; + } + s.clear(); + } else if (*c == '\0' && s.length() == 0) { + if (t == Type::param && last_param.length() > 0) { + m_keysvalues[last_param] = ""; + } + s.clear(); + } else { + s += *c; + } + } while (*c++ != '\0'); + } + return true; +} + +} // namespace emsesp diff --git a/src/WebAPIService.h b/src/WebAPIService.h index dd932fa20..13fd5aa66 100644 --- a/src/WebAPIService.h +++ b/src/WebAPIService.h @@ -23,16 +23,52 @@ #include #include +#include +#include +#include + #define EMSESP_API_SERVICE_PATH "/api" namespace emsesp { +typedef std::unordered_map KeyValueMap_t; +typedef std::vector Folder_t; + +class SUrlParser { + private: + KeyValueMap_t m_keysvalues; + Folder_t m_folders; + + public: + SUrlParser(){}; + SUrlParser(const char * url); + + bool parse(const char * url); + + Folder_t & paths() { + return m_folders; + }; + + KeyValueMap_t & params() { + return m_keysvalues; + }; + + std::string path(); +}; + class WebAPIService { public: - WebAPIService(AsyncWebServer * server); + WebAPIService(AsyncWebServer * server, SecurityManager * securityManager); private: - void webAPIService(AsyncWebServerRequest * request); + SecurityManager * _securityManager; + AsyncCallbackJsonWebHandler _apiHandler; // for POSTs + + void webAPIService_post(AsyncWebServerRequest * request, JsonVariant & json); // for POSTs + void webAPIService_get(AsyncWebServerRequest * request); // for GETs + + void parse(AsyncWebServerRequest * request, std::string & device, std::string & cmd, int id, std::string & value); + void send_message_response(AsyncWebServerRequest * request, uint16_t error_code, const char * error_message = nullptr); }; } // namespace emsesp diff --git a/src/WebDevicesService.cpp b/src/WebDevicesService.cpp index e16d50b8d..bf70cc8e3 100644 --- a/src/WebDevicesService.cpp +++ b/src/WebDevicesService.cpp @@ -110,7 +110,7 @@ void WebDevicesService::device_data(AsyncWebServerRequest * request, JsonVariant void WebDevicesService::write_value(AsyncWebServerRequest * request, JsonVariant & json) { // only issue commands if the API is enabled EMSESP::webSettingsService.read([&](WebSettings & settings) { - if (!settings.api_enabled) { + if (!settings.notoken_api) { request->send(403); // forbidden error return; } diff --git a/src/WebSettingsService.cpp b/src/WebSettingsService.cpp index f1a4d2396..9302e88ff 100644 --- a/src/WebSettingsService.cpp +++ b/src/WebSettingsService.cpp @@ -55,7 +55,7 @@ void WebSettings::read(WebSettings & settings, JsonObject & root) { root["dallas_parasite"] = settings.dallas_parasite; root["led_gpio"] = settings.led_gpio; root["hide_led"] = settings.hide_led; - root["api_enabled"] = settings.api_enabled; + root["notoken_api"] = settings.notoken_api; root["analog_enabled"] = settings.analog_enabled; root["pbutton_gpio"] = settings.pbutton_gpio; root["board_profile"] = settings.board_profile; @@ -169,7 +169,7 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings) settings.master_thermostat = root["master_thermostat"] | EMSESP_DEFAULT_MASTER_THERMOSTAT; // doesn't need any follow-up actions - settings.api_enabled = root["api_enabled"] | EMSESP_DEFAULT_API_ENABLED; + settings.notoken_api = root["notoken_api"] | EMSESP_DEFAULT_NOTOKEN_API; return StateUpdateResult::CHANGED; } diff --git a/src/WebSettingsService.h b/src/WebSettingsService.h index 2af02dcd6..38e7ae785 100644 --- a/src/WebSettingsService.h +++ b/src/WebSettingsService.h @@ -50,7 +50,7 @@ class WebSettings { bool dallas_parasite; uint8_t led_gpio; bool hide_led; - bool api_enabled; + bool notoken_api; bool analog_enabled; uint8_t pbutton_gpio; String board_profile; diff --git a/src/default_settings.h b/src/default_settings.h index d5b442127..ab7520207 100644 --- a/src/default_settings.h +++ b/src/default_settings.h @@ -76,8 +76,8 @@ #define EMSESP_DEFAULT_DALLAS_PARASITE false #endif -#ifndef EMSESP_DEFAULT_API_ENABLED -#define EMSESP_DEFAULT_API_ENABLED false // turn off, because its insecure +#ifndef EMSESP_DEFAULT_NOTOKEN_API +#define EMSESP_DEFAULT_NOTOKEN_API false #endif #ifndef EMSESP_DEFAULT_BOOL_FORMAT diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 9972933e1..20f3bf936 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -39,7 +39,7 @@ WebSettingsService EMSESP::webSettingsService = WebSettingsService(&webServer, & WebStatusService EMSESP::webStatusService = WebStatusService(&webServer, EMSESP::esp8266React.getSecurityManager()); WebDevicesService EMSESP::webDevicesService = WebDevicesService(&webServer, EMSESP::esp8266React.getSecurityManager()); -WebAPIService EMSESP::webAPIService = WebAPIService(&webServer); +WebAPIService EMSESP::webAPIService = WebAPIService(&webServer, EMSESP::esp8266React.getSecurityManager()); using DeviceFlags = EMSdevice; using DeviceType = EMSdevice::DeviceType; @@ -90,6 +90,15 @@ void EMSESP::fetch_device_values(const uint8_t device_id) { } } +// for a specific EMS device type go and request data values +void EMSESP::fetch_device_values_type(const uint8_t device_type) { + for (const auto & emsdevice : emsdevices) { + if ((emsdevice) && (emsdevice->device_type() == device_type)) { + emsdevice->fetch_values(); + } + } +} + // clears list of recognized devices void EMSESP::clear_all_devices() { // temporary removed: clearing the list causes a crash, the associated commands and mqtt should also be removed. @@ -744,7 +753,8 @@ bool EMSESP::process_telegram(std::shared_ptr telegram) { } read_next_ = false; } else if (watch() == WATCH_ON) { - if ((watch_id_ == WATCH_ID_NONE) || (telegram->type_id == watch_id_) || ((watch_id_ < 0x80) && ((telegram->src == watch_id_) || (telegram->dest == watch_id_)))) { + if ((watch_id_ == WATCH_ID_NONE) || (telegram->type_id == watch_id_) + || ((watch_id_ < 0x80) && ((telegram->src == watch_id_) || (telegram->dest == watch_id_)))) { LOG_NOTICE(pretty_telegram(telegram).c_str()); } else if (!trace_raw_) { LOG_TRACE(pretty_telegram(telegram).c_str()); @@ -785,7 +795,8 @@ bool EMSESP::process_telegram(std::shared_ptr telegram) { found = emsdevice->handle_telegram(telegram); // if we correctly processes the telegram follow up with sending it via MQTT if needed if (found && Mqtt::connected()) { - if ((mqtt_.get_publish_onchange(emsdevice->device_type()) && emsdevice->has_update()) || (telegram->type_id == publish_id_ && telegram->dest == txservice_.ems_bus_id())) { + if ((mqtt_.get_publish_onchange(emsdevice->device_type()) && emsdevice->has_update()) + || (telegram->type_id == publish_id_ && telegram->dest == txservice_.ems_bus_id())) { if (telegram->type_id == publish_id_) { publish_id_ = 0; } @@ -803,7 +814,8 @@ bool EMSESP::process_telegram(std::shared_ptr telegram) { if (watch() == WATCH_UNKNOWN) { LOG_NOTICE(pretty_telegram(telegram).c_str()); } - if (first_scan_done_ && !knowndevice && (telegram->src != EMSbus::ems_bus_id()) && (telegram->src != 0x0B) && (telegram->src != 0x0C) && (telegram->src != 0x0D)) { + if (first_scan_done_ && !knowndevice && (telegram->src != EMSbus::ems_bus_id()) && (telegram->src != 0x0B) && (telegram->src != 0x0C) + && (telegram->src != 0x0D)) { send_read_request(EMSdevice::EMS_TYPE_VERSION, telegram->src); } } @@ -899,7 +911,8 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, std:: // sometimes boilers share the same product id as controllers // so only add boilers if the device_id is 0x08, which is fixed for EMS if (device.device_type == DeviceType::BOILER) { - if (device_id == EMSdevice::EMS_DEVICE_ID_BOILER || (device_id >= EMSdevice::EMS_DEVICE_ID_BOILER_1 && device_id <= EMSdevice::EMS_DEVICE_ID_BOILER_F)) { + if (device_id == EMSdevice::EMS_DEVICE_ID_BOILER + || (device_id >= EMSdevice::EMS_DEVICE_ID_BOILER_1 && device_id <= EMSdevice::EMS_DEVICE_ID_BOILER_F)) { device_p = &device; break; } @@ -915,7 +928,8 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, std:: if (device_p == nullptr) { LOG_NOTICE(F("Unrecognized EMS device (device ID 0x%02X, product ID %d). Please report on GitHub."), device_id, product_id); std::string name("unknown"); - emsdevices.push_back(EMSFactory::add(DeviceType::GENERIC, device_id, product_id, version, name, DeviceFlags::EMS_DEVICE_FLAG_NONE, EMSdevice::Brand::NO_BRAND)); + emsdevices.push_back( + EMSFactory::add(DeviceType::GENERIC, device_id, product_id, version, name, DeviceFlags::EMS_DEVICE_FLAG_NONE, EMSdevice::Brand::NO_BRAND)); return false; // not found } @@ -933,7 +947,9 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, std:: return true; } - Command::add_with_json(device_type, F_(info), [device_type](const char * value, const int8_t id, JsonObject & json) { return command_info(device_type, json, id); }); + Command::add_with_json(device_type, F_(info), [device_type](const char * value, const int8_t id, JsonObject & json) { + return command_info(device_type, json, id); + }); return true; } @@ -952,7 +968,8 @@ bool EMSESP::command_info(uint8_t device_type, JsonObject & json, const int8_t i } for (const auto & emsdevice : emsdevices) { - if (emsdevice && (emsdevice->device_type() == device_type) && ((device_type != DeviceType::THERMOSTAT) || (emsdevice->device_id() == EMSESP::actual_master_thermostat()))) { + if (emsdevice && (emsdevice->device_type() == device_type) + && ((device_type != DeviceType::THERMOSTAT) || (emsdevice->device_id() == EMSESP::actual_master_thermostat()))) { has_value |= emsdevice->generate_values_json(json, tag, (id < 1), (id == -1)); // nested for id -1,0 & console for id -1 } } @@ -966,7 +983,12 @@ void EMSESP::send_read_request(const uint16_t type_id, const uint8_t dest, const } // sends write request -void EMSESP::send_write_request(const uint16_t type_id, const uint8_t dest, const uint8_t offset, uint8_t * message_data, const uint8_t message_length, const uint16_t validate_typeid) { +void EMSESP::send_write_request(const uint16_t type_id, + const uint8_t dest, + const uint8_t offset, + uint8_t * message_data, + const uint8_t message_length, + const uint16_t validate_typeid) { txservice_.add(Telegram::Operation::TX_WRITE, dest, type_id, offset, message_data, message_length, validate_typeid, true); } diff --git a/src/emsesp.h b/src/emsesp.h index 6d1e4ac05..40dc7aa13 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -178,6 +178,7 @@ class EMSESP { } static void fetch_device_values(const uint8_t device_id = 0); + static void fetch_device_values_type(const uint8_t device_type); static bool add_device(const uint8_t device_id, const uint8_t product_id, std::string & version, const uint8_t brand); static void scan_devices(); diff --git a/src/version.h b/src/version.h index 587ba7833..cb113bc50 100644 --- a/src/version.h +++ b/src/version.h @@ -1,2 +1,2 @@ -#define EMSESP_APP_VERSION "3.0.3b4" +#define EMSESP_APP_VERSION "3.0.3b5" #define EMSESP_PLATFORM "ESP32" From e113ebd298c86c123bd09c0eec418c83154ff767 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 2 May 2021 22:09:09 +0200 Subject: [PATCH 007/114] fetch command also per device type --- src/system.cpp | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/system.cpp b/src/system.cpp index 8a6aa203b..18fb363da 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -63,35 +63,55 @@ bool System::command_send(const char * value, const int8_t id) { // fetch device values bool System::command_fetch(const char * value, const int8_t id) { - LOG_INFO(F("Requesting data from EMS devices")); - EMSESP::fetch_device_values(); + std::string value_s(14, '\0'); + if (Helpers::value2string(value, value_s)) { + if (value_s == "all") { + LOG_INFO(F("Requesting data from EMS devices")); + EMSESP::fetch_device_values(); + return true; + } else if (value_s == "boiler") { + EMSESP::fetch_device_values_type(EMSdevice::DeviceType::BOILER); + return true; + } else if (value_s == "thermostat") { + EMSESP::fetch_device_values_type(EMSdevice::DeviceType::THERMOSTAT); + return true; + } else if (value_s == "solar") { + EMSESP::fetch_device_values_type(EMSdevice::DeviceType::SOLAR); + return true; + } else if (value_s == "mixer") { + EMSESP::fetch_device_values_type(EMSdevice::DeviceType::MIXER); + return true; + } + } + + EMSESP::fetch_device_values(); // default if no name or id is given return true; } // mqtt publish bool System::command_publish(const char * value, const int8_t id) { - std::string ha(14, '\0'); - if (Helpers::value2string(value, ha)) { - if (ha == "ha") { + std::string value_s(14, '\0'); + if (Helpers::value2string(value, value_s)) { + if (value_s == "ha") { EMSESP::publish_all(true); // includes HA LOG_INFO(F("Publishing all data to MQTT, including HA configs")); return true; - } else if (ha == "boiler") { + } else if (value_s == "boiler") { EMSESP::publish_device_values(EMSdevice::DeviceType::BOILER); return true; - } else if (ha == "thermostat") { + } else if (value_s == "thermostat") { EMSESP::publish_device_values(EMSdevice::DeviceType::THERMOSTAT); return true; - } else if (ha == "solar") { + } else if (value_s == "solar") { EMSESP::publish_device_values(EMSdevice::DeviceType::SOLAR); return true; - } else if (ha == "mixer") { + } else if (value_s == "mixer") { EMSESP::publish_device_values(EMSdevice::DeviceType::MIXER); return true; - } else if (ha == "other") { + } else if (value_s == "other") { EMSESP::publish_other_values(); return true; - } else if (ha == "dallassensor") { + } else if (value_s == "dallassensor") { EMSESP::publish_sensor_values(true); return true; } @@ -848,7 +868,7 @@ bool System::command_settings(const char * value, const int8_t id, JsonObject & node["dallas_parasite"] = settings.dallas_parasite; node["led_gpio"] = settings.led_gpio; node["hide_led"] = settings.hide_led; - node["api_enabled"] = settings.api_enabled; + node["notoken_api"] = settings.notoken_api; node["analog_enabled"] = settings.analog_enabled; node["pbutton_gpio"] = settings.pbutton_gpio; node["board_profile"] = settings.board_profile; From f0e7ede499aff4c595705575d6526bb0e8926457 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 2 May 2021 22:17:16 +0200 Subject: [PATCH 008/114] merge with latest dev --- src/devices/thermostat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index c03c1161a..a058cbab1 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -779,7 +779,7 @@ void Thermostat::process_CRFMonitor(std::shared_ptr telegram) { } has_update(telegram->read_value(hc->curr_roomTemp, 0)); // is * 10 has_update(telegram->read_bitvalue(hc->modetype, 2, 0)); - has_update(telegram->read_bitvalue(hc->mode, 2, 4)); // bit 4, mode (auto=0 or off=1) + has_update(telegram->read_bitvalue(hc->mode, 2, 4)); // bit 4, mode (auto=0 or off=1) has_update(telegram->read_value(hc->setpoint_roomTemp, 6, 1)); // is * 2, force as single byte has_update(telegram->read_value(hc->targetflowtemp, 4)); } From e9068e702e691e7ad7219746e6530f850bbc9634 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 5 May 2021 08:03:13 +0200 Subject: [PATCH 009/114] fix mixer HA-id nested --- src/devices/mixer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index ba3dee030..dc8f28068 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -97,7 +97,14 @@ bool Mixer::publish_ha_config() { snprintf_P(name, sizeof(name), PSTR("Mixer %02X"), device_id() - 0x20 + 1); doc["name"] = name; - doc["val_tpl"] = FJSON("{{value_json.id}}"); + char tpl[30]; + if (type_ == Type::HC) { + snprintf_P(tpl, sizeof(tpl), PSTR("{{value_json.hc%d.id}}"), device_id() - 0x20 + 1); + } else { + snprintf_P(tpl, sizeof(tpl), PSTR("{{value_json.wwc%d.id}}"), device_id() - 0x28 + 1); + } + doc["val_tpl"] = tpl; + JsonObject dev = doc.createNestedObject("dev"); dev["name"] = FJSON("EMS-ESP Mixer"); dev["sw"] = EMSESP_APP_VERSION; From 32f477726b4f8f99eba13ece454f62d7ce60ae94 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 5 May 2021 08:04:06 +0200 Subject: [PATCH 010/114] allow not only commands in api --- src/WebAPIService.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/WebAPIService.cpp b/src/WebAPIService.cpp index 035059d24..98caebd02 100644 --- a/src/WebAPIService.cpp +++ b/src/WebAPIService.cpp @@ -173,10 +173,6 @@ void WebAPIService::parse(AsyncWebServerRequest * request, std::string & device_ if (cmd_s.empty()) { cmd_s = "info"; } - if (Command::find_command(device_type, cmd_s.c_str()) == nullptr) { - send_message_response(request, 422, "Invalid cmd"); // Unprocessable Entity - return; - } // check that we have permissions first. We require authenticating on 1 or more of these conditions: // 1. any HTTP POSTs or PUTs From 7f52ef8bd8e2b3b1cb4d8329bb9bb04534223529 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 5 May 2021 18:48:07 +0200 Subject: [PATCH 011/114] info shows shortnames, only valid hcs --- src/WebAPIService.cpp | 34 +++++++++------------------------- src/dallassensor.cpp | 20 ++++++-------------- src/emsdevice.cpp | 2 ++ src/emsesp.cpp | 6 ++++-- 4 files changed, 21 insertions(+), 41 deletions(-) diff --git a/src/WebAPIService.cpp b/src/WebAPIService.cpp index 98caebd02..a018e9f42 100644 --- a/src/WebAPIService.cpp +++ b/src/WebAPIService.cpp @@ -129,29 +129,17 @@ void WebAPIService::parse(AsyncWebServerRequest * request, std::string & device_ // parse paths and json data // /{device}[/{hc}][/{name}] // first param must be a valid device, which includes "system" - device_s = p.paths().front(); - device_type = EMSdevice::device_name_2_device_type(device_s.c_str()); + device_s = p.paths().front(); - // if there are no more paths parameters, default to 'info' auto num_paths = p.paths().size(); - if (num_paths > 1) { - auto path2 = p.paths()[1]; // get next path - // if it's a system, the next path must be a command (info, settings,...) - if (device_type == EMSdevice::DeviceType::SYSTEM) { - cmd_s = path2; - } else { - // it's an EMS device - // path2 could be a hc which is optional or a name. first check if it's a hc - if (path2.substr(0, 2) == "hc") { - id_n = (byte)path2[2] - '0'; // bit of a hack - // there must be a name following - if (num_paths > 2) { - cmd_s = p.paths()[2]; - } - } else { - cmd_s = path2; - } - } + if (num_paths == 1) { + // if there are no more paths parameters, default to 'info' + cmd_s = "info"; + } else if (num_paths == 2) { + cmd_s = p.paths()[1]; + } else if (num_paths > 2) { + // command-check makes prefix to TAG + cmd_s = p.paths()[1] + "/" + p.paths()[2]; } } @@ -169,10 +157,6 @@ void WebAPIService::parse(AsyncWebServerRequest * request, std::string & device_ } // cmd check - // if the cmd is empty, default it 'info' - if (cmd_s.empty()) { - cmd_s = "info"; - } // check that we have permissions first. We require authenticating on 1 or more of these conditions: // 1. any HTTP POSTs or PUTs diff --git a/src/dallassensor.cpp b/src/dallassensor.cpp index dd1dd7dc5..467c80306 100644 --- a/src/dallassensor.cpp +++ b/src/dallassensor.cpp @@ -310,7 +310,7 @@ bool DallasSensor::updated_values() { // returns false if empty // e.g. dallassensor_data = {"sensor1":{"id":"28-EA41-9497-0E03-5F","temp":23.30},"sensor2":{"id":"28-233D-9497-0C03-8B","temp":24.0}} bool DallasSensor::command_info(const char * value, const int8_t id, JsonObject & json) { - if (sensors_.size() == 0) { + if (sensors_.size() == 0 || id != -1) { return false; } @@ -318,22 +318,14 @@ bool DallasSensor::command_info(const char * value, const int8_t id, JsonObject for (const auto & sensor : sensors_) { char sensorID[10]; // sensor{1-n} snprintf_P(sensorID, 10, PSTR("sensor%d"), i++); - if (id == 0) { - if (Mqtt::dallas_format() == Mqtt::Dallas_Format::SENSORID && Helpers::hasValue(sensor.temperature_c)) { - json[sensor.to_string()] = (float)(sensor.temperature_c) / 10; - } else if (Helpers::hasValue(sensor.temperature_c)) { - json[sensorID] = (float)(sensor.temperature_c) / 10; - } - } else { - JsonObject dataSensor = json.createNestedObject(sensorID); - dataSensor["id"] = sensor.to_string(); - if (Helpers::hasValue(sensor.temperature_c)) { - dataSensor["temp"] = (float)(sensor.temperature_c) / 10; - } + if (Mqtt::dallas_format() == Mqtt::Dallas_Format::SENSORID && Helpers::hasValue(sensor.temperature_c)) { + json[sensor.to_string()] = (float)(sensor.temperature_c) / 10; + } else if (Helpers::hasValue(sensor.temperature_c)) { + json[sensorID] = (float)(sensor.temperature_c) / 10; } } - return true; + return (json.size() > 0); } // send all dallas sensor values as a JSON package to MQTT diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index abb7574e0..dd558e15a 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -672,6 +672,8 @@ bool EMSdevice::get_value_info(JsonObject & root, const char * cmd, const int8_t tag = DeviceValueTAG::TAG_HC1 + id - 1; } else if (id >= 8 && id <= 11) { tag = DeviceValueTAG::TAG_WWC1 + id - 8; + } else if (id != -1) { + return false; } // search device value with this tag diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 38c8b741d..1196b77bc 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -984,14 +984,16 @@ bool EMSESP::command_info(uint8_t device_type, JsonObject & json, const int8_t i tag = DeviceValueTAG::TAG_HC1 + id - 1; } else if (id >= 9 && id <= 10) { tag = DeviceValueTAG::TAG_WWC1 + id - 9; - } else { + } else if (id == -1) { tag = DeviceValueTAG::TAG_NONE; + } else { + return false; } for (const auto & emsdevice : emsdevices) { if (emsdevice && (emsdevice->device_type() == device_type) && ((device_type != DeviceType::THERMOSTAT) || (emsdevice->device_id() == EMSESP::actual_master_thermostat()))) { - has_value |= emsdevice->generate_values_json(json, tag, (id < 1), (id == -1)); // nested for id -1,0 & console for id -1 + has_value |= emsdevice->generate_values_json(json, tag, (id == -1), false); // nested for id -1,0 & console for id -1 } } From 3c1b30a5e436efdd310fc605cbb68790510fd7e4 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 6 May 2021 10:10:20 +0200 Subject: [PATCH 012/114] auto formatting --- src/WebDevicesService.cpp | 2 +- src/devices/mixer.cpp | 2 +- src/emsesp.cpp | 6 +++--- src/mqtt.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/WebDevicesService.cpp b/src/WebDevicesService.cpp index bf70cc8e3..9301ea5d3 100644 --- a/src/WebDevicesService.cpp +++ b/src/WebDevicesService.cpp @@ -129,7 +129,7 @@ void WebDevicesService::write_value(AsyncWebServerRequest * request, JsonVariant char s[10]; // the data could be in any format, but we need string JsonVariant data = dv["data"]; - if (data.is()) { + if (data.is()) { ok = Command::call(device_type, cmd, data.as()); } else if (data.is()) { ok = Command::call(device_type, cmd, Helpers::render_value(s, data.as(), 0)); diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index dc8f28068..721fa12bc 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -100,7 +100,7 @@ bool Mixer::publish_ha_config() { char tpl[30]; if (type_ == Type::HC) { snprintf_P(tpl, sizeof(tpl), PSTR("{{value_json.hc%d.id}}"), device_id() - 0x20 + 1); - } else { + } else { snprintf_P(tpl, sizeof(tpl), PSTR("{{value_json.wwc%d.id}}"), device_id() - 0x28 + 1); } doc["val_tpl"] = tpl; diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 1196b77bc..8849c2609 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -323,8 +323,8 @@ void EMSESP::show_device_values(uuid::console::Shell & shell) { shell.printf(" %s: ", key); JsonVariant data = p.value(); shell.print(COLOR_BRIGHT_GREEN); - if (data.is()) { - shell.print(data.as()); + if (data.is()) { + shell.print(data.as()); } else if (data.is()) { shell.print(data.as()); } else if (data.is()) { @@ -986,7 +986,7 @@ bool EMSESP::command_info(uint8_t device_type, JsonObject & json, const int8_t i tag = DeviceValueTAG::TAG_WWC1 + id - 9; } else if (id == -1) { tag = DeviceValueTAG::TAG_NONE; - } else { + } else { return false; } diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 3b0df514e..5b79faa7e 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -387,8 +387,8 @@ void Mqtt::on_message(const char * fulltopic, const char * payload, size_t len) bool cmd_known = false; JsonVariant data = doc["data"]; - if (data.is()) { - cmd_known = Command::call(mf.device_type_, command, data.as(), n); + if (data.is()) { + cmd_known = Command::call(mf.device_type_, command, data.as(), n); } else if (data.is()) { char data_str[10]; cmd_known = Command::call(mf.device_type_, command, Helpers::itoa(data_str, (int16_t)data.as()), n); From 9211d29e1709112bccc3075735818a669102c093 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 6 May 2021 10:10:37 +0200 Subject: [PATCH 013/114] upgrade to 6.18 --- lib/ArduinoJson/ArduinoJson.h | 2 +- lib/ArduinoJson/CHANGELOG.md | 43 ++- lib/ArduinoJson/README.md | 9 +- lib/ArduinoJson/src/ArduinoJson.h | 2 +- lib/ArduinoJson/src/ArduinoJson.hpp | 4 +- .../src/ArduinoJson/Array/ArrayFunctions.hpp | 2 +- .../src/ArduinoJson/Array/ArrayImpl.hpp | 2 +- .../src/ArduinoJson/Array/ArrayIterator.hpp | 2 +- .../src/ArduinoJson/Array/ArrayRef.hpp | 40 ++- .../src/ArduinoJson/Array/ArrayShortcuts.hpp | 4 +- .../src/ArduinoJson/Array/ElementProxy.hpp | 16 +- .../src/ArduinoJson/Array/Utilities.hpp | 5 +- .../ArduinoJson/Collection/CollectionData.hpp | 2 +- .../ArduinoJson/Collection/CollectionImpl.hpp | 4 +- .../src/ArduinoJson/Configuration.hpp | 2 +- .../Deserialization/DeserializationError.hpp | 2 +- .../ArduinoJson/Deserialization/Filter.hpp | 2 +- .../Deserialization/NestingLimit.hpp | 2 +- .../ArduinoJson/Deserialization/Reader.hpp | 2 +- .../Readers/ArduinoStreamReader.hpp | 2 +- .../Readers/ArduinoStringReader.hpp | 2 +- .../Deserialization/Readers/FlashReader.hpp | 2 +- .../Readers/IteratorReader.hpp | 2 +- .../Deserialization/Readers/RamReader.hpp | 2 +- .../Readers/StdStreamReader.hpp | 2 +- .../Deserialization/Readers/VariantReader.hpp | 2 +- .../Deserialization/deserialize.hpp | 2 +- .../Document/BasicJsonDocument.hpp | 2 +- .../Document/DynamicJsonDocument.hpp | 2 +- .../src/ArduinoJson/Document/JsonDocument.hpp | 12 +- .../Document/StaticJsonDocument.hpp | 2 +- .../src/ArduinoJson/Json/EscapeSequence.hpp | 2 +- .../src/ArduinoJson/Json/JsonDeserializer.hpp | 2 +- .../src/ArduinoJson/Json/JsonSerializer.hpp | 12 +- .../src/ArduinoJson/Json/Latch.hpp | 2 +- .../ArduinoJson/Json/PrettyJsonSerializer.hpp | 4 +- .../src/ArduinoJson/Json/TextFormatter.hpp | 34 ++- .../src/ArduinoJson/Json/Utf16.hpp | 2 +- lib/ArduinoJson/src/ArduinoJson/Json/Utf8.hpp | 2 +- .../src/ArduinoJson/Memory/Alignment.hpp | 2 +- .../src/ArduinoJson/Memory/MemoryPool.hpp | 2 +- .../src/ArduinoJson/Misc/SerializedValue.hpp | 2 +- .../src/ArduinoJson/Misc/Visitable.hpp | 2 +- .../MsgPack/MsgPackDeserializer.hpp | 54 ++-- .../ArduinoJson/MsgPack/MsgPackSerializer.hpp | 35 ++- .../src/ArduinoJson/MsgPack/endianess.hpp | 2 +- .../src/ArduinoJson/MsgPack/ieee754.hpp | 2 +- lib/ArduinoJson/src/ArduinoJson/Namespace.hpp | 2 +- .../src/ArduinoJson/Numbers/Float.hpp | 2 +- .../src/ArduinoJson/Numbers/FloatParts.hpp | 2 +- .../src/ArduinoJson/Numbers/FloatTraits.hpp | 2 +- .../src/ArduinoJson/Numbers/Integer.hpp | 2 +- .../ArduinoJson/Numbers/arithmeticCompare.hpp | 2 +- .../src/ArduinoJson/Numbers/convertNumber.hpp | 102 +++---- .../src/ArduinoJson/Numbers/parseNumber.hpp | 22 +- .../src/ArduinoJson/Object/MemberProxy.hpp | 34 ++- .../ArduinoJson/Object/ObjectFunctions.hpp | 2 +- .../src/ArduinoJson/Object/ObjectImpl.hpp | 2 +- .../src/ArduinoJson/Object/ObjectIterator.hpp | 2 +- .../src/ArduinoJson/Object/ObjectRef.hpp | 40 ++- .../ArduinoJson/Object/ObjectShortcuts.hpp | 2 +- .../src/ArduinoJson/Object/Pair.hpp | 2 +- .../src/ArduinoJson/Polyfills/alias_cast.hpp | 2 +- .../src/ArduinoJson/Polyfills/assert.hpp | 2 +- .../src/ArduinoJson/Polyfills/attributes.hpp | 19 +- .../src/ArduinoJson/Polyfills/ctype.hpp | 2 +- .../src/ArduinoJson/Polyfills/integer.hpp | 2 +- .../src/ArduinoJson/Polyfills/limits.hpp | 2 +- .../src/ArduinoJson/Polyfills/math.hpp | 2 +- .../src/ArduinoJson/Polyfills/mpl/max.hpp | 2 +- .../src/ArduinoJson/Polyfills/pgmspace.hpp | 2 +- .../Polyfills/pgmspace_generic.hpp | 2 +- .../ArduinoJson/Polyfills/preprocessor.hpp | 2 +- .../src/ArduinoJson/Polyfills/safe_strcmp.hpp | 2 +- .../ArduinoJson/Polyfills/static_array.hpp | 2 +- .../src/ArduinoJson/Polyfills/type_traits.hpp | 2 +- .../Polyfills/type_traits/conditional.hpp | 2 +- .../Polyfills/type_traits/declval.hpp | 2 +- .../Polyfills/type_traits/enable_if.hpp | 2 +- .../type_traits/integral_constant.hpp | 2 +- .../Polyfills/type_traits/is_array.hpp | 2 +- .../Polyfills/type_traits/is_base_of.hpp | 2 +- .../Polyfills/type_traits/is_class.hpp | 2 +- .../Polyfills/type_traits/is_const.hpp | 2 +- .../Polyfills/type_traits/is_convertible.hpp | 2 +- .../Polyfills/type_traits/is_enum.hpp | 2 +- .../type_traits/is_floating_point.hpp | 2 +- .../Polyfills/type_traits/is_integral.hpp | 2 +- .../Polyfills/type_traits/is_pointer.hpp | 2 +- .../Polyfills/type_traits/is_same.hpp | 2 +- .../Polyfills/type_traits/is_signed.hpp | 2 +- .../Polyfills/type_traits/is_unsigned.hpp | 2 +- .../Polyfills/type_traits/make_unsigned.hpp | 2 +- .../Polyfills/type_traits/remove_const.hpp | 2 +- .../type_traits/remove_reference.hpp | 2 +- .../Polyfills/type_traits/type_identity.hpp | 2 +- .../src/ArduinoJson/Polyfills/utility.hpp | 2 +- .../Serialization/CountingDecorator.hpp | 2 +- .../src/ArduinoJson/Serialization/Writer.hpp | 2 +- .../Writers/ArduinoStringWriter.hpp | 2 +- .../Serialization/Writers/DummyWriter.hpp | 2 +- .../Serialization/Writers/PrintWriter.hpp | 2 +- .../Writers/StaticStringWriter.hpp | 9 +- .../Serialization/Writers/StdStreamWriter.hpp | 2 +- .../Serialization/Writers/StdStringWriter.hpp | 2 +- .../src/ArduinoJson/Serialization/measure.hpp | 2 +- .../ArduinoJson/Serialization/serialize.hpp | 19 +- .../StringStorage/StringCopier.hpp | 2 +- .../ArduinoJson/StringStorage/StringMover.hpp | 2 +- .../StringStorage/StringStorage.hpp | 2 +- .../Strings/ArduinoStringAdapter.hpp | 2 +- .../Strings/ConstRamStringAdapter.hpp | 2 +- .../Strings/FlashStringAdapter.hpp | 2 +- .../Strings/FlashStringIterator.hpp | 2 +- .../src/ArduinoJson/Strings/IsString.hpp | 2 +- .../ArduinoJson/Strings/IsWriteableString.hpp | 2 +- .../ArduinoJson/Strings/RamStringAdapter.hpp | 2 +- .../Strings/SizedFlashStringAdapter.hpp | 2 +- .../Strings/SizedRamStringAdapter.hpp | 2 +- .../ArduinoJson/Strings/StdStringAdapter.hpp | 2 +- .../src/ArduinoJson/Strings/StoragePolicy.hpp | 2 +- .../src/ArduinoJson/Strings/String.hpp | 2 +- .../ArduinoJson/Strings/StringAdapters.hpp | 2 +- .../src/ArduinoJson/Variant/Converter.hpp | 12 + .../src/ArduinoJson/Variant/ConverterImpl.hpp | 268 ++++++++++++++++++ .../src/ArduinoJson/Variant/SlotFunctions.hpp | 2 +- .../src/ArduinoJson/Variant/VariantAs.hpp | 114 -------- .../src/ArduinoJson/Variant/VariantAsImpl.hpp | 57 ---- .../ArduinoJson/Variant/VariantCompare.hpp | 38 +-- .../ArduinoJson/Variant/VariantContent.hpp | 19 +- .../src/ArduinoJson/Variant/VariantData.hpp | 133 ++++----- .../ArduinoJson/Variant/VariantFunctions.hpp | 43 +-- .../src/ArduinoJson/Variant/VariantImpl.hpp | 36 ++- .../src/ArduinoJson/Variant/VariantIs.hpp | 146 ---------- .../ArduinoJson/Variant/VariantOperators.hpp | 20 +- .../src/ArduinoJson/Variant/VariantRef.hpp | 258 +++++++++-------- .../ArduinoJson/Variant/VariantShortcuts.hpp | 2 +- .../src/ArduinoJson/Variant/VariantSlot.hpp | 10 +- .../src/ArduinoJson/Variant/VariantTag.hpp | 2 +- .../src/ArduinoJson/Variant/VariantTo.hpp | 2 +- .../src/ArduinoJson/Variant/Visitor.hpp | 6 +- .../src/ArduinoJson/compatibility.hpp | 4 +- lib/ArduinoJson/src/ArduinoJson/version.hpp | 8 +- lib/ArduinoJson/src/CMakeLists.txt | 2 +- 144 files changed, 1001 insertions(+), 906 deletions(-) create mode 100644 lib/ArduinoJson/src/ArduinoJson/Variant/Converter.hpp create mode 100644 lib/ArduinoJson/src/ArduinoJson/Variant/ConverterImpl.hpp delete mode 100644 lib/ArduinoJson/src/ArduinoJson/Variant/VariantAs.hpp delete mode 100644 lib/ArduinoJson/src/ArduinoJson/Variant/VariantAsImpl.hpp delete mode 100644 lib/ArduinoJson/src/ArduinoJson/Variant/VariantIs.hpp diff --git a/lib/ArduinoJson/ArduinoJson.h b/lib/ArduinoJson/ArduinoJson.h index b5d887ab9..ba79dc8e3 100644 --- a/lib/ArduinoJson/ArduinoJson.h +++ b/lib/ArduinoJson/ArduinoJson.h @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/CHANGELOG.md b/lib/ArduinoJson/CHANGELOG.md index 53c8f010e..f3866b3c8 100644 --- a/lib/ArduinoJson/CHANGELOG.md +++ b/lib/ArduinoJson/CHANGELOG.md @@ -1,9 +1,11 @@ ArduinoJson: change log ======================= -HEAD ----- +v6.18.0 (2021-05-05) +------- +* Added support for custom converters (issue #687) +* Added support for `Printable` (issue #1444) * Removed support for `char` values, see below (issue #1498) * `deserializeJson()` leaves `\uXXXX` unchanged instead of returning `NotSupported` * `deserializeMsgPack()` inserts `null` instead of returning `NotSupported` @@ -11,9 +13,17 @@ HEAD * Added `JsonVariant::is()` (issue #1412) * Added `JsonVariant::is()` (issue #1412) * Changed `JsonVariantConst::is()` to return `false` (issue #1412) +* Simplified `JsonVariant::as()` to always return `T` (see below) +* Updated folders list in `.mbedignore` (PR #1515 by @AGlass0fMilk) +* Fixed member-call-on-null-pointer in `getMember()` when array is empty +* `serializeMsgPack(doc, buffer, size)` doesn't add null-terminator anymore (issue #1545) +* `serializeJson(doc, buffer, size)` adds null-terminator only if there is enough room +* PlatformIO: set `build.libArchive` to `false` (PR #1550 by @askreet) > ### BREAKING CHANGES > +> #### Support for `char` removed +> > We cannot cast a `JsonVariant` to a `char` anymore, so the following will break: > ```c++ > char age = doc["age"]; // error: no matching function for call to 'variantAs(VariantData*&)' @@ -33,6 +43,31 @@ HEAD > int8_t age; > doc["age"] = age; // OK > ``` +> A deprecation warning with the message "Support for `char` is deprecated, use `int8_t` or `uint8_t` instead" was added to allow a smooth transition. +> +> #### `as()` always returns `T` +> +> Previously, `JsonVariant::as()` could return a type different from `T`. +> The most common example is `as()` that returned a `const char*`. +> While this feature simplified a few use cases, it was confusing and complicated the +> implementation of custom converters. +> +> Starting from this version, `as` doesn't try to auto-correct the return type and always return `T`, +> which means that you cannot write this anymore: +> +> ```c++ +> Serial.println(doc["sensor"].as()); // error: invalid conversion from 'const char*' to 'char*' [-fpermissive] +> ``` +> +> Instead, you must write: +> +> ```c++ +> Serial.println(doc["sensor"].as()); // OK +> ``` +> +> A deprecation warning with the message "Replace `as()` with `as()`" was added to allow a smooth transition. +> +> #### `DeserializationError::NotSupported` removed > > On a different topic, `DeserializationError::NotSupported` has been removed. > Instead of returning this error: @@ -40,7 +75,9 @@ HEAD > * `deserializeJson()` leaves `\uXXXX` unchanged (only when `ARDUINOJSON_DECODE_UNICODE` is `0`) > * `deserializeMsgPack()` replaces unsupported values with `null`s > -> Lastly, a very minor change conserns `JsonVariantConst::is()`. +> #### Const-aware `is()` +> +> Lastly, a very minor change concerns `JsonVariantConst::is()`. > It used to return `true` for `JsonArray` and `JsonOject`, but now it returns `false`. > Instead, you must use `JsonArrayConst` and `JsonObjectConst`. diff --git a/lib/ArduinoJson/README.md b/lib/ArduinoJson/README.md index 5b5206c7c..c30028435 100644 --- a/lib/ArduinoJson/README.md +++ b/lib/ArduinoJson/README.md @@ -2,7 +2,7 @@ --- -[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.17.3)](https://www.ardu-badge.com/ArduinoJson/6.17.3) +[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.18.0)](https://www.ardu-badge.com/ArduinoJson/6.18.0) [![Continuous Integration](https://github.com/bblanchon/ArduinoJson/workflows/Continuous%20Integration/badge.svg?branch=6.x)](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A6.x) [![Continuous Integration](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/6.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/arduinojson.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson) @@ -34,10 +34,11 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things). * Deduplicates strings * Versatile * [Supports custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/?utm_source=github&utm_medium=readme) - * Supports [Arduino's `String`](https://arduinojson.org/v6/api/config/enable_arduino_string/) and [STL's `std::string`](https://arduinojson.org/v6/api/config/enable_std_string/?utm_source=github&utm_medium=readme) - * Supports Arduino's `Stream` and [STL's `std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme) + * Supports [Arduino's `String`](https://arduinojson.org/v6/api/config/enable_arduino_string/?utm_source=github&utm_medium=readme) and [STL's `std::string`](https://arduinojson.org/v6/api/config/enable_std_string/?utm_source=github&utm_medium=readme) + * Supports [Arduino's `Stream`](https://arduinojson.org/v6/api/config/enable_arduino_stream/?utm_source=github&utm_medium=readme) and [STL's `std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme) * [Supports Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/?utm_source=github&utm_medium=readme) * Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme#custom-writer) + * Supports custom converters * Portable * Usable on any C++ project (not limited to Arduino) * Compatible with C++98 @@ -86,7 +87,7 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things). * [How-tos](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme) * [FAQ](https://arduinojson.org/v6/faq/?utm_source=github&utm_medium=readme) * [Book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme) - * [Changelog](changelog.md) + * [Changelog](CHANGELOG.md) * Vibrant user community * Most popular of all Arduino libraries on [GitHub](https://github.com/search?o=desc&q=arduino+library&s=stars&type=Repositories) and [PlatformIO](https://platformio.org/lib/search) * [Used in hundreds of projects](https://www.hackster.io/search?i=projects&q=arduinojson) diff --git a/lib/ArduinoJson/src/ArduinoJson.h b/lib/ArduinoJson/src/ArduinoJson.h index e6e2b2425..2984c2379 100644 --- a/lib/ArduinoJson/src/ArduinoJson.h +++ b/lib/ArduinoJson/src/ArduinoJson.h @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson.hpp b/lib/ArduinoJson/src/ArduinoJson.hpp index 52b4f3be9..28d42eef5 100644 --- a/lib/ArduinoJson/src/ArduinoJson.hpp +++ b/lib/ArduinoJson/src/ArduinoJson.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -27,7 +27,7 @@ #include "ArduinoJson/Collection/CollectionImpl.hpp" #include "ArduinoJson/Object/MemberProxy.hpp" #include "ArduinoJson/Object/ObjectImpl.hpp" -#include "ArduinoJson/Variant/VariantAsImpl.hpp" +#include "ArduinoJson/Variant/ConverterImpl.hpp" #include "ArduinoJson/Variant/VariantCompare.hpp" #include "ArduinoJson/Variant/VariantImpl.hpp" diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayFunctions.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayFunctions.hpp index 219be6a74..e7cdc4c5c 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayFunctions.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayFunctions.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayImpl.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayImpl.hpp index e4e41978c..ae06b2046 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayImpl.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayImpl.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayIterator.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayIterator.hpp index b465aa489..fcacc6b6a 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayIterator.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayIterator.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayRef.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayRef.hpp index b92107c18..a991db0d7 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayRef.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayRef.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -164,4 +164,42 @@ class ArrayRef : public ArrayRefBase, private: MemoryPool* _pool; }; + +template <> +struct Converter { + static bool toJson(VariantConstRef src, VariantRef dst) { + return variantCopyFrom(getData(dst), getData(src), getPool(dst)); + } + + static ArrayConstRef fromJson(VariantConstRef src) { + return ArrayConstRef(variantAsArray(getData(src))); + } + + static bool checkJson(VariantConstRef src) { + const VariantData* data = getData(src); + return data && data->isArray(); + } +}; + +template <> +struct Converter { + static bool toJson(VariantConstRef src, VariantRef dst) { + return variantCopyFrom(getData(dst), getData(src), getPool(dst)); + } + + static ArrayRef fromJson(VariantRef src) { + VariantData* data = getData(src); + MemoryPool* pool = getPool(src); + return ArrayRef(pool, data != 0 ? data->asArray() : 0); + } + + static bool checkJson(VariantConstRef) { + return false; + } + + static bool checkJson(VariantRef src) { + VariantData* data = getData(src); + return data && data->isArray(); + } +}; } // namespace ARDUINOJSON_NAMESPACE diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayShortcuts.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayShortcuts.hpp index e39043aa1..fd26d04ae 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayShortcuts.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayShortcuts.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -9,6 +9,8 @@ namespace ARDUINOJSON_NAMESPACE { // Forward declarations. +class ArrayRef; +class ObjectRef; template class ElementProxy; diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp index 6e19d01c2..c6062e492 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -65,10 +65,18 @@ class ElementProxy : public VariantOperators >, } template - FORCE_INLINE typename VariantAs::type as() const { + FORCE_INLINE typename enable_if::value, T>::type as() + const { return getUpstreamElement().template as(); } + template + FORCE_INLINE typename enable_if::value, const char*>::type + ARDUINOJSON_DEPRECATED("Replace as() with as()") + as() const { + return as(); + } + template FORCE_INLINE operator T() const { return getUpstreamElement(); @@ -170,6 +178,10 @@ class ElementProxy : public VariantOperators >, return _array.getOrAddElement(_index); } + friend bool convertToJson(const this_type& src, VariantRef dst) { + return dst.set(src.getUpstreamElement()); + } + TArray _array; const size_t _index; }; diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp index 6deba8fe3..619b91d8d 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -76,7 +76,8 @@ class ArrayCopier1D : public Visitor { VariantSlot* slot = array.head(); while (slot != 0 && size < _capacity) { - _destination[size++] = variantAs(slot->data()); + _destination[size++] = + Converter::fromJson(VariantConstRef(slot->data())); slot = slot->next(); } return size; diff --git a/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp b/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp index 630c2d48e..d2bca45f0 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp b/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp index 51d167790..49a24beed 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -115,6 +115,8 @@ inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const { } inline VariantSlot* CollectionData::getSlot(size_t index) const { + if (!_head) + return 0; return _head->next(index); } diff --git a/lib/ArduinoJson/src/ArduinoJson/Configuration.hpp b/lib/ArduinoJson/src/ArduinoJson/Configuration.hpp index 3c517369b..0c0d4c489 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Configuration.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Configuration.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp index de6b7dedf..7b617111a 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp index 9f50f6e12..7ea3078dc 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp index 88223efdd..06964b43e 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp index 77ca27430..e965c8256 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp index f72ad5fa2..724638f92 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp index b76ce8c71..71571d416 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp index 0d41f7dd0..7eca134d7 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp index 47cfb9250..37c3c317d 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp index 8f577a000..67cf6825b 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp index 44ccdddc8..eebaa2cc0 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp index f9c8fb19b..e56e26264 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp index 045fbcbd8..23295421c 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Document/BasicJsonDocument.hpp b/lib/ArduinoJson/src/ArduinoJson/Document/BasicJsonDocument.hpp index 4ab738973..5c85d8a78 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Document/BasicJsonDocument.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Document/BasicJsonDocument.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Document/DynamicJsonDocument.hpp b/lib/ArduinoJson/src/ArduinoJson/Document/DynamicJsonDocument.hpp index d6c328fd3..de6f41131 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Document/DynamicJsonDocument.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Document/DynamicJsonDocument.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp b/lib/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp index 6ac1ea2d3..d67d93496 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -21,12 +21,12 @@ class JsonDocument : public Visitable { } template - typename VariantAs::type as() { + T as() { return getVariant().template as(); } template - typename VariantConstAs::type as() const { + T as() const { return getVariant().template as(); } @@ -70,7 +70,7 @@ class JsonDocument : public Visitable { } bool set(const JsonDocument& src) { - return to().set(src.as()); + return to().set(src.as()); } template @@ -337,4 +337,8 @@ class JsonDocument : public Visitable { JsonDocument& operator=(const JsonDocument&); }; +inline bool convertToJson(const JsonDocument& src, VariantRef dst) { + return dst.set(src.as()); +} + } // namespace ARDUINOJSON_NAMESPACE diff --git a/lib/ArduinoJson/src/ArduinoJson/Document/StaticJsonDocument.hpp b/lib/ArduinoJson/src/ArduinoJson/Document/StaticJsonDocument.hpp index be204b550..fbbadd43a 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Document/StaticJsonDocument.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Document/StaticJsonDocument.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/EscapeSequence.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/EscapeSequence.hpp index 7e35bd11b..811e82522 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Json/EscapeSequence.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Json/EscapeSequence.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/JsonDeserializer.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/JsonDeserializer.hpp index c20cf4ca8..1a07be866 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Json/JsonDeserializer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Json/JsonDeserializer.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/JsonSerializer.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/JsonSerializer.hpp index a3fe4e24e..5cb9aa270 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Json/JsonSerializer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Json/JsonSerializer.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -14,6 +14,8 @@ namespace ARDUINOJSON_NAMESPACE { template class JsonSerializer : public Visitor { public: + static const bool producesText = true; + JsonSerializer(TWriter writer) : _formatter(writer) {} FORCE_INLINE size_t visitArray(const CollectionData &array) { @@ -71,13 +73,13 @@ class JsonSerializer : public Visitor { return bytesWritten(); } - size_t visitNegativeInteger(UInt value) { - _formatter.writeNegativeInteger(value); + size_t visitSignedInteger(Integer value) { + _formatter.writeInteger(value); return bytesWritten(); } - size_t visitPositiveInteger(UInt value) { - _formatter.writePositiveInteger(value); + size_t visitUnsignedInteger(UInt value) { + _formatter.writeInteger(value); return bytesWritten(); } diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/Latch.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/Latch.hpp index a5d042766..aef1fe368 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Json/Latch.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Json/Latch.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/PrettyJsonSerializer.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/PrettyJsonSerializer.hpp index 3b1b919dc..dbb0c1723 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Json/PrettyJsonSerializer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Json/PrettyJsonSerializer.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -16,7 +16,7 @@ class PrettyJsonSerializer : public JsonSerializer { typedef JsonSerializer base; public: - PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {} + PrettyJsonSerializer(TWriter writer) : base(writer), _nesting(0) {} size_t visitArray(const CollectionData &array) { VariantSlot *slot = array.head(); diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/TextFormatter.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/TextFormatter.hpp index 114e45563..18694f14e 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Json/TextFormatter.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Json/TextFormatter.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -12,6 +12,7 @@ #include #include #include +#include #include namespace ARDUINOJSON_NAMESPACE { @@ -75,28 +76,31 @@ class TextFormatter { FloatParts parts(value); - writePositiveInteger(parts.integral); + writeInteger(parts.integral); if (parts.decimalPlaces) writeDecimals(parts.decimal, parts.decimalPlaces); - if (parts.exponent < 0) { - writeRaw("e-"); - writePositiveInteger(-parts.exponent); - } - - if (parts.exponent > 0) { + if (parts.exponent) { writeRaw('e'); - writePositiveInteger(parts.exponent); + writeInteger(parts.exponent); } } - void writeNegativeInteger(UInt value) { - writeRaw('-'); - writePositiveInteger(value); - } - template - void writePositiveInteger(T value) { + typename enable_if::value>::type writeInteger(T value) { + typedef typename make_unsigned::type unsigned_type; + unsigned_type unsigned_value; + if (value < 0) { + writeRaw('-'); + unsigned_value = unsigned_type(unsigned_type(~value) + 1); + } else { + unsigned_value = unsigned_type(value); + } + writeInteger(unsigned_value); + } + + template + typename enable_if::value>::type writeInteger(T value) { char buffer[22]; char *end = buffer + sizeof(buffer); char *begin = end; diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/Utf16.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/Utf16.hpp index ae10d4d23..4e2750f3b 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Json/Utf16.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Json/Utf16.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/Utf8.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/Utf8.hpp index 4f4bc63e6..a30f77a82 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Json/Utf8.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Json/Utf8.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Memory/Alignment.hpp b/lib/ArduinoJson/src/ArduinoJson/Memory/Alignment.hpp index 9d91e83e9..bf1679879 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Memory/Alignment.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Memory/Alignment.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Memory/MemoryPool.hpp b/lib/ArduinoJson/src/ArduinoJson/Memory/MemoryPool.hpp index 60459eb48..49debf856 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Memory/MemoryPool.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Memory/MemoryPool.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Misc/SerializedValue.hpp b/lib/ArduinoJson/src/ArduinoJson/Misc/SerializedValue.hpp index 97408ee0a..30173bf86 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Misc/SerializedValue.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Misc/SerializedValue.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Misc/Visitable.hpp b/lib/ArduinoJson/src/ArduinoJson/Misc/Visitable.hpp index 8dba09a66..f25d12f2b 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Misc/Visitable.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Misc/Visitable.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp b/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp index ec011846f..49c6fd41d 100644 --- a/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -27,7 +27,7 @@ class MsgPackDeserializer { template DeserializationError parse(VariantData &variant, TFilter filter, NestingLimit nestingLimit) { - parseVariant(variant, filter, nestingLimit); + parseVariant(&variant, filter, nestingLimit); return _foundSomething ? _error : DeserializationError::EmptyInput; } @@ -41,9 +41,9 @@ class MsgPackDeserializer { } template - bool parseVariant(VariantData &variant, TFilter filter, + bool parseVariant(VariantData *variant, TFilter filter, NestingLimit nestingLimit) { - uint8_t code = 0; + uint8_t code = 0; // TODO: why do we need to initialize this variable? if (!readByte(code)) return false; @@ -61,12 +61,12 @@ class MsgPackDeserializer { case 0xc2: if (allowValue) - variant.setBoolean(false); + variant->setBoolean(false); return true; case 0xc3: if (allowValue) - variant.setBoolean(true); + variant->setBoolean(true); return true; case 0xc4: // bin 8 (not supported) @@ -217,7 +217,7 @@ class MsgPackDeserializer { } if (allowValue) - variant.setInteger(static_cast(code)); + variant->setInteger(static_cast(code)); return true; } @@ -263,39 +263,39 @@ class MsgPackDeserializer { } template - bool readInteger(VariantData &variant) { + bool readInteger(VariantData *variant) { T value; if (!readInteger(value)) return false; - variant.setInteger(value); + variant->setInteger(value); return true; } template typename enable_if::type readFloat( - VariantData &variant) { + VariantData *variant) { T value; if (!readBytes(value)) return false; fixEndianess(value); - variant.setFloat(value); + variant->setFloat(value); return true; } template typename enable_if::type readDouble( - VariantData &variant) { + VariantData *variant) { T value; if (!readBytes(value)) return false; fixEndianess(value); - variant.setFloat(value); + variant->setFloat(value); return true; } template typename enable_if::type readDouble( - VariantData &variant) { + VariantData *variant) { uint8_t i[8]; // input is 8 bytes T value; // output is 4 bytes uint8_t *o = reinterpret_cast(&value); @@ -303,12 +303,12 @@ class MsgPackDeserializer { return false; doubleToFloat(i, o); fixEndianess(value); - variant.setFloat(value); + variant->setFloat(value); return true; } template - bool readString(VariantData &variant) { + bool readString(VariantData *variant) { T size; if (!readInteger(size)) return false; @@ -331,11 +331,11 @@ class MsgPackDeserializer { return skipBytes(size); } - bool readString(VariantData &variant, size_t n) { + bool readString(VariantData *variant, size_t n) { if (!readString(n)) return false; - variant.setStringPointer(_stringStorage.save(), - typename TStringStorage::storage_policy()); + variant->setStringPointer(_stringStorage.save(), + typename TStringStorage::storage_policy()); return true; } @@ -357,7 +357,7 @@ class MsgPackDeserializer { } template - bool readArray(VariantData &variant, TFilter filter, + bool readArray(VariantData *variant, TFilter filter, NestingLimit nestingLimit) { TSize size; if (!readInteger(size)) @@ -366,7 +366,7 @@ class MsgPackDeserializer { } template - bool readArray(VariantData &variant, size_t n, TFilter filter, + bool readArray(VariantData *variant, size_t n, TFilter filter, NestingLimit nestingLimit) { if (nestingLimit.reached()) { _error = DeserializationError::TooDeep; @@ -375,7 +375,7 @@ class MsgPackDeserializer { bool allowArray = filter.allowArray(); - CollectionData *array = allowArray ? &variant.toArray() : 0; + CollectionData *array = allowArray ? &variant->toArray() : 0; TFilter memberFilter = filter[0U]; @@ -392,7 +392,7 @@ class MsgPackDeserializer { value = 0; } - if (!parseVariant(*value, memberFilter, nestingLimit.decrement())) + if (!parseVariant(value, memberFilter, nestingLimit.decrement())) return false; } @@ -400,7 +400,7 @@ class MsgPackDeserializer { } template - bool readObject(VariantData &variant, TFilter filter, + bool readObject(VariantData *variant, TFilter filter, NestingLimit nestingLimit) { TSize size; if (!readInteger(size)) @@ -409,14 +409,14 @@ class MsgPackDeserializer { } template - bool readObject(VariantData &variant, size_t n, TFilter filter, + bool readObject(VariantData *variant, size_t n, TFilter filter, NestingLimit nestingLimit) { if (nestingLimit.reached()) { _error = DeserializationError::TooDeep; return false; } - CollectionData *object = filter.allowObject() ? &variant.toObject() : 0; + CollectionData *object = filter.allowObject() ? &variant->toObject() : 0; for (; n; --n) { if (!readKey()) @@ -444,7 +444,7 @@ class MsgPackDeserializer { member = 0; } - if (!parseVariant(*member, memberFilter, nestingLimit.decrement())) + if (!parseVariant(member, memberFilter, nestingLimit.decrement())) return false; } diff --git a/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp b/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp index bb9d05bb2..b1cd8727c 100644 --- a/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -17,6 +17,8 @@ namespace ARDUINOJSON_NAMESPACE { template class MsgPackSerializer : public Visitor { public: + static const bool producesText = false; + MsgPackSerializer(TWriter writer) : _writer(writer) {} template @@ -101,30 +103,37 @@ class MsgPackSerializer : public Visitor { return bytesWritten(); } - size_t visitNegativeInteger(UInt value) { - UInt negated = UInt(~value + 1); - if (value <= 0x20) { - writeInteger(int8_t(negated)); - } else if (value <= 0x80) { + size_t visitSignedInteger(Integer value) { + if (value > 0) { + visitUnsignedInteger(static_cast(value)); + } else if (value >= -0x20) { + writeInteger(int8_t(value)); + } else if (value >= -0x80) { writeByte(0xD0); - writeInteger(int8_t(negated)); - } else if (value <= 0x8000) { + writeInteger(int8_t(value)); + } else if (value >= -0x8000) { writeByte(0xD1); - writeInteger(int16_t(negated)); - } else if (value <= 0x80000000) { + writeInteger(int16_t(value)); + } +#if ARDUINOJSON_USE_LONG_LONG + else if (value >= -0x80000000LL) +#else + else +#endif + { writeByte(0xD2); - writeInteger(int32_t(negated)); + writeInteger(int32_t(value)); } #if ARDUINOJSON_USE_LONG_LONG else { writeByte(0xD3); - writeInteger(int64_t(negated)); + writeInteger(int64_t(value)); } #endif return bytesWritten(); } - size_t visitPositiveInteger(UInt value) { + size_t visitUnsignedInteger(UInt value) { if (value <= 0x7F) { writeInteger(uint8_t(value)); } else if (value <= 0xFF) { diff --git a/lib/ArduinoJson/src/ArduinoJson/MsgPack/endianess.hpp b/lib/ArduinoJson/src/ArduinoJson/MsgPack/endianess.hpp index ff1bf8ed9..74f7e9dae 100644 --- a/lib/ArduinoJson/src/ArduinoJson/MsgPack/endianess.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/MsgPack/endianess.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/MsgPack/ieee754.hpp b/lib/ArduinoJson/src/ArduinoJson/MsgPack/ieee754.hpp index 19ead87e4..016d5334d 100644 --- a/lib/ArduinoJson/src/ArduinoJson/MsgPack/ieee754.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/MsgPack/ieee754.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Namespace.hpp b/lib/ArduinoJson/src/ArduinoJson/Namespace.hpp index 88b67dd42..2d85440aa 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Namespace.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Namespace.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/Float.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/Float.hpp index de5884ef3..bbaca0454 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Numbers/Float.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Numbers/Float.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatParts.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatParts.hpp index 7bdfe9f37..4e53add39 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatParts.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatParts.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatTraits.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatTraits.hpp index 4286af016..60b1dfd1a 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatTraits.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatTraits.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/Integer.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/Integer.hpp index d5e3a15f4..fb656a7d9 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Numbers/Integer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Numbers/Integer.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/arithmeticCompare.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/arithmeticCompare.hpp index caf6e3361..bfd41d548 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Numbers/arithmeticCompare.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Numbers/arithmeticCompare.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/convertNumber.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/convertNumber.hpp index fad7c6d71..02bbefa50 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Numbers/convertNumber.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Numbers/convertNumber.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -15,84 +15,86 @@ #endif #include -#include -#include #include +#include namespace ARDUINOJSON_NAMESPACE { +// uint32 -> int32 +// uint64 -> int32 template -typename enable_if::value && sizeof(TOut) <= sizeof(TIn), +typename enable_if::value && is_unsigned::value && + is_integral::value && sizeof(TOut) <= sizeof(TIn), bool>::type -canStorePositiveInteger(TIn value) { +canConvertNumber(TIn value) { return value <= TIn(numeric_limits::highest()); } +// uint32 -> int64 template -typename enable_if::value && sizeof(TIn) < sizeof(TOut), +typename enable_if::value && is_unsigned::value && + is_integral::value && sizeof(TIn) < sizeof(TOut), bool>::type -canStorePositiveInteger(TIn) { +canConvertNumber(TIn) { return true; } +// uint32 -> float +// int32 -> float template -typename enable_if::value, bool>::type -canStorePositiveInteger(TIn) { +typename enable_if::value && is_floating_point::value, + bool>::type +canConvertNumber(TIn) { return true; } +// int64 -> int32 template -typename enable_if::value, bool>::type -canStoreNegativeInteger(TIn) { +typename enable_if::value && is_signed::value && + is_integral::value && is_signed::value && + sizeof(TOut) < sizeof(TIn), + bool>::type +canConvertNumber(TIn value) { + return value >= TIn(numeric_limits::lowest()) && + value <= TIn(numeric_limits::highest()); +} + +// int32 -> int32 +// int32 -> int64 +template +typename enable_if::value && is_signed::value && + is_integral::value && is_signed::value && + sizeof(TIn) <= sizeof(TOut), + bool>::type +canConvertNumber(TIn) { return true; } +// int32 -> uint32 template -typename enable_if::value && is_signed::value && - sizeof(TOut) <= sizeof(TIn), +typename enable_if::value && is_signed::value && + is_integral::value && is_unsigned::value, bool>::type -canStoreNegativeInteger(TIn value) { - return value <= TIn(numeric_limits::highest()) + 1; +canConvertNumber(TIn value) { + if (value < 0) + return false; + return value <= TIn(numeric_limits::highest()); } +// float -> int32 +// float -> int64 template -typename enable_if::value && is_signed::value && - sizeof(TIn) < sizeof(TOut), +typename enable_if::value && + !is_floating_point::value, bool>::type -canStoreNegativeInteger(TIn) { - return true; -} - -template -typename enable_if::value && is_unsigned::value, - bool>::type -canStoreNegativeInteger(TIn) { - return false; -} - -template -TOut convertPositiveInteger(TIn value) { - return canStorePositiveInteger(value) ? TOut(value) : 0; -} - -template -TOut convertNegativeInteger(TIn value) { - return canStoreNegativeInteger(value) ? TOut(~value + 1) : 0; -} - -template -typename enable_if::value, TOut>::type convertFloat( - TIn value) { - return TOut(value); -} - -template -typename enable_if::value, TOut>::type convertFloat( - TIn value) { +canConvertNumber(TIn value) { return value >= numeric_limits::lowest() && - value <= numeric_limits::highest() - ? TOut(value) - : 0; + value <= numeric_limits::highest(); +} + +template +TOut convertNumber(TIn value) { + return canConvertNumber(value) ? TOut(value) : 0; } } // namespace ARDUINOJSON_NAMESPACE diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/parseNumber.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/parseNumber.hpp index eb3ce579c..cf050c78d 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Numbers/parseNumber.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Numbers/parseNumber.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include namespace ARDUINOJSON_NAMESPACE { @@ -69,11 +69,17 @@ inline bool parseNumber(const char* s, VariantData& result) { } if (*s == '\0') { - if (is_negative) - result.setNegativeInteger(UInt(mantissa)); - else - result.setPositiveInteger(UInt(mantissa)); - return true; + if (is_negative) { + const mantissa_t sintMantissaMax = mantissa_t(1) + << (sizeof(Integer) * 8 - 1); + if (mantissa <= sintMantissaMax) { + result.setInteger(Integer(~mantissa + 1)); + return true; + } + } else { + result.setInteger(UInt(mantissa)); + return true; + } } // avoid mantissa overflow @@ -142,6 +148,6 @@ inline T parseNumber(const char* s) { VariantData value; value.init(); // VariantData is a POD, so it has no constructor parseNumber(s, value); - return variantAs(&value); + return Converter::fromJson(VariantConstRef(&value)); } } // namespace ARDUINOJSON_NAMESPACE diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp index c3cd9d514..0bee84bf2 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -46,20 +46,6 @@ class MemberProxy : public VariantOperators >, template FORCE_INLINE typename enable_if::value, this_type &>::type operator=(const TValue &src) { - /******************************************************************** - ** THIS IS NOT A BUG IN THE LIBRARY ** - ** -------------------------------- ** - ** Get a compilation error pointing here? ** - ** It doesn't mean the error *is* here. ** - ** Often, it's because you try to assign the wrong value type. ** - ** ** - ** For example: ** - ** char age = 42 ** - ** doc["age"] = age; ** - ** Instead, use: ** - ** int8_t age = 42; ** - ** doc["age"] = age; ** - ********************************************************************/ getOrAddUpstreamMember().set(src); return *this; } @@ -81,9 +67,17 @@ class MemberProxy : public VariantOperators >, return getUpstreamMember().isNull(); } - template - FORCE_INLINE typename VariantAs::type as() const { - return getUpstreamMember().template as(); + template + FORCE_INLINE typename enable_if::value, T>::type as() + const { + return getUpstreamMember().template as(); + } + + template + FORCE_INLINE typename enable_if::value, const char *>::type + ARDUINOJSON_DEPRECATED("Replace as() with as()") + as() const { + return as(); } template @@ -193,6 +187,10 @@ class MemberProxy : public VariantOperators >, return _object.getOrAddMember(_key); } + friend bool convertToJson(const this_type &src, VariantRef dst) { + return dst.set(src.getUpstreamMember()); + } + TObject _object; TStringRef _key; }; diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectFunctions.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectFunctions.hpp index b784c86e6..1b46e8426 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectFunctions.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectFunctions.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectImpl.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectImpl.hpp index 97c6e8ce0..d66b61cad 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectImpl.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectImpl.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectIterator.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectIterator.hpp index 6f70c5d9f..d72945990 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectIterator.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectIterator.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectRef.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectRef.hpp index 618f1ecdb..c945fb6ca 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectRef.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectRef.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -236,4 +236,42 @@ class ObjectRef : public ObjectRefBase, private: MemoryPool* _pool; }; + +template <> +struct Converter { + static bool toJson(VariantConstRef src, VariantRef dst) { + return variantCopyFrom(getData(dst), getData(src), getPool(dst)); + } + + static ObjectConstRef fromJson(VariantConstRef src) { + return ObjectConstRef(variantAsObject(getData(src))); + } + + static bool checkJson(VariantConstRef src) { + const VariantData* data = getData(src); + return data && data->isObject(); + } +}; + +template <> +struct Converter { + static bool toJson(VariantConstRef src, VariantRef dst) { + return variantCopyFrom(getData(dst), getData(src), getPool(dst)); + } + + static ObjectRef fromJson(VariantRef src) { + VariantData* data = getData(src); + MemoryPool* pool = getPool(src); + return ObjectRef(pool, data != 0 ? data->asObject() : 0); + } + + static bool checkJson(VariantConstRef) { + return false; + } + + static bool checkJson(VariantRef src) { + VariantData* data = getData(src); + return data && data->isObject(); + } +}; } // namespace ARDUINOJSON_NAMESPACE diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectShortcuts.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectShortcuts.hpp index 579adc746..0f3409f5f 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectShortcuts.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectShortcuts.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/Pair.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/Pair.hpp index 213426c6a..44fce7518 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Object/Pair.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Object/Pair.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/alias_cast.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/alias_cast.hpp index b7a040ee1..8f8e2770c 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/alias_cast.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/alias_cast.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/assert.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/assert.hpp index 5fa2b4598..1030ec60e 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/assert.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/assert.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/attributes.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/attributes.hpp index 66fd688f2..f04c9acce 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/attributes.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/attributes.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -8,23 +8,32 @@ #define FORCE_INLINE // __forceinline causes C4714 when returning std::string #define NO_INLINE __declspec(noinline) -#define DEPRECATED(msg) __declspec(deprecated(msg)) + +#ifndef ARDUINOJSON_DEPRECATED +#define ARDUINOJSON_DEPRECATED(msg) __declspec(deprecated(msg)) +#endif #elif defined(__GNUC__) // GCC or Clang #define FORCE_INLINE __attribute__((always_inline)) #define NO_INLINE __attribute__((noinline)) + +#ifndef ARDUINOJSON_DEPRECATED #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -#define DEPRECATED(msg) __attribute__((deprecated(msg))) +#define ARDUINOJSON_DEPRECATED(msg) __attribute__((deprecated(msg))) #else -#define DEPRECATED(msg) __attribute__((deprecated)) +#define ARDUINOJSON_DEPRECATED(msg) __attribute__((deprecated)) +#endif #endif #else // Other compilers #define FORCE_INLINE #define NO_INLINE -#define DEPRECATED(msg) + +#ifndef ARDUINOJSON_DEPRECATED +#define ARDUINOJSON_DEPRECATED(msg) +#endif #endif diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/ctype.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/ctype.hpp index fd3683d6a..bd7a8cc65 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/ctype.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/ctype.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/integer.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/integer.hpp index 2d9985ded..066c7b800 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/integer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/integer.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/limits.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/limits.hpp index 65cd79ffc..80048284b 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/limits.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/limits.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/math.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/math.hpp index 635200c32..eff272add 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/math.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/math.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/mpl/max.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/mpl/max.hpp index 21484cd51..9ac47a53d 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/mpl/max.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/mpl/max.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace.hpp index d0333aaa0..f253818e0 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace_generic.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace_generic.hpp index 39c3755c0..f5bbd85e5 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace_generic.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace_generic.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/preprocessor.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/preprocessor.hpp index a3370c14c..488654b21 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/preprocessor.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/preprocessor.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/safe_strcmp.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/safe_strcmp.hpp index dcb175ba6..e017b5dda 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/safe_strcmp.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/safe_strcmp.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/static_array.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/static_array.hpp index eac4d9472..a877b4caa 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/static_array.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/static_array.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits.hpp index 6d6ffb675..4a8ff4b94 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/conditional.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/conditional.hpp index 3ae1d2838..e42d1bb99 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/conditional.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/conditional.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/declval.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/declval.hpp index 541cae46e..87081123a 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/declval.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/declval.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/enable_if.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/enable_if.hpp index 4e1f0a7c4..cc29b3375 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/enable_if.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/enable_if.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/integral_constant.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/integral_constant.hpp index 98a8a44b3..b53d7111c 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/integral_constant.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/integral_constant.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_array.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_array.hpp index eb6148a80..ee739a70a 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_array.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_array.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp index 2af9a6282..32b41cd95 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_class.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_class.hpp index 05bceeebd..a3808f3a3 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_class.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_class.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_const.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_const.hpp index a49b0b61a..32e758c98 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_const.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_const.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_convertible.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_convertible.hpp index 7f2724320..847525a93 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_convertible.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_convertible.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_enum.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_enum.hpp index 973d937b2..26aec1de0 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_enum.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_enum.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp index d2a26c8ad..b7e9d3d24 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_integral.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_integral.hpp index 61ef33120..26e895c8a 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_integral.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_integral.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_pointer.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_pointer.hpp index 39d286978..a24953964 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_pointer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_pointer.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_same.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_same.hpp index 374f9e56c..db5da9bdf 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_same.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_same.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_signed.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_signed.hpp index 08b27e654..fbb701cf7 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_signed.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_signed.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp index 8a24e592b..be2649829 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/make_unsigned.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/make_unsigned.hpp index 97c7bcc5f..4cf2d08b8 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/make_unsigned.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/make_unsigned.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_const.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_const.hpp index 9adae4a3f..5a19eb18d 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_const.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_const.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp index 7098d322d..181285087 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/type_identity.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/type_identity.hpp index d1b6052c1..c464a47c3 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/type_identity.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/type_identity.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/utility.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/utility.hpp index 363e1ae45..c99bc9919 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/utility.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/utility.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/CountingDecorator.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/CountingDecorator.hpp index bd4432c18..3d89fb1d6 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Serialization/CountingDecorator.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Serialization/CountingDecorator.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writer.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writer.hpp index cbbc5ca73..52bd1175d 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writer.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp index ba0adfb5d..5efa6e492 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/DummyWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/DummyWriter.hpp index d8561de96..a26a1f1cf 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/DummyWriter.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/DummyWriter.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/PrintWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/PrintWriter.hpp index d702bd894..13a64912c 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/PrintWriter.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/PrintWriter.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StaticStringWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StaticStringWriter.hpp index e36779335..1a4213b83 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StaticStringWriter.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StaticStringWriter.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -8,18 +8,14 @@ namespace ARDUINOJSON_NAMESPACE { -// A Print implementation that allows to write in a char[] class StaticStringWriter { public: - StaticStringWriter(char *buf, size_t size) : end(buf + size - 1), p(buf) { - *p = '\0'; - } + StaticStringWriter(char *buf, size_t size) : end(buf + size), p(buf) {} size_t write(uint8_t c) { if (p >= end) return 0; *p++ = static_cast(c); - *p = '\0'; return 1; } @@ -29,7 +25,6 @@ class StaticStringWriter { *p++ = static_cast(*s++); n--; } - *p = '\0'; return size_t(p - begin); } diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStreamWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStreamWriter.hpp index d0d534289..e08ba4d60 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStreamWriter.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStreamWriter.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp index eb56b2b32..c1f7cc00f 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/measure.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/measure.hpp index 7b656f650..6d199944c 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Serialization/measure.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Serialization/measure.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/serialize.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/serialize.hpp index 73a720e2e..16d2e4ef1 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Serialization/serialize.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Serialization/serialize.hpp @@ -1,4 +1,4 @@ -// ArduinoJson - arduinojson.org +// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License @@ -23,11 +23,23 @@ size_t serialize(const TSource &source, TDestination &destination) { } template