From 690033c2d1ede7381a92fb5d052096e1198facbb Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 5 Nov 2020 16:51:16 +0100 Subject: [PATCH 01/55] F-Keys Linux+Putty, multible commands with ';' --- lib/uuid-console/src/shell.cpp | 163 +++++++++++++++------------------ 1 file changed, 72 insertions(+), 91 deletions(-) diff --git a/lib/uuid-console/src/shell.cpp b/lib/uuid-console/src/shell.cpp index 7156bddfd..549de97dd 100644 --- a/lib/uuid-console/src/shell.cpp +++ b/lib/uuid-console/src/shell.cpp @@ -213,82 +213,70 @@ void Shell::loop_normal() { default: if (esc_) { - if ((c == '[') || (c == 'O')) { - // start of sequence - } else if (c >= '0' && (c <= '9')) { - // numbers - esc_ = (esc_ & 0x7F) * 10 + c - '0'; - } else if (c == 'A') { - // cursor up + if (c == 'A') { // cursor up line_buffer_ = line_old_; cursor_ = 0; - esc_ = 0; - } else if (c == 'B') { - // cursor down + } else if (c == 'B') { // cursor down line_buffer_.clear(); cursor_ = 0; - esc_ = 0; - } else if (c == 'C') { - // cursor right + } else if (c == 'C') { // cursor right if (cursor_) { cursor_--; } - esc_ = 0; - } else if (c == 'D') { - // cursor left + } else if (c == 'D') { // cursor left if (cursor_ < line_buffer_.length()) { cursor_++; } - esc_ = 0; - } else if (c == 'H') { - // Home + } else if (c == 'H') { // Home cursor_ = line_buffer_.length(); - esc_ = 0; - } else if (c == 'F') { - // End + } else if (c == 'F') { // End cursor_ = 0; - esc_ = 0; - } else if (c == 'P') { - // F1 - set_command_str(F("help")); - esc_ = 0; - } else if (c == 'Q') { - // F2 - set_command_str(F("show")); - esc_ = 0; - } else if (c == '~') { - // function keys with number - if ((esc_ == 3) && cursor_) { - // del + } else if (c >= 'P' && c <= 'Z') { // F1 - F11, Linux, VT100 + // set esc-number like ESCn~ + esc_ = 11 + c - 'P'; + } + if (c == '~' || (c >= 'P' && c <= 'Z')) { // function keys with number ESCn~ + if ((esc_ == 3) && cursor_) { // del cursor_--; line_buffer_.erase(line_buffer_.length() - cursor_ - 1, 1); - } else if (esc_ == 4) { - // end + } else if (esc_ == 4) { // end cursor_ = 0; - } else if (esc_ == 1) { - // pos1 + } else if (esc_ == 1) { // pos1 cursor_ = line_buffer_.length(); - } else if (esc_ == 11) { - // F1 and F10 + } else if (esc_ == 11) { // F1 set_command_str(F("help")); - } else if (esc_ == 12) { - // F2 + } else if (esc_ == 12) { // F2 set_command_str(F("show")); - } else if (esc_ == 20) { - // F9 + } else if (esc_ == 13) { // F3 + set_command_str(F("log notice")); + } else if (esc_ == 14) { // F4 + set_command_str(F("log info")); + } else if (esc_ == 15) { // F5 + set_command_str(F("log debug")); + } else if (esc_ == 17) { // F6 + set_command_str(F("watch off")); + } else if (esc_ == 18) { // F7 + set_command_str(F("watch on")); + } else if (esc_ == 19) { // F8 + set_command_str(F("watch raw")); + } else if (esc_ == 20) { // F9 + set_command_str(F("call system info")); + } else if (esc_ == 21) { // F10 + set_command_str(F("call system report")); + } else if (esc_ == 23) { // F11 line_buffer_ = read_flash_string(F("send telegram \"0B \"")); cursor_ = 1; - } else if (esc_ == 15) { - // F5 - set_command_str(F("call system report")); + } else if (esc_ == 24) { // F12 + set_command_str(F("log debug; watch raw")); } esc_ = 0; - } else { - // all other chars end sequence + } else if (c >= '0' && (c <= '9')) { // numbers + esc_ = (esc_ & 0x7F) * 10 + c - '0'; + } else if ((c != '[') && (c != 'O')) { // all other chars except start of sequence esc_ = 0; } + // process normal ascii text } else if (c >= '\x20' && c <= '\x7E') { - // ASCII text if (line_buffer_.length() < maximum_command_line_length_) { line_buffer_.insert(line_buffer_.length() - cursor_, 1, c); } @@ -506,31 +494,41 @@ void Shell::maximum_command_line_length(size_t length) { } void Shell::process_command() { - CommandLine command_line{line_buffer_}; - - println(); - prompt_displayed_ = false; - - if (!command_line->empty()) { - if (commands_) { - auto execution = commands_->execute_command(*this, std::move(command_line)); - - if (execution.error != nullptr) { - println(execution.error); - } + if (line_buffer_.empty()) { + return; + } + line_old_ = line_buffer_; + while (!line_buffer_.empty()) { + size_t pos = line_buffer_.find(';'); + std::string line1; + if (pos < line_buffer_.length()) { + line1 = line_buffer_.substr(0, pos); + line_buffer_.erase(0, pos + 1); } else { - println(F("No commands configured")); + line1 = line_buffer_; + line_buffer_.clear(); + cursor_ = 0; } - line_old_ = line_buffer_; - } + CommandLine command_line{line1}; - cursor_ = 0; - line_buffer_.clear(); + println(); + prompt_displayed_ = false; - if (running()) { - display_prompt(); + if (!command_line->empty()) { + if (commands_) { + auto execution = commands_->execute_command(*this, std::move(command_line)); + if (execution.error != nullptr) { + println(execution.error); + } + } else { + println(F("No commands configured")); + } + } + ::yield(); } - ::yield(); + // if (running()) { + // display_prompt(); + // } } void Shell::process_completion() { @@ -538,11 +536,9 @@ void Shell::process_completion() { if (!command_line->empty() && commands_) { auto completion = commands_->complete_command(*this, command_line); - bool redisplay = false; if (!completion.help.empty()) { println(); - redisplay = true; for (auto & help : completion.help) { std::string help_line = help.to_string(maximum_command_line_length_); @@ -552,18 +548,8 @@ void Shell::process_completion() { } if (!completion.replacement->empty()) { - if (!redisplay) { - erase_current_line(); - prompt_displayed_ = false; - redisplay = true; - } - line_buffer_ = completion.replacement.to_string(maximum_command_line_length_); } - - if (redisplay) { - display_prompt(); - } } ::yield(); @@ -587,15 +573,10 @@ void Shell::process_password(bool completed) { } void Shell::invoke_command(const std::string & line) { - if (!line_buffer_.empty()) { - println(); - prompt_displayed_ = false; - } - if (!prompt_displayed_) { - display_prompt(); - } + erase_current_line(); + prompt_displayed_ = false; line_buffer_ = line; - print(line_buffer_); + display_prompt(); process_command(); } From 8165e697a7d08f9608316a487961566cbf22d8c4 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 6 Nov 2020 13:17:51 +0100 Subject: [PATCH 02/55] solar pump working time, #598 --- CHANGELOG_LATEST.md | 1 + src/devices/solar.cpp | 14 +++++++++++--- src/devices/solar.h | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 229cc4451..2d1344466 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -2,6 +2,7 @@ ### Added - function keys in editor: cursor, del, pos1, end. F1=help, F2=show, F10=report +- add sm100 pump working time and energy units ### Fixed - mixer IPM pumpstatus diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index 0dd816302..132fc4a33 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -45,6 +45,7 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s register_telegram_type(0x0364, F("SM100Status"), false, [&](std::shared_ptr t) { process_SM100Status(t); }); register_telegram_type(0x036A, F("SM100Status2"), false, [&](std::shared_ptr t) { process_SM100Status2(t); }); register_telegram_type(0x038E, F("SM100Energy"), true, [&](std::shared_ptr t) { process_SM100Energy(t); }); + register_telegram_type(0x0391, F("SM100Time"), true, [&](std::shared_ptr t) { process_SM100Time(t); }); } } @@ -175,9 +176,9 @@ void Solar::register_mqtt_ha_config(bool force) { Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(solarPumpModulation), this->device_type(), "solarPumpModulation", F_(percent), nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(cylinderPumpModulation), this->device_type(), "cylinderPumpModulation", F_(percent), nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(pumpWorkMin), this->device_type(), "pumpWorkMin", nullptr, nullptr); - Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(energyLastHour), this->device_type(), "energyLastHour", nullptr, nullptr); - Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(energyToday), this->device_type(), "energyToday", nullptr, nullptr); - Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(energyTotal), this->device_type(), "energyTotal", nullptr, nullptr); + Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(energyLastHour), this->device_type(), "energyLastHour", F_(wh), nullptr); + Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(energyToday), this->device_type(), "energyToday", F_(wh), nullptr); + Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(energyTotal), this->device_type(), "energyTotal", F_(kwh), nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(solarPump), this->device_type(), "solarPump", nullptr, nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(valveStatus), this->device_type(), "valveStatus", nullptr, nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(tankHeated), this->device_type(), "tankHeated", nullptr, nullptr); @@ -370,6 +371,13 @@ void Solar::process_SM100Energy(std::shared_ptr telegram) { changed_ |= telegram->read_value(energyTotal_, 8); // total / 10 in kWh } +/* + * SM100Time - type 0x0391 EMS+ for pump working time + */ +void Solar::process_SM100Time(std::shared_ptr telegram) { + changed_ |= telegram->read_value(pumpWorkMin_, 1, 3); +} + /* * Junkers ISM1 Solar Module - type 0x0103 EMS+ for energy readings * e.g. B0 00 FF 00 00 03 32 00 00 00 00 13 00 D6 00 00 00 FB D0 F0 diff --git a/src/devices/solar.h b/src/devices/solar.h index 526bf885b..dcc649a12 100644 --- a/src/devices/solar.h +++ b/src/devices/solar.h @@ -78,6 +78,7 @@ class Solar : public EMSdevice { void process_SM100Status(std::shared_ptr telegram); void process_SM100Status2(std::shared_ptr telegram); void process_SM100Energy(std::shared_ptr telegram); + void process_SM100Time(std::shared_ptr telegram); void process_SM100wwTemperature(std::shared_ptr telegram); void process_SM100wwStatus(std::shared_ptr telegram); From f6ee6ec35fa6b0ad19dc34eb4204ed7ccf8e5650 Mon Sep 17 00:00:00 2001 From: MichaelDvP <59284019+MichaelDvP@users.noreply.github.com> Date: Fri, 6 Nov 2020 14:25:40 +0100 Subject: [PATCH 03/55] show solar pumpWorkMin in shell --- src/devices/solar.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index 132fc4a33..f865945d2 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -77,6 +77,7 @@ void Solar::device_info_web(JsonArray & root) { print_value_json(root, F("energyLastHour"), nullptr, F_(energyLastHour), F_(wh), json); print_value_json(root, F("energyToday"), nullptr, F_(energyToday), F_(wh), json); print_value_json(root, F("energyTotal"), nullptr, F_(energyTotal), F_(kwh), json); + print_value_json(root, F("pumpWorkMin"), nullptr, F_(pumpWorkMin), F_(min), json); if (Helpers::hasValue(pumpWorkMin_)) { JsonObject dataElement = root.createNestedObject(); @@ -111,6 +112,7 @@ void Solar::show_values(uuid::console::Shell & shell) { print_value_json(shell, F("energyLastHour"), nullptr, F_(energyLastHour), F_(wh), json); print_value_json(shell, F("energyToday"), nullptr, F_(energyToday), F_(wh), json); print_value_json(shell, F("energyTotal"), nullptr, F_(energyTotal), F_(kwh), json); + print_value_json(shell, F("pumpWorkMin"), nullptr, F_(pumpWorkMin), F_(min), json); if (Helpers::hasValue(pumpWorkMin_)) { shell.printfln(F(" %s: %d days %d hours %d minutes"), @@ -175,7 +177,7 @@ void Solar::register_mqtt_ha_config(bool force) { Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(heatExchangerTemp), this->device_type(), "heatExchangerTemp", F_(degrees), nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(solarPumpModulation), this->device_type(), "solarPumpModulation", F_(percent), nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(cylinderPumpModulation), this->device_type(), "cylinderPumpModulation", F_(percent), nullptr); - Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(pumpWorkMin), this->device_type(), "pumpWorkMin", nullptr, nullptr); + Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(pumpWorkMin), this->device_type(), "pumpWorkMin", F_(min), nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(energyLastHour), this->device_type(), "energyLastHour", F_(wh), nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(energyToday), this->device_type(), "energyToday", F_(wh), nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(energyTotal), this->device_type(), "energyTotal", F_(kwh), nullptr); From f997e88ca01e77db4fa245eb4abfa32b6aa6fd4f Mon Sep 17 00:00:00 2001 From: MichaelDvP <59284019+MichaelDvP@users.noreply.github.com> Date: Fri, 6 Nov 2020 17:13:34 +0100 Subject: [PATCH 04/55] nofrost temperature signed --- src/devices/thermostat.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 8e949ca69..2fa179193 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -58,7 +58,7 @@ class Thermostat : public EMSdevice { uint8_t heatingtype = EMS_VALUE_UINT_NOTSET; // type of heating: 1 radiator, 2 convectors, 3 floors, 4 room supply uint8_t targetflowtemp = EMS_VALUE_UINT_NOTSET; uint8_t summertemp = EMS_VALUE_UINT_NOTSET; - uint8_t nofrosttemp = EMS_VALUE_UINT_NOTSET; + int8_t nofrosttemp = EMS_VALUE_INT_NOTSET; // signed -20°C to +10°C uint8_t designtemp = EMS_VALUE_UINT_NOTSET; // heating curve design temp at MinExtTemp int8_t offsettemp = EMS_VALUE_INT_NOTSET; // heating curve offest temp at roomtemp signed! uint8_t manualtemp = EMS_VALUE_UINT_NOTSET; @@ -325,4 +325,4 @@ class Thermostat : public EMSdevice { } // namespace emsesp -#endif \ No newline at end of file +#endif From effe7cf54321b2450f7083df658df97e2493d894 Mon Sep 17 00:00:00 2001 From: MichaelDvP <59284019+MichaelDvP@users.noreply.github.com> Date: Sun, 8 Nov 2020 12:43:54 +0100 Subject: [PATCH 05/55] linefeed on empty command --- lib/uuid-console/src/shell.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/uuid-console/src/shell.cpp b/lib/uuid-console/src/shell.cpp index 549de97dd..73258d398 100644 --- a/lib/uuid-console/src/shell.cpp +++ b/lib/uuid-console/src/shell.cpp @@ -495,7 +495,8 @@ void Shell::maximum_command_line_length(size_t length) { void Shell::process_command() { if (line_buffer_.empty()) { - return; + println(); + return; } line_old_ = line_buffer_; while (!line_buffer_.empty()) { From 0823c1bbae60c426b1568343d06377d1e17e2620 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 8 Nov 2020 15:26:22 +0100 Subject: [PATCH 06/55] add heating curve RC300 --- CHANGELOG_LATEST.md | 1 + src/devices/thermostat.cpp | 138 +++++++++++++++++++++++++++++++------ src/devices/thermostat.h | 8 ++- src/locale_EN.h | 1 + 4 files changed, 125 insertions(+), 23 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 2d1344466..b90d40fc7 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -3,6 +3,7 @@ ### Added - function keys in editor: cursor, del, pos1, end. F1=help, F2=show, F10=report - add sm100 pump working time and energy units +- heating curve parameters for RC300 ### Fixed - mixer IPM pumpstatus diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 184da790c..19ba9d831 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -114,10 +114,12 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i monitor_typeids = {0x02A5, 0x02A6, 0x02A7, 0x02A8}; set_typeids = {0x02B9, 0x02BA, 0x02BB, 0x02BC}; summer_typeids = {0x02AF, 0x02B0, 0x02B1, 0x02B2}; + curve_typeids = {0x029B, 0x029C, 0x029D, 0x029E}; for (uint8_t i = 0; i < monitor_typeids.size(); i++) { register_telegram_type(monitor_typeids[i], F("RC300Monitor"), false, [&](std::shared_ptr t) { process_RC300Monitor(t); }); register_telegram_type(set_typeids[i], F("RC300Set"), false, [&](std::shared_ptr t) { process_RC300Set(t); }); register_telegram_type(summer_typeids[i], F("RC300Summer"), false, [&](std::shared_ptr t) { process_RC300Summer(t); }); + register_telegram_type(curve_typeids[i], F("RC300Curves"), false, [&](std::shared_ptr t) { process_RC300Curve(t); }); } register_telegram_type(0x2F5, F("RC300WWmode"), true, [&](std::shared_ptr t) { process_RC300WWmode(t); }); register_telegram_type(0x31B, F("RC300WWtemp"), true, [&](std::shared_ptr t) { process_RC300WWtemp(t); }); @@ -171,6 +173,9 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i for (uint8_t i = 0; i < summer_typeids.size(); i++) { EMSESP::send_read_request(summer_typeids[i], device_id); } + for (uint8_t i = 0; i < curve_typeids.size(); i++) { + EMSESP::send_read_request(curve_typeids[i], device_id); + } } // namespace emsesp // prepare data for Web UI @@ -226,6 +231,7 @@ void Thermostat::device_info_web(JsonArray & root) { print_value_json(root, F("designtemp"), FPSTR(prefix_str), F_(designtemp), F_(degrees), json); print_value_json(root, F("roominfluence"), FPSTR(prefix_str), F_(roominfluence), F_(degrees), json); print_value_json(root, F("flowtempoffset"), FPSTR(prefix_str), F_(flowtempoffset), F_(degrees), json); + print_value_json(root, F("maxflowtemp"), F_(2spaces), F_(maxflowtemp), F_(degrees), json); print_value_json(root, F("summertemp"), FPSTR(prefix_str), F_(summertemp), F_(degrees), json); print_value_json(root, F("summermode"), FPSTR(prefix_str), F_(summermode), F_(degrees), json); print_value_json(root, F("mode"), FPSTR(prefix_str), F_(mode), nullptr, json); @@ -310,6 +316,7 @@ void Thermostat::show_values(uuid::console::Shell & shell) { print_value_json(shell, F("designtemp"), F_(2spaces), F_(designtemp), F_(degrees), json); print_value_json(shell, F("roominfluence"), F_(2spaces), F_(roominfluence), F_(degrees), json); print_value_json(shell, F("flowtempoffset"), F_(2spaces), F_(flowtempoffset), F_(degrees), json); + print_value_json(shell, F("maxflowtemp"), F_(2spaces), F_(maxflowtemp), F_(degrees), json); print_value_json(shell, F("summertemp"), F_(2spaces), F_(summertemp), F_(degrees), json); print_value_json(shell, F("summermode"), F_(2spaces), F_(summermode), F_(degrees), json); print_value_json(shell, F("mode"), F_(2spaces), F_(mode), nullptr, json); @@ -600,6 +607,11 @@ bool Thermostat::export_values_hc(uint8_t mqtt_format, JsonObject & rootThermost dataThermostat["flowtempoffset"] = hc->flowtempoffset; } + // Flow temperature offset + if (Helpers::hasValue(hc->maxflowtemp)) { + dataThermostat["maxflowtemp"] = hc->maxflowtemp; + } + // Summer temperature if (Helpers::hasValue(hc->summertemp)) { dataThermostat["summertemp"] = hc->summertemp; @@ -679,13 +691,15 @@ std::shared_ptr Thermostat::heating_circuit(const ui // if hc_num is 0 then return the first existing hc in the list if (hc_num == AUTO_HEATING_CIRCUIT) { for (const auto & heating_circuit : heating_circuits_) { - return heating_circuit; + if (heating_circuit->is_active()) { + return heating_circuit; + } } } // otherwise find a match for (const auto & heating_circuit : heating_circuits_) { - if (heating_circuit->hc_num() == hc_num) { + if ((heating_circuit->hc_num() == hc_num) && heating_circuit->is_active()) { return heating_circuit; } } @@ -808,6 +822,7 @@ void Thermostat::register_mqtt_ha_config() { if (model == EMS_DEVICE_FLAG_RC300 || model == EMS_DEVICE_FLAG_RC100) { Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(dampedtemp), this->device_type(), "dampedtemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(building), this->device_type(), "building", nullptr, nullptr); + Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(minexttemp), this->device_type(), "minexttemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(floordry), this->device_type(), "floordry", nullptr, nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(floordrytemp), this->device_type(), "floordrytemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(wwmode), this->device_type(), "wwmode", nullptr, nullptr); @@ -927,6 +942,11 @@ void Thermostat::register_mqtt_ha_config(uint8_t hc_num) { Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(manualtemp), this->device_type(), "manualtemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(comforttemp), this->device_type(), "comforttemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(summertemp), this->device_type(), "summertemp", F_(degrees), F_(icontemperature)); + Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(designtemp), this->device_type(), "designtemp", F_(degrees), F_(icontemperature)); + Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(offsettemp), this->device_type(), "offsettemp", F_(degrees), F_(icontemperature)); + Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(maxflowtemp), this->device_type(), "maxflowtemp", F_(degrees), F_(icontemperature)); + Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(roominfluence), this->device_type(), "roominfluence", F_(degrees), F_(icontemperature)); + Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(nofrosttemp), this->device_type(), "nofrosttemp", F_(degrees), F_(icontemperature)); break; case EMS_DEVICE_FLAG_RC20_2: Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(daytemp), this->device_type(), "daytemp", F_(degrees), F_(icontemperature)); @@ -944,6 +964,7 @@ void Thermostat::register_mqtt_ha_config(uint8_t hc_num) { Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(summertemp), this->device_type(), "summertemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(nofrosttemp), this->device_type(), "nofrosttemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(roominfluence), this->device_type(), "roominfluence", F_(degrees), F_(icontemperature)); + Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(maxflowtemp), this->device_type(), "maxflowtemp", F_(degrees), F_(icontemperature)); break; case EMS_DEVICE_FLAG_JUNKERS: Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(modetype), this->device_type(), "modetype", nullptr, nullptr); @@ -1094,6 +1115,12 @@ std::string Thermostat::mode_tostring(uint8_t mode) { case HeatingCircuit::Mode::DESIGN: return read_flash_string(F("design")); break; + case HeatingCircuit::Mode::MAXFLOW: + return read_flash_string(F("maxflow")); + break; + case HeatingCircuit::Mode::ROOMINFLUENCE: + return read_flash_string(F("roominfluence")); + break; default: case HeatingCircuit::Mode::UNKNOWN: return read_flash_string(F("unknown")); @@ -1268,8 +1295,28 @@ void Thermostat::process_RC300Set(std::shared_ptr telegram) { // types 0x2AF ff void Thermostat::process_RC300Summer(std::shared_ptr telegram) { std::shared_ptr hc = heating_circuit(telegram); + changed_ |= telegram->read_value(hc->roominfluence, 0); + changed_ |= telegram->read_value(hc->offsettemp, 2); changed_ |= telegram->read_value(hc->summertemp, 6); changed_ |= telegram->read_value(hc->summer_setmode, 7); + if (hc->heatingtype < 3) { + changed_ |= telegram->read_value(hc->designtemp, 4); + } else { + changed_ |= telegram->read_value(hc->designtemp, 5); + } +} + +// types 0x29B ff +void Thermostat::process_RC300Curve(std::shared_ptr telegram) { + std::shared_ptr hc = heating_circuit(telegram); + changed_ |= telegram->read_value(hc->heatingtype, 1); // 1=radiator, 2=convector, 3=floor + changed_ |= telegram->read_value(hc->nofrosttemp, 6); + if (hc->heatingtype < 3) { + changed_ |= telegram->read_value(hc->maxflowtemp, 8); + } else { + changed_ |= telegram->read_value(hc->maxflowtemp, 7); + } + } // types 0x31B (and 0x31C?) @@ -1306,6 +1353,7 @@ void Thermostat::process_RC300OutdoorTemp(std::shared_ptr telegr // 0x240 RC300 parameter void Thermostat::process_RC300Settings(std::shared_ptr telegram) { changed_ |= telegram->read_value(ibaBuildingType_, 9); // 1=light, 2=medium, 3=heavy + changed_ |= telegram->read_value(ibaMinExtTemperature_, 10); } // 0x267 RC300 floordrying @@ -1564,24 +1612,6 @@ bool Thermostat::set_control(const char * value, const int8_t id) { return true; } -// Set roominfluence -bool Thermostat::set_roominfluence(const char * value, const int8_t id) { - uint8_t hc_num = (id == -1) ? AUTO_HEATING_CIRCUIT : id; - std::shared_ptr hc = heating_circuit(hc_num); - if (hc == nullptr) { - LOG_WARNING(F("Set roominfluence: Heating Circuit %d not found or activated"), hc_num); - return false; - } - int t = 0; - if (!Helpers::value2number(value, t)) { - LOG_WARNING(F("Set roominfluence: Invalid value")); - return false; - } - LOG_INFO(F("Setting roominfluence to %d"), t); - write_command(set_typeids[hc->hc_num() - 1], 4, t, set_typeids[hc->hc_num() - 1]); - return true; -} - // sets the thermostat ww working mode, where mode is a string, ems and ems+ bool Thermostat::set_wwmode(const char * value, const int8_t id) { uint8_t set = 0xFF; @@ -1957,6 +1987,12 @@ bool Thermostat::set_temperature(const float temperature, const std::string & mo if (mode_tostring(HeatingCircuit::Mode::DESIGN) == mode) { return set_temperature(temperature, HeatingCircuit::Mode::DESIGN, hc_num); } + if (mode_tostring(HeatingCircuit::Mode::MAXFLOW) == mode) { + return set_temperature(temperature, HeatingCircuit::Mode::DESIGN, hc_num); + } + if (mode_tostring(HeatingCircuit::Mode::ROOMINFLUENCE) == mode) { + return set_temperature(temperature, HeatingCircuit::Mode::DESIGN, hc_num); + } LOG_WARNING(F("Set temperature: Invalid mode")); return false; @@ -2005,7 +2041,44 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co case HeatingCircuit::Mode::ECO: offset = 0x04; // eco offset break; - default: + case HeatingCircuit::Mode::OFFSET: + offset = 2; + set_typeid = summer_typeids[hc->hc_num() - 1]; + validate_typeid = set_typeid; + break; + case HeatingCircuit::Mode::DESIGN: + set_typeid = summer_typeids[hc->hc_num() - 1]; + validate_typeid = set_typeid; + if (hc->heatingtype == 3) { + offset = 5; + } else { + offset = 4; + } + factor = 1; + break; + case HeatingCircuit::Mode::MAXFLOW: + set_typeid = curve_typeids[hc->hc_num() - 1]; + validate_typeid = set_typeid; + if (hc->heatingtype == 3) { + offset = 7; + } else { + offset = 8; + } + factor = 1; + break; + case HeatingCircuit::Mode::NOFROST: + set_typeid = curve_typeids[hc->hc_num() - 1]; + validate_typeid = set_typeid; + offset = 6; + factor = 1; + break; + case HeatingCircuit::Mode::ROOMINFLUENCE: + set_typeid = summer_typeids[hc->hc_num() - 1]; + validate_typeid = set_typeid; + offset = 0; + factor = 1; + break; + default: case HeatingCircuit::Mode::AUTO: uint8_t mode_ = hc->get_mode(this->flags()); if (mode_ == HeatingCircuit::Mode::MANUAL) { @@ -2067,6 +2140,14 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co offset = EMS_OFFSET_RC35Set_temp_nofrost; factor = 1; break; + case HeatingCircuit::Mode::ROOMINFLUENCE: + offset = 4; + factor = 1; + break; + case HeatingCircuit::Mode::MAXFLOW: + offset = 15; + factor = 1; + break; default: case HeatingCircuit::Mode::AUTO: // automatic selection, if no type is defined, we use the standard code validate_typeid = monitor_typeids[hc->hc_num() - 1]; //get setpoint roomtemp back @@ -2226,6 +2307,14 @@ bool Thermostat::set_flowtempoffset(const char * value, const int8_t id) { return set_temperature_value(value, id, HeatingCircuit::Mode::FLOWOFFSET); } +bool Thermostat::set_maxflowtemp(const char * value, const int8_t id) { + return set_temperature_value(value, id, HeatingCircuit::Mode::MAXFLOW); +} + +bool Thermostat::set_roominfluence(const char * value, const int8_t id) { + return set_temperature_value(value, id, HeatingCircuit::Mode::ROOMINFLUENCE); +} + // API commands for MQTT and Console void Thermostat::add_commands() { // if this thermostat doesn't support write, don't add the commands @@ -2251,6 +2340,12 @@ void Thermostat::add_commands() { register_mqtt_cmd(F("wwtemp"), [&](const char * value, const int8_t id) { return set_wwtemp(value, id); }); register_mqtt_cmd(F("wwtemplow"), [&](const char * value, const int8_t id) { return set_wwtemplow(value, id); }); register_mqtt_cmd(F("building"), [&](const char * value, const int8_t id) { return set_building(value, id); }); + register_mqtt_cmd(F("nofrosttemp"), [&](const char * value, const int8_t id) { return set_nofrosttemp(value, id); }); + register_mqtt_cmd(F("designtemp"), [&](const char * value, const int8_t id) { return set_designtemp(value, id); }); + register_mqtt_cmd(F("offsettemp"), [&](const char * value, const int8_t id) { return set_offsettemp(value, id); }); + register_mqtt_cmd(F("maxflowtemp"), [&](const char * value, const int8_t id) { return set_maxflowtemp(value, id); }); + register_mqtt_cmd(F("minexttemp"), [&](const char * value, const int8_t id) { return set_minexttemp(value, id); }); + register_mqtt_cmd(F("roominfluence"), [&](const char * value, const int8_t id) { return set_roominfluence(value, id); }); break; case EMS_DEVICE_FLAG_RC20_2: register_mqtt_cmd(F("nighttemp"), [&](const char * value, const int8_t id) { return set_nighttemp(value, id); }); @@ -2280,6 +2375,7 @@ void Thermostat::add_commands() { register_mqtt_cmd(F("wwcircmode"), [&](const char * value, const int8_t id) { return set_wwcircmode(value, id); }); register_mqtt_cmd(F("roominfluence"), [&](const char * value, const int8_t id) { return set_roominfluence(value, id); }); register_mqtt_cmd(F("flowtempoffset"), [&](const char * value, const int8_t id) { return set_flowtempoffset(value, id); }); + register_mqtt_cmd(F("maxflowtemp"), [&](const char * value, const int8_t id) { return set_maxflowtemp(value, id); }); break; case EMS_DEVICE_FLAG_JUNKERS: register_mqtt_cmd(F("nofrosttemp"), [&](const char * value, const int8_t id) { return set_nofrosttemp(value, id); }); diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 2fa179193..8e0902c65 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -65,6 +65,7 @@ class Thermostat : public EMSdevice { uint8_t summer_setmode = EMS_VALUE_UINT_NOTSET; uint8_t roominfluence = EMS_VALUE_UINT_NOTSET; uint8_t flowtempoffset = EMS_VALUE_UINT_NOTSET; + uint8_t maxflowtemp = EMS_VALUE_UINT_NOTSET; uint8_t hc_num() const { return hc_num_; @@ -86,7 +87,7 @@ class Thermostat : public EMSdevice { uint8_t get_mode(uint8_t flags) const; uint8_t get_mode_type(uint8_t flags) const; - enum Mode : uint8_t { UNKNOWN, OFF, MANUAL, AUTO, DAY, NIGHT, HEAT, NOFROST, ECO, HOLIDAY, COMFORT, OFFSET, DESIGN, SUMMER, FLOWOFFSET }; + enum Mode : uint8_t { UNKNOWN, OFF, MANUAL, AUTO, DAY, NIGHT, HEAT, NOFROST, ECO, HOLIDAY, COMFORT, OFFSET, DESIGN, SUMMER, FLOWOFFSET, MAXFLOW, ROOMINFLUENCE }; // for sorting based on hc number friend inline bool operator<(const std::shared_ptr & lhs, const std::shared_ptr & rhs) { @@ -131,6 +132,7 @@ class Thermostat : public EMSdevice { std::vector set_typeids; std::vector timer_typeids; std::vector summer_typeids; + std::vector curve_typeids; std::string datetime_; // date and time stamp std::string errorCode_; // code from 0xA2 as string i.e. "A22(816)" @@ -273,6 +275,7 @@ class Thermostat : public EMSdevice { void process_RC300OutdoorTemp(std::shared_ptr telegram); void process_RC300Settings(std::shared_ptr telegram); void process_RC300Floordry(std::shared_ptr telegram); + void process_RC300Curve(std::shared_ptr telegram); void process_JunkersMonitor(std::shared_ptr telegram); void process_JunkersSet(std::shared_ptr telegram); void process_JunkersSet2(std::shared_ptr telegram); @@ -308,6 +311,7 @@ class Thermostat : public EMSdevice { bool set_remotetemp(const char * value, const int8_t id); bool set_roominfluence(const char * value, const int8_t id); bool set_flowtempoffset(const char * value, const int8_t id); + bool set_maxflowtemp(const char * value, const int8_t id); // set functions - these don't use the id/hc, the parameters are ignored bool set_wwmode(const char * value, const int8_t id); @@ -325,4 +329,4 @@ class Thermostat : public EMSdevice { } // namespace emsesp -#endif +#endif \ No newline at end of file diff --git a/src/locale_EN.h b/src/locale_EN.h index d9bfa5d74..a5c35175f 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -266,6 +266,7 @@ MAKE_PSTR(summertemp, "Summer temperature") MAKE_PSTR(summermode, "Summer mode") MAKE_PSTR(roominfluence, "Room influence") MAKE_PSTR(flowtempoffset, "Flow temperature offset") +MAKE_PSTR(maxflowtemp, "Max. flow temperature") MAKE_PSTR(mode, "Mode") MAKE_PSTR(modetype, "Mode type") From bb9ca4fc29d540f52ea7bcd757a48bb054898f79 Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 8 Nov 2020 20:21:18 +0100 Subject: [PATCH 07/55] debug comments --- lib/framework/FSPersistence.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/framework/FSPersistence.h b/lib/framework/FSPersistence.h index 390be5ce1..64ec179c2 100644 --- a/lib/framework/FSPersistence.h +++ b/lib/framework/FSPersistence.h @@ -33,10 +33,12 @@ class FSPersistence { jsonDocument.shrinkToFit(); // added by proddy JsonObject jsonObject = jsonDocument.as(); - // debug added by Proddy - // Serial.printf("Read File: %s: ", _filePath); - // serializeJson(jsonDocument, Serial); - // Serial.println(); +// debug added by Proddy +#if defined(EMSESP_FORCE_SERIAL) + Serial.printf("Read File: %s: ", _filePath); + serializeJson(jsonDocument, Serial); + Serial.println(); +#endif _statefulService->updateWithoutPropagation(jsonObject, _stateUpdater); settingsFile.close(); @@ -64,12 +66,10 @@ class FSPersistence { return false; } -// debug added by Proddy -#if defined(EMSESP_DEBUG) - Serial.printf("Write File: %s: ", _filePath); - serializeJson(jsonDocument, Serial); - Serial.println(); -#endif + // debug added by Proddy + // Serial.printf("Write File: %s: ", _filePath); + // serializeJson(jsonDocument, Serial); + // Serial.println(); // serialize the data to the file serializeJson(jsonDocument, settingsFile); From 240710fbbe5888da9be342142d0c9689d7b4e32e Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 8 Nov 2020 20:23:01 +0100 Subject: [PATCH 08/55] add syslog enabled - it was causing mem issues with esp32 --- .../src/project/EMSESPSettingsController.tsx | 17 +++++++--- interface/src/project/EMSESPtypes.ts | 1 + lib_standalone/ESP8266React.h | 3 +- src/WebSettingsService.cpp | 2 ++ src/WebSettingsService.h | 4 ++- src/system.cpp | 33 ++++++++++++++----- src/system.h | 1 + 7 files changed, 46 insertions(+), 15 deletions(-) diff --git a/interface/src/project/EMSESPSettingsController.tsx b/interface/src/project/EMSESPSettingsController.tsx index 24871b020..46060536e 100644 --- a/interface/src/project/EMSESPSettingsController.tsx +++ b/interface/src/project/EMSESPSettingsController.tsx @@ -209,11 +209,21 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps) Syslog + + } + label="Enable Syslog" + /> - OFF ERR INFO DEBUG read([&](WiFiSettings & settings) { hostname(settings.hostname.c_str()); }); @@ -207,8 +212,11 @@ void System::upload_status(bool in_progress) { // checks system health and handles LED flashing wizardry void System::loop() { #ifndef EMSESP_STANDALONE - syslog_.loop(); + if (syslog_enabled_) { + syslog_.loop(); + } #endif + led_monitor(); // check status and report back using the LED system_check(); // check system health if (analog_enabled_) { @@ -481,13 +489,18 @@ void System::show_system(uuid::console::Shell & shell) { EMSESP::webSettingsService.read([&](WebSettings & settings) { shell.println(); - shell.printfln(F("Syslog:")); - shell.print(F_(1space)); - shell.printfln(F_(host_fmt), !settings.syslog_host.isEmpty() ? settings.syslog_host.c_str() : uuid::read_flash_string(F_(unset)).c_str()); - shell.print(F_(1space)); - shell.printfln(F_(log_level_fmt), uuid::log::format_level_lowercase(static_cast(settings.syslog_level))); - shell.print(F_(1space)); - shell.printfln(F_(mark_interval_fmt), settings.syslog_mark_interval); + + if (!settings.syslog_enabled) { + shell.printfln(F("Syslog: disabled")); + } else { + shell.printfln(F("Syslog:")); + shell.print(F_(1space)); + shell.printfln(F_(host_fmt), !settings.syslog_host.isEmpty() ? settings.syslog_host.c_str() : uuid::read_flash_string(F_(unset)).c_str()); + shell.print(F_(1space)); + shell.printfln(F_(log_level_fmt), uuid::log::format_level_lowercase(static_cast(settings.syslog_level))); + shell.print(F_(1space)); + shell.printfln(F_(mark_interval_fmt), settings.syslog_mark_interval); + } }); #endif @@ -803,6 +816,7 @@ bool System::check_upgrade() { settings.shower_timer = custom_settings["shower_timer"] | EMSESP_DEFAULT_SHOWER_TIMER; settings.master_thermostat = custom_settings["master_thermostat"] | EMSESP_DEFAULT_MASTER_THERMOSTAT; settings.ems_bus_id = custom_settings["bus_id"] | EMSESP_DEFAULT_EMS_BUS_ID; + settings.syslog_enabled = false; settings.syslog_host = EMSESP_DEFAULT_SYSLOG_HOST; settings.syslog_level = EMSESP_DEFAULT_SYSLOG_LEVEL; settings.syslog_mark_interval = EMSESP_DEFAULT_SYSLOG_MARK_INTERVAL; @@ -918,6 +932,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & json JsonObject node = json.createNestedObject("Settings"); node["tx_mode"] = settings.tx_mode; node["ems_bus_id"] = settings.ems_bus_id; + node["syslog_enabled"] = settings.syslog_enabled; node["syslog_level"] = settings.syslog_level; node["syslog_mark_interval"] = settings.syslog_mark_interval; node["syslog_host"] = settings.syslog_host; diff --git a/src/system.h b/src/system.h index 78f73f01a..32b6a8fae 100644 --- a/src/system.h +++ b/src/system.h @@ -109,6 +109,7 @@ class System { // settings static bool hide_led_; + static bool syslog_enabled_; uint8_t syslog_level_; uint32_t syslog_mark_interval_; String syslog_host_; From 8c207a9ddfa2751b910ec694c69fcf770b6d641d Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 8 Nov 2020 20:23:52 +0100 Subject: [PATCH 09/55] updated arduinojson to 6.17.1 --- lib/ArduinoJson/CHANGELOG.md | 7 ++ lib/ArduinoJson/CONTRIBUTING.md | 11 +++ lib/ArduinoJson/README.md | 2 +- .../src/ArduinoJson/Array/ElementProxy.hpp | 5 +- .../src/ArduinoJson/Configuration.hpp | 17 ++++ .../MsgPack/MsgPackDeserializer.hpp | 2 +- .../src/ArduinoJson/Object/MemberProxy.hpp | 5 +- .../src/ArduinoJson/Polyfills/integer.hpp | 30 +++++++ .../ArduinoJson/Variant/VariantOperators.hpp | 21 ++--- .../src/ArduinoJson/Variant/VariantRef.hpp | 6 +- .../src/ArduinoJson/Variant/VariantSlot.hpp | 14 ++- .../src/ArduinoJson/Variant/VariantTag.hpp | 16 ++++ lib/ArduinoJson/src/ArduinoJson/version.hpp | 4 +- lib/ArduinoJson/src/CMakeLists.txt | 90 ------------------- 14 files changed, 117 insertions(+), 113 deletions(-) create mode 100644 lib/ArduinoJson/CONTRIBUTING.md create mode 100644 lib/ArduinoJson/src/ArduinoJson/Polyfills/integer.hpp create mode 100644 lib/ArduinoJson/src/ArduinoJson/Variant/VariantTag.hpp delete mode 100644 lib/ArduinoJson/src/CMakeLists.txt diff --git a/lib/ArduinoJson/CHANGELOG.md b/lib/ArduinoJson/CHANGELOG.md index d140edaa2..c819bb791 100644 --- a/lib/ArduinoJson/CHANGELOG.md +++ b/lib/ArduinoJson/CHANGELOG.md @@ -1,6 +1,13 @@ ArduinoJson: change log ======================= +v6.17.1 (2020-11-07) +------- + +* Fixed error `ambiguous overload for 'operator|'` (issue #1411) +* Fixed `operator|(MemberProxy, JsonObject)` (issue #1415) +* Allowed more than 32767 values in non-embedded mode (issue #1414) + v6.17.0 (2020-10-19) ------- diff --git a/lib/ArduinoJson/CONTRIBUTING.md b/lib/ArduinoJson/CONTRIBUTING.md new file mode 100644 index 000000000..5d4b96cf9 --- /dev/null +++ b/lib/ArduinoJson/CONTRIBUTING.md @@ -0,0 +1,11 @@ +# Contribution to ArduinoJson + +First, thank you for taking the time to contribute to this project. + +You can submit changes via GitHub Pull Requests. + +Please: + +1. Unit test every change in behavior +2. Use clang-format in "file" mode to format the code +3. Consider using the Continuous Integration (Travis and AppVeyor) diff --git a/lib/ArduinoJson/README.md b/lib/ArduinoJson/README.md index 3516985e8..bbb852728 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.0)](https://www.ardu-badge.com/ArduinoJson/6.17.0) +[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.17.1)](https://www.ardu-badge.com/ArduinoJson/6.17.1) [![Build Status](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/6.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x) [![Build Status](https://travis-ci.org/bblanchon/ArduinoJson.svg?branch=6.x)](https://travis-ci.org/bblanchon/ArduinoJson) [![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) diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp index 6d47ef371..41166b6ae 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp @@ -19,10 +19,13 @@ namespace ARDUINOJSON_NAMESPACE { template class ElementProxy : public VariantOperators >, public VariantShortcuts >, - public Visitable { + public Visitable, + public VariantTag { typedef ElementProxy this_type; public: + typedef VariantRef variant_type; + FORCE_INLINE ElementProxy(TArray array, size_t index) : _array(array), _index(index) {} diff --git a/lib/ArduinoJson/src/ArduinoJson/Configuration.hpp b/lib/ArduinoJson/src/ArduinoJson/Configuration.hpp index 42ba498ef..32a6f339b 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Configuration.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Configuration.hpp @@ -83,6 +83,18 @@ #define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10 #endif +// Number of bits to store the pointer to next node +// (saves RAM but limits the number of values in a document) +#ifndef ARDUINOJSON_SLOT_OFFSET_SIZE +#if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 2 +// Address space == 16-bit => max 127 values +#define ARDUINOJSON_SLOT_OFFSET_SIZE 1 +#else +// Address space > 16-bit => max 32767 values +#define ARDUINOJSON_SLOT_OFFSET_SIZE 2 +#endif +#endif + #else // ARDUINOJSON_EMBEDDED_MODE // On a computer we have plenty of memory so we can use doubles @@ -114,6 +126,11 @@ #define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50 #endif +// Number of bits to store the pointer to next node +#ifndef ARDUINOJSON_SLOT_OFFSET_SIZE +#define ARDUINOJSON_SLOT_OFFSET_SIZE 4 +#endif + #endif // ARDUINOJSON_EMBEDDED_MODE #ifdef ARDUINO diff --git a/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp b/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp index 76228541c..8d9d63d35 100644 --- a/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp @@ -48,7 +48,7 @@ class MsgPackDeserializer { template bool parseVariant(VariantData &variant, TFilter filter, NestingLimit nestingLimit) { - uint8_t code = 0; + uint8_t code = 0; if (!readByte(code)) return false; diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp index a9ee6034f..1963deaea 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp @@ -21,10 +21,13 @@ namespace ARDUINOJSON_NAMESPACE { template class MemberProxy : public VariantOperators >, public VariantShortcuts >, - public Visitable { + public Visitable, + public VariantTag { typedef MemberProxy this_type; public: + typedef VariantRef variant_type; + FORCE_INLINE MemberProxy(TObject variant, TStringRef key) : _object(variant), _key(key) {} diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/integer.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/integer.hpp new file mode 100644 index 000000000..8dfebb092 --- /dev/null +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/integer.hpp @@ -0,0 +1,30 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2020 +// MIT License + +#pragma once + +#include // int8_t, int16_t + +#include + +namespace ARDUINOJSON_NAMESPACE { + +template +struct int_t; + +template <> +struct int_t<8> { + typedef int8_t type; +}; + +template <> +struct int_t<16> { + typedef int16_t type; +}; + +template <> +struct int_t<32> { + typedef int32_t type; +}; +} // namespace ARDUINOJSON_NAMESPACE diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantOperators.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantOperators.hpp index 79379e814..df4e9df28 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantOperators.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantOperators.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace ARDUINOJSON_NAMESPACE { @@ -17,23 +18,23 @@ CompareResult compare(const T1 &lhs, const T2 &rhs); // VariantCompare.cpp template struct VariantOperators { - // Returns the default value if the VariantRef is undefined of incompatible + // Returns the default value if the VariantRef is undefined or incompatible template - friend typename enable_if::value, T>::type operator|( - const TVariant &variant, const T &defaultValue) { + friend typename enable_if::value, T>::type operator|( + const TVariant &variant, T defaultValue) { if (variant.template is()) return variant.template as(); else return defaultValue; } - - // Returns the default value if the VariantRef is undefined of incompatible - // Special case for string: null is treated as undefined + // Returns the default value if the VariantRef is undefined or incompatible template - friend typename enable_if::value, T>::type operator|( - const TVariant &variant, T defaultValue) { - const char *value = variant.template as(); - return value ? value : defaultValue; + friend typename enable_if::value, typename T::variant_type>::type + operator|(const TVariant &variant, T defaultValue) { + if (variant) + return variant; + else + return defaultValue; } // value == TVariant diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantRef.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantRef.hpp index c82ec1eac..a8b9067a6 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantRef.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantRef.hpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace ARDUINOJSON_NAMESPACE { @@ -23,12 +24,9 @@ namespace ARDUINOJSON_NAMESPACE { class ArrayRef; class ObjectRef; -template -class MemberProxy; - // Contains the methods shared by VariantRef and VariantConstRef template -class VariantRefBase { +class VariantRefBase : public VariantTag { public: // Tells wether the variant has the specified type. // Returns true if the variant has type type T, false otherwise. diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantSlot.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantSlot.hpp index af6467097..38494f3b0 100644 --- a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantSlot.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantSlot.hpp @@ -4,15 +4,15 @@ #pragma once -#include // int8_t, int16_t - +#include +#include #include #include #include namespace ARDUINOJSON_NAMESPACE { -typedef conditional::type VariantSlotDiff; +typedef int_t::type VariantSlotDiff; class VariantSlot { // CAUTION: same layout as VariantData @@ -61,11 +61,19 @@ class VariantSlot { } void setNext(VariantSlot* slot) { + ARDUINOJSON_ASSERT(!slot || slot - this >= + numeric_limits::lowest()); + ARDUINOJSON_ASSERT(!slot || slot - this <= + numeric_limits::highest()); _next = VariantSlotDiff(slot ? slot - this : 0); } void setNextNotNull(VariantSlot* slot) { ARDUINOJSON_ASSERT(slot != 0); + ARDUINOJSON_ASSERT(slot - this >= + numeric_limits::lowest()); + ARDUINOJSON_ASSERT(slot - this <= + numeric_limits::highest()); _next = VariantSlotDiff(slot - this); } diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantTag.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantTag.hpp new file mode 100644 index 000000000..e9a08aecd --- /dev/null +++ b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantTag.hpp @@ -0,0 +1,16 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2020 +// MIT License + +#pragma once + +#include + +namespace ARDUINOJSON_NAMESPACE { + +struct VariantTag {}; + +template +struct IsVariant : is_base_of {}; + +} // namespace ARDUINOJSON_NAMESPACE diff --git a/lib/ArduinoJson/src/ArduinoJson/version.hpp b/lib/ArduinoJson/src/ArduinoJson/version.hpp index 46b6bc62e..cd57a4dae 100644 --- a/lib/ArduinoJson/src/ArduinoJson/version.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/version.hpp @@ -4,7 +4,7 @@ #pragma once -#define ARDUINOJSON_VERSION "6.17.0" +#define ARDUINOJSON_VERSION "6.17.1" #define ARDUINOJSON_VERSION_MAJOR 6 #define ARDUINOJSON_VERSION_MINOR 17 -#define ARDUINOJSON_VERSION_REVISION 0 +#define ARDUINOJSON_VERSION_REVISION 1 diff --git a/lib/ArduinoJson/src/CMakeLists.txt b/lib/ArduinoJson/src/CMakeLists.txt deleted file mode 100644 index de0032ae2..000000000 --- a/lib/ArduinoJson/src/CMakeLists.txt +++ /dev/null @@ -1,90 +0,0 @@ -# ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2020 -# MIT License - -# I have no idea what this is about, I simply followed the instructions from: -# https://dominikberner.ch/cmake-interface-lib/ - -add_library(ArduinoJson INTERFACE) - -include(GNUInstallDirs) - -# Adding the install interface generator expression makes sure that the include -# files are installed to the proper location (provided by GNUInstallDirs) -target_include_directories(ArduinoJson - INTERFACE - $ - $ -) - -target_compile_definitions(ArduinoJson - INTERFACE - ARDUINOJSON_DEBUG=$ -) - -# locations are provided by GNUInstallDirs -install( - TARGETS - ArduinoJson - EXPORT - ArduinoJson_Targets - ARCHIVE DESTINATION - ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION - ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION - ${CMAKE_INSTALL_BINDIR} -) - -include(CMakePackageConfigHelpers) - -if(${CMAKE_VERSION} VERSION_GREATER "3.14.0") - set(ARCH_INDEPENDENT "ARCH_INDEPENDENT") -endif() - -write_basic_package_version_file( - "${PROJECT_BINARY_DIR}/ArduinoJsonConfigVersion.cmake" - VERSION - ${PROJECT_VERSION} - COMPATIBILITY - SameMajorVersion - ${ARCH_INDEPENDENT} -) - -configure_package_config_file( - "${PROJECT_SOURCE_DIR}/extras/ArduinoJsonConfig.cmake.in" - "${PROJECT_BINARY_DIR}/ArduinoJsonConfig.cmake" - INSTALL_DESTINATION - ${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake) - -install( - EXPORT - ArduinoJson_Targets - FILE - ArduinoJsonTargets.cmake - DESTINATION - ${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake -) - -install( - FILES - "${PROJECT_BINARY_DIR}/ArduinoJsonConfig.cmake" - "${PROJECT_BINARY_DIR}/ArduinoJsonConfigVersion.cmake" - DESTINATION - "${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake" -) - -install( - FILES - ArduinoJson.h - ArduinoJson.hpp - DESTINATION - include -) - -install( - DIRECTORY - "${CMAKE_CURRENT_SOURCE_DIR}/ArduinoJson" - DESTINATION - include -) From 9285180f2d13033e45e36e7ce31092666ac8ce29 Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 8 Nov 2020 20:24:18 +0100 Subject: [PATCH 10/55] add debug scripts back --- scripts/analyze_stackdmp.py | 26 +++ scripts/decoder.py | 319 ++++++++++++++++++++++++++++++++++++ scripts/decoder.sh | 4 + 3 files changed, 349 insertions(+) create mode 100644 scripts/analyze_stackdmp.py create mode 100644 scripts/decoder.py create mode 100644 scripts/decoder.sh diff --git a/scripts/analyze_stackdmp.py b/scripts/analyze_stackdmp.py new file mode 100644 index 000000000..a686a5446 --- /dev/null +++ b/scripts/analyze_stackdmp.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +from subprocess import call +import os + +# example stackdmp.txt would contain text like below copied & pasted from a 'crash dump' command: + +# >>>stack>>> +# 3fffff20: 3fff32f0 00000003 3fff3028 402101b2 +# 3fffff30: 3fffdad0 3fff3280 0000000d 402148aa +# 3fffff40: 3fffdad0 3fff3280 3fff326c 3fff32f0 +# 3fffff50: 0000000d 3fff326c 3fff3028 402103bd +# 3fffff60: 0000000d 3fff34cc 40211de4 3fff34cc +# 3fffff70: 3fff3028 3fff14c4 3fff301c 3fff34cc +# 3fffff80: 3fffdad0 3fff14c4 3fff3028 40210493 +# 3fffff90: 3fffdad0 00000000 3fff14c4 4020a738 +# 3fffffa0: 3fffdad0 00000000 3fff349c 40211e90 +# 3fffffb0: feefeffe feefeffe 3ffe8558 40100b01 +# <<[0-9]*)\\):$") +COUNTER_REGEX = re.compile('^epc1=(?P0x[0-9a-f]+) epc2=(?P0x[0-9a-f]+) epc3=(?P0x[0-9a-f]+) ' + 'excvaddr=(?P0x[0-9a-f]+) depc=(?P0x[0-9a-f]+)$') +CTX_REGEX = re.compile("^ctx: (?P.+)$") +POINTER_REGEX = re.compile('^sp: (?P[0-9a-f]+) end: (?P[0-9a-f]+) offset: (?P[0-9a-f]+)$') +STACK_BEGIN = '>>>stack>>>' +STACK_END = '<<[0-9a-f]+):\W+(?P[0-9a-f]+) (?P[0-9a-f]+) (?P[0-9a-f]+) (?P[0-9a-f]+)(\W.*)?$') + +StackLine = namedtuple("StackLine", ["offset", "content"]) + + +class ExceptionDataParser(object): + def __init__(self): + self.exception = None + + self.epc1 = None + self.epc2 = None + self.epc3 = None + self.excvaddr = None + self.depc = None + + self.ctx = None + + self.sp = None + self.end = None + self.offset = None + + self.stack = [] + + def _parse_backtrace(self, line): + if line.startswith('Backtrace:'): + self.stack = [StackLine(offset=0, content=(addr,)) for addr in BACKTRACE_REGEX.findall(line)] + return None + return self._parse_backtrace + + def _parse_exception(self, line): + match = EXCEPTION_REGEX.match(line) + if match is not None: + self.exception = int(match.group('exc')) + return self._parse_counters + return self._parse_exception + + def _parse_counters(self, line): + match = COUNTER_REGEX.match(line) + if match is not None: + self.epc1 = match.group("epc1") + self.epc2 = match.group("epc2") + self.epc3 = match.group("epc3") + self.excvaddr = match.group("excvaddr") + self.depc = match.group("depc") + return self._parse_ctx + return self._parse_counters + + def _parse_ctx(self, line): + match = CTX_REGEX.match(line) + if match is not None: + self.ctx = match.group("ctx") + return self._parse_pointers + return self._parse_ctx + + def _parse_pointers(self, line): + match = POINTER_REGEX.match(line) + if match is not None: + self.sp = match.group("sp") + self.end = match.group("end") + self.offset = match.group("offset") + return self._parse_stack_begin + return self._parse_pointers + + def _parse_stack_begin(self, line): + if line == STACK_BEGIN: + return self._parse_stack_line + return self._parse_stack_begin + + def _parse_stack_line(self, line): + if line != STACK_END: + match = STACK_REGEX.match(line) + if match is not None: + self.stack.append(StackLine(offset=match.group("off"), + content=(match.group("c1"), match.group("c2"), match.group("c3"), + match.group("c4")))) + return self._parse_stack_line + return None + + def parse_file(self, file, platform, stack_only=False): + if platform == 'ESP32': + func = self._parse_backtrace + else: + func = self._parse_exception + if stack_only: + func = self._parse_stack_begin + + for line in file: + func = func(line.strip()) + if func is None: + break + + if func is not None: + print("ERROR: Parser not complete!") + sys.exit(1) + + +class AddressResolver(object): + def __init__(self, tool_path, elf_path): + self._tool = tool_path + self._elf = elf_path + self._address_map = {} + + def _lookup(self, addresses): + cmd = [self._tool, "-aipfC", "-e", self._elf] + [addr for addr in addresses if addr is not None] + + if sys.version_info[0] < 3: + output = subprocess.check_output(cmd) + else: + output = subprocess.check_output(cmd, encoding="utf-8") + + line_regex = re.compile("^(?P[0-9a-fx]+): (?P.+)$") + + last = None + for line in output.splitlines(): + line = line.strip() + match = line_regex.match(line) + + if match is None: + if last is not None and line.startswith('(inlined by)'): + line = line [12:].strip() + self._address_map[last] += ("\n \-> inlined by: " + line) + continue + + if match.group("result") == '?? ??:0': + continue + + self._address_map[match.group("addr")] = match.group("result") + last = match.group("addr") + + def fill(self, parser): + addresses = [parser.epc1, parser.epc2, parser.epc3, parser.excvaddr, parser.sp, parser.end, parser.offset] + for line in parser.stack: + addresses.extend(line.content) + + self._lookup(addresses) + + def _sanitize_addr(self, addr): + if addr.startswith("0x"): + addr = addr[2:] + + fill = "0" * (8 - len(addr)) + return "0x" + fill + addr + + def resolve_addr(self, addr): + out = self._sanitize_addr(addr) + + if out in self._address_map: + out += ": " + self._address_map[out] + + return out + + def resolve_stack_addr(self, addr, full=True): + addr = self._sanitize_addr(addr) + if addr in self._address_map: + return addr + ": " + self._address_map[addr] + + if full: + return "[DATA (0x" + addr + ")]" + + return None + + +def print_addr(name, value, resolver): + print("{}:{} {}".format(name, " " * (8 - len(name)), resolver.resolve_addr(value))) + + +def print_stack_full(lines, resolver): + print("stack:") + for line in lines: + print(line.offset + ":") + for content in line.content: + print(" " + resolver.resolve_stack_addr(content)) + + +def print_stack(lines, resolver): + print("stack:") + for line in lines: + for content in line.content: + out = resolver.resolve_stack_addr(content, full=False) + if out is None: + continue + print(out) + + +def print_result(parser, resolver, platform, full=True, stack_only=False): + if platform == 'ESP8266' and not stack_only: + print('Exception: {} ({})'.format(parser.exception, EXCEPTIONS[parser.exception])) + + print("") + print_addr("epc1", parser.epc1, resolver) + print_addr("epc2", parser.epc2, resolver) + print_addr("epc3", parser.epc3, resolver) + print_addr("excvaddr", parser.excvaddr, resolver) + print_addr("depc", parser.depc, resolver) + + print("") + print("ctx: " + parser.ctx) + + print("") + print_addr("sp", parser.sp, resolver) + print_addr("end", parser.end, resolver) + print_addr("offset", parser.offset, resolver) + + print("") + if full: + print_stack_full(parser.stack, resolver) + else: + print_stack(parser.stack, resolver) + + +def parse_args(): + parser = argparse.ArgumentParser(description="decode ESP Stacktraces.") + + parser.add_argument("-p", "--platform", help="The platform to decode from", choices=PLATFORMS.keys(), + default="ESP8266") + parser.add_argument("-t", "--tool", help="Path to the xtensa toolchain", + default="~/.platformio/packages/toolchain-xtensa/") + parser.add_argument("-e", "--elf", help="path to elf file", required=True) + parser.add_argument("-f", "--full", help="Print full stack dump", action="store_true") + parser.add_argument("-s", "--stack_only", help="Decode only a stractrace", action="store_true") + parser.add_argument("file", help="The file to read the exception data from ('-' for STDIN)", default="-") + + return parser.parse_args() + + +if __name__ == "__main__": + args = parse_args() + + if args.file == "-": + file = sys.stdin + else: + if not os.path.exists(args.file): + print("ERROR: file " + args.file + " not found") + sys.exit(1) + file = open(args.file, "r") + + addr2line = os.path.join(os.path.abspath(os.path.expanduser(args.tool)), + "bin/xtensa-" + PLATFORMS[args.platform] + "-elf-addr2line") + if os.name == 'nt': + addr2line += '.exe' + if not os.path.exists(addr2line): + print("ERROR: addr2line not found (" + addr2line + ")") + + elf_file = os.path.abspath(os.path.expanduser(args.elf)) + if not os.path.exists(elf_file): + print("ERROR: elf file not found (" + elf_file + ")") + + parser = ExceptionDataParser() + resolver = AddressResolver(addr2line, elf_file) + + parser.parse_file(file, args.platform, args.stack_only) + resolver.fill(parser) + + print_result(parser, resolver, args.platform, args.full, args.stack_only) \ No newline at end of file diff --git a/scripts/decoder.sh b/scripts/decoder.sh new file mode 100644 index 000000000..93802af72 --- /dev/null +++ b/scripts/decoder.sh @@ -0,0 +1,4 @@ +# python decoder.py -s -e ../.pio/build/esp8266-local/firmware.elf stackdmp.txt + +python decoder.py -p ESP32 -e ../.pio/build/esp32-local/firmware.elf stackdmp.txt -t ~/.platformio/packages/toolchain-xtensa32 + From 9662d60c941e8417413498a0e9b159270b9f02ca Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 8 Nov 2020 20:26:36 +0100 Subject: [PATCH 11/55] fix error in debug mode --- src/WebAPIService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebAPIService.cpp b/src/WebAPIService.cpp index dd5ef85c7..499741713 100644 --- a/src/WebAPIService.cpp +++ b/src/WebAPIService.cpp @@ -98,7 +98,7 @@ void WebAPIService::webAPIService(AsyncWebServerRequest * request) { cmd.c_str(), data.c_str(), id.c_str(), - ok ? F("OK") : F("Invalid")); + ok ? PSTR("OK") : PSTR("Invalid")); EMSESP::logger().info(debug.c_str()); if (json.size()) { char buffer2[EMSESP_MAX_JSON_SIZE_LARGE]; From ba02c1e08421f28e7d804816d7ab8bc2c76ac6ff Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 8 Nov 2020 20:36:28 +0100 Subject: [PATCH 12/55] formatting --- src/emsdevice.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/emsdevice.h b/src/emsdevice.h index 3ea0d9008..81ac08c44 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -283,8 +283,7 @@ class EMSdevice { uint16_t telegram_type_id_; // it's type_id const __FlashStringHelper * telegram_type_name_; // e.g. RC20Message bool fetch_; // if this type_id be queried automatically - - process_function_p process_function_; + process_function_p process_function_; TelegramFunction(uint16_t telegram_type_id, const __FlashStringHelper * telegram_type_name, bool fetch, process_function_p process_function) : telegram_type_id_(telegram_type_id) From db1d32ddc2182a8ced3a2f78c3def479df98432e Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 8 Nov 2020 20:36:48 +0100 Subject: [PATCH 13/55] test function changes --- src/console.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/console.cpp b/src/console.cpp index 95e03ce72..ac96c2cbd 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -20,9 +20,7 @@ #include "emsesp.h" #include "version.h" -#if defined(EMSESP_DEBUG) #include "test/test.h" -#endif namespace emsesp { @@ -494,28 +492,20 @@ 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("test")}, flash_string_vector{F_(name_optional)}, - [](Shell & shell, const std::vector & arguments __attribute__((unused))) { + [](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")}, - flash_string_vector{F_(name_optional)}, [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - if (arguments.size() == 0) { - Test::run_test(shell, "default"); - } else { - Test::run_test(shell, arguments.front()); - } + Test::run_test(shell, "default"); }); #endif From bf5183be8af4175ad74bc3f5ea6d736e86bd1d0b Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 8 Nov 2020 20:38:22 +0100 Subject: [PATCH 14/55] mqtt experiments to reduce heap --- src/mqtt.cpp | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 0d9d828e7..09febd6fc 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -211,14 +211,12 @@ void Mqtt::show_mqtt(uuid::console::Shell & shell) { } } shell.println(); -} // namespace emsesp +} -#if defined(EMSESP_DEBUG) // simulate receiving a MQTT message, used only for testing void Mqtt::incoming(const char * topic, const char * payload) { on_message(topic, payload, strlen(payload)); } -#endif // received an MQTT message that we subscribed too void Mqtt::on_message(const char * topic, const char * payload, size_t len) { @@ -697,8 +695,6 @@ void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, cons return; } - return; // TODO - StaticJsonDocument doc; doc["name"] = name; @@ -768,11 +764,12 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix, strcpy(new_entity, entity); } - std::string device_name = EMSdevice::device_type_2_device_name(device_type); + char device_name[50]; + strcpy(device_name, EMSdevice::device_type_2_device_name(device_type).c_str()); // build unique identifier, replacing all . with _ as not to break HA std::string uniq(50, '\0'); - snprintf_P(&uniq[0], uniq.capacity() + 1, PSTR("%s_%s"), device_name.c_str(), new_entity); + snprintf_P(&uniq[0], uniq.capacity() + 1, PSTR("%s_%s"), device_name, new_entity); std::replace(uniq.begin(), uniq.end(), '.', '_'); // topic @@ -782,9 +779,9 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix, // state topic char stat_t[MQTT_TOPIC_MAX_SIZE]; if (suffix != nullptr) { - snprintf_P(stat_t, sizeof(stat_t), PSTR("%s/%s_data%s"), hostname_.c_str(), device_name.c_str(), uuid::read_flash_string(suffix).c_str()); + snprintf_P(stat_t, sizeof(stat_t), PSTR("%s/%s_data%s"), hostname_.c_str(), device_name, uuid::read_flash_string(suffix).c_str()); } else { - snprintf_P(stat_t, sizeof(stat_t), PSTR("%s/%s_data"), hostname_.c_str(), device_name.c_str()); + snprintf_P(stat_t, sizeof(stat_t), PSTR("%s/%s_data"), hostname_.c_str(), device_name); } // value template @@ -793,20 +790,23 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix, // ha device char ha_device[40]; - snprintf_P(ha_device, sizeof(ha_device), PSTR("ems-esp-%s"), device_name.c_str()); + snprintf_P(ha_device, sizeof(ha_device), PSTR("ems-esp-%s"), device_name); // name char new_name[50]; if (prefix != nullptr) { - snprintf_P(new_name, sizeof(new_name), PSTR("%s %s %s"), device_name.c_str(), prefix, uuid::read_flash_string(name).c_str()); + snprintf_P(new_name, sizeof(new_name), PSTR("%s %s %s"), device_name, prefix, uuid::read_flash_string(name).c_str()); } else { - snprintf_P(new_name, sizeof(new_name), PSTR("%s %s"), device_name.c_str(), uuid::read_flash_string(name).c_str()); + snprintf_P(new_name, sizeof(new_name), PSTR("%s %s"), device_name, uuid::read_flash_string(name).c_str()); } new_name[0] = toupper(new_name[0]); // capitalize first letter StaticJsonDocument doc; + + // DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_SMALL); + doc["name"] = new_name; - doc["uniq_id"] = uniq; + doc["uniq_id"] = uniq.c_str(); if (uom != nullptr) { doc["unit_of_meas"] = uom; } @@ -823,6 +823,9 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix, // std::string payload_text; char payload_text[300]; serializeJson(doc, payload_text); // convert json to string + // queue_publish_message(topic, payload_text, true); + + // publish_retain(topic, doc.as(), true); uint16_t packet_id = mqttClient_->publish(topic, 0, true, payload_text); if (!packet_id) { @@ -835,7 +838,7 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix, #endif } - // delay(MQTT_PUBLISH_WAIT); // don't flood asynctcp + delay(MQTT_PUBLISH_WAIT); // don't flood asynctcp } } // namespace emsesp From 2d0272d956ed6d6d89f6cfb5c6d7617efda4c1dd Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 8 Nov 2020 20:38:33 +0100 Subject: [PATCH 15/55] formatting --- src/mqtt.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mqtt.h b/src/mqtt.h index 6111c073a..ed1970cb6 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -118,9 +118,7 @@ class Mqtt { mqttClient_->disconnect(); } -#if defined(EMSESP_DEBUG) void incoming(const char * topic, const char * payload); // for testing only -#endif static bool connected() { #if defined(EMSESP_STANDALONE) From 4f57d583fae781da85ad2b1a69d07ceec79ebe27 Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 8 Nov 2020 20:38:50 +0100 Subject: [PATCH 16/55] test for crashes --- src/test/test.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/test.cpp b/src/test/test.cpp index 31ceed99d..b4dbb0bf4 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -26,8 +26,11 @@ namespace emsesp { // create some fake test data // used with the 'test' command, under su/admin void Test::run_test(uuid::console::Shell & shell, const std::string & command) { + // switch to su + shell.add_flags(CommandFlags::ADMIN); + if (command == "default") { - run_test(shell, "mixer"); // add the default test case here + run_test(shell, "general"); // add the default test case here } if (command.empty()) { @@ -239,6 +242,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { shell.printfln(F("Testing adding a boiler & thermostat...")); std::string version("1.2.3"); + EMSESP::add_device(0x08, 123, version, EMSdevice::Brand::BUDERUS); // Nefit Trendline EMSESP::add_device(0x18, 157, version, EMSdevice::Brand::BOSCH); // Bosch CR100 - https://github.com/proddy/EMS-ESP/issues/355 From 3d9a6ee017dff5d820efa919a41beb5bcdd77330 Mon Sep 17 00:00:00 2001 From: Paul Date: Sun, 8 Nov 2020 20:42:50 +0100 Subject: [PATCH 17/55] updated example - for debugging --- example_pio_local.ini | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/example_pio_local.ini b/example_pio_local.ini index 1c60ad8e1..b34ec8817 100644 --- a/example_pio_local.ini +++ b/example_pio_local.ini @@ -1,6 +1,29 @@ +[platformio] +; default_envs = esp32-local +default_envs = esp8266-local + [env] -upload_protocol = espota -upload_flags = - --port=8266 - --auth=ems-esp-neo -upload_port = ems-esp.local +; upload_port = COM3 +upload_port = COM7 + +; upload_protocol = espota +; upload_flags = +; --port=8266 +; --auth=ems-esp-neo +; upload_port = ems-esp.local + +[common] +debug_flags = -DEMSESP_DEBUG + +[env:esp32-local] +monitor_filters = esp32_exception_decoder +debug_tool = esp-prog +debug_init_break = tbreak setup +build_type = debug +extra_scripts = + ; pre:scripts/build_interface.py + +[env:esp8266-local] +monitor_filters = esp8266_exception_decoder +extra_scripts = + ; pre:scripts/build_interface.py From a94db9754af84af289498cb31caf99b98128eb37 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 8 Nov 2020 20:53:18 +0100 Subject: [PATCH 18/55] formatting --- src/telegram.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/telegram.h b/src/telegram.h index 57c36a548..52a71bd9d 100644 --- a/src/telegram.h +++ b/src/telegram.h @@ -384,7 +384,7 @@ class TxService : public EMSbus { void send_telegram(const QueuedTxTelegram & tx_telegram); void send_telegram(const uint8_t * data, const uint8_t length); -}; // namespace emsesp +}; } // namespace emsesp From 4ce076317022e0a48f93748fcd6ae399319fc07b Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 8 Nov 2020 20:53:49 +0100 Subject: [PATCH 19/55] remove test, change "send telegram" format --- src/locale_EN.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/locale_EN.h b/src/locale_EN.h index a5c35175f..1b99a3faf 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -67,10 +67,6 @@ MAKE_PSTR_WORD(bar) MAKE_PSTR_WORD(min) MAKE_PSTR_WORD(uA) -#if defined(EMSESP_DEBUG) -MAKE_PSTR_WORD(test) -#endif - // for commands MAKE_PSTR_WORD(call) MAKE_PSTR_WORD(cmd) @@ -116,7 +112,7 @@ MAKE_PSTR(bus_id_fmt, "Bus ID = %02X") MAKE_PSTR(watchid_optional, "[ID]") MAKE_PSTR(watch_format_optional, "[off | on | raw]") MAKE_PSTR(invalid_watch, "Invalid watch type") -MAKE_PSTR(data_mandatory, "<\"XX XX ...\">") +MAKE_PSTR(data_mandatory, "\"XX XX ...\"") MAKE_PSTR(percent, "%") MAKE_PSTR(degrees, "°C") MAKE_PSTR(asterisks, "********") From 5088e3acee97a1bde815f1c3daf83677269760a1 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 8 Nov 2020 20:54:08 +0100 Subject: [PATCH 20/55] auto formatting --- src/devices/thermostat.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 19ba9d831..09d077ca3 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -114,7 +114,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i monitor_typeids = {0x02A5, 0x02A6, 0x02A7, 0x02A8}; set_typeids = {0x02B9, 0x02BA, 0x02BB, 0x02BC}; summer_typeids = {0x02AF, 0x02B0, 0x02B1, 0x02B2}; - curve_typeids = {0x029B, 0x029C, 0x029D, 0x029E}; + curve_typeids = {0x029B, 0x029C, 0x029D, 0x029E}; for (uint8_t i = 0; i < monitor_typeids.size(); i++) { register_telegram_type(monitor_typeids[i], F("RC300Monitor"), false, [&](std::shared_ptr t) { process_RC300Monitor(t); }); register_telegram_type(set_typeids[i], F("RC300Set"), false, [&](std::shared_ptr t) { process_RC300Set(t); }); @@ -176,7 +176,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i for (uint8_t i = 0; i < curve_typeids.size(); i++) { EMSESP::send_read_request(curve_typeids[i], device_id); } -} // namespace emsesp +} // prepare data for Web UI void Thermostat::device_info_web(JsonArray & root) { @@ -1316,7 +1316,6 @@ void Thermostat::process_RC300Curve(std::shared_ptr telegram) { } else { changed_ |= telegram->read_value(hc->maxflowtemp, 7); } - } // types 0x31B (and 0x31C?) @@ -2042,7 +2041,7 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co offset = 0x04; // eco offset break; case HeatingCircuit::Mode::OFFSET: - offset = 2; + offset = 2; set_typeid = summer_typeids[hc->hc_num() - 1]; validate_typeid = set_typeid; break; @@ -2066,19 +2065,19 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co } factor = 1; break; - case HeatingCircuit::Mode::NOFROST: + case HeatingCircuit::Mode::NOFROST: set_typeid = curve_typeids[hc->hc_num() - 1]; validate_typeid = set_typeid; - offset = 6; - factor = 1; + offset = 6; + factor = 1; break; case HeatingCircuit::Mode::ROOMINFLUENCE: set_typeid = summer_typeids[hc->hc_num() - 1]; validate_typeid = set_typeid; - offset = 0; - factor = 1; + offset = 0; + factor = 1; break; - default: + default: case HeatingCircuit::Mode::AUTO: uint8_t mode_ = hc->get_mode(this->flags()); if (mode_ == HeatingCircuit::Mode::MANUAL) { @@ -2387,5 +2386,4 @@ void Thermostat::add_commands() { } } - } // namespace emsesp From 7d73efbd316032b906caad255b6f791859e6d5f4 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 8 Nov 2020 20:54:24 +0100 Subject: [PATCH 21/55] prevent crash when `send telegram` too short --- src/telegram.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/telegram.cpp b/src/telegram.cpp index 1da3f2170..4fb9e78af 100644 --- a/src/telegram.cpp +++ b/src/telegram.cpp @@ -429,6 +429,11 @@ void TxService::add(const uint8_t operation, // format is EMS 1.0 (src, dest, type_id, offset, data) // length is the length of the whole telegram data, excluding the CRC void TxService::add(uint8_t operation, const uint8_t * data, const uint8_t length, const bool front) { + // check length + if (length < 5) { + return; + } + // build header. src, dest and offset have fixed positions uint8_t src = data[0]; uint8_t dest = data[1]; From 8c62977ad3b71253e68726a527f59460c0ecc6a4 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 10 Nov 2020 11:22:03 +0100 Subject: [PATCH 22/55] thermostat minflowtemp and fixes --- src/devices/thermostat.cpp | 78 ++++++++++++++++++++++++++++++++++++-- src/devices/thermostat.h | 5 ++- src/locale_EN.h | 4 ++ 3 files changed, 82 insertions(+), 5 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 09d077ca3..8fdf26c42 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -199,6 +199,7 @@ void Thermostat::device_info_web(JsonArray & root) { print_value_json(root, F("wwmode"), nullptr, F_(wwmode), nullptr, json_main); print_value_json(root, F("wwtemp"), nullptr, F_(wwtemp), nullptr, json_main); print_value_json(root, F("wwtemplow"), nullptr, F_(wwtemplow), nullptr, json_main); + print_value_json(root, F("wwextra1"), nullptr, F_(wwextra1), nullptr, json_main); print_value_json(root, F("wwcircmode"), nullptr, F_(wwcircmode), nullptr, json_main); } @@ -231,6 +232,7 @@ void Thermostat::device_info_web(JsonArray & root) { print_value_json(root, F("designtemp"), FPSTR(prefix_str), F_(designtemp), F_(degrees), json); print_value_json(root, F("roominfluence"), FPSTR(prefix_str), F_(roominfluence), F_(degrees), json); print_value_json(root, F("flowtempoffset"), FPSTR(prefix_str), F_(flowtempoffset), F_(degrees), json); + print_value_json(root, F("minflowtemp"), F_(2spaces), F_(minflowtemp), F_(degrees), json); print_value_json(root, F("maxflowtemp"), F_(2spaces), F_(maxflowtemp), F_(degrees), json); print_value_json(root, F("summertemp"), FPSTR(prefix_str), F_(summertemp), F_(degrees), json); print_value_json(root, F("summermode"), FPSTR(prefix_str), F_(summermode), F_(degrees), json); @@ -284,6 +286,7 @@ void Thermostat::show_values(uuid::console::Shell & shell) { print_value_json(shell, F("wwmode"), nullptr, F_(wwmode), nullptr, json_main); print_value_json(shell, F("wwtemp"), nullptr, F_(wwtemp), nullptr, json_main); print_value_json(shell, F("wwtemplow"), nullptr, F_(wwtemplow), nullptr, json_main); + print_value_json(shell, F("wwextra1"), nullptr, F_(wwextra1), nullptr, json_main); print_value_json(shell, F("wwcircmode"), nullptr, F_(wwcircmode), nullptr, json_main); } @@ -316,6 +319,7 @@ void Thermostat::show_values(uuid::console::Shell & shell) { print_value_json(shell, F("designtemp"), F_(2spaces), F_(designtemp), F_(degrees), json); print_value_json(shell, F("roominfluence"), F_(2spaces), F_(roominfluence), F_(degrees), json); print_value_json(shell, F("flowtempoffset"), F_(2spaces), F_(flowtempoffset), F_(degrees), json); + print_value_json(shell, F("minflowtemp"), F_(2spaces), F_(minflowtemp), F_(degrees), json); print_value_json(shell, F("maxflowtemp"), F_(2spaces), F_(maxflowtemp), F_(degrees), json); print_value_json(shell, F("summertemp"), F_(2spaces), F_(summertemp), F_(degrees), json); print_value_json(shell, F("summermode"), F_(2spaces), F_(summermode), F_(degrees), json); @@ -480,6 +484,16 @@ bool Thermostat::export_values_main(JsonObject & rootThermostat) { rootThermostat["wwtemplow"] = wwTempLow_; } + // Warm water extra1 + if (Helpers::hasValue(wwExtra1_)) { + rootThermostat["wwextra1"] = wwExtra1_; + } + + // Warm water extra2 + if (Helpers::hasValue(wwExtra2_)) { + rootThermostat["wwextra2"] = wwExtra2_; + } + // Warm Water circulation mode if (Helpers::hasValue(wwCircMode_)) { char s[7]; @@ -607,7 +621,12 @@ bool Thermostat::export_values_hc(uint8_t mqtt_format, JsonObject & rootThermost dataThermostat["flowtempoffset"] = hc->flowtempoffset; } - // Flow temperature offset + // Min Flow temperature offset + if (Helpers::hasValue(hc->minflowtemp)) { + dataThermostat["minflowtemp"] = hc->minflowtemp; + } + + // Max Flow temperature offset if (Helpers::hasValue(hc->maxflowtemp)) { dataThermostat["maxflowtemp"] = hc->maxflowtemp; } @@ -944,6 +963,7 @@ void Thermostat::register_mqtt_ha_config(uint8_t hc_num) { Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(summertemp), this->device_type(), "summertemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(designtemp), this->device_type(), "designtemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(offsettemp), this->device_type(), "offsettemp", F_(degrees), F_(icontemperature)); + Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(minflowtemp), this->device_type(), "minflowtemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(maxflowtemp), this->device_type(), "maxflowtemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(roominfluence), this->device_type(), "roominfluence", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(nofrosttemp), this->device_type(), "nofrosttemp", F_(degrees), F_(icontemperature)); @@ -964,6 +984,7 @@ void Thermostat::register_mqtt_ha_config(uint8_t hc_num) { Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(summertemp), this->device_type(), "summertemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(nofrosttemp), this->device_type(), "nofrosttemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(roominfluence), this->device_type(), "roominfluence", F_(degrees), F_(icontemperature)); + Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(minflowtemp), this->device_type(), "minflowtemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(maxflowtemp), this->device_type(), "maxflowtemp", F_(degrees), F_(icontemperature)); break; case EMS_DEVICE_FLAG_JUNKERS: @@ -1115,6 +1136,9 @@ std::string Thermostat::mode_tostring(uint8_t mode) { case HeatingCircuit::Mode::DESIGN: return read_flash_string(F("design")); break; + case HeatingCircuit::Mode::MINFLOW: + return read_flash_string(F("minflow")); + break; case HeatingCircuit::Mode::MAXFLOW: return read_flash_string(F("maxflow")); break; @@ -1304,6 +1328,7 @@ void Thermostat::process_RC300Summer(std::shared_ptr telegram) { } else { changed_ |= telegram->read_value(hc->designtemp, 5); } + changed_ |= telegram->read_value(hc->minflowtemp, 8); } // types 0x29B ff @@ -1417,10 +1442,13 @@ void Thermostat::process_RC35Set(std::shared_ptr telegram) { changed_ |= telegram->read_value(hc->summertemp, 22); // is * 1 changed_ |= telegram->read_value(hc->nofrosttemp, 23); // is * 1 changed_ |= telegram->read_value(hc->flowtempoffset, 24); // is * 1, only in mixed circuits + changed_ |= telegram->read_value(hc->minflowtemp, 16); if (hc->heatingtype == 3) { changed_ |= telegram->read_value(hc->designtemp, 36); // is * 1 + changed_ |= telegram->read_value(hc->maxflowtemp, 35); // is * 1 } else { changed_ |= telegram->read_value(hc->designtemp, 17); // is * 1 + changed_ |= telegram->read_value(hc->maxflowtemp, 15); // is * 1 } } @@ -1656,6 +1684,24 @@ bool Thermostat::set_wwtemplow(const char * value, const int8_t id) { return true; } +// Set ww onetime RC300, ems+ +bool Thermostat::set_wwonetime(const char * value, const int8_t id) { + bool b = false; + if (!Helpers::value2bool(value, b)) { + LOG_WARNING(F("Set warm water onetime: Invalid value")); + return false; + } + char s[7]; + LOG_INFO(F("Setting warm water onetime to %s"), Helpers::render_boolean(s, b)); + if (b) { + write_command(0x031D, 0, 1); + write_command(0x031D, 2, 2, 0x031D); + } else { + write_command(0x031D, 0, 0, 0x031D); + } + return true; +} + // sets the thermostat ww circulation working mode, where mode is a string bool Thermostat::set_wwcircmode(const char * value, const int8_t id) { @@ -1986,11 +2032,14 @@ bool Thermostat::set_temperature(const float temperature, const std::string & mo if (mode_tostring(HeatingCircuit::Mode::DESIGN) == mode) { return set_temperature(temperature, HeatingCircuit::Mode::DESIGN, hc_num); } + if (mode_tostring(HeatingCircuit::Mode::MINFLOW) == mode) { + return set_temperature(temperature, HeatingCircuit::Mode::MINFLOW, hc_num); + } if (mode_tostring(HeatingCircuit::Mode::MAXFLOW) == mode) { - return set_temperature(temperature, HeatingCircuit::Mode::DESIGN, hc_num); + return set_temperature(temperature, HeatingCircuit::Mode::MAXFLOW, hc_num); } if (mode_tostring(HeatingCircuit::Mode::ROOMINFLUENCE) == mode) { - return set_temperature(temperature, HeatingCircuit::Mode::DESIGN, hc_num); + return set_temperature(temperature, HeatingCircuit::Mode::ROOMINFLUENCE, hc_num); } LOG_WARNING(F("Set temperature: Invalid mode")); @@ -2055,6 +2104,12 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co } factor = 1; break; + case HeatingCircuit::Mode::MINFLOW: + set_typeid = summer_typeids[hc->hc_num() - 1]; + validate_typeid = set_typeid; + offset = 8; + factor = 1; + break; case HeatingCircuit::Mode::MAXFLOW: set_typeid = curve_typeids[hc->hc_num() - 1]; validate_typeid = set_typeid; @@ -2143,8 +2198,16 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co offset = 4; factor = 1; break; + case HeatingCircuit::Mode::MINFLOW: + offset = 16; + factor = 1; + break; case HeatingCircuit::Mode::MAXFLOW: - offset = 15; + if (hc->heatingtype == 3) { + offset = 35; + } else { + offset = 15; + } factor = 1; break; default: @@ -2310,6 +2373,10 @@ bool Thermostat::set_maxflowtemp(const char * value, const int8_t id) { return set_temperature_value(value, id, HeatingCircuit::Mode::MAXFLOW); } +bool Thermostat::set_minflowtemp(const char * value, const int8_t id) { + return set_temperature_value(value, id, HeatingCircuit::Mode::MINFLOW); +} + bool Thermostat::set_roominfluence(const char * value, const int8_t id) { return set_temperature_value(value, id, HeatingCircuit::Mode::ROOMINFLUENCE); } @@ -2338,10 +2405,12 @@ void Thermostat::add_commands() { register_mqtt_cmd(F("wwmode"), [&](const char * value, const int8_t id) { return set_wwmode(value, id); }); register_mqtt_cmd(F("wwtemp"), [&](const char * value, const int8_t id) { return set_wwtemp(value, id); }); register_mqtt_cmd(F("wwtemplow"), [&](const char * value, const int8_t id) { return set_wwtemplow(value, id); }); + register_mqtt_cmd(F("wwonetime"), [&](const char * value, const int8_t id) { return set_wwonetime(value, id); }); register_mqtt_cmd(F("building"), [&](const char * value, const int8_t id) { return set_building(value, id); }); register_mqtt_cmd(F("nofrosttemp"), [&](const char * value, const int8_t id) { return set_nofrosttemp(value, id); }); register_mqtt_cmd(F("designtemp"), [&](const char * value, const int8_t id) { return set_designtemp(value, id); }); register_mqtt_cmd(F("offsettemp"), [&](const char * value, const int8_t id) { return set_offsettemp(value, id); }); + register_mqtt_cmd(F("minflowtemp"), [&](const char * value, const int8_t id) { return set_minflowtemp(value, id); }); register_mqtt_cmd(F("maxflowtemp"), [&](const char * value, const int8_t id) { return set_maxflowtemp(value, id); }); register_mqtt_cmd(F("minexttemp"), [&](const char * value, const int8_t id) { return set_minexttemp(value, id); }); register_mqtt_cmd(F("roominfluence"), [&](const char * value, const int8_t id) { return set_roominfluence(value, id); }); @@ -2374,6 +2443,7 @@ void Thermostat::add_commands() { register_mqtt_cmd(F("wwcircmode"), [&](const char * value, const int8_t id) { return set_wwcircmode(value, id); }); register_mqtt_cmd(F("roominfluence"), [&](const char * value, const int8_t id) { return set_roominfluence(value, id); }); register_mqtt_cmd(F("flowtempoffset"), [&](const char * value, const int8_t id) { return set_flowtempoffset(value, id); }); + register_mqtt_cmd(F("minflowtemp"), [&](const char * value, const int8_t id) { return set_minflowtemp(value, id); }); register_mqtt_cmd(F("maxflowtemp"), [&](const char * value, const int8_t id) { return set_maxflowtemp(value, id); }); break; case EMS_DEVICE_FLAG_JUNKERS: diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 8e0902c65..2366674a6 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -65,6 +65,7 @@ class Thermostat : public EMSdevice { uint8_t summer_setmode = EMS_VALUE_UINT_NOTSET; uint8_t roominfluence = EMS_VALUE_UINT_NOTSET; uint8_t flowtempoffset = EMS_VALUE_UINT_NOTSET; + uint8_t minflowtemp = EMS_VALUE_UINT_NOTSET; uint8_t maxflowtemp = EMS_VALUE_UINT_NOTSET; uint8_t hc_num() const { @@ -87,7 +88,7 @@ class Thermostat : public EMSdevice { uint8_t get_mode(uint8_t flags) const; uint8_t get_mode_type(uint8_t flags) const; - enum Mode : uint8_t { UNKNOWN, OFF, MANUAL, AUTO, DAY, NIGHT, HEAT, NOFROST, ECO, HOLIDAY, COMFORT, OFFSET, DESIGN, SUMMER, FLOWOFFSET, MAXFLOW, ROOMINFLUENCE }; + enum Mode : uint8_t { UNKNOWN, OFF, MANUAL, AUTO, DAY, NIGHT, HEAT, NOFROST, ECO, HOLIDAY, COMFORT, OFFSET, DESIGN, SUMMER, FLOWOFFSET, MINFLOW, MAXFLOW, ROOMINFLUENCE }; // for sorting based on hc number friend inline bool operator<(const std::shared_ptr & lhs, const std::shared_ptr & rhs) { @@ -311,12 +312,14 @@ class Thermostat : public EMSdevice { bool set_remotetemp(const char * value, const int8_t id); bool set_roominfluence(const char * value, const int8_t id); bool set_flowtempoffset(const char * value, const int8_t id); + bool set_minflowtemp(const char * value, const int8_t id); bool set_maxflowtemp(const char * value, const int8_t id); // set functions - these don't use the id/hc, the parameters are ignored bool set_wwmode(const char * value, const int8_t id); bool set_wwtemp(const char * value, const int8_t id); bool set_wwtemplow(const char * value, const int8_t id); + bool set_wwonetime(const char * value, const int8_t id); bool set_wwcircmode(const char * value, const int8_t id); bool set_datetime(const char * value, const int8_t id); bool set_minexttemp(const char * value, const int8_t id); diff --git a/src/locale_EN.h b/src/locale_EN.h index 1b99a3faf..b7abe921e 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -66,6 +66,7 @@ MAKE_PSTR_WORD(publish) MAKE_PSTR_WORD(bar) MAKE_PSTR_WORD(min) MAKE_PSTR_WORD(uA) +MAKE_PSTR_WORD(timeout) // for commands MAKE_PSTR_WORD(call) @@ -241,6 +242,8 @@ MAKE_PSTR(floordrytemp, "Floordrying temperature") MAKE_PSTR(wwmode, "Warm water mode") MAKE_PSTR(wwtemp, "Warm water high temperature") MAKE_PSTR(wwtemplow, "Warm water low temperature") +MAKE_PSTR(wwextra1, "Warm water circuit 1 extra") +MAKE_PSTR(wwextra2, "Warm water circuit 2 extra") MAKE_PSTR(wwcircmode, "Warm water circulation mode") // thermostat - per heating circuit @@ -262,6 +265,7 @@ MAKE_PSTR(summertemp, "Summer temperature") MAKE_PSTR(summermode, "Summer mode") MAKE_PSTR(roominfluence, "Room influence") MAKE_PSTR(flowtempoffset, "Flow temperature offset") +MAKE_PSTR(minflowtemp, "Min. flow temperature") MAKE_PSTR(maxflowtemp, "Max. flow temperature") MAKE_PSTR(mode, "Mode") MAKE_PSTR(modetype, "Mode type") From b210517333198411b001ed7cacb177d9ad59717e Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 10 Nov 2020 11:23:18 +0100 Subject: [PATCH 23/55] syslog settings changeable while running --- .../src/project/EMSESPSettingsController.tsx | 4 +++- src/system.cpp | 17 +++++++++++++---- src/system.h | 16 ++++++++-------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/interface/src/project/EMSESPSettingsController.tsx b/interface/src/project/EMSESPSettingsController.tsx index 46060536e..f883aead6 100644 --- a/interface/src/project/EMSESPSettingsController.tsx +++ b/interface/src/project/EMSESPSettingsController.tsx @@ -237,7 +237,9 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps) variant="outlined" onChange={handleValueChange('syslog_level')} margin="normal"> + OFF ERR + NOTICE INFO DEBUG @@ -245,7 +247,7 @@ function EMSESPSettingsControllerForm(props: EMSESPSettingsControllerFormProps) validators={['required', 'isNumber', 'minNumber:0', 'maxNumber:65535']} errorMessages={['Syslog Mark is required', "Must be a number", "Must be 0 or higher", "Max value is 10"]} name="syslog_mark_interval" - label="Syslog Mark Interval (seconds)" + label="Syslog Mark Interval (seconds, 0=off)" fullWidth variant="outlined" value={data.syslog_mark_interval} diff --git a/src/system.cpp b/src/system.cpp index aea35479b..756f0b76e 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -39,6 +39,11 @@ uint16_t System::analog_ = 0; bool System::analog_enabled_ = false; bool System::syslog_enabled_ = false; std::string System::hostname_; +int8_t System::syslog_level_ = -1; +uint32_t System::syslog_mark_interval_ = 0; +String System::syslog_host_; + + // send on/off to a gpio pin // value: true = HIGH, false = LOW @@ -120,6 +125,13 @@ void System::syslog_init() { }); #ifndef EMSESP_STANDALONE + if (!syslog_enabled_) { + syslog_.log_level((uuid::log::Level)-1); + syslog_.mark_interval(0); + syslog_.destination(0); + return; + } + syslog_.start(); // syslog service re-start // configure syslog @@ -155,9 +167,6 @@ void System::start() { Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(send), System::command_send); Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info); Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(report), System::command_report); - if (settings.syslog_enabled) { - syslog_init(); // init SysLog - } }); @@ -172,8 +181,8 @@ void System::init() { EMSESP::webSettingsService.read([&](WebSettings & settings) { Helpers::bool_format(settings.bool_format); analog_enabled_ = settings.analog_enabled; - syslog_enabled_ = settings.syslog_enabled; }); + syslog_init(); // init SysLog EMSESP::esp8266React.getWiFiSettingsService()->read([&](WiFiSettings & settings) { hostname(settings.hostname.c_str()); }); diff --git a/src/system.h b/src/system.h index 32b6a8fae..808b189fa 100644 --- a/src/system.h +++ b/src/system.h @@ -59,9 +59,9 @@ class System { static void show_mem(const char * note); static void set_led(); static void init(); + static void syslog_init(); bool check_upgrade(); - void syslog_init(); void send_heartbeat(); static std::string hostname() { @@ -108,13 +108,13 @@ class System { static std::string hostname_; // settings - static bool hide_led_; - static bool syslog_enabled_; - uint8_t syslog_level_; - uint32_t syslog_mark_interval_; - String syslog_host_; - static uint8_t led_gpio_; - static bool analog_enabled_; + static bool hide_led_; + static bool syslog_enabled_; + static int8_t syslog_level_; + static uint32_t syslog_mark_interval_; + static String syslog_host_; + static uint8_t led_gpio_; + static bool analog_enabled_; }; } // namespace emsesp From 1e42be051bd8ee0372d64307e5439cf37d9c9cfa Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 10 Nov 2020 11:30:53 +0100 Subject: [PATCH 24/55] set telnet timeout from console --- src/console.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/console.cpp b/src/console.cpp index ac96c2cbd..d90832a72 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -300,6 +300,16 @@ void EMSESPShell::add_console_commands() { "local"); }); + 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 timout is %d minutes"), value); + }); + commands->add_command(ShellContext::MAIN, CommandFlags::ADMIN, flash_string_vector{F_(send), F_(telegram)}, From 027fec29a7542fd505c1966706cca853ec0d72b9 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 10 Nov 2020 11:36:35 +0100 Subject: [PATCH 25/55] update changelog --- CHANGELOG_LATEST.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index b90d40fc7..4cd23dcdc 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -10,6 +10,7 @@ ### Changed - optimized MQTT for HA to reduce mem fragmentation issues +- change syslog settings without reboot ### Removed - old scripts From 82a35f9a7efc80c962b34ff930a76bcf478e5fd7 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 10 Nov 2020 12:46:26 +0100 Subject: [PATCH 26/55] fix compile warnings/errors --- src/console.cpp | 2 ++ src/devices/thermostat.cpp | 7 +------ src/system.cpp | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/console.cpp b/src/console.cpp index d90832a72..7a24f8294 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -300,6 +300,7 @@ void EMSESPShell::add_console_commands() { "local"); }); +#ifndef EMSESP_STANDALONE commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(set), F_(timeout)}, @@ -309,6 +310,7 @@ void EMSESPShell::add_console_commands() { telnet_.initial_idle_timeout(value * 60); shell.printfln(F("Telnet timout is %d minutes"), value); }); +#endif commands->add_command(ShellContext::MAIN, CommandFlags::ADMIN, diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 8fdf26c42..b76b7badc 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1693,12 +1693,7 @@ bool Thermostat::set_wwonetime(const char * value, const int8_t id) { } char s[7]; LOG_INFO(F("Setting warm water onetime to %s"), Helpers::render_boolean(s, b)); - if (b) { - write_command(0x031D, 0, 1); - write_command(0x031D, 2, 2, 0x031D); - } else { - write_command(0x031D, 0, 0, 0x031D); - } + write_command(0x02F5, 11, b ? 0xFF : 0x00, 0x031D); return true; } diff --git a/src/system.cpp b/src/system.cpp index 756f0b76e..6009ecb5b 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -128,7 +128,7 @@ void System::syslog_init() { if (!syslog_enabled_) { syslog_.log_level((uuid::log::Level)-1); syslog_.mark_interval(0); - syslog_.destination(0); + syslog_.destination((IPAddress)0); return; } From f5b7bad2fb44502d69fd6e8f3488d7bed3e98776 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Wed, 11 Nov 2020 09:15:58 +0100 Subject: [PATCH 27/55] thermostat typos, trigger new dev build --- CHANGELOG_LATEST.md | 2 +- src/devices/thermostat.cpp | 4 ++-- src/system.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 4cd23dcdc..868159566 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -1,7 +1,7 @@ # Changelog ### Added -- function keys in editor: cursor, del, pos1, end. F1=help, F2=show, F10=report +- function keys in editor: cursor, del, home, end. F1=help, F2=show, and other shortcuts - add sm100 pump working time and energy units - heating curve parameters for RC300 diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index b76b7badc..cdaf6f7e9 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -232,8 +232,8 @@ void Thermostat::device_info_web(JsonArray & root) { print_value_json(root, F("designtemp"), FPSTR(prefix_str), F_(designtemp), F_(degrees), json); print_value_json(root, F("roominfluence"), FPSTR(prefix_str), F_(roominfluence), F_(degrees), json); print_value_json(root, F("flowtempoffset"), FPSTR(prefix_str), F_(flowtempoffset), F_(degrees), json); - print_value_json(root, F("minflowtemp"), F_(2spaces), F_(minflowtemp), F_(degrees), json); - print_value_json(root, F("maxflowtemp"), F_(2spaces), F_(maxflowtemp), F_(degrees), json); + print_value_json(root, F("minflowtemp"), FPSTR(prefix_str), F_(minflowtemp), F_(degrees), json); + print_value_json(root, F("maxflowtemp"), FPSTR(prefix_str), F_(maxflowtemp), F_(degrees), json); print_value_json(root, F("summertemp"), FPSTR(prefix_str), F_(summertemp), F_(degrees), json); print_value_json(root, F("summermode"), FPSTR(prefix_str), F_(summermode), F_(degrees), json); print_value_json(root, F("mode"), FPSTR(prefix_str), F_(mode), nullptr, json); diff --git a/src/system.cpp b/src/system.cpp index 6009ecb5b..dde28449d 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -128,7 +128,7 @@ void System::syslog_init() { if (!syslog_enabled_) { syslog_.log_level((uuid::log::Level)-1); syslog_.mark_interval(0); - syslog_.destination((IPAddress)0); + syslog_.destination((IPAddress)((uint32_t)0)); return; } From 1578168167a722606492bbe854c06a2360e4492b Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 13 Nov 2020 13:29:19 +0100 Subject: [PATCH 28/55] split HA-config in smaller blocks, add publish command --- CHANGELOG_LATEST.md | 3 +- src/dallassensor.cpp | 4 +-- src/dallassensor.h | 2 +- src/devices/boiler.cpp | 61 +++++++++++++++++++++------------ src/devices/boiler.h | 8 +++-- src/devices/heatpump.cpp | 25 +++++++------- src/devices/heatpump.h | 2 +- src/devices/mixer.cpp | 24 ++++++------- src/devices/mixer.h | 2 +- src/devices/solar.cpp | 13 ++++--- src/devices/solar.h | 2 +- src/devices/thermostat.cpp | 43 +++++++++++++++--------- src/devices/thermostat.h | 2 +- src/emsesp.cpp | 69 ++++++++++++++++++++++++++++++++------ src/emsesp.h | 4 ++- src/mqtt.cpp | 36 ++++++++++---------- src/mqtt.h | 8 +++-- src/system.cpp | 7 ++++ src/system.h | 1 + 19 files changed, 202 insertions(+), 114 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 868159566..996a1f35a 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -2,7 +2,7 @@ ### Added - function keys in editor: cursor, del, home, end. F1=help, F2=show, and other shortcuts -- add sm100 pump working time and energy units +- SM100 pump working time and energy units - heating curve parameters for RC300 ### Fixed @@ -11,6 +11,7 @@ ### Changed - optimized MQTT for HA to reduce mem fragmentation issues - change syslog settings without reboot +- HA-config split in smaller blocks ### Removed - old scripts diff --git a/src/dallassensor.cpp b/src/dallassensor.cpp index b1a0bf53c..b83297489 100644 --- a/src/dallassensor.cpp +++ b/src/dallassensor.cpp @@ -309,7 +309,7 @@ bool DallasSensor::export_values(JsonObject & json) { } // send all dallas sensor values as a JSON package to MQTT -void DallasSensor::publish_values() { +void DallasSensor::publish_values(const bool force) { uint8_t num_sensors = sensors_.size(); if (num_sensors == 0) { @@ -340,7 +340,7 @@ void DallasSensor::publish_values() { // create the HA MQTT config // to e.g. homeassistant/sensor/ems-esp/dallas_28-233D-9497-0C03/config if (mqtt_format_ == Mqtt::Format::HA) { - if (!(registered_ha_[sensor_no - 1])) { + if (!(registered_ha_[sensor_no - 1]) || force) { StaticJsonDocument config; config["dev_cla"] = F("temperature"); diff --git a/src/dallassensor.h b/src/dallassensor.h index bcc4e8e0d..0f4ebddb2 100644 --- a/src/dallassensor.h +++ b/src/dallassensor.h @@ -58,7 +58,7 @@ class DallasSensor { void start(); void loop(); - void publish_values(); + void publish_values(const bool force); void reload(); bool updated_values(); diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 3cb34e0c1..e4558e64f 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -74,17 +74,13 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const // create the config topics for Home Assistant MQTT Discovery // for each of the main elements -void Boiler::register_mqtt_ha_config(bool force) { - if ((mqtt_ha_config_ && !force)) { - return; - } - +void Boiler::register_mqtt_ha_config() { if (!Mqtt::connected()) { return; } // Create the Master device - StaticJsonDocument doc; + StaticJsonDocument doc; doc["name"] = F("Service Code"); doc["uniq_id"] = F("boiler"); doc["ic"] = F("mdi:home-thermometer-outline"); @@ -141,8 +137,17 @@ void Boiler::register_mqtt_ha_config(bool force) { Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(burnWorkMin), this->device_type(), "burnWorkMin", F_(min), nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(heatWorkMin), this->device_type(), "heatWorkMin", F_(min), nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(UBAuptime), this->device_type(), "UBAuptime", F_(min), nullptr); + mqtt_ha_config_ = true; // done +} - // ww +// create the config topics for Home Assistant MQTT Discovery +// for each of the ww elements +void Boiler::register_mqtt_ha_config_ww() { + + if (!Mqtt::connected()) { + return; + } + // ww Mqtt::register_mqtt_ha_sensor(nullptr, F_(mqtt_suffix_ww), F_(wWSelTemp), this->device_type(), "wWSelTemp", F_(degrees), F_(iconcruise)); Mqtt::register_mqtt_ha_sensor(nullptr, F_(mqtt_suffix_ww), F_(wWSetTemp), this->device_type(), "wWSetTemp", F_(degrees), F_(icontemperature)); Mqtt::register_mqtt_ha_sensor(nullptr, F_(mqtt_suffix_ww), F_(wWDisinfectionTemp), this->device_type(), "wWDisinfectionTemp", F_(degrees), F_(icontemperature)); @@ -170,14 +175,15 @@ void Boiler::register_mqtt_ha_config(bool force) { Mqtt::register_mqtt_ha_sensor(nullptr, F_(mqtt_suffix_ww), F_(wWStarts), this->device_type(), "wWStarts", nullptr, nullptr); Mqtt::register_mqtt_ha_sensor(nullptr, F_(mqtt_suffix_ww), F_(wWWorkM), this->device_type(), "wWWorkM", F_(min), nullptr); - mqtt_ha_config_ = true; // done + mqtt_ha_config_ww_ = true; // done } // send stuff to the Web UI void Boiler::device_info_web(JsonArray & root) { // fetch the values into a JSON document - DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_LARGE); - JsonObject json = doc.to(); + // DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_LARGE); + StaticJsonDocument doc; + JsonObject json = doc.to(); if (!export_values_main(json)) { return; // empty } @@ -618,19 +624,29 @@ bool Boiler::export_values_main(JsonObject & json) { void Boiler::publish_values(JsonObject & json, bool force) { // handle HA first if (Mqtt::mqtt_format() == Mqtt::Format::HA) { - register_mqtt_ha_config(force); + if (force) { + mqtt_ha_config_ = false; + mqtt_ha_config_ww_ = false; + } + // register ww in next cycle if both unregistered + if (!mqtt_ha_config_) { + register_mqtt_ha_config(); + return; + } else if (!mqtt_ha_config_ww_) { + register_mqtt_ha_config_ww(); + return; + } } - DynamicJsonDocument doc_main(EMSESP_MAX_JSON_SIZE_LARGE); - JsonObject json_main = doc_main.to(); - if (export_values_main(json_main)) { - Mqtt::publish(F("boiler_data"), doc_main.as()); + StaticJsonDocument doc; + JsonObject json_data = doc.to(); + if (export_values_main(json_data)) { + Mqtt::publish(F("boiler_data"), json_data); } + json_data.clear(); - DynamicJsonDocument doc_ww(EMSESP_MAX_JSON_SIZE_LARGE); - JsonObject json_ww = doc_ww.to(); - if (export_values_ww(json_ww)) { - Mqtt::publish(F("boiler_data_ww"), doc_ww.as()); + if (export_values_ww(json_data)) { + Mqtt::publish(F("boiler_data_ww"), json_data); } // send out heating and tapwater status @@ -651,13 +667,14 @@ void Boiler::show_values(uuid::console::Shell & shell) { EMSdevice::show_values(shell); // for showing the header // fetch the values into a JSON document - DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_LARGE); - JsonObject json = doc.to(); + // DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_LARGE); + StaticJsonDocument doc; + JsonObject json = doc.to(); if (!export_values_main(json)) { return; // empty } export_values_ww(json); // append ww values - doc.shrinkToFit(); + // doc.shrinkToFit(); print_value_json(shell, F("heatingActive"), nullptr, F_(heatingActive), nullptr, json); print_value_json(shell, F("tapwaterActive"), nullptr, F_(tapwaterActive), nullptr, json); diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 3fe2f0fc1..173882080 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -47,13 +47,15 @@ class Boiler : public EMSdevice { private: static uuid::log::Logger logger_; - void register_mqtt_ha_config(bool force); + void register_mqtt_ha_config(); + void register_mqtt_ha_config_ww(); void check_active(); bool export_values_main(JsonObject & doc); bool export_values_ww(JsonObject & doc); - bool changed_ = false; - bool mqtt_ha_config_ = false; // HA MQTT Discovery + bool changed_ = false; + bool mqtt_ha_config_ = false; // HA MQTT Discovery + bool mqtt_ha_config_ww_ = false; // HA MQTT Discovery static constexpr uint8_t EMS_TYPE_UBAParameterWW = 0x33; static constexpr uint8_t EMS_TYPE_UBAFunctionTest = 0x1D; diff --git a/src/devices/heatpump.cpp b/src/devices/heatpump.cpp index ef4adf175..463a4cd7d 100644 --- a/src/devices/heatpump.cpp +++ b/src/devices/heatpump.cpp @@ -49,8 +49,8 @@ bool Heatpump::export_values(JsonObject & json) { void Heatpump::device_info_web(JsonArray & root) { // fetch the values into a JSON document - StaticJsonDocument doc; - JsonObject json = doc.to(); + StaticJsonDocument doc; + JsonObject json = doc.to(); if (!export_values(json)) { return; // empty } @@ -64,8 +64,8 @@ void Heatpump::show_values(uuid::console::Shell & shell) { EMSdevice::show_values(shell); // always call this to show header // fetch the values into a JSON document - StaticJsonDocument doc; - JsonObject json = doc.to(); + StaticJsonDocument doc; + JsonObject json = doc.to(); if (!export_values(json)) { return; // empty } @@ -78,27 +78,26 @@ void Heatpump::show_values(uuid::console::Shell & shell) { void Heatpump::publish_values(JsonObject & json, bool force) { // handle HA first if (Mqtt::mqtt_format() == Mqtt::Format::HA) { - register_mqtt_ha_config(force); + if (!mqtt_ha_config_ || force) { + register_mqtt_ha_config(); + return; + } } - StaticJsonDocument doc; - JsonObject json_data = doc.to(); + StaticJsonDocument doc; + JsonObject json_data = doc.to(); if (export_values(json_data)) { Mqtt::publish(F("heatpump_data"), doc.as()); } } -void Heatpump::register_mqtt_ha_config(bool force) { - if ((mqtt_ha_config_ && !force)) { - return; - } - +void Heatpump::register_mqtt_ha_config() { if (!Mqtt::connected()) { return; } // Create the Master device - StaticJsonDocument doc; + StaticJsonDocument doc; doc["name"] = F_(EMSESP); doc["uniq_id"] = F_(heatpump); doc["ic"] = F_(iconheatpump); diff --git a/src/devices/heatpump.h b/src/devices/heatpump.h index a1b641cc6..2f453523c 100644 --- a/src/devices/heatpump.h +++ b/src/devices/heatpump.h @@ -45,7 +45,7 @@ class Heatpump : public EMSdevice { private: static uuid::log::Logger logger_; - void register_mqtt_ha_config(bool force); + void register_mqtt_ha_config(); uint8_t airHumidity_ = EMS_VALUE_UINT_NOTSET; uint8_t dewTemperature_ = EMS_VALUE_UINT_NOTSET; diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index 43354768d..41c636c51 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -62,7 +62,7 @@ void Mixer::device_info_web(JsonArray & root) { } // fetch the values into a JSON document - StaticJsonDocument doc; + StaticJsonDocument doc; JsonObject json = doc.to(); if (!export_values_format(Mqtt::Format::SINGLE, json)) { return; // empty @@ -101,7 +101,7 @@ void Mixer::show_values(uuid::console::Shell & shell) { } // fetch the values into a JSON document - StaticJsonDocument doc; + StaticJsonDocument doc; JsonObject json = doc.to(); if (!export_values_format(Mqtt::Format::SINGLE, json)) { return; // empty @@ -128,13 +128,16 @@ void Mixer::show_values(uuid::console::Shell & shell) { void Mixer::publish_values(JsonObject & json, bool force) { // handle HA first if (Mqtt::mqtt_format() == Mqtt::Format::HA) { - register_mqtt_ha_config(force); + if (!mqtt_ha_config_ || force) { + register_mqtt_ha_config(); + return; + } } if (Mqtt::mqtt_format() == Mqtt::Format::SINGLE) { StaticJsonDocument doc; - JsonObject json = doc.to(); - if (export_values_format(Mqtt::mqtt_format(), json)) { + JsonObject json_data = doc.to(); + if (export_values_format(Mqtt::mqtt_format(), json_data)) { char topic[30]; if (type() == Type::HC) { snprintf_P(topic, 30, PSTR("mixer_data_hc%d"), hc_); @@ -150,23 +153,18 @@ void Mixer::publish_values(JsonObject & json, bool force) { } // publish config topic for HA MQTT Discovery -void Mixer::register_mqtt_ha_config(bool force) { - if ((mqtt_ha_config_ && !force)) { - return; - } - +void Mixer::register_mqtt_ha_config() { if (!Mqtt::connected()) { return; } // if we don't have valid values for this HC don't add it ever again - if (!Helpers::hasValue(status_)) { - mqtt_ha_config_ = true; + if (!Helpers::hasValue(pumpStatus_)) { return; } // Create the Master device - StaticJsonDocument doc; + StaticJsonDocument doc; char name[20]; snprintf_P(name, sizeof(name), PSTR("Mixer %02X"), device_id() - 0x20 + 1); diff --git a/src/devices/mixer.h b/src/devices/mixer.h index bdf3b98b3..4341b214c 100644 --- a/src/devices/mixer.h +++ b/src/devices/mixer.h @@ -46,7 +46,7 @@ class Mixer : public EMSdevice { static uuid::log::Logger logger_; bool export_values_format(uint8_t mqtt_format, JsonObject & doc); - void register_mqtt_ha_config(bool force); + void register_mqtt_ha_config(); void process_MMPLUSStatusMessage_HC(std::shared_ptr telegram); void process_MMPLUSStatusMessage_WWC(std::shared_ptr telegram); diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index f865945d2..900cfdd2c 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -127,7 +127,10 @@ void Solar::show_values(uuid::console::Shell & shell) { void Solar::publish_values(JsonObject & json, bool force) { // handle HA first if (Mqtt::mqtt_format() == Mqtt::Format::HA) { - register_mqtt_ha_config(force); + if ((!mqtt_ha_config_ || force)) { + register_mqtt_ha_config(); + return; + } } StaticJsonDocument doc; @@ -142,17 +145,13 @@ void Solar::publish_values(JsonObject & json, bool force) { } // publish config topic for HA MQTT Discovery -void Solar::register_mqtt_ha_config(bool force) { - if ((mqtt_ha_config_ && !force)) { - return; - } - +void Solar::register_mqtt_ha_config() { if (!Mqtt::connected()) { return; } // Create the Master device - StaticJsonDocument doc; + StaticJsonDocument doc; doc["name"] = F_(EMSESP); doc["uniq_id"] = F_(solar); doc["ic"] = F_(iconthermostat); diff --git a/src/devices/solar.h b/src/devices/solar.h index dcc649a12..3054b912b 100644 --- a/src/devices/solar.h +++ b/src/devices/solar.h @@ -44,7 +44,7 @@ class Solar : public EMSdevice { private: static uuid::log::Logger logger_; - void register_mqtt_ha_config(bool force); + void register_mqtt_ha_config(); int16_t collectorTemp_ = EMS_VALUE_SHORT_NOTSET; // TS1: Temperature sensor for collector array 1 int16_t tankBottomTemp_ = EMS_VALUE_SHORT_NOTSET; // TS2: Temperature sensor 1 cylinder, bottom (solar thermal system) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index cdaf6f7e9..3a8605632 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -180,7 +180,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // prepare data for Web UI void Thermostat::device_info_web(JsonArray & root) { - StaticJsonDocument doc_main; + StaticJsonDocument doc_main; JsonObject json_main = doc_main.to(); if (export_values_main(json_main)) { print_value_json(root, F("time"), nullptr, F_(time), nullptr, json_main); @@ -336,10 +336,16 @@ void Thermostat::publish_values(JsonObject & json, bool force) { if (EMSESP::actual_master_thermostat() != this->device_id()) { return; } + // see if we have already registered this with HA MQTT Discovery, if not send the config + if (Mqtt::mqtt_format() == Mqtt::Format::HA) { + if (!ha_config(force)) { + return; + } + } - StaticJsonDocument doc; - JsonObject json_data = doc.to(); - bool has_data = false; + StaticJsonDocument doc; + JsonObject json_data = doc.to(); + bool has_data = false; // if MQTT is in single mode send out the main data to the thermostat_data topic has_data |= export_values_main(json_data); @@ -354,10 +360,6 @@ void Thermostat::publish_values(JsonObject & json, bool force) { // if we're in HA or CUSTOM, send out the complete topic with all the data if (Mqtt::mqtt_format() != Mqtt::Format::SINGLE && has_data) { - // see if we have already registered this with HA MQTT Discovery, if not send the config - if (Mqtt::mqtt_format() == Mqtt::Format::HA) { - ha_config(force); - } Mqtt::publish(F("thermostat_data"), json_data); } } @@ -685,23 +687,32 @@ bool Thermostat::export_values_hc(uint8_t mqtt_format, JsonObject & rootThermost } // set up HA MQTT Discovery -void Thermostat::ha_config(bool force) { +bool Thermostat::ha_config(bool force) { if (!Mqtt::connected()) { - return; + return false; + } + if (force) { + for (const auto & hc : heating_circuits_) { + hc->ha_registered(false); + } + ha_registered(false); } - if (force || !ha_registered()) { + if (!ha_registered()) { register_mqtt_ha_config(); ha_registered(true); + return false; } // check to see which heating circuits need publishing for (const auto & hc : heating_circuits_) { - if (force || (hc->is_active() && !hc->ha_registered())) { + if (hc->is_active() && !hc->ha_registered()) { register_mqtt_ha_config(hc->hc_num()); hc->ha_registered(true); + return false; } } + return true; } // returns the heating circuit object based on the hc number @@ -809,7 +820,7 @@ std::shared_ptr Thermostat::heating_circuit(std::sha // publish config topic for HA MQTT Discovery // homeassistant/climate/ems-esp/thermostat/config void Thermostat::register_mqtt_ha_config() { - StaticJsonDocument doc; + StaticJsonDocument doc; doc["uniq_id"] = F("thermostat"); doc["ic"] = F("mdi:home-thermometer-outline"); @@ -865,13 +876,13 @@ void Thermostat::register_mqtt_ha_config() { void Thermostat::register_mqtt_ha_config(uint8_t hc_num) { StaticJsonDocument doc; - char str1[40]; + char str1[20]; snprintf_P(str1, sizeof(str1), PSTR("Thermostat hc%d"), hc_num); - char str2[40]; + char str2[20]; snprintf_P(str2, sizeof(str2), PSTR("thermostat_hc%d"), hc_num); - char str3[40]; + char str3[25]; snprintf_P(str3, sizeof(str3), PSTR("~/%s"), str2); doc["mode_cmd_t"] = str3; doc["temp_cmd_t"] = str3; diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 2366674a6..2e8999a1b 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -248,7 +248,7 @@ class Thermostat : public EMSdevice { void register_mqtt_ha_config(); void register_mqtt_ha_config(uint8_t hc_num); - void ha_config(bool force = false); + bool ha_config(bool force = false); bool thermostat_ha_cmd(const char * message, uint8_t hc_num); void process_RCOutdoorTemp(std::shared_ptr telegram); diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 91b30df71..117f1f706 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -64,6 +64,7 @@ uint16_t EMSESP::publish_id_ = 0; bool EMSESP::tap_water_active_ = false; // for when Boiler states we having running warm water. used in Shower() uint32_t EMSESP::last_fetch_ = 0; uint8_t EMSESP::unique_id_count_ = 0; +uint8_t EMSESP::publish_all_idx_ = 0; // for a specific EMS device go and request data values // or if device_id is 0 it will fetch from all our known and active devices @@ -290,29 +291,74 @@ void EMSESP::show_sensor_values(uuid::console::Shell & shell) { // MQTT publish everything, immediately void EMSESP::publish_all(bool force) { + if (force) { + publish_all_idx_ = 1; + return; + } if (Mqtt::connected()) { - publish_device_values(EMSdevice::DeviceType::BOILER, force); - publish_device_values(EMSdevice::DeviceType::THERMOSTAT, force); - publish_device_values(EMSdevice::DeviceType::SOLAR, force); - publish_device_values(EMSdevice::DeviceType::MIXER, force); + publish_device_values(EMSdevice::DeviceType::BOILER, false); + publish_device_values(EMSdevice::DeviceType::THERMOSTAT, false); + publish_device_values(EMSdevice::DeviceType::SOLAR, false); + publish_device_values(EMSdevice::DeviceType::MIXER, false); publish_other_values(); - publish_sensor_values(true); + publish_sensor_values(true, false); system_.send_heartbeat(); } } +// on command "publish HA" loop and wait between devices for publishing all sensors +void EMSESP::publish_all_loop() { + static uint32_t last = 0; + if (!Mqtt::connected() || !publish_all_idx_) { + return; + } + // every HA-sensor takes 20 ms, wait ~2 sec to finish (boiler have ~70 sensors) + if ((uuid::get_uptime() - last < 2000)) { + return; + } + last = uuid::get_uptime(); + switch (publish_all_idx_++) { + case 1: + publish_device_values(EMSdevice::DeviceType::BOILER, true); + break; + case 2: + publish_device_values(EMSdevice::DeviceType::THERMOSTAT, true); + break; + case 3: + publish_device_values(EMSdevice::DeviceType::SOLAR, true); + break; + case 4: + publish_device_values(EMSdevice::DeviceType::MIXER, true); + break; + case 5: + publish_other_values(); + break; + case 6: + publish_sensor_values(true, true); + break; + case 7: + system_.send_heartbeat(); + break; + default: + // all finished + publish_all_idx_ = 0; + last = 0; + } +} + // create json doc for the devices values and add to MQTT publish queue // special case for Mixer units, since we want to bundle all devices together into one payload void EMSESP::publish_device_values(uint8_t device_type, bool force) { if (device_type == EMSdevice::DeviceType::MIXER && Mqtt::mqtt_format() != Mqtt::Format::SINGLE) { - DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_LARGE); - JsonObject json = doc.to(); + // DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_LARGE); + StaticJsonDocument doc; + JsonObject json = doc.to(); for (const auto & emsdevice : emsdevices) { if (emsdevice && (emsdevice->device_type() == device_type)) { emsdevice->publish_values(json, force); } } - doc.shrinkToFit(); + // doc.shrinkToFit(); Mqtt::publish("mixer_data", doc.as()); return; } @@ -335,9 +381,9 @@ void EMSESP::publish_other_values() { } } -void EMSESP::publish_sensor_values(const bool force) { - if (dallassensor_.updated_values() || force) { - dallassensor_.publish_values(); +void EMSESP::publish_sensor_values(const bool time, const bool force) { + if (dallassensor_.updated_values() || time || force) { + dallassensor_.publish_values(force); } } @@ -936,6 +982,7 @@ void EMSESP::loop() { system_.loop(); // does LED and checks system health, and syslog service shower_.loop(); // check for shower on/off dallassensor_.loop(); // this will also send out via MQTT + publish_all_loop(); mqtt_.loop(); // sends out anything in the queue via MQTT console_.loop(); // telnet/serial console rxservice_.loop(); // process any incoming Rx telegrams diff --git a/src/emsesp.h b/src/emsesp.h index 0fd6d976a..dbcdb6a04 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -63,7 +63,7 @@ class EMSESP { static void publish_device_values(uint8_t device_type, bool force = false); static void publish_other_values(); - static void publish_sensor_values(const bool force = false); + static void publish_sensor_values(const bool time, const bool force = false); static void publish_all(bool force = false); #ifdef EMSESP_STANDALONE @@ -184,6 +184,7 @@ class EMSESP { static void process_UBADevices(std::shared_ptr telegram); static void process_version(std::shared_ptr telegram); static void publish_response(std::shared_ptr telegram); + static void publish_all_loop(); static bool command_info(uint8_t device_type, JsonObject & json); @@ -207,6 +208,7 @@ class EMSESP { static uint16_t publish_id_; static bool tap_water_active_; static uint8_t unique_id_count_; + static uint8_t publish_all_idx_; }; } // namespace emsesp diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 09febd6fc..7dc881187 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -40,7 +40,7 @@ bool Mqtt::mqtt_enabled_; std::vector Mqtt::mqtt_subfunctions_; uint16_t Mqtt::mqtt_publish_fails_ = 0; -size_t Mqtt::maximum_mqtt_messages_ = Mqtt::MAX_MQTT_MESSAGES; +// size_t Mqtt::maximum_mqtt_messages_ = Mqtt::MAX_MQTT_MESSAGES; uint16_t Mqtt::mqtt_message_id_ = 0; std::list Mqtt::mqtt_messages_; char will_topic_[Mqtt::MQTT_TOPIC_MAX_SIZE]; // because MQTT library keeps only char pointer @@ -527,7 +527,7 @@ std::shared_ptr Mqtt::queue_message(const uint8_t operation, } // if the queue is full, make room but removing the last one - if (mqtt_messages_.size() >= maximum_mqtt_messages_) { + if (mqtt_messages_.size() >= MAX_MQTT_MESSAGES) { mqtt_messages_.pop_front(); } mqtt_messages_.emplace_back(mqtt_message_id_++, std::move(message)); @@ -695,7 +695,8 @@ void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, cons return; } - StaticJsonDocument doc; + DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_SMALL); + // StaticJsonDocument doc; doc["name"] = name; doc["uniq_id"] = entity; @@ -723,11 +724,13 @@ void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, cons snprintf_P(ha_device, sizeof(ha_device), PSTR("ems-esp-%s"), EMSdevice::device_type_2_device_name(device_type).c_str()); ids.add(ha_device); + doc.shrinkToFit(); + char topic[MQTT_TOPIC_MAX_SIZE]; snprintf_P(topic, sizeof(topic), PSTR("homeassistant/binary_sensor/ems-esp/%s/config"), entity); // convert json to string and publish immediately with retain forced to true - char payload_text[300]; + char payload_text[256]; serializeJson(doc, payload_text); // convert json to string uint16_t packet_id = mqttClient_->publish(topic, 0, true, payload_text); #if defined(EMSESP_STANDALONE) @@ -740,7 +743,9 @@ void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, cons } #endif - delay(MQTT_PUBLISH_WAIT); + // delay(MQTT_PUBLISH_WAIT); + delay(50); + } // HA config for a normal 'sensor' type @@ -761,11 +766,11 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix, if (prefix != nullptr) { snprintf_P(new_entity, sizeof(new_entity), PSTR("%s.%s"), prefix, entity); } else { - strcpy(new_entity, entity); + strncpy(new_entity, entity, sizeof(new_entity)); } char device_name[50]; - strcpy(device_name, EMSdevice::device_type_2_device_name(device_type).c_str()); + strncpy(device_name, EMSdevice::device_type_2_device_name(device_type).c_str(), sizeof(device_name)); // build unique identifier, replacing all . with _ as not to break HA std::string uniq(50, '\0'); @@ -801,9 +806,8 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix, } new_name[0] = toupper(new_name[0]); // capitalize first letter - StaticJsonDocument doc; - - // DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_SMALL); + DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_SMALL); + // StaticJsonDocument doc; doc["name"] = new_name; doc["uniq_id"] = uniq.c_str(); @@ -819,13 +823,10 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix, JsonArray ids = dev.createNestedArray("ids"); ids.add(ha_device); + doc.shrinkToFit(); // convert json to string and publish immediately with retain forced to true - // std::string payload_text; - char payload_text[300]; + char payload_text[256]; serializeJson(doc, payload_text); // convert json to string - // queue_publish_message(topic, payload_text, true); - - // publish_retain(topic, doc.as(), true); uint16_t packet_id = mqttClient_->publish(topic, 0, true, payload_text); if (!packet_id) { @@ -838,7 +839,8 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix, #endif } - delay(MQTT_PUBLISH_WAIT); // don't flood asynctcp -} + // delay(MQTT_PUBLISH_WAIT); // don't flood asynctcp + delay(50); // enough time to send the short message out +} } // namespace emsesp diff --git a/src/mqtt.h b/src/mqtt.h index ed1970cb6..8b987dbb4 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -40,7 +40,9 @@ using uuid::console::Shell; #define EMSESP_MAX_JSON_SIZE_SMALL 256 // for smaller json docs when using StaticJsonDocument #define EMSESP_MAX_JSON_SIZE_MEDIUM 768 // for smaller json docs from ems devices, when using StaticJsonDocument -#define EMSESP_MAX_JSON_SIZE_LARGE 2048 // for large json docs from ems devices, like boiler or thermostat data. Using DynamicJsonDocument +// #define EMSESP_MAX_JSON_SIZE_LARGE 2048 // for large json docs from ems devices, like boiler or thermostat data. Using DynamicJsonDocument +// mqtt does not publish larger than 1570 on esp8266, boiler message is split and now smaller +#define EMSESP_MAX_JSON_SIZE_LARGE 1536 // for large json docs from ems devices, like boiler or thermostat data. Using StaticJsonDocument namespace emsesp { @@ -170,10 +172,10 @@ class Mqtt { static AsyncMqttClient * mqttClient_; - static size_t maximum_mqtt_messages_; + // static size_t maximum_mqtt_messages_; static uint16_t mqtt_message_id_; - static constexpr size_t MAX_MQTT_MESSAGES = 70; // size of queue + static constexpr size_t MAX_MQTT_MESSAGES = 20; // size of queue static constexpr uint32_t MQTT_PUBLISH_WAIT = 200; // delay between sending publishes, to account for large payloads static constexpr uint8_t MQTT_PUBLISH_MAX_RETRY = 3; // max retries for giving up on publishing diff --git a/src/system.cpp b/src/system.cpp index dde28449d..524561998 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -65,6 +65,12 @@ bool System::command_send(const char * value, const int8_t id) { return true; } +// publish +bool System::command_publish(const char * value, const int8_t id) { + EMSESP::publish_all(); // ignore value and id + return true; +} + // restart EMS-ESP void System::restart() { LOG_NOTICE(F("Restarting system...")); @@ -165,6 +171,7 @@ void System::start() { EMSESP::webSettingsService.read([&](WebSettings & settings) { Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(pin), System::command_pin); Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(send), System::command_send); + Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(publish), System::command_publish); Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info); Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(report), System::command_report); }); diff --git a/src/system.h b/src/system.h index 808b189fa..a5f5c44e7 100644 --- a/src/system.h +++ b/src/system.h @@ -50,6 +50,7 @@ class System { static bool command_pin(const char * value, const int8_t id); static bool command_send(const char * value, const int8_t id); + static bool command_publish(const char * value, const int8_t id); static bool command_info(const char * value, const int8_t id, JsonObject & json); static bool command_report(const char * value, const int8_t id, JsonObject & json); From c2536d8b2cf8a0327175bd59cf7134351d16fb84 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 13 Nov 2020 15:20:52 +0100 Subject: [PATCH 29/55] Junkers FR50 as device-type Junker2, fix #605 --- src/device_library.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device_library.h b/src/device_library.h index eca924972..6481f2af9 100644 --- a/src/device_library.h +++ b/src/device_library.h @@ -87,7 +87,7 @@ {107, DeviceType::THERMOSTAT, F("FR100"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_2}, // older model {108, DeviceType::THERMOSTAT, F("FR110"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_2}, // older model {111, DeviceType::THERMOSTAT, F("FR10"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS}, -{147, DeviceType::THERMOSTAT, F("FR50"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS}, +{147, DeviceType::THERMOSTAT, F("FR50"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_2}, {191, DeviceType::THERMOSTAT, F("FR120"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS | DeviceFlags::EMS_DEVICE_FLAG_JUNKERS_2}, // older model {192, DeviceType::THERMOSTAT, F("FW120"), DeviceFlags::EMS_DEVICE_FLAG_JUNKERS}, From 4805fb6c46d91f2a3d7c5947329a6a57e541b4d5 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 14 Nov 2020 00:01:56 +0100 Subject: [PATCH 30/55] don't send shower MQTT if MQTT disabled --- src/shower.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shower.cpp b/src/shower.cpp index be67e0067..4d1a2559d 100644 --- a/src/shower.cpp +++ b/src/shower.cpp @@ -28,7 +28,9 @@ void Shower::start() { shower_alert_ = settings.shower_alert; }); - send_mqtt_stat(false); // send first MQTT publish + if (Mqtt::enabled()) { + send_mqtt_stat(false); // send first MQTT publish + } } void Shower::loop() { From 716cbf7e861d730ae162b2aa3c6b3b092dc78f19 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 14 Nov 2020 00:02:12 +0100 Subject: [PATCH 31/55] updated --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1176cfd07..aafac8a94 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ firmware /lib/framework/WWWData.h /interface/build/ /interface/node_modules/ +.VSCodeCounter/ From 055504381069e904a61a9a20e6ce2db0f427de49 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 14 Nov 2020 00:03:04 +0100 Subject: [PATCH 32/55] text changes --- src/dallassensor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dallassensor.cpp b/src/dallassensor.cpp index b1a0bf53c..940e6e74e 100644 --- a/src/dallassensor.cpp +++ b/src/dallassensor.cpp @@ -84,12 +84,12 @@ void DallasSensor::loop() { bus_.reset_search(); state_ = State::SCANNING; } else if (time_now - last_activity_ > READ_TIMEOUT_MS) { - LOG_ERROR(F("Sensor read timeout")); + LOG_WARNING(F("Dallas sensor read timeout")); state_ = State::IDLE; } } else if (state_ == State::SCANNING) { if (time_now - last_activity_ > SCAN_TIMEOUT_MS) { - LOG_ERROR(F("Sensor scan timeout")); + LOG_ERROR(F("Dallas sensor scan timeout")); state_ = State::IDLE; } else { uint8_t addr[ADDR_LEN] = {0}; @@ -129,11 +129,11 @@ void DallasSensor::loop() { break; default: - LOG_ERROR(F("Unknown sensor %s"), Sensor(addr).to_string().c_str()); + LOG_ERROR(F("Unknown dallas sensor %s"), Sensor(addr).to_string().c_str()); break; } } else { - LOG_ERROR(F("Invalid sensor %s"), Sensor(addr).to_string().c_str()); + LOG_ERROR(F("Invalid dallas sensor %s"), Sensor(addr).to_string().c_str()); } } else { if (!parasite_) { From 8bd7b21f30ecb5f7aff69e8391d6caaa9e6f0d3d Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 14 Nov 2020 00:05:00 +0100 Subject: [PATCH 33/55] minor updates --- src/test/test.cpp | 175 ++++++++++++++++++++-------------------------- src/test/test.h | 3 +- 2 files changed, 76 insertions(+), 102 deletions(-) diff --git a/src/test/test.cpp b/src/test/test.cpp index b4dbb0bf4..bc67357c7 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -27,10 +27,10 @@ namespace emsesp { // used with the 'test' command, under su/admin void Test::run_test(uuid::console::Shell & shell, const std::string & command) { // switch to su - shell.add_flags(CommandFlags::ADMIN); + // shell.add_flags(CommandFlags::ADMIN); if (command == "default") { - run_test(shell, "general"); // add the default test case here + run_test(shell, "boiler"); // add the default test case here } if (command.empty()) { @@ -38,6 +38,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { } if (command == "render") { + shell.printfln(F("Testing render...")); + uint8_t test1 = 12; int8_t test2 = -12; uint16_t test3 = 456; @@ -133,6 +135,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { } if (command == "devices") { + shell.printfln(F("Testing devices...")); + EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); // this is important otherwise nothing will be picked up! //emsdevices.push_back(EMSFactory::add(EMSdevice::DeviceType::BOILER, EMSdevice::EMS_DEVICE_ID_BOILER, 0, "", "My Boiler", 0, 0)); @@ -141,39 +145,29 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { rx_telegram({0x08, 0x00, 0x07, 0x00, 0x0B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); } - if (command == "boiler") { - // question: do we need to set the mask? - std::string version("1.2.3"); - EMSESP::add_device(0x08, 123, version, EMSdevice::Brand::BUDERUS); // Nefit Trendline - - // UBAuptime - uart_telegram({0x08, 0x0B, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70}); - - shell.invoke_command("show"); - shell.invoke_command("call boiler info"); - } - // check for boiler and controller on same product_id if (command == "double") { - // question: do we need to set the mask? - std::string version("1.2.3"); - EMSESP::add_device(0x08, 206, version, EMSdevice::Brand::BUDERUS); // Nefit Excellent HR30 - EMSESP::add_device(0x09, 206, version, EMSdevice::Brand::BUDERUS); // Nefit Excellent HR30 Controller + shell.printfln(F("Testing double...")); + + add_device(0x08, 206); // Nefit Excellent HR30 + add_device(0x09, 206); // Nefit Excellent HR30 Controller // UBAuptime uart_telegram({0x08, 0x0B, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70}); } - // unknown device - + // unknown device if (command == "unknown") { + shell.printfln(F("Testing unknown...")); + // question: do we need to set the mask? std::string version("1.2.3"); // add boiler - EMSESP::add_device(0x08, 84, version, EMSdevice::Brand::BUDERUS); + add_device(0x08, 84); - // add Controller - BC10 GB142 - but using the same device_id to see what happens - EMSESP::add_device(0x09, 84, version, EMSdevice::Brand::BUDERUS); + // add Controller - BC10 GB142 - but using the same product_id to see what happens + add_device(0x09, 84); // simulate getting version information back from an unknown device // note there is no brand (byte 9) @@ -184,11 +178,15 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { } if (command == "unknown2") { + shell.printfln(F("Testing unknown2...")); + // simulate getting version information back from an unknown device rx_telegram({0x09, 0x0B, 0x02, 0x00, 0x5A, 0x01, 0x02}); // product id is 90 which doesn't exist } if (command == "gateway") { + shell.printfln(F("Testing Gateway...")); + // add 0x48 KM200, via a version command rx_telegram({0x48, 0x0B, 0x02, 0x00, 0xBD, 0x04, 0x06, 00, 00, 00, 00, 00, 00, 00}); @@ -197,8 +195,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { rx_telegram({0x08, 0x00, 0x07, 0x00, 0x09, 01, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00, 00}); // add thermostat - Thermostat: RC300/RC310/Moduline 3000/CW400/Sense II (DeviceID:0x10, ProductID:158, Version:03.03) ** master device ** - std::string version("01.03"); - EMSESP::add_device(0x10, 158, version, EMSdevice::Brand::BUDERUS); + add_device(0x10, 158); // Nefit Trendline // simulate incoming telegram // Thermostat(0x10) -> 48(0x48), ?(0x26B), data: 6B 08 4F 00 00 00 02 00 00 00 02 00 03 00 03 00 03 @@ -208,9 +205,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { if (command == "web") { shell.printfln(F("Testing Web...")); - std::string version("1.2.3"); - EMSESP::add_device(0x08, 123, version, EMSdevice::Brand::BUDERUS); // Nefit Trendline - EMSESP::add_device(0x18, 157, version, EMSdevice::Brand::BOSCH); // Bosch CR100 - https://github.com/proddy/EMS-ESP/issues/355 + add_device(0x08, 123); // Nefit Trendline + add_device(0x18, 157); // Bosch CR100 // 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) @@ -238,13 +234,23 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { shell.println(); } + if (command == "boiler") { + shell.printfln(F("Testing boiler...")); + + add_device(0x08, 123); // Nefit Trendline + + // UBAuptime + uart_telegram({0x08, 0x0B, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70}); + + shell.invoke_command("show"); + shell.invoke_command("call boiler info"); + } + if (command == "general") { - shell.printfln(F("Testing adding a boiler & thermostat...")); + shell.printfln(F("Testing adding a general boiler & thermostat...")); - std::string version("1.2.3"); - - EMSESP::add_device(0x08, 123, version, EMSdevice::Brand::BUDERUS); // Nefit Trendline - EMSESP::add_device(0x18, 157, version, EMSdevice::Brand::BOSCH); // Bosch CR100 - https://github.com/proddy/EMS-ESP/issues/355 + add_device(0x08, 123); // Nefit Trendline + // add_device(0x18, 157); // Bosch CR100 // 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) @@ -269,20 +275,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { if (command == "fr120") { shell.printfln(F("Testing adding a thermostat FR120...")); - // add_device(0x10, 165, version, EMSdevice::Brand::BUDERUS); - // add_device(0x17, 125, version, EMSdevice::Brand::BUDERUS); // test unknown class test - // add_device(0x17, 93, version, EMSdevice::Brand::BUDERUS); - // add_device(0x17, 254, version, EMSdevice::Brand::BUDERUS); // test unknown product_id - - // EMSESP::add_device(0x18, 157, version, EMSdevice::Brand::BOSCH); // Bosch CR100 - https://github.com/proddy/EMS-ESP/issues/355 - - std::string version("1.2.3"); - - // add a boiler - // EMSESP::add_device(0x08, 123, version, EMSdevice::Brand::BUDERUS); // Nefit Trendline - // add a thermostat - EMSESP::add_device(0x10, 191, version, EMSdevice::Brand::JUNKERS); // FR120 + add_device(0x10, 191); // FR120 // HC1 uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x6F, 0x00, 0xCF, 0x21, 0x2E, 0x20, 0x00, 0x2E, 0x24, @@ -295,20 +289,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { if (command == "thermostat") { shell.printfln(F("Testing adding a thermostat FW120...")); - // add_device(0x10, 165, version, EMSdevice::Brand::BUDERUS); - // add_device(0x17, 125, version, EMSdevice::Brand::BUDERUS); // test unknown class test - // add_device(0x17, 93, version, EMSdevice::Brand::BUDERUS); - // add_device(0x17, 254, version, EMSdevice::Brand::BUDERUS); // test unknown product_id - - // EMSESP::add_device(0x18, 157, version, EMSdevice::Brand::BOSCH); // Bosch CR100 - https://github.com/proddy/EMS-ESP/issues/355 - - std::string version("1.2.3"); - - // add a boiler - // EMSESP::add_device(0x08, 123, version, EMSdevice::Brand::BUDERUS); // Nefit Trendline - // add a thermostat - EMSESP::add_device(0x10, 192, version, EMSdevice::Brand::JUNKERS); // FW120 + add_device(0x10, 192); // FW120 // HC1 uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x6F, 0x00, 0xCF, 0x21, 0x2E, 0x20, 0x00, 0x2E, 0x24, @@ -331,13 +313,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { if (command == "tc100") { shell.printfln(F("Testing adding a TC100 thermostat to the EMS bus...")); - std::string version("02.21"); - - // add a boiler - // EMSESP::add_device(0x08, 123, version, EMSdevice::Brand::BUDERUS); // Nefit Trendline - // add a thermostat - EMSESP::add_device(0x18, 202, version, EMSdevice::Brand::BOSCH); // Bosch TC100 - https://github.com/proddy/EMS-ESP/issues/474 + add_device(0x18, 202); // Bosch TC100 - https://github.com/proddy/EMS-ESP/issues/474 // 0x0A uart_telegram({0x98, 0x0B, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -349,8 +326,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); - std::string version("1.2.3"); - EMSESP::add_device(0x30, 163, version, EMSdevice::Brand::BUDERUS); // SM100 + add_device(0x30, 163); // SM100 // 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 @@ -377,19 +353,19 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); - std::string version("1.2.3"); - // add heatpump - EMSESP::add_device(0x38, 200, version, EMSdevice::Brand::BUDERUS); // Enviline module + add_device(0x38, 200); // Enviline module // add a thermostat - EMSESP::add_device(0x10, 192, version, EMSdevice::Brand::JUNKERS); // FW120 + add_device(0x10, 192); // FW120 + uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x6F, 0x00, 0xCF, 0x21, 0x2E, 0x20, 0x00, 0x2E, 0x24, 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); // HC1 uart_telegram("38 0B FF 00 03 7B 0C 34 00 74"); shell.invoke_command("call"); shell.invoke_command("call heatpump info"); + EMSESP::show_device_values(shell); } @@ -398,8 +374,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); - std::string version("1.2.3"); - EMSESP::add_device(0x30, 164, version, EMSdevice::Brand::BUDERUS); // SM200 + add_device(0x30, 164); // SM200 // 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 @@ -433,13 +408,11 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); - std::string version("1.2.3"); - EMSESP::add_device(0x10, 158, version, EMSdevice::Brand::BUDERUS); // RC300 - EMSESP::add_device(0x48, 189, version, EMSdevice::Brand::BUDERUS); // KM200 + add_device(0x10, 158); // RC300 + add_device(0x48, 189); // KM200 // see https://github.com/proddy/EMS-ESP/issues/390 - /* uart_telegram_withCRC("90 48 FF 04 01 A6 5C"); uart_telegram_withCRC("90 48 FF 00 01 A6 4C"); uart_telegram_withCRC("90 48 FF 08 01 A7 6D"); @@ -477,7 +450,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { uart_telegram_withCRC("C8 90 FF 00 02 01 A6 D0"); // uart_telegram_withCRC("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"); - */ uart_telegram_withCRC("C8 90 F7 02 01 FF 01 A6 BA"); @@ -498,8 +470,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_HT3); // switch to junkers - std::string version("1.2.3"); - EMSESP::add_device(0x18, 157, version, EMSdevice::Brand::BOSCH); // Bosch CR100 - https://github.com/proddy/EMS-ESP/issues/355 + add_device(0x18, 157); // Bosch CR100 - https://github.com/proddy/EMS-ESP/issues/355 // 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) @@ -669,8 +640,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { shell.printfln(F("Testing Commands...")); // add a thermostat with 3 HCs - std::string version("1.2.3"); - EMSESP::add_device(0x10, 192, version, EMSdevice::Brand::JUNKERS); // FW120 + add_device(0x10, 192); // FW120 + uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x6F, 0x00, 0xCF, 0x21, 0x2E, 0x20, 0x00, 0x2E, 0x24, 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); // HC1 uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x70, 0x00, 0xCF, 0x22, 0x2F, 0x10, 0x00, 0x2E, 0x24, @@ -711,12 +682,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { }); // add a boiler - // question: do we need to set the mask? - std::string version("1.2.3"); - EMSESP::add_device(0x08, 123, version, EMSdevice::Brand::BUDERUS); // Nefit Trendline + add_device(0x08, 123); // Nefit Trendline // add a thermostat - EMSESP::add_device(0x18, 157, version, EMSdevice::Brand::BOSCH); // Bosch CR100 - https://github.com/proddy/EMS-ESP/issues/355 + add_device(0x18, 157); // Bosch CR100 - https://github.com/proddy/EMS-ESP/issues/355 // RCPLUSStatusMessage_HC1(0x01A5) - HC1 uart_telegram({0x98, 0x00, 0xFF, 0x00, 0x01, 0xA5, 0x00, 0xCF, 0x21, 0x2E, 0x00, 0x00, 0x2E, 0x24, @@ -791,23 +760,31 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { } 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}); } // https://github.com/proddy/EMS-ESP/issues/380#issuecomment-633663007 if (command == "rx3") { + shell.printfln(F("Testing rx3...")); + uart_telegram({0x21, 0x0B, 0xFF, 0x00}); } // testing the UART tx command, without a queue if (command == "tx2") { + shell.printfln(F("Testing tx2...")); + uint8_t t[] = {0x0B, 0x88, 0x18, 0x00, 0x20, 0xD4}; // including CRC EMSuart::transmit(t, sizeof(t)); } // send read request with offset if (command == "offset") { + shell.printfln(F("Testing offset...")); + // send_read_request(0x18, 0x08); EMSESP::txservice_.read_request(0x18, 0x08, 27); // no offset } @@ -824,14 +801,13 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { }); EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); - std::string version("1.2.3"); // add controller - EMSESP::add_device(0x09, 114, version, EMSdevice::Brand::BUDERUS); + add_device(0x09, 114); - EMSESP::add_device(0x28, 160, version, EMSdevice::Brand::BUDERUS); // MM100, WWC - EMSESP::add_device(0x29, 161, version, EMSdevice::Brand::BUDERUS); // MM200, WWC - EMSESP::add_device(0x20, 160, version, EMSdevice::Brand::BOSCH); // MM100 + add_device(0x28, 160); // MM100, WWC + add_device(0x29, 161); // MM200, WWC + add_device(0x20, 160); // MM100 // WWC1 on 0x29 uart_telegram({0xA9, 0x00, 0xFF, 0x00, 0x02, 0x32, 0x02, 0x6C, 0x00, 0x3C, 0x00, 0x3C, 0x3C, 0x46, 0x02, 0x03, 0x03, 0x00, 0x3C}); @@ -849,9 +825,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { shell.invoke_command("show mqtt"); shell.invoke_command("call mixer"); } - - // finally dump to console - EMSESP::loop(); } // simulates a telegram in the Rx queue, but without the CRC which is added automatically @@ -878,7 +851,7 @@ void Test::uart_telegram(const std::vector & rx_data) { } data[i] = EMSESP::rxservice_.calculate_crc(data, i); EMSESP::incoming_telegram(data, i + 1); - EMSESP::rxservice_.loop(); + // EMSESP::rxservice_.loop(); } // takes raw string, assuming it contains the CRC. This is what is output from 'watch raw' @@ -916,7 +889,7 @@ void Test::uart_telegram_withCRC(const char * rx_data) { } EMSESP::incoming_telegram(data, count + 1); - EMSESP::rxservice_.loop(); + // EMSESP::rxservice_.loop(); } // takes raw string, adds CRC to end @@ -956,14 +929,14 @@ void Test::uart_telegram(const char * rx_data) { data[count + 1] = EMSESP::rxservice_.calculate_crc(data, count + 1); // add CRC EMSESP::incoming_telegram(data, count + 2); - EMSESP::rxservice_.loop(); + // EMSESP::rxservice_.loop(); } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" - - -#pragma GCC diagnostic pop +// Sends version telegram. Version is hardcoded to 1.0 +void Test::add_device(uint8_t device_id, uint8_t product_id) { + // Send version: 09 0B 02 00 PP V1 V2 + uart_telegram({device_id, EMSESP_DEFAULT_EMS_BUS_ID, EMSdevice::EMS_TYPE_VERSION, 0, product_id, 1, 0}); +} } // namespace emsesp diff --git a/src/test/test.h b/src/test/test.h index 470cdd62e..4dcb75e41 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -40,12 +40,13 @@ namespace emsesp { class Test { public: - static void run_test(uuid::console::Shell & shell, const std::string & command); // only for testing + static void run_test(uuid::console::Shell & shell, const std::string & command); static void dummy_mqtt_commands(const char * message); static void rx_telegram(const std::vector & data); static void uart_telegram(const std::vector & rx_data); static void uart_telegram(const char * rx_data); static void uart_telegram_withCRC(const char * rx_data); + static void add_device(uint8_t device_id, uint8_t product_id); }; } // namespace emsesp From 3ffa9ee5acc558f4115b5e4ff108818c2c3b842b Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 14 Nov 2020 00:08:05 +0100 Subject: [PATCH 34/55] move device unique_id count into constructor --- src/emsdevice.h | 3 ++- src/emsesp.cpp | 11 ++++++----- src/emsesp.h | 1 - 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/emsdevice.h b/src/emsdevice.h index 81ac08c44..a4a9fe2a1 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -43,6 +43,7 @@ class EMSdevice { , name_(name) , flags_(flags) , brand_(brand) { + unique_id_++; } virtual ~EMSdevice() = default; // destructor of base class must always be virtual because it's a polymorphic class @@ -270,7 +271,7 @@ class EMSdevice { static constexpr uint8_t EMS_DEVICE_FLAG_JUNKERS_2 = (1 << 6); // 6th bit set if older models, like FR120, FR100 private: - uint8_t unique_id_; + uint8_t unique_id_ = 0; uint8_t device_type_ = DeviceType::SYSTEM; uint8_t device_id_ = 0; uint8_t product_id_ = 0; diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 91b30df71..ad6273945 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -63,7 +63,6 @@ bool EMSESP::read_next_ = false; uint16_t EMSESP::publish_id_ = 0; bool EMSESP::tap_water_active_ = false; // for when Boiler states we having running warm water. used in Shower() uint32_t EMSESP::last_fetch_ = 0; -uint8_t EMSESP::unique_id_count_ = 0; // for a specific EMS device go and request data values // or if device_id is 0 it will fetch from all our known and active devices @@ -722,17 +721,19 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, std:: return false; // not found } - std::string name = uuid::read_flash_string(device_p->name); - emsdevices.push_back(EMSFactory::add(device_p->device_type, device_id, device_p->product_id, version, name, device_p->flags, brand)); - emsdevices.back()->unique_id(++unique_id_count_); + auto name = uuid::read_flash_string(device_p->name); + auto device_type = device_p->device_type; + auto flags = device_p->flags; LOG_DEBUG(F("Adding new device %s (device ID 0x%02X, product ID %d, version %s)"), name.c_str(), device_id, product_id, version.c_str()); + emsdevices.push_back(EMSFactory::add(device_type, device_id, product_id, version, name, flags, brand)); + fetch_device_values(device_id); // go and fetch its data // add info command, but not for all devices - uint8_t device_type = device_p->device_type; if ((device_type == DeviceType::CONNECT) || (device_type == DeviceType::CONTROLLER) || (device_type == DeviceType::GATEWAY)) { 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); }); diff --git a/src/emsesp.h b/src/emsesp.h index 0fd6d976a..5b6e95052 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -206,7 +206,6 @@ class EMSESP { static bool read_next_; static uint16_t publish_id_; static bool tap_water_active_; - static uint8_t unique_id_count_; }; } // namespace emsesp From 937998d9e30ec2b48a4b3a62d7c8cb77f00ce228 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 14 Nov 2020 00:10:40 +0100 Subject: [PATCH 35/55] 2.1.1b2 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 4616c4e4d..94e8574ec 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "2.1.1b1" +#define EMSESP_APP_VERSION "2.1.1b2" From 18d8d223fbabd9d4b48034aadce61bd54e61c2f4 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 00:20:04 +0100 Subject: [PATCH 36/55] updated pio examples --- debug_pio_local.ini | 31 +++++++++++++++++++++++++++++++ example_pio_local.ini | 8 ++------ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 debug_pio_local.ini diff --git a/debug_pio_local.ini b/debug_pio_local.ini new file mode 100644 index 000000000..89cbe9dad --- /dev/null +++ b/debug_pio_local.ini @@ -0,0 +1,31 @@ +[platformio] +; default_envs = esp32-local +default_envs = esp8266-local + +[env] +; upload_port = COM3 +upload_port = COM7 + +; upload_protocol = espota +; upload_flags = +; --port=8266 +; --auth=ems-esp-neo +; upload_port = ems-esp.local + +[common] +debug_flags = -DEMSESP_DEBUG + +[env:esp32-local] +monitor_filters = esp32_exception_decoder +debug_tool = esp-prog +debug_init_break = tbreak setup +build_type = debug +extra_scripts = + ; pre:scripts/build_interface.py + +[env:esp8266-local] +monitor_filters = esp8266_exception_decoder +extra_scripts = + ; pre:scripts/build_interface.py + scripts/main_script.py + diff --git a/example_pio_local.ini b/example_pio_local.ini index b34ec8817..9cd8d72ff 100644 --- a/example_pio_local.ini +++ b/example_pio_local.ini @@ -13,17 +13,13 @@ upload_port = COM7 ; upload_port = ems-esp.local [common] -debug_flags = -DEMSESP_DEBUG [env:esp32-local] -monitor_filters = esp32_exception_decoder -debug_tool = esp-prog -debug_init_break = tbreak setup -build_type = debug extra_scripts = ; pre:scripts/build_interface.py [env:esp8266-local] -monitor_filters = esp8266_exception_decoder extra_scripts = ; pre:scripts/build_interface.py + scripts/main_script.py + From ba793e0408714adbeb5622ba6aa471646e63c69f Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 14 Nov 2020 10:31:55 +0100 Subject: [PATCH 37/55] commands "fetch" and "publish ha" as call (#608) --- CHANGELOG_LATEST.md | 2 ++ src/console.cpp | 30 ------------------------------ src/system.cpp | 21 +++++++++++++++++++-- src/system.h | 1 + 4 files changed, 22 insertions(+), 32 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 996a1f35a..4f49d423c 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -4,6 +4,7 @@ - function keys in editor: cursor, del, home, end. F1=help, F2=show, and other shortcuts - SM100 pump working time and energy units - heating curve parameters for RC300 +- `wwonetime` for RC300 thermostat ### Fixed - mixer IPM pumpstatus @@ -12,6 +13,7 @@ - optimized MQTT for HA to reduce mem fragmentation issues - change syslog settings without reboot - HA-config split in smaller blocks +- commands `fetch` and `publish [ha]` as call ### Removed - old scripts diff --git a/src/console.cpp b/src/console.cpp index 7a24f8294..4e39942dd 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -108,28 +108,6 @@ void EMSESPShell::add_console_commands() { // commands->remove_context_commands(ShellContext::MAIN); commands->remove_all_commands(); - commands->add_command(ShellContext::MAIN, - CommandFlags::USER, - flash_string_vector{F_(fetch)}, - [&](Shell & shell, const std::vector & arguments __attribute__((unused))) { - shell.printfln(F("Requesting data from EMS devices")); - EMSESP::fetch_device_values(); - }); - - commands->add_command(ShellContext::MAIN, - CommandFlags::ADMIN, - flash_string_vector{F_(publish)}, - flash_string_vector{F_(ha_optional)}, - [&](Shell & shell, const std::vector & arguments) { - if (arguments.empty()) { - EMSESP::publish_all(); - shell.printfln(F("Published all data to MQTT")); - } else { - EMSESP::publish_all(true); - shell.printfln(F("Published all data to MQTT, including HA configs")); - } - }); - commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(show)}, @@ -312,14 +290,6 @@ void EMSESPShell::add_console_commands() { }); #endif - commands->add_command(ShellContext::MAIN, - CommandFlags::ADMIN, - flash_string_vector{F_(send), F_(telegram)}, - flash_string_vector{F_(data_mandatory)}, - [](Shell & shell __attribute__((unused)), const std::vector & arguments) { - EMSESP::send_raw_telegram(arguments.front().c_str()); - }); - commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(watch)}, diff --git a/src/system.cpp b/src/system.cpp index 524561998..45a40d633 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -59,15 +59,31 @@ bool System::command_pin(const char * value, const int8_t id) { return false; } -// send raw +// send raw to ems bool System::command_send(const char * value, const int8_t id) { EMSESP::send_raw_telegram(value); // ignore id return true; } -// publish +// 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(); + return true; +} + +// mqtt publish bool System::command_publish(const char * value, const int8_t id) { + std::string ha(10, '\0'); + if (Helpers::value2string(value, ha)) { + if (ha == "ha") { + EMSESP::publish_all(true); // includes HA + LOG_INFO(F("Published all data to MQTT, including HA configs")); + return true; + } + } EMSESP::publish_all(); // ignore value and id + LOG_INFO(F("Published all data to MQTT")); return true; } @@ -172,6 +188,7 @@ void System::start() { Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(pin), System::command_pin); Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(send), System::command_send); Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(publish), System::command_publish); + Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(fetch), System::command_fetch); Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info); Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(report), System::command_report); }); diff --git a/src/system.h b/src/system.h index a5f5c44e7..0af8a8aae 100644 --- a/src/system.h +++ b/src/system.h @@ -51,6 +51,7 @@ class System { static bool command_pin(const char * value, const int8_t id); static bool command_send(const char * value, const int8_t id); static bool command_publish(const char * value, const int8_t id); + static bool command_fetch(const char * value, const int8_t id); static bool command_info(const char * value, const int8_t id, JsonObject & json); static bool command_report(const char * value, const int8_t id, JsonObject & json); From 808ef71c0e232c886ea6c07d615ca2d367b9ea93 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 11:44:08 +0100 Subject: [PATCH 38/55] don't create MQTT commands if MQTT disabled --- src/command.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/command.cpp b/src/command.cpp index d2a203f23..f083cee23 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -68,7 +68,9 @@ void Command::add(const uint8_t device_type, const uint8_t device_id, const __Fl cmdfunctions_.emplace_back(device_type, cmd, cb, nullptr); // see if we need to subscribe - Mqtt::register_command(device_type, device_id, cmd, cb); + if (Mqtt::enabled()) { + Mqtt::register_command(device_type, device_id, cmd, cb); + } } // add a command to the list, which does return json object as output From b19500f84b87c4239a6a21c68c7de2e2d7f6fc3b Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 12:48:21 +0100 Subject: [PATCH 39/55] updates to core web framework --- interface/package-lock.json | 1847 +++++++++-------- interface/package.json | 42 +- .../authentication/AuthenticationWrapper.tsx | 6 +- interface/src/ntp/TZ.tsx | 418 ++-- 4 files changed, 1210 insertions(+), 1103 deletions(-) diff --git a/interface/package-lock.json b/interface/package-lock.json index de68bb46f..014040ec8 100644 --- a/interface/package-lock.json +++ b/interface/package-lock.json @@ -13,21 +13,9 @@ } }, "@babel/compat-data": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz", - "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==", - "requires": { - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "semver": "^5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.5.tgz", + "integrity": "sha512-DTsS7cxrsH3by8nqQSpFSyjSfSYl57D6Cf4q8dW3LK83tBKBDCkfcay1nYkXq1nIHXnpX8WMMb/O25HOy3h1zg==" }, "@babel/core": { "version": "7.9.0", @@ -65,11 +53,11 @@ } }, "@babel/generator": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.4.tgz", - "integrity": "sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", + "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", "requires": { - "@babel/types": "^7.11.0", + "@babel/types": "^7.12.5", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -108,24 +96,23 @@ } }, "@babel/helper-builder-react-jsx-experimental": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.5.tgz", - "integrity": "sha512-Buewnx6M4ttG+NLkKyt7baQn7ScC/Td+e99G914fRU8fGIUivDDgVIQeDHFa5e4CRSJQt58WpNHhsAZgtzVhsg==", + "version": "7.12.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.12.4.tgz", + "integrity": "sha512-AjEa0jrQqNk7eDQOo0pTfUOwQBMF+xVqrausQwT9/rTKy0g04ggFNaJpaE09IQMn9yExluigWMJcj0WC7bq+Og==", "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-module-imports": "^7.10.4", - "@babel/types": "^7.10.5" + "@babel/helper-module-imports": "^7.12.1", + "@babel/types": "^7.12.1" } }, "@babel/helper-compilation-targets": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz", - "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz", + "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==", "requires": { - "@babel/compat-data": "^7.10.4", - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "levenary": "^1.1.1", + "@babel/compat-data": "^7.12.5", + "@babel/helper-validator-option": "^7.12.1", + "browserslist": "^4.14.5", "semver": "^5.5.0" }, "dependencies": { @@ -137,26 +124,25 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz", - "integrity": "sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz", + "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==", "requires": { "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.10.5", + "@babel/helper-member-expression-to-functions": "^7.12.1", "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1", "@babel/helper-split-export-declaration": "^7.10.4" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz", - "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.1.tgz", + "integrity": "sha512-rsZ4LGvFTZnzdNZR5HZdmJVuXK8834R5QkF3WvcnBhrlVtF0HSIUC6zbreL9MgjTywhKokn8RIYRiq99+DLAxA==", "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-regex": "^7.10.4", - "regexpu-core": "^4.7.0" + "regexpu-core": "^4.7.1" } }, "@babel/helper-define-map": { @@ -170,11 +156,11 @@ } }, "@babel/helper-explode-assignable-expression": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz", - "integrity": "sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz", + "integrity": "sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==", "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.1" } }, "@babel/helper-function-name": { @@ -204,32 +190,34 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", - "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz", + "integrity": "sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ==", "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.1" } }, "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.5" } }, "@babel/helper-module-transforms": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", - "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", "requires": { - "@babel/helper-module-imports": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", "@babel/template": "^7.10.4", - "@babel/types": "^7.11.0", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", "lodash": "^4.17.19" } }, @@ -255,42 +243,40 @@ } }, "@babel/helper-remap-async-to-generator": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz", - "integrity": "sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz", + "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==", "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-wrap-function": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.1" } }, "@babel/helper-replace-supers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", - "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.5.tgz", + "integrity": "sha512-5YILoed0ZyIpF4gKcpZitEnXEJ9UoDRki1Ey6xz46rxOzfNMAhVIJMoune1hmPVxh40LRv1+oafz7UsWX+vyWA==", "requires": { - "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-member-expression-to-functions": "^7.12.1", "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" } }, "@babel/helper-simple-access": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", - "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", "requires": { - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.1" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", - "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", + "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.1" } }, "@babel/helper-split-export-declaration": { @@ -306,10 +292,15 @@ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" }, + "@babel/helper-validator-option": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.1.tgz", + "integrity": "sha512-YpJabsXlJVWP0USHjnC/AQDTLlZERbON577YUVO/wLpqyj6HAtVYnWaQaN0iUN+1/tWn3c+uKKXjRut5115Y2A==" + }, "@babel/helper-wrap-function": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", - "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", + "version": "7.12.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz", + "integrity": "sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow==", "requires": { "@babel/helper-function-name": "^7.10.4", "@babel/template": "^7.10.4", @@ -318,13 +309,13 @@ } }, "@babel/helpers": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", - "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", + "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", "requires": { "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" } }, "@babel/highlight": { @@ -338,26 +329,26 @@ } }, "@babel/parser": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.4.tgz", - "integrity": "sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA==" + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", + "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==" }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz", - "integrity": "sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz", + "integrity": "sha512-d+/o30tJxFxrA1lhzJqiUcEJdI6jKlNregCv5bASeGf2Q4MXmnwH7viDo7nhx1/ohf09oaH8j1GVYG/e3Yqk6A==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.12.1", "@babel/plugin-syntax-async-generators": "^7.8.0" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz", - "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", + "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-create-class-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, @@ -372,103 +363,103 @@ } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz", - "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", + "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-dynamic-import": "^7.8.0" } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz", - "integrity": "sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz", + "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz", - "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz", + "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.0" } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz", - "integrity": "sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz", + "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", - "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", + "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz", - "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.5.tgz", + "integrity": "sha512-UiAnkKuOrCyjZ3sYNHlRlfuZJbBHknMQ9VMwVeX97Ofwx7RpD6gS2HfqTCh8KNUQgcOm8IKt103oR4KIjh7Q8g==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", - "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", + "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.10.4" + "@babel/plugin-transform-parameters": "^7.12.1" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz", - "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz", + "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", - "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.1.tgz", + "integrity": "sha512-c2uRpY6WzaVDzynVY9liyykS+kVU+WRZPMPYpkelXH8KBt1oXoI89kPbZKKG/jDT5UK92FTW2fZkZaJhdiBabw==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz", - "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz", + "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-create-class-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz", - "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz", + "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-create-regexp-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, @@ -481,17 +472,17 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", - "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", + "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-decorators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.4.tgz", - "integrity": "sha512-2NaoC6fAk2VMdhY1eerkfHV+lVYC1u8b+jmRJISqANCJlTxYy19HGdIkkQtix2UtkcPuPu+IlDgrVseZnU03bw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.1.tgz", + "integrity": "sha512-ir9YW5daRrTYiy9UJ2TzdNIJEZu8KclVzDcfSt4iEmOtwQ4llPtWInNKJyKnVXp1vE4bbVd5S31M/im3mYMO1w==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } @@ -513,9 +504,9 @@ } }, "@babel/plugin-syntax-flow": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.10.4.tgz", - "integrity": "sha512-yxQsX1dJixF4qEEdzVbst3SZQ58Nrooz8NV9Z9GL4byTE25BvJgl5lf0RECUf0fh28rZBb/RYTWn/eeKwCMrZQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.1.tgz", + "integrity": "sha512-1lBLLmtxrwpm4VKmtVFselI/P3pX+G63fAtUUt6b2Nzgao77KNDwyuRt90Mj2/9pKobtt68FdvjfqohZjg/FCA==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } @@ -529,9 +520,9 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz", - "integrity": "sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", + "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } @@ -585,107 +576,107 @@ } }, "@babel/plugin-syntax-top-level-await": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz", - "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", + "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-typescript": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.10.4.tgz", - "integrity": "sha512-oSAEz1YkBCAKr5Yiq8/BNtvSAPwkp/IyUnwZogd8p+F0RuYQQrLeRUzIQhueQTTBy/F+a40uS7OFKxnkRvmvFQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.1.tgz", + "integrity": "sha512-UZNEcCY+4Dp9yYRCAHrHDU+9ZXLYaY9MgBXSRLkB9WjYFRR6quJBumfVrEkUxrePPBwFcpWfNKXqVRQQtm7mMA==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz", - "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz", + "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz", - "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz", + "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==", "requires": { - "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-module-imports": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4" + "@babel/helper-remap-async-to-generator": "^7.12.1" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz", - "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz", + "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz", - "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.1.tgz", + "integrity": "sha512-zJyAC9sZdE60r1nVQHblcfCj29Dh2Y0DOvlMkcqSo0ckqjiCwNiUezUKw+RjOCwGfpLRwnAeQ2XlLpsnGkvv9w==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-classes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz", - "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz", + "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==", "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-define-map": "^7.10.4", "@babel/helper-function-name": "^7.10.4", "@babel/helper-optimise-call-expression": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1", "@babel/helper-split-export-declaration": "^7.10.4", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz", - "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz", + "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-destructuring": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz", - "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz", + "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz", - "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz", + "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-create-regexp-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz", - "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz", + "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz", - "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz", + "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==", "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4" @@ -701,197 +692,195 @@ } }, "@babel/plugin-transform-for-of": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz", - "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz", + "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz", - "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz", + "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==", "requires": { "@babel/helper-function-name": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz", - "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz", + "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz", - "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz", + "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz", - "integrity": "sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz", + "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==", "requires": { - "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", - "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz", + "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==", "requires": { - "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-simple-access": "^7.12.1", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz", - "integrity": "sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz", + "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==", "requires": { "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-validator-identifier": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", - "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz", + "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==", "requires": { - "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz", - "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz", + "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.1" } }, "@babel/plugin-transform-new-target": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz", - "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz", + "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-object-super": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz", - "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz", + "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4" + "@babel/helper-replace-supers": "^7.12.1" } }, "@babel/plugin-transform-parameters": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz", - "integrity": "sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz", + "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==", "requires": { - "@babel/helper-get-function-arity": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-property-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz", - "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz", + "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-react-constant-elements": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.10.4.tgz", - "integrity": "sha512-cYmQBW1pXrqBte1raMkAulXmi7rjg3VI6ZLg9QIic8Hq7BtYXaWuZSxsr2siOMI6SWwpxjWfnwhTUrd7JlAV7g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.12.1.tgz", + "integrity": "sha512-KOHd0tIRLoER+J+8f9DblZDa1fLGPwaaN1DI1TVHuQFOpjHV22C3CUB3obeC4fexHY9nx+fH0hQNvLFFfA1mxA==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-react-display-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.4.tgz", - "integrity": "sha512-Zd4X54Mu9SBfPGnEcaGcOrVAYOtjT2on8QZkLKEq1S/tHexG39d9XXGZv19VfRrDjPJzFmPfTAqOQS1pfFOujw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz", + "integrity": "sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-react-jsx": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz", - "integrity": "sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.5.tgz", + "integrity": "sha512-2xkcPqqrYiOQgSlM/iwto1paPijjsDbUynN13tI6bosDz/jOW3CRzYguIE8wKX32h+msbBM22Dv5fwrFkUOZjQ==", "requires": { "@babel/helper-builder-react-jsx": "^7.10.4", - "@babel/helper-builder-react-jsx-experimental": "^7.10.4", + "@babel/helper-builder-react-jsx-experimental": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" + "@babel/plugin-syntax-jsx": "^7.12.1" } }, "@babel/plugin-transform-react-jsx-development": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.4.tgz", - "integrity": "sha512-RM3ZAd1sU1iQ7rI2dhrZRZGv0aqzNQMbkIUCS1txYpi9wHQ2ZHNjo5TwX+UD6pvFW4AbWqLVYvKy5qJSAyRGjQ==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.5.tgz", + "integrity": "sha512-1JJusg3iPgsZDthyWiCr3KQiGs31ikU/mSf2N2dSYEAO0GEImmVUbWf0VoSDGDFTAn5Dj4DUiR6SdIXHY7tELA==", "requires": { - "@babel/helper-builder-react-jsx-experimental": "^7.10.4", + "@babel/helper-builder-react-jsx-experimental": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" + "@babel/plugin-syntax-jsx": "^7.12.1" } }, "@babel/plugin-transform-react-jsx-self": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.4.tgz", - "integrity": "sha512-yOvxY2pDiVJi0axdTWHSMi5T0DILN+H+SaeJeACHKjQLezEzhLx9nEF9xgpBLPtkZsks9cnb5P9iBEi21En3gg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.1.tgz", + "integrity": "sha512-FbpL0ieNWiiBB5tCldX17EtXgmzeEZjFrix72rQYeq9X6nUK38HCaxexzVQrZWXanxKJPKVVIU37gFjEQYkPkA==", "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-react-jsx-source": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.5.tgz", - "integrity": "sha512-wTeqHVkN1lfPLubRiZH3o73f4rfon42HpgxUSs86Nc+8QIcm/B9s8NNVXu/gwGcOyd7yDib9ikxoDLxJP0UiDA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.12.1.tgz", + "integrity": "sha512-keQ5kBfjJNRc6zZN1/nVHCd6LLIHq4aUKcVnvE/2l+ZZROSbqoiGFRtT5t3Is89XJxBQaP7NLZX2jgGHdZvvFQ==", "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-react-pure-annotations": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.4.tgz", - "integrity": "sha512-+njZkqcOuS8RaPakrnR9KvxjoG1ASJWpoIv/doyWngId88JoFlPlISenGXjrVacZUIALGUr6eodRs1vmPnF23A==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz", + "integrity": "sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg==", "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-regenerator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz", - "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz", + "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==", "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz", - "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz", + "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } @@ -915,99 +904,99 @@ } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz", - "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz", + "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz", - "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz", + "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0" + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz", - "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.1.tgz", + "integrity": "sha512-CiUgKQ3AGVk7kveIaPEET1jNDhZZEl1RPMWdTBE1799bdz++SwqDHStmxfCtDfBhQgCl38YRiSnrMuUMZIWSUQ==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/helper-regex": "^7.10.4" } }, "@babel/plugin-transform-template-literals": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz", - "integrity": "sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz", + "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==", "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz", - "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.1.tgz", + "integrity": "sha512-EPGgpGy+O5Kg5pJFNDKuxt9RdmTgj5sgrus2XVeMp/ZIbOESadgILUbm50SNpghOh3/6yrbsH+NB5+WJTmsA7Q==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-typescript": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.11.0.tgz", - "integrity": "sha512-edJsNzTtvb3MaXQwj8403B7mZoGu9ElDJQZOKjGUnvilquxBA3IQoEIOvkX/1O8xfAsnHS/oQhe2w/IXrr+w0w==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.1.tgz", + "integrity": "sha512-VrsBByqAIntM+EYMqSm59SiMEf7qkmI9dqMt6RbD/wlwueWmYcI0FFK5Fj47pP6DRZm+3teXjosKlwcZJ5lIMw==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.5", + "@babel/helper-create-class-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-typescript": "^7.10.4" + "@babel/plugin-syntax-typescript": "^7.12.1" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz", - "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz", + "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==", "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz", - "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", + "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-create-regexp-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/preset-env": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.0.tgz", - "integrity": "sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.1.tgz", + "integrity": "sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg==", "requires": { - "@babel/compat-data": "^7.11.0", - "@babel/helper-compilation-targets": "^7.10.4", - "@babel/helper-module-imports": "^7.10.4", + "@babel/compat-data": "^7.12.1", + "@babel/helper-compilation-targets": "^7.12.1", + "@babel/helper-module-imports": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-proposal-async-generator-functions": "^7.10.4", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/plugin-proposal-dynamic-import": "^7.10.4", - "@babel/plugin-proposal-export-namespace-from": "^7.10.4", - "@babel/plugin-proposal-json-strings": "^7.10.4", - "@babel/plugin-proposal-logical-assignment-operators": "^7.11.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", - "@babel/plugin-proposal-numeric-separator": "^7.10.4", - "@babel/plugin-proposal-object-rest-spread": "^7.11.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.10.4", - "@babel/plugin-proposal-optional-chaining": "^7.11.0", - "@babel/plugin-proposal-private-methods": "^7.10.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.10.4", + "@babel/helper-validator-option": "^7.12.1", + "@babel/plugin-proposal-async-generator-functions": "^7.12.1", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-dynamic-import": "^7.12.1", + "@babel/plugin-proposal-export-namespace-from": "^7.12.1", + "@babel/plugin-proposal-json-strings": "^7.12.1", + "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-numeric-separator": "^7.12.1", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.1", + "@babel/plugin-proposal-private-methods": "^7.12.1", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.10.4", + "@babel/plugin-syntax-class-properties": "^7.12.1", "@babel/plugin-syntax-dynamic-import": "^7.8.0", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.0", @@ -1017,45 +1006,42 @@ "@babel/plugin-syntax-object-rest-spread": "^7.8.0", "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.10.4", - "@babel/plugin-transform-arrow-functions": "^7.10.4", - "@babel/plugin-transform-async-to-generator": "^7.10.4", - "@babel/plugin-transform-block-scoped-functions": "^7.10.4", - "@babel/plugin-transform-block-scoping": "^7.10.4", - "@babel/plugin-transform-classes": "^7.10.4", - "@babel/plugin-transform-computed-properties": "^7.10.4", - "@babel/plugin-transform-destructuring": "^7.10.4", - "@babel/plugin-transform-dotall-regex": "^7.10.4", - "@babel/plugin-transform-duplicate-keys": "^7.10.4", - "@babel/plugin-transform-exponentiation-operator": "^7.10.4", - "@babel/plugin-transform-for-of": "^7.10.4", - "@babel/plugin-transform-function-name": "^7.10.4", - "@babel/plugin-transform-literals": "^7.10.4", - "@babel/plugin-transform-member-expression-literals": "^7.10.4", - "@babel/plugin-transform-modules-amd": "^7.10.4", - "@babel/plugin-transform-modules-commonjs": "^7.10.4", - "@babel/plugin-transform-modules-systemjs": "^7.10.4", - "@babel/plugin-transform-modules-umd": "^7.10.4", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4", - "@babel/plugin-transform-new-target": "^7.10.4", - "@babel/plugin-transform-object-super": "^7.10.4", - "@babel/plugin-transform-parameters": "^7.10.4", - "@babel/plugin-transform-property-literals": "^7.10.4", - "@babel/plugin-transform-regenerator": "^7.10.4", - "@babel/plugin-transform-reserved-words": "^7.10.4", - "@babel/plugin-transform-shorthand-properties": "^7.10.4", - "@babel/plugin-transform-spread": "^7.11.0", - "@babel/plugin-transform-sticky-regex": "^7.10.4", - "@babel/plugin-transform-template-literals": "^7.10.4", - "@babel/plugin-transform-typeof-symbol": "^7.10.4", - "@babel/plugin-transform-unicode-escapes": "^7.10.4", - "@babel/plugin-transform-unicode-regex": "^7.10.4", + "@babel/plugin-syntax-top-level-await": "^7.12.1", + "@babel/plugin-transform-arrow-functions": "^7.12.1", + "@babel/plugin-transform-async-to-generator": "^7.12.1", + "@babel/plugin-transform-block-scoped-functions": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.1", + "@babel/plugin-transform-classes": "^7.12.1", + "@babel/plugin-transform-computed-properties": "^7.12.1", + "@babel/plugin-transform-destructuring": "^7.12.1", + "@babel/plugin-transform-dotall-regex": "^7.12.1", + "@babel/plugin-transform-duplicate-keys": "^7.12.1", + "@babel/plugin-transform-exponentiation-operator": "^7.12.1", + "@babel/plugin-transform-for-of": "^7.12.1", + "@babel/plugin-transform-function-name": "^7.12.1", + "@babel/plugin-transform-literals": "^7.12.1", + "@babel/plugin-transform-member-expression-literals": "^7.12.1", + "@babel/plugin-transform-modules-amd": "^7.12.1", + "@babel/plugin-transform-modules-commonjs": "^7.12.1", + "@babel/plugin-transform-modules-systemjs": "^7.12.1", + "@babel/plugin-transform-modules-umd": "^7.12.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1", + "@babel/plugin-transform-new-target": "^7.12.1", + "@babel/plugin-transform-object-super": "^7.12.1", + "@babel/plugin-transform-parameters": "^7.12.1", + "@babel/plugin-transform-property-literals": "^7.12.1", + "@babel/plugin-transform-regenerator": "^7.12.1", + "@babel/plugin-transform-reserved-words": "^7.12.1", + "@babel/plugin-transform-shorthand-properties": "^7.12.1", + "@babel/plugin-transform-spread": "^7.12.1", + "@babel/plugin-transform-sticky-regex": "^7.12.1", + "@babel/plugin-transform-template-literals": "^7.12.1", + "@babel/plugin-transform-typeof-symbol": "^7.12.1", + "@babel/plugin-transform-unicode-escapes": "^7.12.1", + "@babel/plugin-transform-unicode-regex": "^7.12.1", "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.11.0", - "browserslist": "^4.12.0", + "@babel/types": "^7.12.1", "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", "semver": "^5.5.0" }, "dependencies": { @@ -1067,9 +1053,9 @@ } }, "@babel/preset-modules": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", - "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", @@ -1079,17 +1065,17 @@ } }, "@babel/preset-react": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.10.4.tgz", - "integrity": "sha512-BrHp4TgOIy4M19JAfO1LhycVXOPWdDbTRep7eVyatf174Hff+6Uk53sDyajqZPu8W1qXRBiYOfIamek6jA7YVw==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.12.5.tgz", + "integrity": "sha512-jcs++VPrgyFehkMezHtezS2BpnUlR7tQFAyesJn1vGTO9aTFZrgIQrA5YydlTwxbcjMwkFY6i04flCigRRr3GA==", "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-transform-react-display-name": "^7.10.4", - "@babel/plugin-transform-react-jsx": "^7.10.4", - "@babel/plugin-transform-react-jsx-development": "^7.10.4", - "@babel/plugin-transform-react-jsx-self": "^7.10.4", - "@babel/plugin-transform-react-jsx-source": "^7.10.4", - "@babel/plugin-transform-react-pure-annotations": "^7.10.4" + "@babel/plugin-transform-react-display-name": "^7.12.1", + "@babel/plugin-transform-react-jsx": "^7.12.5", + "@babel/plugin-transform-react-jsx-development": "^7.12.5", + "@babel/plugin-transform-react-jsx-self": "^7.12.1", + "@babel/plugin-transform-react-jsx-source": "^7.12.1", + "@babel/plugin-transform-react-pure-annotations": "^7.12.1" } }, "@babel/preset-typescript": { @@ -1102,17 +1088,17 @@ } }, "@babel/runtime": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", - "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/runtime-corejs3": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.11.2.tgz", - "integrity": "sha512-qh5IR+8VgFz83VBa6OkaET6uN/mJOhHONuy3m1sgF0CV6mXdPSEBdA7e1eUbVvyNtANjMbg22JUv71BaDXLY6A==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.12.5.tgz", + "integrity": "sha512-roGr54CsTmNPPzZoCP1AmDXuBoNao7tnSA83TXTwt+UK5QVyh1DIJnrgYRPWKCF2flqZQXwa7Yr8v7VmLzF0YQ==", "requires": { "core-js-pure": "^3.0.0", "regenerator-runtime": "^0.13.4" @@ -1129,25 +1115,25 @@ } }, "@babel/traverse": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", - "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", + "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.11.0", + "@babel/generator": "^7.12.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/parser": "^7.11.0", - "@babel/types": "^7.11.0", + "@babel/parser": "^7.12.5", + "@babel/types": "^7.12.5", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "version": "7.12.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz", + "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==", "requires": { "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.19", @@ -1600,9 +1586,9 @@ } }, "@types/babel__core": { - "version": "7.1.9", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", - "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", + "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", "requires": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0", @@ -1612,35 +1598,30 @@ } }, "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.3.tgz", + "integrity": "sha512-uCoznIPDmnickEi6D0v11SBpW0OuVqHJCa7syXqQHy5uktSCreIlt0iglsCnmvz8yCb38hGcWeseA8cWJSwv5Q==", "requires": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "@types/babel__traverse": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", - "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.15.tgz", + "integrity": "sha512-Pzh9O3sTK8V6I1olsXpCfj2k/ygO2q1X0vhhnDrEQyYLHZesWz+zMZMVcwXLCYf0U36EtmyYaFGPfXlTtDHe3A==", "requires": { "@babel/types": "^7.3.0" } }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" - }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -1656,9 +1637,9 @@ } }, "@types/history": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.7.tgz", - "integrity": "sha512-2xtoL22/3Mv6a70i4+4RB7VgbDDORoWwjcqeNysojZA0R7NK17RbY5Gof/2QiFfJgX+KkWghbwJ+d/2SB8Ndzg==" + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz", + "integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==" }, "@types/istanbul-lib-coverage": { "version": "2.0.3", @@ -1683,19 +1664,22 @@ } }, "@types/json-schema": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", - "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==" + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", + "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==" }, "@types/jwt-decode": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@types/jwt-decode/-/jwt-decode-2.2.1.tgz", - "integrity": "sha512-aWw2YTtAdT7CskFyxEX2K21/zSDStuf/ikI3yBqmwpwJF0pS+/IX5DWv+1UFffZIbruP6cnT9/LAJV1gFwAT1A==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/jwt-decode/-/jwt-decode-3.1.0.tgz", + "integrity": "sha512-tthwik7TKkou3mVnBnvVuHnHElbjtdbM63pdBCbZTirCt3WAdM73Y79mOri7+ljsS99ZVwUFZHLMxJuJnv/z1w==", + "requires": { + "jwt-decode": "*" + } }, "@types/lodash": { - "version": "4.14.159", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.159.tgz", - "integrity": "sha512-gF7A72f7WQN33DpqOWw9geApQPh4M3PxluMtaHxWHXEGSN12/WbcEk/eNSqWNQcQhF66VSZ06vCF94CrHwXJDg==" + "version": "4.14.165", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz", + "integrity": "sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==" }, "@types/material-ui": { "version": "0.21.8", @@ -1712,9 +1696,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.12.54", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.54.tgz", - "integrity": "sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w==" + "version": "12.19.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.4.tgz", + "integrity": "sha512-o3oj1bETk8kBwzz1WlO6JWL/AfAA3Vm6J1B3C9CsdxHYp7XgPiH7OEXPUbZTndHlRaIElrANkQfe6ZmfJb3H2w==" }, "@types/parse-json": { "version": "4.0.0", @@ -1732,18 +1716,18 @@ "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, "@types/react": { - "version": "16.9.46", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.46.tgz", - "integrity": "sha512-dbHzO3aAq1lB3jRQuNpuZ/mnu+CdD3H0WVaaBQA8LTT3S33xhVBUj232T8M3tAhSWJs/D/UqORYUlJNl/8VQZg==", + "version": "16.9.56", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.56.tgz", + "integrity": "sha512-gIkl4J44G/qxbuC6r2Xh+D3CGZpJ+NdWTItAPmZbR5mUS+JQ8Zvzpl0ea5qT/ZT3ZNTUcDKUVqV3xBE8wv/DyQ==", "requires": { "@types/prop-types": "*", "csstype": "^3.0.2" }, "dependencies": { "csstype": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.2.tgz", - "integrity": "sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==" + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.4.tgz", + "integrity": "sha512-xc8DUsCLmjvCfoD7LTGE0ou2MIWLx0K9RCZwSHMOdynqRsP4MtUcLeqh1HcQ2dInwDTqn+3CE0/FZh1et+p4jA==" } } }, @@ -1756,17 +1740,17 @@ } }, "@types/react-dom": { - "version": "16.9.8", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz", - "integrity": "sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA==", + "version": "16.9.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.9.tgz", + "integrity": "sha512-jE16FNWO3Logq/Lf+yvEAjKzhpST/Eac8EMd1i4dgZdMczfgqC8EjpxwNgEe3SExHYLliabXDh9DEhhqnlXJhg==", "requires": { "@types/react": "*" } }, "@types/react-material-ui-form-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/react-material-ui-form-validator/-/react-material-ui-form-validator-2.0.6.tgz", - "integrity": "sha512-JOs2fvVSR6AXWUJv+ALkBShzbwlzxiYJJTy8kN5sbaj/HBqDLcCRGBDmnfZiHyEF6Wwp2KxoD7o8m23mKcb5cA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/react-material-ui-form-validator/-/react-material-ui-form-validator-2.1.0.tgz", + "integrity": "sha512-izwjulCvMsN01H8oF8X1IN7QDMHeaGmjYoAxL/cmlUJLtFH0BLLUNmlmZERrjNM+MOJAXUaOkwoCqOHlCtqCzQ==", "requires": { "@types/material-ui": "*", "@types/react": "*" @@ -1782,9 +1766,9 @@ } }, "@types/react-router-dom": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.5.tgz", - "integrity": "sha512-ArBM4B1g3BWLGbaGvwBGO75GNFbLDUthrDojV2vHLih/Tq8M+tgvY1DSwkuNrPSwdp/GUL93WSEpTZs8nVyJLw==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.6.tgz", + "integrity": "sha512-gjrxYqxz37zWEdMVvQtWPFMFj1dRDb4TGOcgyOfSXTrEXdF92L00WE3C471O3TV/RF1oskcStkXsOU0Ete4s/g==", "requires": { "@types/history": "*", "@types/react": "*", @@ -1805,9 +1789,9 @@ "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" }, "@types/yargs": { - "version": "13.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.10.tgz", - "integrity": "sha512-MU10TSgzNABgdzKvQVW1nuuT+sgBMWeXNc3XOs5YXV5SDAK+PPja2eUuBNB9iqElu03xyEDqlnGw0jgl4nbqGQ==", + "version": "13.0.11", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.11.tgz", + "integrity": "sha512-NRqD6T4gktUrDi1o1wLH3EKC1o2caCr7/wR87ODcbVITQF106OM3sFN92ysZ++wqelOd1CTzatnOBRDYYG6wGQ==", "requires": { "@types/yargs-parser": "*" } @@ -2040,9 +2024,9 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "abab": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.4.tgz", - "integrity": "sha512-Eu9ELJWCz/c1e9gTiCY+FceWxcqzjYEbqMgtndnuSqZSUCOL73TWNK2mHfIj4Cw2E/ongOp+JISVNCmovt2KYQ==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" }, "accepts": { "version": "1.3.7", @@ -2054,9 +2038,9 @@ } }, "acorn": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", - "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==" + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" }, "acorn-globals": { "version": "4.3.4", @@ -2068,16 +2052,16 @@ }, "dependencies": { "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" } } }, "acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==" + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" }, "acorn-walk": { "version": "6.2.0", @@ -2090,60 +2074,39 @@ "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==" }, "adjust-sourcemap-loader": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz", - "integrity": "sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz", + "integrity": "sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw==", "requires": { - "assert": "1.4.1", - "camelcase": "5.0.0", - "loader-utils": "1.2.3", - "object-path": "0.11.4", - "regex-parser": "2.2.10" + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" }, "dependencies": { - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==" - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - }, "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", "requires": { "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" + "emojis-list": "^3.0.0", + "json5": "^2.1.2" } } } }, "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "requires": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "ajv": { - "version": "6.12.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", - "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2339,11 +2302,27 @@ } }, "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", "requires": { + "object-assign": "^4.1.1", "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + } + } } }, "assert-plus": { @@ -2395,9 +2374,9 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "attr-accept": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.1.tgz", - "integrity": "sha512-GpefLMsbH5ojNgfTW+OBin2xKzuHfyeNA+qCktzZojBhbA/lPZdCFMWdwk5ajb989Ok7ZT+EADqvW3TAFNMjhA==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", + "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==" }, "autoprefixer": { "version": "9.8.6", @@ -2419,9 +2398,9 @@ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.1.tgz", - "integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==" + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, "axobject-query": { "version": "2.2.0", @@ -2686,22 +2665,22 @@ } }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", + "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "parse-json": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", - "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, @@ -2718,9 +2697,9 @@ } }, "babel-plugin-named-asset-import": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz", - "integrity": "sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA==" + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz", + "integrity": "sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw==" }, "babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", @@ -3025,15 +3004,6 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -3240,14 +3210,15 @@ } }, "browserslist": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz", - "integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==", + "version": "4.14.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.7.tgz", + "integrity": "sha512-BSVRLCeG3Xt/j/1cCGj1019Wbty0H+Yvu2AOuZSuoaUWn3RatbL33Cxk+Q4jRMRAbOm0p7SLravLjpnT6s0vzQ==", "requires": { - "caniuse-lite": "^1.0.30001111", - "electron-to-chromium": "^1.3.523", - "escalade": "^3.0.2", - "node-releases": "^1.1.60" + "caniuse-lite": "^1.0.30001157", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.591", + "escalade": "^3.1.1", + "node-releases": "^1.1.66" } }, "bser": { @@ -3340,6 +3311,15 @@ "unset-value": "^1.0.0" } }, + "call-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", + "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.0" + } + }, "call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", @@ -3373,6 +3353,13 @@ "requires": { "pascal-case": "^3.1.1", "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } } }, "camelcase": { @@ -3392,9 +3379,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001117", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001117.tgz", - "integrity": "sha512-4tY0Fatzdx59kYjQs+bNxUwZB03ZEBgVmJ1UkFPz/Q8OLiUUbjct2EdpnXj0fvFTPej2EkbPIG0w8BWsjAyk1Q==" + "version": "1.0.30001157", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001157.tgz", + "integrity": "sha512-gOerH9Wz2IRZ2ZPdMfBvyOi3cjaz4O4dgNwPGzx8EhqAs4+2IL/O+fJsbt+znSigujoZG8bVcIAUM/I/E5K3MA==" }, "capture-exit": { "version": "2.0.0", @@ -3430,9 +3417,9 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, "chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -3441,7 +3428,7 @@ "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" + "readdirp": "~3.5.0" }, "dependencies": { "anymatch": { @@ -3500,6 +3487,13 @@ "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", "requires": { "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } } }, "ci-info": { @@ -3637,12 +3631,12 @@ } }, "color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", + "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", "requires": { "color-convert": "^1.9.1", - "color-string": "^1.5.2" + "color-string": "^1.5.4" } }, "color-convert": { @@ -3659,9 +3653,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz", + "integrity": "sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==", "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -3813,9 +3807,9 @@ } }, "confusing-browser-globals": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", - "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==" + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", + "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==" }, "connect-history-api-fallback": { "version": "1.6.0", @@ -3919,16 +3913,16 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.7.0.tgz", + "integrity": "sha512-NwS7fI5M5B85EwpWuIwJN4i/fbisQUwLwiSNUWeXlkAZ0sbBjLEvLvFLf1uzAUV66PcEPt4xCGCmOZSxVf3xzA==" }, "core-js-compat": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", - "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.7.0.tgz", + "integrity": "sha512-V8yBI3+ZLDVomoWICO6kq/CD28Y4r1M7CWeO4AGpMdMfseu8bkSubBmUPySMGKRTS+su4XQ07zUkAsiu9FCWTg==", "requires": { - "browserslist": "^4.8.5", + "browserslist": "^4.14.6", "semver": "7.0.0" }, "dependencies": { @@ -3940,9 +3934,9 @@ } }, "core-js-pure": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", - "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==" + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.7.0.tgz", + "integrity": "sha512-EZD2ckZysv8MMt4J6HSvS9K2GdtlZtdBncKAmF9lr2n0c9dJUaUN88PSTjvgwCgQPWKTkERXITgS6JJRAnljtg==" }, "core-util-is": { "version": "1.0.2", @@ -4175,9 +4169,9 @@ } }, "css-what": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", - "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==" + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==" }, "cssdb": { "version": "4.4.0", @@ -4261,26 +4255,26 @@ "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" }, "csso": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", - "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.1.0.tgz", + "integrity": "sha512-h+6w/W1WqXaJA4tb1dk7r5tVbOm97MsKxzwnvOR04UQ6GILroryjMWu3pmCCtL2mLaEStQ0fZgeGiy99mo7iyg==", "requires": { - "css-tree": "1.0.0-alpha.39" + "css-tree": "^1.0.0" }, "dependencies": { "css-tree": { - "version": "1.0.0-alpha.39", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", - "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0.tgz", + "integrity": "sha512-CdVYz/Yuqw0VdKhXPBIgi8DO3NicJVYZNWeX9XcIuSp9ZoFT5IcleVRW07O5rMjdcx1mb+MEJPknTTEW7DdsYw==", "requires": { - "mdn-data": "2.0.6", + "mdn-data": "2.0.12", "source-map": "^0.6.1" } }, "mdn-data": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", - "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==" + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.12.tgz", + "integrity": "sha512-ULbAlgzVb8IqZ0Hsxm6hHSlQl3Jckst2YEQS7fODu9ilNWy2LvcoSY7TRFIktABP2mdppBioc66va90T+NUs8Q==" } } }, @@ -4352,11 +4346,11 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "decamelize": { @@ -4636,9 +4630,9 @@ }, "dependencies": { "csstype": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.2.tgz", - "integrity": "sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==" + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.4.tgz", + "integrity": "sha512-xc8DUsCLmjvCfoD7LTGE0ou2MIWLx0K9RCZwSHMOdynqRsP4MtUcLeqh1HcQ2dInwDTqn+3CE0/FZh1et+p4jA==" } } }, @@ -4652,9 +4646,9 @@ }, "dependencies": { "domelementtype": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", - "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.2.tgz", + "integrity": "sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA==" } } }, @@ -4700,12 +4694,19 @@ "requires": { "no-case": "^3.0.3", "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } } }, "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "requires": { "is-obj": "^2.0.0" } @@ -4785,9 +4786,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.540", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.540.tgz", - "integrity": "sha512-IoGiZb8SMqTtkDYJtP8EtCdvv3VMtd1QoTlypO2RUBxRq/Wk0rU5IzhzhMckPaC9XxDqUvWsL0XKOBhTiYVN3w==" + "version": "1.3.592", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.592.tgz", + "integrity": "sha512-kGNowksvqQiPb1pUSQKpd8JFoGPLxYOwduNRCqCxGh/2Q1qE2JdmwouCW41lUzDxOb/2RIV4lR0tVIfboWlO9A==" }, "elliptic": { "version": "6.5.3", @@ -4887,9 +4888,9 @@ } }, "entities": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", - "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==" }, "errno": { "version": "0.1.7", @@ -4908,19 +4909,19 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" } @@ -4965,9 +4966,9 @@ } }, "escalade": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz", - "integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-html": { "version": "1.0.3", @@ -5052,9 +5053,9 @@ } }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", + "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -5400,10 +5401,11 @@ } }, "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", + "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", "requires": { + "is-core-module": "^2.0.0", "path-parse": "^1.0.6" } } @@ -5415,11 +5417,11 @@ "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==" }, "eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, @@ -5467,11 +5469,18 @@ } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + } } }, "estraverse": { @@ -5490,9 +5499,9 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, "events": { "version": "3.2.0", @@ -5679,9 +5688,9 @@ }, "dependencies": { "type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", - "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==" } } }, @@ -5884,19 +5893,13 @@ } }, "file-selector": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.1.12.tgz", - "integrity": "sha512-Kx7RTzxyQipHuiqyZGf+Nz4vY9R1XGxuQl/hLoJwq+J4avk/9wxxgZyHKtbyIPJmbD4A66DWGYfyykWNpcYutQ==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.2.3.tgz", + "integrity": "sha512-d+hc9ctodLSVG55V2V5I4/eJBEr2p2na/kDN46Ty7PBhdp/Q5NmeQTXKa1Hx3AcIL1lgSFKZI0ve/v5ZXGCDkQ==", "requires": { - "tslib": "^1.9.0" + "tslib": "^2.0.3" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, "filesize": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.0.1.tgz", @@ -6245,15 +6248,25 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==" + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, + "get-intrinsic": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", + "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", @@ -6777,9 +6790,9 @@ } }, "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "iferr": { "version": "0.1.5", @@ -6930,11 +6943,10 @@ }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -6974,9 +6986,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } @@ -7062,9 +7074,9 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==" }, "is-ci": { "version": "2.0.0", @@ -7087,6 +7099,14 @@ "rgba-regex": "^1.0.0" } }, + "is-core-module": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", + "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -7160,6 +7180,11 @@ "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=" }, + "is-negative-zero": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", + "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=" + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -7521,9 +7546,9 @@ }, "dependencies": { "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" }, "jsdom": { "version": "14.1.0", @@ -7623,11 +7648,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } + "optional": true } } }, @@ -8006,6 +8027,11 @@ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -8083,9 +8109,9 @@ }, "dependencies": { "csstype": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.2.tgz", - "integrity": "sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==" + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.4.tgz", + "integrity": "sha512-xc8DUsCLmjvCfoD7LTGE0ou2MIWLx0K9RCZwSHMOdynqRsP4MtUcLeqh1HcQ2dInwDTqn+3CE0/FZh1et+p4jA==" } } }, @@ -8166,9 +8192,9 @@ } }, "jwt-decode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", - "integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.1.tgz", + "integrity": "sha512-EaH9dTD9ogCmxZRdiTsIUIJslqjoFfk8nEAi+Bq8u/aUjrVuhZ6eZjhWRH6SC9NBA0Lwr3K35H2zDnWvK/n4vQ==" }, "killable": { "version": "1.0.1", @@ -8375,9 +8401,9 @@ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" }, "loglevel": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", - "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.0.tgz", + "integrity": "sha512-i2sY04nal5jDcagM3FMfG++T69GEEM8CYuOfeOIvmXzOIcwE9a/CJPR0MFM97pYMj/u10lzz7/zd7+qwhrBTqQ==" }, "loose-envify": { "version": "1.4.0", @@ -8393,6 +8419,13 @@ "integrity": "sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ==", "requires": { "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } } }, "lru-cache": { @@ -8602,11 +8635,11 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "mini-create-react-context": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz", - "integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", + "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", "requires": { - "@babel/runtime": "^7.5.5", + "@babel/runtime": "^7.12.1", "tiny-warning": "^1.0.3" } }, @@ -8755,9 +8788,9 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "moment": { - "version": "2.27.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz", - "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==" + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" }, "move-concurrently": { "version": "1.0.1", @@ -8814,12 +8847,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "optional": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -8877,12 +8904,19 @@ "requires": { "lower-case": "^2.0.1", "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } } }, "node-forge": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", - "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" }, "node-int64": { "version": "0.4.0", @@ -8957,21 +8991,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } - } } } }, @@ -9000,9 +9019,9 @@ } }, "node-releases": { - "version": "1.1.60", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", - "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==" + "version": "1.1.66", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.66.tgz", + "integrity": "sha512-JHEQ1iWPGK+38VLB2H9ef2otU4l8s3yAMt9Xf934r6+ojCYDMHPMqvCc9TnzfeFSP1QEOeU6YZEd3+De0LTCgg==" }, "normalize-package-data": { "version": "2.5.0", @@ -9047,9 +9066,9 @@ } }, "notistack": { - "version": "0.9.17", - "resolved": "https://registry.npmjs.org/notistack/-/notistack-0.9.17.tgz", - "integrity": "sha512-nypTN6sEe+q98wMaxF/UwatA1yAq948+bZOo9JKYR+tU65DW0ipWyx8DseJ3UJYvb6VDD+Fqo83qwayQ46bEEA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/notistack/-/notistack-1.0.1.tgz", + "integrity": "sha512-2T1WkokzRCM8N9EdueaXja160IMFIMHVhRu0fGkDje7qCzwBHlTMZY2NULQzB2GFOO6iGVzl5GCX2XrJIzI8bw==", "requires": { "clsx": "^1.1.0", "hoist-non-react-statics": "^3.3.0" @@ -9122,12 +9141,33 @@ "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==" }, "object-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.3.tgz", + "integrity": "sha512-teyqLvFWzLkq5B9ki8FVWA902UER2qkxmdA4nLf+wjOLAWgxzCWZNCxpDq9MvE8MmhWNr+I8w3BN49Vx36Y6Xg==", "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "object-keys": { @@ -9135,11 +9175,6 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, - "object-path": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", - "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" - }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -9149,14 +9184,14 @@ } }, "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" } }, "object.entries": { @@ -9243,9 +9278,9 @@ } }, "open": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-7.1.0.tgz", - "integrity": "sha512-lLPI5KgOwEYCDKXf4np7y1PBEkj7HYIyP2DY8mVDRnx0VIIu6bNrRB0R66TuO7Mack6EnTNLm4uvcl1UoklTpA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/open/-/open-7.3.0.tgz", + "integrity": "sha512-mgLwQIx2F/ye9SmbrUkurZCnkoXyXyu9EbHtJZrICjVAJfyMArdHp3KkixGdZx1ZHFPNIwl0DDM1dFFqXbTLZw==", "requires": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" @@ -9420,6 +9455,13 @@ "requires": { "dot-case": "^3.0.3", "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } } }, "parent-module": { @@ -9475,6 +9517,13 @@ "requires": { "no-case": "^3.0.3", "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } } }, "pascalcase": { @@ -9681,9 +9730,9 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { - "version": "7.0.32", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", - "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -9718,9 +9767,9 @@ } }, "postcss-calc": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.3.tgz", - "integrity": "sha512-IB/EAEmZhIMEIhG7Ov4x+l47UaXOS1n2f4FBUk/aKllQhtSCxWhTzn0nJgkqN7fo/jcWySvWTSB6Syk9L+31bA==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", + "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", "requires": { "postcss": "^7.0.27", "postcss-selector-parser": "^6.0.2", @@ -9953,9 +10002,9 @@ } }, "postcss-font-variant": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.0.tgz", - "integrity": "sha512-M8BFYKOvCrI2aITzDad7kWuXXTm0YhGdP9Q8HanmN4EF1Hmcgs1KK5rSHylt/lUJe8yLxiSwWAHdScoEiIxztg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz", + "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==", "requires": { "postcss": "^7.0.2" } @@ -9997,9 +10046,9 @@ } }, "postcss-load-config": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", - "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", + "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", "requires": { "cosmiconfig": "^5.0.0", "import-cwd": "^2.0.0" @@ -10548,13 +10597,14 @@ } }, "postcss-selector-parser": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", - "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz", + "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==", "requires": { "cssesc": "^3.0.0", "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "uniq": "^1.0.1", + "util-deprecate": "^1.0.2" } }, "postcss-svgo": { @@ -10611,17 +10661,17 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, "pretty-bytes": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz", - "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==" + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz", + "integrity": "sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA==" }, "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" + "lodash": "^4.17.20", + "renderkid": "^2.0.4" } }, "pretty-format": { @@ -10676,12 +10726,12 @@ "integrity": "sha512-OzSf6gcCUQ01byV4BgwyUCswlaQQ6gzXc23aLQWhicvfX9kfsUiUhgt3CCQej8jDnl8/PhGF31JdHX2/MzF3WA==" }, "prompts": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", - "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", + "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", "requires": { "kleur": "^3.0.3", - "sisteransi": "^1.0.4" + "sisteransi": "^1.0.5" } }, "prop-types": { @@ -10851,9 +10901,9 @@ } }, "react": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", - "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -11062,9 +11112,9 @@ } }, "react-dom": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", - "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -11073,25 +11123,26 @@ } }, "react-dropzone": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-11.0.3.tgz", - "integrity": "sha512-+MoMOoKZfkZ9i1+qEFl2ZU29AB/c9K2bFxyACqGynguJunmqO+k2PJ2AcuiH51xVNl9R7q/x5QdBaIWb6RtoSw==", + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-11.2.4.tgz", + "integrity": "sha512-EGSvK2CxFTuc28WxwuJCICyuYFX8b+sRumwU6Bs6sTbElV2HtQkT0d6C+HEee6XfbjiLIZ+Th9uji27rvo2wGw==", "requires": { - "attr-accept": "^2.0.0", - "file-selector": "^0.1.12", + "attr-accept": "^2.2.1", + "file-selector": "^0.2.2", "prop-types": "^15.7.2" } }, "react-error-overlay": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.7.tgz", - "integrity": "sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==" + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.8.tgz", + "integrity": "sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw==" }, "react-form-validator-core": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/react-form-validator-core/-/react-form-validator-core-0.6.5.tgz", - "integrity": "sha512-TOGksWHld6wHrCpAoTJBeS6xc6iOXWYCmNb3GPHCY8IjnMpJY2Uv/t73w/gCYWJgv3ucA+jxUsf4qKmx1f3QEQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/react-form-validator-core/-/react-form-validator-core-1.0.0.tgz", + "integrity": "sha512-J+itG0oD/6VikXWJlOyjpoe3QaB35iX2WeFuQ1psxyJ5KkjMncBcOjUw/lemW8dYCOC7vQTFGUjlvwkGenTgig==", "requires": { + "create-react-context": "^0.3.0", "promise-polyfill": "8.1.0", "prop-types": "^15.0.0", "react-lifecycles-compat": "^3.0.2" @@ -11114,19 +11165,6 @@ "requires": { "prop-types": "^15.0.0", "react-form-validator-core": "1.0.0" - }, - "dependencies": { - "react-form-validator-core": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/react-form-validator-core/-/react-form-validator-core-1.0.0.tgz", - "integrity": "sha512-J+itG0oD/6VikXWJlOyjpoe3QaB35iX2WeFuQ1psxyJ5KkjMncBcOjUw/lemW8dYCOC7vQTFGUjlvwkGenTgig==", - "requires": { - "create-react-context": "^0.3.0", - "promise-polyfill": "8.1.0", - "prop-types": "^15.0.0", - "react-lifecycles-compat": "^3.0.2" - } - } } }, "react-router": { @@ -11161,9 +11199,9 @@ } }, "react-scripts": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.3.tgz", - "integrity": "sha512-oSnoWmii/iKdeQiwaO6map1lUaZLmG0xIUyb/HwCVFLT7gNbj8JZ9RmpvMCZ4fB98ZUMRfNmp/ft8uy/xD1RLA==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.4.tgz", + "integrity": "sha512-7J7GZyF/QvZkKAZLneiOIhHozvOMHey7hO9cdO9u68jjhGZlI8hDdOm6UyuHofn6Ajc9Uji5I6Psm/nKNuWdyw==", "requires": { "@babel/core": "7.9.0", "@svgr/webpack": "4.3.3", @@ -11207,7 +11245,7 @@ "react-app-polyfill": "^1.0.6", "react-dev-utils": "^10.2.1", "resolve": "1.15.0", - "resolve-url-loader": "3.1.1", + "resolve-url-loader": "3.1.2", "sass-loader": "8.0.2", "semver": "6.3.0", "style-loader": "0.23.1", @@ -11293,9 +11331,9 @@ } }, "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "requires": { "picomatch": "^2.2.1" } @@ -11317,9 +11355,9 @@ } }, "regenerate": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", - "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==" + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "regenerate-unicode-properties": { "version": "8.2.0", @@ -11352,9 +11390,9 @@ } }, "regex-parser": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz", - "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==" + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", + "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" }, "regexp.prototype.flags": { "version": "1.3.0", @@ -11371,9 +11409,9 @@ "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" }, "regexpu-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", - "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", "requires": { "regenerate": "^1.4.0", "regenerate-unicode-properties": "^8.2.0", @@ -11414,15 +11452,15 @@ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "renderkid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", - "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.4.tgz", + "integrity": "sha512-K2eXrSOJdq+HuKzlcjOlGoOarUu5SDguDEhE7+Ah4zuOWL40j8A/oHvLlLob9PSTNvVnBd+/q0Er1QfpEuem5g==", "requires": { "css-select": "^1.1.0", "dom-converter": "^0.2", "htmlparser2": "^3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" + "lodash": "^4.17.20", + "strip-ansi": "^3.0.0" }, "dependencies": { "ansi-regex": { @@ -11567,11 +11605,11 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, "resolve-url-loader": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz", - "integrity": "sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz", + "integrity": "sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ==", "requires": { - "adjust-sourcemap-loader": "2.0.0", + "adjust-sourcemap-loader": "3.0.0", "camelcase": "5.3.1", "compose-function": "3.0.3", "convert-source-map": "1.7.0", @@ -11712,11 +11750,18 @@ } }, "rxjs": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz", - "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==", + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", + "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", "requires": { "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } } }, "safe-buffer": { @@ -11818,13 +11863,13 @@ } }, "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" } }, "select-hose": { @@ -11833,11 +11878,11 @@ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" }, "selfsigned": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", - "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", + "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", "requires": { - "node-forge": "0.9.0" + "node-forge": "^0.10.0" } }, "semver": { @@ -12056,12 +12101,33 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" }, "side-channel": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", - "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.3.tgz", + "integrity": "sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g==", "requires": { - "es-abstract": "^1.17.0-next.1", - "object-inspect": "^1.7.0" + "es-abstract": "^1.18.0-next.0", + "object-inspect": "^1.8.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "signal-exit": { @@ -12335,9 +12401,9 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", + "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==" }, "spdy": { "version": "4.0.2", @@ -12606,21 +12672,63 @@ } }, "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.2.tgz", + "integrity": "sha512-8oAG/hi14Z4nOVP0z6mdiVZ/wqjDtWSLygMigTzAb+7aPEDTleeFf+WrF+alzecxIRkckkJVn+dTlwzJXORATw==", "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.2.tgz", + "integrity": "sha512-7F6CdBTl5zyu30BJFdzSTlSlLPwODC23Od+iLoVH8X6+3fvDPPuBVVj9iaB1GOsSTSIgVfsfm27R2FGrAPznWg==", "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "string_decoder": { @@ -12941,9 +13049,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { "has-flag": "^4.0.0" } @@ -13030,9 +13138,9 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", "requires": { "setimmediate": "^1.0.4" } @@ -13131,9 +13239,9 @@ "integrity": "sha512-CrG5GqAAzMT7144Cl+UIFP7mz/iIhiy+xQ6GGcnjTezhALT02uPMRw7tgDSESgB5MsfKt55+GPWw4ir1kVtMIQ==" }, "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==" }, "tsutils": { "version": "3.17.1", @@ -13141,6 +13249,13 @@ "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", "requires": { "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } } }, "tty-browserify": { @@ -13194,9 +13309,9 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typescript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", - "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==" + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", + "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==" }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", @@ -13321,9 +13436,9 @@ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "requires": { "punycode": "^2.1.0" } @@ -13374,17 +13489,17 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", "requires": { - "inherits": "2.0.1" + "inherits": "2.0.3" }, "dependencies": { "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" } } }, @@ -13420,9 +13535,9 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, "v8-compile-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", - "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==" }, "validate-npm-package-license": { "version": "3.0.4", @@ -13498,20 +13613,20 @@ } }, "watchpack": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", - "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", "requires": { "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.0" + "watchpack-chokidar2": "^2.0.1" } }, "watchpack-chokidar2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", - "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", "optional": true, "requires": { "chokidar": "^2.1.8" @@ -13547,11 +13662,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } + "optional": true }, "glob-parent": { "version": "3.1.0", @@ -13682,9 +13793,9 @@ }, "dependencies": { "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" }, "cacache": { "version": "12.0.4", @@ -13949,11 +14060,7 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } + "optional": true }, "glob-parent": { "version": "3.1.0", @@ -14133,9 +14240,9 @@ } }, "whatwg-fetch": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.4.0.tgz", - "integrity": "sha512-rsum2ulz2iuZH08mJkT0Yi6JnKhwdw4oeyMjokgxd+mmqYSd9cPpOQf01TIWgjxG/U4+QR+AwKq6lSbXVxkyoQ==" + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz", + "integrity": "sha512-jXkLtsR42xhXg7akoDKvKWE40eJeI+2KZqcp2h3NsOrRnDvtWX36KcKl30dy+hxECivdk2BVUHVNrPtoMBUx6A==" }, "whatwg-mimetype": { "version": "2.3.0", @@ -14431,11 +14538,11 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, "xregexp": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", - "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.4.0.tgz", + "integrity": "sha512-83y4aa8o8o4NZe+L+46wpa+F1cWR/wCGOWI3tzqUso0w3/KAvXy0+Di7Oe/cbNMixDR4Jmi7NEybWU6ps25Wkg==", "requires": { - "@babel/runtime-corejs3": "^7.8.3" + "@babel/runtime-corejs3": "^7.12.1" } }, "xtend": { diff --git a/interface/package.json b/interface/package.json index 5a7b0798d..b4080e10f 100644 --- a/interface/package.json +++ b/interface/package.json @@ -3,30 +3,30 @@ "version": "0.1.0", "private": true, "dependencies": { - "@material-ui/core": "^4.9.8", + "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", - "@types/jwt-decode": "^2.2.1", - "@types/lodash": "^4.14.157", + "@types/jwt-decode": "^3.1.0", + "@types/lodash": "^4.14.165", "@types/node": "^12.12.32", - "@types/react": "^16.9.27", - "@types/react-dom": "^16.9.5", - "@types/react-material-ui-form-validator": "^2.0.5", - "@types/react-router": "^5.1.3", - "@types/react-router-dom": "^5.1.3", + "@types/react": "^16.9.56", + "@types/react-dom": "^16.9.9", + "@types/react-material-ui-form-validator": "^2.1.0", + "@types/react-router": "^5.1.8", + "@types/react-router-dom": "^5.1.6", "compression-webpack-plugin": "^4.0.0", - "jwt-decode": "^2.2.0", - "lodash": "^4.17.19", - "mime-types": "^2.1.25", - "moment": "^2.26.0", - "notistack": "^0.9.17", - "react": "^16.13.1", - "react-dom": "^16.13.1", - "react-dropzone": "^11.0.1", - "react-form-validator-core": "^0.6.4", - "react-material-ui-form-validator": "^2.0.10", - "react-router": "^5.1.2", - "react-router-dom": "^5.1.2", - "react-scripts": "3.4.3", + "jwt-decode": "^3.1.1", + "lodash": "^4.17.20", + "mime-types": "^2.1.27", + "moment": "^2.29.1", + "notistack": "^1.0.1", + "react": "^16.14.0", + "react-dom": "^16.14.0", + "react-dropzone": "^11.2.4", + "react-form-validator-core": "^1.0.0", + "react-material-ui-form-validator": "^2.1.1", + "react-router": "^5.2.0", + "react-router-dom": "^5.2.0", + "react-scripts": "3.4.4", "sockette": "^2.0.6", "typescript": "^4.0.2", "zlib": "^1.0.5" diff --git a/interface/src/authentication/AuthenticationWrapper.tsx b/interface/src/authentication/AuthenticationWrapper.tsx index 9a8de065a..f70a17209 100644 --- a/interface/src/authentication/AuthenticationWrapper.tsx +++ b/interface/src/authentication/AuthenticationWrapper.tsx @@ -9,7 +9,7 @@ import { AuthenticationContext, Me } from './AuthenticationContext'; import FullScreenLoading from '../components/FullScreenLoading'; import { withFeatures, WithFeaturesProps } from '../features/FeaturesContext'; -export const decodeMeJWT = (accessToken: string): Me => jwtDecode(accessToken); +export const decodeMeJWT = (accessToken: string): Me => jwtDecode(accessToken) as Me; interface AuthenticationWrapperState { context: AuthenticationContext; @@ -59,7 +59,7 @@ class AuthenticationWrapper extends React.Component { - // proddy removed + // commented out, always need security - proddy // if (!this.props.features.security) { // this.setState({ initialized: true, context: { ...this.state.context, me: { admin: true, username: "admin" } } }); // return; @@ -107,4 +107,4 @@ class AuthenticationWrapper extends React.Component-1", + "Africa/Casablanca": "UNK-1", "Africa/Ceuta": "CET-1CEST,M3.5.0,M10.5.0/3", "Africa/Conakry": "GMT0", "Africa/Dakar": "GMT0", "Africa/Dar_es_Salaam": "EAT-3", "Africa/Djibouti": "EAT-3", "Africa/Douala": "WAT-1", - "Africa/El_Aaiun": "<+01>-1", + "Africa/El_Aaiun": "UNK-1", "Africa/Freetown": "GMT0", "Africa/Gaborone": "CAT-2", "Africa/Harare": "CAT-2", @@ -62,63 +62,63 @@ export const TIME_ZONES: TimeZones = { "America/Anchorage": "AKST9AKDT,M3.2.0,M11.1.0", "America/Anguilla": "AST4", "America/Antigua": "AST4", - "America/Araguaina": "<-03>3", - "America/Argentina/Buenos_Aires": "<-03>3", - "America/Argentina/Catamarca": "<-03>3", - "America/Argentina/Cordoba": "<-03>3", - "America/Argentina/Jujuy": "<-03>3", - "America/Argentina/La_Rioja": "<-03>3", - "America/Argentina/Mendoza": "<-03>3", - "America/Argentina/Rio_Gallegos": "<-03>3", - "America/Argentina/Salta": "<-03>3", - "America/Argentina/San_Juan": "<-03>3", - "America/Argentina/San_Luis": "<-03>3", - "America/Argentina/Tucuman": "<-03>3", - "America/Argentina/Ushuaia": "<-03>3", + "America/Araguaina": "UNK3", + "America/Argentina/Buenos_Aires": "UNK3", + "America/Argentina/Catamarca": "UNK3", + "America/Argentina/Cordoba": "UNK3", + "America/Argentina/Jujuy": "UNK3", + "America/Argentina/La_Rioja": "UNK3", + "America/Argentina/Mendoza": "UNK3", + "America/Argentina/Rio_Gallegos": "UNK3", + "America/Argentina/Salta": "UNK3", + "America/Argentina/San_Juan": "UNK3", + "America/Argentina/San_Luis": "UNK3", + "America/Argentina/Tucuman": "UNK3", + "America/Argentina/Ushuaia": "UNK3", "America/Aruba": "AST4", - "America/Asuncion": "<-04>4<-03>,M10.1.0/0,M3.4.0/0", + "America/Asuncion": "UNK4UNK,M10.1.0/0,M3.4.0/0", "America/Atikokan": "EST5", - "America/Bahia": "<-03>3", + "America/Bahia": "UNK3", "America/Bahia_Banderas": "CST6CDT,M4.1.0,M10.5.0", "America/Barbados": "AST4", - "America/Belem": "<-03>3", + "America/Belem": "UNK3", "America/Belize": "CST6", "America/Blanc-Sablon": "AST4", - "America/Boa_Vista": "<-04>4", - "America/Bogota": "<-05>5", + "America/Boa_Vista": "UNK4", + "America/Bogota": "UNK5", "America/Boise": "MST7MDT,M3.2.0,M11.1.0", "America/Cambridge_Bay": "MST7MDT,M3.2.0,M11.1.0", - "America/Campo_Grande": "<-04>4", + "America/Campo_Grande": "UNK4", "America/Cancun": "EST5", - "America/Caracas": "<-04>4", - "America/Cayenne": "<-03>3", + "America/Caracas": "UNK4", + "America/Cayenne": "UNK3", "America/Cayman": "EST5", "America/Chicago": "CST6CDT,M3.2.0,M11.1.0", "America/Chihuahua": "MST7MDT,M4.1.0,M10.5.0", "America/Costa_Rica": "CST6", "America/Creston": "MST7", - "America/Cuiaba": "<-04>4", + "America/Cuiaba": "UNK4", "America/Curacao": "AST4", "America/Danmarkshavn": "GMT0", - "America/Dawson": "PST8PDT,M3.2.0,M11.1.0", + "America/Dawson": "MST7", "America/Dawson_Creek": "MST7", "America/Denver": "MST7MDT,M3.2.0,M11.1.0", "America/Detroit": "EST5EDT,M3.2.0,M11.1.0", "America/Dominica": "AST4", "America/Edmonton": "MST7MDT,M3.2.0,M11.1.0", - "America/Eirunepe": "<-05>5", + "America/Eirunepe": "UNK5", "America/El_Salvador": "CST6", - "America/Fortaleza": "<-03>3", "America/Fort_Nelson": "MST7", + "America/Fortaleza": "UNK3", "America/Glace_Bay": "AST4ADT,M3.2.0,M11.1.0", - "America/Godthab": "<-03>3<-02>,M3.5.0/-2,M10.5.0/-1", + "America/Godthab": "UNK3UNK,M3.5.0/-2,M10.5.0/-1", "America/Goose_Bay": "AST4ADT,M3.2.0,M11.1.0", "America/Grand_Turk": "EST5EDT,M3.2.0,M11.1.0", "America/Grenada": "AST4", "America/Guadeloupe": "AST4", "America/Guatemala": "CST6", - "America/Guayaquil": "<-05>5", - "America/Guyana": "<-04>4", + "America/Guayaquil": "UNK5", + "America/Guyana": "UNK4", "America/Halifax": "AST4ADT,M3.2.0,M11.1.0", "America/Havana": "CST5CDT,M3.2.0/0,M11.1.0/1", "America/Hermosillo": "MST7", @@ -137,13 +137,13 @@ export const TIME_ZONES: TimeZones = { "America/Kentucky/Louisville": "EST5EDT,M3.2.0,M11.1.0", "America/Kentucky/Monticello": "EST5EDT,M3.2.0,M11.1.0", "America/Kralendijk": "AST4", - "America/La_Paz": "<-04>4", - "America/Lima": "<-05>5", + "America/La_Paz": "UNK4", + "America/Lima": "UNK5", "America/Los_Angeles": "PST8PDT,M3.2.0,M11.1.0", "America/Lower_Princes": "AST4", - "America/Maceio": "<-03>3", + "America/Maceio": "UNK3", "America/Managua": "CST6", - "America/Manaus": "<-04>4", + "America/Manaus": "UNK4", "America/Marigot": "AST4", "America/Martinique": "AST4", "America/Matamoros": "CST6CDT,M3.2.0,M11.1.0", @@ -152,41 +152,41 @@ export const TIME_ZONES: TimeZones = { "America/Merida": "CST6CDT,M4.1.0,M10.5.0", "America/Metlakatla": "AKST9AKDT,M3.2.0,M11.1.0", "America/Mexico_City": "CST6CDT,M4.1.0,M10.5.0", - "America/Miquelon": "<-03>3<-02>,M3.2.0,M11.1.0", + "America/Miquelon": "UNK3UNK,M3.2.0,M11.1.0", "America/Moncton": "AST4ADT,M3.2.0,M11.1.0", "America/Monterrey": "CST6CDT,M4.1.0,M10.5.0", - "America/Montevideo": "<-03>3", + "America/Montevideo": "UNK3", "America/Montreal": "EST5EDT,M3.2.0,M11.1.0", "America/Montserrat": "AST4", "America/Nassau": "EST5EDT,M3.2.0,M11.1.0", "America/New_York": "EST5EDT,M3.2.0,M11.1.0", "America/Nipigon": "EST5EDT,M3.2.0,M11.1.0", "America/Nome": "AKST9AKDT,M3.2.0,M11.1.0", - "America/Noronha": "<-02>2", + "America/Noronha": "UNK2", "America/North_Dakota/Beulah": "CST6CDT,M3.2.0,M11.1.0", "America/North_Dakota/Center": "CST6CDT,M3.2.0,M11.1.0", "America/North_Dakota/New_Salem": "CST6CDT,M3.2.0,M11.1.0", "America/Ojinaga": "MST7MDT,M3.2.0,M11.1.0", "America/Panama": "EST5", "America/Pangnirtung": "EST5EDT,M3.2.0,M11.1.0", - "America/Paramaribo": "<-03>3", + "America/Paramaribo": "UNK3", "America/Phoenix": "MST7", "America/Port-au-Prince": "EST5EDT,M3.2.0,M11.1.0", "America/Port_of_Spain": "AST4", - "America/Porto_Velho": "<-04>4", + "America/Porto_Velho": "UNK4", "America/Puerto_Rico": "AST4", - "America/Punta_Arenas": "<-03>3", + "America/Punta_Arenas": "UNK3", "America/Rainy_River": "CST6CDT,M3.2.0,M11.1.0", "America/Rankin_Inlet": "CST6CDT,M3.2.0,M11.1.0", - "America/Recife": "<-03>3", + "America/Recife": "UNK3", "America/Regina": "CST6", "America/Resolute": "CST6CDT,M3.2.0,M11.1.0", - "America/Rio_Branco": "<-05>5", - "America/Santarem": "<-03>3", - "America/Santiago": "<-04>4<-03>,M9.1.6/24,M4.1.6/24", + "America/Rio_Branco": "UNK5", + "America/Santarem": "UNK3", + "America/Santiago": "UNK4UNK,M9.1.6/24,M4.1.6/24", "America/Santo_Domingo": "AST4", - "America/Sao_Paulo": "<-03>3", - "America/Scoresbysund": "<-01>1<+00>,M3.5.0/0,M10.5.0/1", + "America/Sao_Paulo": "UNK3", + "America/Scoresbysund": "UNK1UNK,M3.5.0/0,M10.5.0/1", "America/Sitka": "AKST9AKDT,M3.2.0,M11.1.0", "America/St_Barthelemy": "AST4", "America/St_Johns": "NST3:30NDT,M3.2.0,M11.1.0", @@ -202,129 +202,164 @@ export const TIME_ZONES: TimeZones = { "America/Toronto": "EST5EDT,M3.2.0,M11.1.0", "America/Tortola": "AST4", "America/Vancouver": "PST8PDT,M3.2.0,M11.1.0", - "America/Whitehorse": "PST8PDT,M3.2.0,M11.1.0", + "America/Whitehorse": "MST7", "America/Winnipeg": "CST6CDT,M3.2.0,M11.1.0", "America/Yakutat": "AKST9AKDT,M3.2.0,M11.1.0", "America/Yellowknife": "MST7MDT,M3.2.0,M11.1.0", - "Antarctica/Casey": "<+08>-8", - "Antarctica/Davis": "<+07>-7", - "Antarctica/DumontDUrville": "<+10>-10", - "Antarctica/Macquarie": "<+11>-11", - "Antarctica/Mawson": "<+05>-5", + "Antarctica/Casey": "UNK-8", + "Antarctica/Davis": "UNK-7", + "Antarctica/DumontDUrville": "UNK-10", + "Antarctica/Macquarie": "UNK-11", + "Antarctica/Mawson": "UNK-5", "Antarctica/McMurdo": "NZST-12NZDT,M9.5.0,M4.1.0/3", - "Antarctica/Palmer": "<-03>3", - "Antarctica/Rothera": "<-03>3", - "Antarctica/Syowa": "<+03>-3", - "Antarctica/Troll": "<+00>0<+02>-2,M3.5.0/1,M10.5.0/3", - "Antarctica/Vostok": "<+06>-6", + "Antarctica/Palmer": "UNK3", + "Antarctica/Rothera": "UNK3", + "Antarctica/Syowa": "UNK-3", + "Antarctica/Troll": "UNK0UNK-2,M3.5.0/1,M10.5.0/3", + "Antarctica/Vostok": "UNK-6", "Arctic/Longyearbyen": "CET-1CEST,M3.5.0,M10.5.0/3", - "Asia/Aden": "<+03>-3", - "Asia/Almaty": "<+06>-6", + "Asia/Aden": "UNK-3", + "Asia/Almaty": "UNK-6", "Asia/Amman": "EET-2EEST,M3.5.4/24,M10.5.5/1", - "Asia/Anadyr": "<+12>-12", - "Asia/Aqtau": "<+05>-5", - "Asia/Aqtobe": "<+05>-5", - "Asia/Ashgabat": "<+05>-5", - "Asia/Atyrau": "<+05>-5", - "Asia/Baghdad": "<+03>-3", - "Asia/Bahrain": "<+03>-3", - "Asia/Baku": "<+04>-4", - "Asia/Bangkok": "<+07>-7", - "Asia/Barnaul": "<+07>-7", + "Asia/Anadyr": "UNK-12", + "Asia/Aqtau": "UNK-5", + "Asia/Aqtobe": "UNK-5", + "Asia/Ashgabat": "UNK-5", + "Asia/Atyrau": "UNK-5", + "Asia/Baghdad": "UNK-3", + "Asia/Bahrain": "UNK-3", + "Asia/Baku": "UNK-4", + "Asia/Bangkok": "UNK-7", + "Asia/Barnaul": "UNK-7", "Asia/Beirut": "EET-2EEST,M3.5.0/0,M10.5.0/0", - "Asia/Bishkek": "<+06>-6", - "Asia/Brunei": "<+08>-8", - "Asia/Chita": "<+09>-9", - "Asia/Choibalsan": "<+08>-8", - "Asia/Colombo": "<+0530>-5:30", + "Asia/Bishkek": "UNK-6", + "Asia/Brunei": "UNK-8", + "Asia/Chita": "UNK-9", + "Asia/Choibalsan": "UNK-8", + "Asia/Colombo": "UNK-5:30", "Asia/Damascus": "EET-2EEST,M3.5.5/0,M10.5.5/0", - "Asia/Dhaka": "<+06>-6", - "Asia/Dili": "<+09>-9", - "Asia/Dubai": "<+04>-4", - "Asia/Dushanbe": "<+05>-5", + "Asia/Dhaka": "UNK-6", + "Asia/Dili": "UNK-9", + "Asia/Dubai": "UNK-4", + "Asia/Dushanbe": "UNK-5", "Asia/Famagusta": "EET-2EEST,M3.5.0/3,M10.5.0/4", "Asia/Gaza": "EET-2EEST,M3.5.5/0,M10.5.6/1", "Asia/Hebron": "EET-2EEST,M3.5.5/0,M10.5.6/1", - "Asia/Ho_Chi_Minh": "<+07>-7", + "Asia/Ho_Chi_Minh": "UNK-7", "Asia/Hong_Kong": "HKT-8", - "Asia/Hovd": "<+07>-7", - "Asia/Irkutsk": "<+08>-8", + "Asia/Hovd": "UNK-7", + "Asia/Irkutsk": "UNK-8", "Asia/Jakarta": "WIB-7", "Asia/Jayapura": "WIT-9", "Asia/Jerusalem": "IST-2IDT,M3.4.4/26,M10.5.0", - "Asia/Kabul": "<+0430>-4:30", - "Asia/Kamchatka": "<+12>-12", + "Asia/Kabul": "UNK-4:30", + "Asia/Kamchatka": "UNK-12", "Asia/Karachi": "PKT-5", - "Asia/Kathmandu": "<+0545>-5:45", - "Asia/Khandyga": "<+09>-9", + "Asia/Kathmandu": "UNK-5:45", + "Asia/Khandyga": "UNK-9", "Asia/Kolkata": "IST-5:30", - "Asia/Krasnoyarsk": "<+07>-7", - "Asia/Kuala_Lumpur": "<+08>-8", - "Asia/Kuching": "<+08>-8", - "Asia/Kuwait": "<+03>-3", + "Asia/Krasnoyarsk": "UNK-7", + "Asia/Kuala_Lumpur": "UNK-8", + "Asia/Kuching": "UNK-8", + "Asia/Kuwait": "UNK-3", "Asia/Macau": "CST-8", - "Asia/Magadan": "<+11>-11", + "Asia/Magadan": "UNK-11", "Asia/Makassar": "WITA-8", "Asia/Manila": "PST-8", - "Asia/Muscat": "<+04>-4", + "Asia/Muscat": "UNK-4", "Asia/Nicosia": "EET-2EEST,M3.5.0/3,M10.5.0/4", - "Asia/Novokuznetsk": "<+07>-7", - "Asia/Novosibirsk": "<+07>-7", - "Asia/Omsk": "<+06>-6", - "Asia/Oral": "<+05>-5", - "Asia/Phnom_Penh": "<+07>-7", + "Asia/Novokuznetsk": "UNK-7", + "Asia/Novosibirsk": "UNK-7", + "Asia/Omsk": "UNK-6", + "Asia/Oral": "UNK-5", + "Asia/Phnom_Penh": "UNK-7", "Asia/Pontianak": "WIB-7", "Asia/Pyongyang": "KST-9", - "Asia/Qatar": "<+03>-3", - "Asia/Qyzylorda": "<+05>-5", - "Asia/Riyadh": "<+03>-3", - "Asia/Sakhalin": "<+11>-11", - "Asia/Samarkand": "<+05>-5", + "Asia/Qatar": "UNK-3", + "Asia/Qyzylorda": "UNK-5", + "Asia/Riyadh": "UNK-3", + "Asia/Sakhalin": "UNK-11", + "Asia/Samarkand": "UNK-5", "Asia/Seoul": "KST-9", "Asia/Shanghai": "CST-8", - "Asia/Singapore": "<+08>-8", - "Asia/Srednekolymsk": "<+11>-11", + "Asia/Singapore": "UNK-8", + "Asia/Srednekolymsk": "UNK-11", "Asia/Taipei": "CST-8", - "Asia/Tashkent": "<+05>-5", - "Asia/Tbilisi": "<+04>-4", - "Asia/Tehran": "<+0330>-3:30<+0430>,J79/24,J263/24", - "Asia/Thimphu": "<+06>-6", + "Asia/Tashkent": "UNK-5", + "Asia/Tbilisi": "UNK-4", + "Asia/Tehran": "UNK-3:30UNK,J79/24,J263/24", + "Asia/Thimphu": "UNK-6", "Asia/Tokyo": "JST-9", - "Asia/Tomsk": "<+07>-7", - "Asia/Ulaanbaatar": "<+08>-8", - "Asia/Urumqi": "<+06>-6", - "Asia/Ust-Nera": "<+10>-10", - "Asia/Vientiane": "<+07>-7", - "Asia/Vladivostok": "<+10>-10", - "Asia/Yakutsk": "<+09>-9", - "Asia/Yangon": "<+0630>-6:30", - "Asia/Yekaterinburg": "<+05>-5", - "Asia/Yerevan": "<+04>-4", - "Atlantic/Azores": "<-01>1<+00>,M3.5.0/0,M10.5.0/1", + "Asia/Tomsk": "UNK-7", + "Asia/Ulaanbaatar": "UNK-8", + "Asia/Urumqi": "UNK-6", + "Asia/Ust-Nera": "UNK-10", + "Asia/Vientiane": "UNK-7", + "Asia/Vladivostok": "UNK-10", + "Asia/Yakutsk": "UNK-9", + "Asia/Yangon": "UNK-6:30", + "Asia/Yekaterinburg": "UNK-5", + "Asia/Yerevan": "UNK-4", + "Atlantic/Azores": "UNK1UNK,M3.5.0/0,M10.5.0/1", "Atlantic/Bermuda": "AST4ADT,M3.2.0,M11.1.0", "Atlantic/Canary": "WET0WEST,M3.5.0/1,M10.5.0", - "Atlantic/Cape_Verde": "<-01>1", + "Atlantic/Cape_Verde": "UNK1", "Atlantic/Faroe": "WET0WEST,M3.5.0/1,M10.5.0", "Atlantic/Madeira": "WET0WEST,M3.5.0/1,M10.5.0", "Atlantic/Reykjavik": "GMT0", - "Atlantic/South_Georgia": "<-02>2", - "Atlantic/Stanley": "<-03>3", + "Atlantic/South_Georgia": "UNK2", "Atlantic/St_Helena": "GMT0", + "Atlantic/Stanley": "UNK3", "Australia/Adelaide": "ACST-9:30ACDT,M10.1.0,M4.1.0/3", "Australia/Brisbane": "AEST-10", "Australia/Broken_Hill": "ACST-9:30ACDT,M10.1.0,M4.1.0/3", "Australia/Currie": "AEST-10AEDT,M10.1.0,M4.1.0/3", "Australia/Darwin": "ACST-9:30", - "Australia/Eucla": "<+0845>-8:45", + "Australia/Eucla": "UNK-8:45", "Australia/Hobart": "AEST-10AEDT,M10.1.0,M4.1.0/3", "Australia/Lindeman": "AEST-10", - "Australia/Lord_Howe": "<+1030>-10:30<+11>-11,M10.1.0,M4.1.0", + "Australia/Lord_Howe": "UNK-10:30UNK-11,M10.1.0,M4.1.0", "Australia/Melbourne": "AEST-10AEDT,M10.1.0,M4.1.0/3", "Australia/Perth": "AWST-8", "Australia/Sydney": "AEST-10AEDT,M10.1.0,M4.1.0/3", + "Etc/GMT": "GMT0", + "Etc/GMT+0": "GMT0", + "Etc/GMT+1": "UNK1", + "Etc/GMT+10": "UNK10", + "Etc/GMT+11": "UNK11", + "Etc/GMT+12": "UNK12", + "Etc/GMT+2": "UNK2", + "Etc/GMT+3": "UNK3", + "Etc/GMT+4": "UNK4", + "Etc/GMT+5": "UNK5", + "Etc/GMT+6": "UNK6", + "Etc/GMT+7": "UNK7", + "Etc/GMT+8": "UNK8", + "Etc/GMT+9": "UNK9", + "Etc/GMT-0": "GMT0", + "Etc/GMT-1": "UNK-1", + "Etc/GMT-10": "UNK-10", + "Etc/GMT-11": "UNK-11", + "Etc/GMT-12": "UNK-12", + "Etc/GMT-13": "UNK-13", + "Etc/GMT-14": "UNK-14", + "Etc/GMT-2": "UNK-2", + "Etc/GMT-3": "UNK-3", + "Etc/GMT-4": "UNK-4", + "Etc/GMT-5": "UNK-5", + "Etc/GMT-6": "UNK-6", + "Etc/GMT-7": "UNK-7", + "Etc/GMT-8": "UNK-8", + "Etc/GMT-9": "UNK-9", + "Etc/GMT0": "GMT0", + "Etc/Greenwich": "GMT0", + "Etc/UCT": "UTC0", + "Etc/UTC": "UTC0", + "Etc/Universal": "UTC0", + "Etc/Zulu": "UTC0", "Europe/Amsterdam": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Andorra": "CET-1CEST,M3.5.0,M10.5.0/3", - "Europe/Astrakhan": "<+04>-4", + "Europe/Astrakhan": "UNK-4", "Europe/Athens": "EET-2EEST,M3.5.0/3,M10.5.0/4", "Europe/Belgrade": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Berlin": "CET-1CEST,M3.5.0,M10.5.0/3", @@ -340,11 +375,11 @@ export const TIME_ZONES: TimeZones = { "Europe/Guernsey": "GMT0BST,M3.5.0/1,M10.5.0", "Europe/Helsinki": "EET-2EEST,M3.5.0/3,M10.5.0/4", "Europe/Isle_of_Man": "GMT0BST,M3.5.0/1,M10.5.0", - "Europe/Istanbul": "<+03>-3", + "Europe/Istanbul": "UNK-3", "Europe/Jersey": "GMT0BST,M3.5.0/1,M10.5.0", "Europe/Kaliningrad": "EET-2", "Europe/Kiev": "EET-2EEST,M3.5.0/3,M10.5.0/4", - "Europe/Kirov": "<+03>-3", + "Europe/Kirov": "UNK-3", "Europe/Lisbon": "WET0WEST,M3.5.0/1,M10.5.0", "Europe/Ljubljana": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/London": "GMT0BST,M3.5.0/1,M10.5.0", @@ -352,7 +387,7 @@ export const TIME_ZONES: TimeZones = { "Europe/Madrid": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Malta": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Mariehamn": "EET-2EEST,M3.5.0/3,M10.5.0/4", - "Europe/Minsk": "<+03>-3", + "Europe/Minsk": "UNK-3", "Europe/Monaco": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Moscow": "MSK-3", "Europe/Oslo": "CET-1CEST,M3.5.0,M10.5.0/3", @@ -361,111 +396,76 @@ export const TIME_ZONES: TimeZones = { "Europe/Prague": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Riga": "EET-2EEST,M3.5.0/3,M10.5.0/4", "Europe/Rome": "CET-1CEST,M3.5.0,M10.5.0/3", - "Europe/Samara": "<+04>-4", + "Europe/Samara": "UNK-4", "Europe/San_Marino": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Sarajevo": "CET-1CEST,M3.5.0,M10.5.0/3", - "Europe/Saratov": "<+04>-4", + "Europe/Saratov": "UNK-4", "Europe/Simferopol": "MSK-3", "Europe/Skopje": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Sofia": "EET-2EEST,M3.5.0/3,M10.5.0/4", "Europe/Stockholm": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Tallinn": "EET-2EEST,M3.5.0/3,M10.5.0/4", "Europe/Tirane": "CET-1CEST,M3.5.0,M10.5.0/3", - "Europe/Ulyanovsk": "<+04>-4", + "Europe/Ulyanovsk": "UNK-4", "Europe/Uzhgorod": "EET-2EEST,M3.5.0/3,M10.5.0/4", "Europe/Vaduz": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Vatican": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Vienna": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Vilnius": "EET-2EEST,M3.5.0/3,M10.5.0/4", - "Europe/Volgograd": "<+04>-4", + "Europe/Volgograd": "UNK-4", "Europe/Warsaw": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Zagreb": "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Zaporozhye": "EET-2EEST,M3.5.0/3,M10.5.0/4", "Europe/Zurich": "CET-1CEST,M3.5.0,M10.5.0/3", "Indian/Antananarivo": "EAT-3", - "Indian/Chagos": "<+06>-6", - "Indian/Christmas": "<+07>-7", - "Indian/Cocos": "<+0630>-6:30", + "Indian/Chagos": "UNK-6", + "Indian/Christmas": "UNK-7", + "Indian/Cocos": "UNK-6:30", "Indian/Comoro": "EAT-3", - "Indian/Kerguelen": "<+05>-5", - "Indian/Mahe": "<+04>-4", - "Indian/Maldives": "<+05>-5", - "Indian/Mauritius": "<+04>-4", + "Indian/Kerguelen": "UNK-5", + "Indian/Mahe": "UNK-4", + "Indian/Maldives": "UNK-5", + "Indian/Mauritius": "UNK-4", "Indian/Mayotte": "EAT-3", - "Indian/Reunion": "<+04>-4", - "Pacific/Apia": "<+13>-13<+14>,M9.5.0/3,M4.1.0/4", + "Indian/Reunion": "UNK-4", + "Pacific/Apia": "UNK-13UNK,M9.5.0/3,M4.1.0/4", "Pacific/Auckland": "NZST-12NZDT,M9.5.0,M4.1.0/3", - "Pacific/Bougainville": "<+11>-11", - "Pacific/Chatham": "<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45", - "Pacific/Chuuk": "<+10>-10", - "Pacific/Easter": "<-06>6<-05>,M9.1.6/22,M4.1.6/22", - "Pacific/Efate": "<+11>-11", - "Pacific/Enderbury": "<+13>-13", - "Pacific/Fakaofo": "<+13>-13", - "Pacific/Fiji": "<+12>-12<+13>,M11.2.0,M1.2.3/99", - "Pacific/Funafuti": "<+12>-12", - "Pacific/Galapagos": "<-06>6", - "Pacific/Gambier": "<-09>9", - "Pacific/Guadalcanal": "<+11>-11", + "Pacific/Bougainville": "UNK-11", + "Pacific/Chatham": "UNK-12:45UNK,M9.5.0/2:45,M4.1.0/3:45", + "Pacific/Chuuk": "UNK-10", + "Pacific/Easter": "UNK6UNK,M9.1.6/22,M4.1.6/22", + "Pacific/Efate": "UNK-11", + "Pacific/Enderbury": "UNK-13", + "Pacific/Fakaofo": "UNK-13", + "Pacific/Fiji": "UNK-12UNK,M11.2.0,M1.2.3/99", + "Pacific/Funafuti": "UNK-12", + "Pacific/Galapagos": "UNK6", + "Pacific/Gambier": "UNK9", + "Pacific/Guadalcanal": "UNK-11", "Pacific/Guam": "ChST-10", "Pacific/Honolulu": "HST10", - "Pacific/Kiritimati": "<+14>-14", - "Pacific/Kosrae": "<+11>-11", - "Pacific/Kwajalein": "<+12>-12", - "Pacific/Majuro": "<+12>-12", - "Pacific/Marquesas": "<-0930>9:30", + "Pacific/Kiritimati": "UNK-14", + "Pacific/Kosrae": "UNK-11", + "Pacific/Kwajalein": "UNK-12", + "Pacific/Majuro": "UNK-12", + "Pacific/Marquesas": "UNK9:30", "Pacific/Midway": "SST11", - "Pacific/Nauru": "<+12>-12", - "Pacific/Niue": "<-11>11", - "Pacific/Norfolk": "<+11>-11<+12>,M10.1.0,M4.1.0/3", - "Pacific/Noumea": "<+11>-11", + "Pacific/Nauru": "UNK-12", + "Pacific/Niue": "UNK11", + "Pacific/Norfolk": "UNK-11UNK,M10.1.0,M4.1.0/3", + "Pacific/Noumea": "UNK-11", "Pacific/Pago_Pago": "SST11", - "Pacific/Palau": "<+09>-9", - "Pacific/Pitcairn": "<-08>8", - "Pacific/Pohnpei": "<+11>-11", - "Pacific/Port_Moresby": "<+10>-10", - "Pacific/Rarotonga": "<-10>10", + "Pacific/Palau": "UNK-9", + "Pacific/Pitcairn": "UNK8", + "Pacific/Pohnpei": "UNK-11", + "Pacific/Port_Moresby": "UNK-10", + "Pacific/Rarotonga": "UNK10", "Pacific/Saipan": "ChST-10", - "Pacific/Tahiti": "<-10>10", - "Pacific/Tarawa": "<+12>-12", - "Pacific/Tongatapu": "<+13>-13", - "Pacific/Wake": "<+12>-12", - "Pacific/Wallis": "<+12>-12", - "Etc/GMT": "GMT0", - "Etc/GMT-0": "GMT0", - "Etc/GMT-1": "<+01>-1", - "Etc/GMT-2": "<+02>-2", - "Etc/GMT-3": "<+03>-3", - "Etc/GMT-4": "<+04>-4", - "Etc/GMT-5": "<+05>-5", - "Etc/GMT-6": "<+06>-6", - "Etc/GMT-7": "<+07>-7", - "Etc/GMT-8": "<+08>-8", - "Etc/GMT-9": "<+09>-9", - "Etc/GMT-10": "<+10>-10", - "Etc/GMT-11": "<+11>-11", - "Etc/GMT-12": "<+12>-12", - "Etc/GMT-13": "<+13>-13", - "Etc/GMT-14": "<+14>-14", - "Etc/GMT0": "GMT0", - "Etc/GMT+0": "GMT0", - "Etc/GMT+1": "<-01>1", - "Etc/GMT+2": "<-02>2", - "Etc/GMT+3": "<-03>3", - "Etc/GMT+4": "<-04>4", - "Etc/GMT+5": "<-05>5", - "Etc/GMT+6": "<-06>6", - "Etc/GMT+7": "<-07>7", - "Etc/GMT+8": "<-08>8", - "Etc/GMT+9": "<-09>9", - "Etc/GMT+10": "<-10>10", - "Etc/GMT+11": "<-11>11", - "Etc/GMT+12": "<-12>12", - "Etc/UCT": "UTC0", - "Etc/UTC": "UTC0", - "Etc/Greenwich": "GMT0", - "Etc/Universal": "UTC0", - "Etc/Zulu": "UTC0" + "Pacific/Tahiti": "UNK10", + "Pacific/Tarawa": "UNK-12", + "Pacific/Tongatapu": "UNK-13", + "Pacific/Wake": "UNK-12", + "Pacific/Wallis": "UNK-12" } export function selectedTimeZone(label: string, format: string) { @@ -476,4 +476,4 @@ export function timeZoneSelectItems() { return Object.keys(TIME_ZONES).map(label => ( {label} )); -} +} \ No newline at end of file From 5219cf60f147a2686d2e148c6a968e980a4a7249 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 12:48:56 +0100 Subject: [PATCH 40/55] restart MQTT when settings change from Web --- lib/framework/MqttSettingsService.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/framework/MqttSettingsService.cpp b/lib/framework/MqttSettingsService.cpp index 16f2c8790..41fd7675c 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -4,7 +4,6 @@ namespace emsesp { class EMSESP { public: - static System system_; static Mqtt mqtt_; static DallasSensor dallassensor_; }; @@ -93,14 +92,12 @@ AsyncMqttClient * MqttSettingsService::getMqttClient() { } void MqttSettingsService::onMqttConnect(bool sessionPresent) { - /* - Serial.print(F("Connected to MQTT, ")); - if (sessionPresent) { - Serial.println(F("with persistent session")); - } else { - Serial.println(F("without persistent session")); - } - */ + // Serial.print(F("Connected to MQTT, ")); + // if (sessionPresent) { + // Serial.println(F("with persistent session")); + // } else { + // Serial.println(F("without persistent session")); + // } } void MqttSettingsService::onMqttDisconnect(AsyncMqttClientDisconnectReason reason) { @@ -116,6 +113,7 @@ void MqttSettingsService::onConfigUpdated() { // added by proddy // reload EMS-ESP MQTT settings + emsesp::EMSESP::mqtt_.start(); } #ifdef ESP32 From 842683aae1a32fd3c0b81cc25156ccdecc96c21a Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 12:49:10 +0100 Subject: [PATCH 41/55] comments --- lib/framework/FSPersistence.h | 10 ++++---- lib/framework/OTASettingsService.cpp | 35 ++++++++++++++-------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/lib/framework/FSPersistence.h b/lib/framework/FSPersistence.h index 64ec179c2..f0da8cc57 100644 --- a/lib/framework/FSPersistence.h +++ b/lib/framework/FSPersistence.h @@ -66,10 +66,12 @@ class FSPersistence { return false; } - // debug added by Proddy - // Serial.printf("Write File: %s: ", _filePath); - // serializeJson(jsonDocument, Serial); - // Serial.println(); +// debug added by Proddy +#if defined(EMSESP_FORCE_SERIAL) + Serial.printf("Write File: %s: ", _filePath); + serializeJson(jsonDocument, Serial); + Serial.println(); +#endif // serialize the data to the file serializeJson(jsonDocument, settingsFile); diff --git a/lib/framework/OTASettingsService.cpp b/lib/framework/OTASettingsService.cpp index 3fd002448..100892235 100644 --- a/lib/framework/OTASettingsService.cpp +++ b/lib/framework/OTASettingsService.cpp @@ -46,24 +46,23 @@ void OTASettingsService::configureArduinoOTA() { emsesp::System::upload_status(false); }); - /* - _arduinoOTA->onProgress([](unsigned int progress, unsigned int total) { - Serial.printf_P(PSTR("Progress: %u%%\r\n"), (progress / (total / 100))); - }); - _arduinoOTA->onError([](ota_error_t error) { - Serial.printf("Error[%u]: ", error); - if (error == OTA_AUTH_ERROR) - Serial.println(F("Auth Failed")); - else if (error == OTA_BEGIN_ERROR) - Serial.println(F("Begin Failed")); - else if (error == OTA_CONNECT_ERROR) - Serial.println(F("Connect Failed")); - else if (error == OTA_RECEIVE_ERROR) - Serial.println(F("Receive Failed")); - else if (error == OTA_END_ERROR) - Serial.println(F("End Failed")); - }); - */ + // _arduinoOTA->onProgress([](unsigned int progress, unsigned int total) { + // Serial.printf_P(PSTR("Progress: %u%%\r\n"), (progress / (total / 100))); + // }); + // _arduinoOTA->onError([](ota_error_t error) { + // Serial.printf("Error[%u]: ", error); + // if (error == OTA_AUTH_ERROR) + // Serial.println(F("Auth Failed")); + // else if (error == OTA_BEGIN_ERROR) + // Serial.println(F("Begin Failed")); + // else if (error == OTA_CONNECT_ERROR) + // Serial.println(F("Connect Failed")); + // else if (error == OTA_RECEIVE_ERROR) + // Serial.println(F("Receive Failed")); + // else if (error == OTA_END_ERROR) + // Serial.println(F("End Failed")); + // }); + _arduinoOTA->begin(); } } From 6fefb8fd8f819db2b7d3db855c154bba2cf359f5 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 12:49:29 +0100 Subject: [PATCH 42/55] prevent serial when in debug mode, during update check --- src/system.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/system.cpp b/src/system.cpp index 45a40d633..9733834b2 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -698,7 +698,7 @@ bool System::check_upgrade() { l_cfg.setAutoFormat(false); LittleFS.setConfig(l_cfg); // do not auto format if it can't find LittleFS if (LittleFS.begin()) { -#if defined(EMSESP_DEBUG) +#if defined(EMSESP_FORCE_SERIAL) Serial.begin(115200); Serial.println(F("FS is Littlefs")); Serial.end(); @@ -713,7 +713,7 @@ bool System::check_upgrade() { cfg.setAutoFormat(false); // prevent formatting when opening SPIFFS filesystem SPIFFS.setConfig(cfg); if (!SPIFFS.begin()) { -#if defined(EMSESP_DEBUG) +#if defined(EMSESP_FORCE_SERIAL) Serial.begin(115200); Serial.println(F("No old SPIFFS found!")); Serial.end(); @@ -812,9 +812,7 @@ bool System::check_upgrade() { file.close(); if (failed) { -#if defined(EMSESP_DEBUG) Serial.println(F("Failed to read system config. Quitting.")); -#endif SPIFFS.end(); Serial.end(); return false; @@ -837,10 +835,6 @@ bool System::check_upgrade() { Serial.printf(PSTR("Error. Failed to deserialize custom json, error %s\n"), error.c_str()); failed = true; } else { -#if defined(EMSESP_DEBUG) - serializeJson(doc, Serial); - Serial.println(); -#endif custom_settings = doc["settings"]; EMSESP::webSettingsService.update( [&](WebSettings & settings) { @@ -868,9 +862,7 @@ bool System::check_upgrade() { SPIFFS.end(); if (failed) { -#if defined(EMSESP_DEBUG) Serial.println(F("Failed to read custom config. Quitting.")); -#endif Serial.end(); return false; } From 4a4d664d7df3858b5284e96adada69d969a24411 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 12:49:49 +0100 Subject: [PATCH 43/55] don't setup mqtt if it's disabled --- src/mqtt.cpp | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 7dc881187..3ab2ae3c3 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -356,6 +356,11 @@ void Mqtt::start() { mqtt_enabled_ = mqttSettings.enabled; }); + // if MQTT disabled, quit + if (!mqtt_enabled_) { + return; + } + mqttClient_->onConnect([this](bool sessionPresent) { on_connect(); }); mqttClient_->onDisconnect([this](AsyncMqttClientDisconnectReason reason) { @@ -609,26 +614,6 @@ void Mqtt::process_queue() { return; } - // show queue - Debug only - /* - Serial.printf("MQTT queue:\n\r"); - for (const auto & message : mqtt_messages_) { - auto content = message.content_; - if (content->operation == Operation::PUBLISH) { - // Publish messages - Serial.printf(" [%02d] (Pub) topic=%s payload=%s (pid %d, retry #%d)\n\r", - message.id_, - content->topic.c_str(), - content->payload.c_str(), - message.packet_id_, - message.retry_count_); - } else { - // Subscribe messages - Serial.printf(" [%02d] (Sub) topic=%s\n\r", message.id_, content->topic.c_str()); - } - } - */ - // fetch first from queue and create the full topic name auto mqtt_message = mqtt_messages_.front(); auto message = mqtt_message.content_; From 30d032b9864b3d94887f35b5bc83dd10369db06c Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 15:31:28 +0100 Subject: [PATCH 44/55] updates to processing order --- src/test/test.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/test/test.cpp b/src/test/test.cpp index bc67357c7..35d8bbeea 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -27,10 +27,10 @@ namespace emsesp { // used with the 'test' command, under su/admin void Test::run_test(uuid::console::Shell & shell, const std::string & command) { // switch to su - // shell.add_flags(CommandFlags::ADMIN); + shell.add_flags(CommandFlags::ADMIN); if (command == "default") { - run_test(shell, "boiler"); // add the default test case here + run_test(shell, "general"); // add the default test case here } if (command.empty()) { @@ -250,7 +250,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { shell.printfln(F("Testing adding a general boiler & thermostat...")); add_device(0x08, 123); // Nefit Trendline - // add_device(0x18, 157); // Bosch CR100 + add_device(0x18, 157); // Bosch CR100 // 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) @@ -267,9 +267,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { 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}); + shell.invoke_command("show devices"); shell.invoke_command("show"); - shell.invoke_command("publish"); - shell.invoke_command("show mqtt"); + // shell.invoke_command("publish"); + // shell.invoke_command("show mqtt"); } if (command == "fr120") { @@ -838,6 +839,7 @@ void Test::rx_telegram(const std::vector & rx_data) { } data[i] = EMSESP::rxservice_.calculate_crc(data, i); EMSESP::rxservice_.add(data, len + 1); + EMSESP::loop(); } // simulates a telegram straight from UART, but without the CRC which is added automatically @@ -851,7 +853,7 @@ void Test::uart_telegram(const std::vector & rx_data) { } data[i] = EMSESP::rxservice_.calculate_crc(data, i); EMSESP::incoming_telegram(data, i + 1); - // EMSESP::rxservice_.loop(); + EMSESP::loop(); } // takes raw string, assuming it contains the CRC. This is what is output from 'watch raw' @@ -889,7 +891,7 @@ void Test::uart_telegram_withCRC(const char * rx_data) { } EMSESP::incoming_telegram(data, count + 1); - // EMSESP::rxservice_.loop(); + EMSESP::loop(); } // takes raw string, adds CRC to end @@ -929,7 +931,7 @@ void Test::uart_telegram(const char * rx_data) { data[count + 1] = EMSESP::rxservice_.calculate_crc(data, count + 1); // add CRC EMSESP::incoming_telegram(data, count + 2); - // EMSESP::rxservice_.loop(); + EMSESP::loop(); } // Sends version telegram. Version is hardcoded to 1.0 From af08bc607d9081b141532484aad342b25e14e6bf Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 15:31:51 +0100 Subject: [PATCH 45/55] roll back changes with device unique_id --- src/emsdevice.h | 3 +-- src/emsesp.cpp | 13 +++++++------ src/emsesp.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/emsdevice.h b/src/emsdevice.h index a4a9fe2a1..81ac08c44 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -43,7 +43,6 @@ class EMSdevice { , name_(name) , flags_(flags) , brand_(brand) { - unique_id_++; } virtual ~EMSdevice() = default; // destructor of base class must always be virtual because it's a polymorphic class @@ -271,7 +270,7 @@ class EMSdevice { static constexpr uint8_t EMS_DEVICE_FLAG_JUNKERS_2 = (1 << 6); // 6th bit set if older models, like FR120, FR100 private: - uint8_t unique_id_ = 0; + uint8_t unique_id_; uint8_t device_type_ = DeviceType::SYSTEM; uint8_t device_id_ = 0; uint8_t product_id_ = 0; diff --git a/src/emsesp.cpp b/src/emsesp.cpp index c7c982743..89ba830fb 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -64,6 +64,7 @@ uint16_t EMSESP::publish_id_ = 0; bool EMSESP::tap_water_active_ = false; // for when Boiler states we having running warm water. used in Shower() uint32_t EMSESP::last_fetch_ = 0; uint8_t EMSESP::publish_all_idx_ = 0; +uint8_t EMSESP::unique_id_count_ = 0; // for a specific EMS device go and request data values // or if device_id is 0 it will fetch from all our known and active devices @@ -215,10 +216,9 @@ void EMSESP::show_ems(uuid::console::Shell & shell) { shell.printfln(F(" #tx fails (after %d retries): %d"), TxService::MAXIMUM_TX_RETRIES, txservice_.telegram_fail_count()); shell.printfln(F(" Rx line quality: %d%%"), rxservice_.quality()); shell.printfln(F(" Tx line quality: %d%%"), txservice_.quality()); + shell.println(); } - shell.println(); - // Rx queue auto rx_telegrams = rxservice_.queue(); if (rx_telegrams.empty()) { @@ -694,7 +694,7 @@ void EMSESP::show_devices(uuid::console::Shell & shell) { // shell.printf(F("[factory ID: %d] "), device_class.first); for (const auto & emsdevice : emsdevices) { if ((emsdevice) && (emsdevice->device_type() == device_class.first)) { - shell.printf(F("%s: %s"), emsdevice->device_type_name().c_str(), emsdevice->to_string().c_str()); + shell.printf(F("(%d) %s: %s"), emsdevice->unique_id(), emsdevice->device_type_name().c_str(), emsdevice->to_string().c_str()); if ((emsdevice->device_type() == EMSdevice::DeviceType::THERMOSTAT) && (emsdevice->device_id() == actual_master_thermostat())) { shell.printf(F(" ** master device **")); } @@ -772,6 +772,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, std:: auto flags = device_p->flags; LOG_DEBUG(F("Adding new device %s (device ID 0x%02X, product ID %d, version %s)"), name.c_str(), device_id, product_id, version.c_str()); emsdevices.push_back(EMSFactory::add(device_type, device_id, product_id, version, name, flags, brand)); + emsdevices.back()->unique_id(++unique_id_count_); fetch_device_values(device_id); // go and fetch its data @@ -981,12 +982,12 @@ void EMSESP::loop() { } system_.loop(); // does LED and checks system health, and syslog service + rxservice_.loop(); // process any incoming Rx telegrams shower_.loop(); // check for shower on/off dallassensor_.loop(); // this will also send out via MQTT publish_all_loop(); - mqtt_.loop(); // sends out anything in the queue via MQTT - console_.loop(); // telnet/serial console - rxservice_.loop(); // process any incoming Rx telegrams + mqtt_.loop(); // sends out anything in the queue via MQTT + console_.loop(); // telnet/serial console // force a query on the EMS devices to fetch latest data at a set interval (1 min) if ((uuid::get_uptime() - last_fetch_ > EMS_FETCH_FREQUENCY)) { diff --git a/src/emsesp.h b/src/emsesp.h index 053884ba0..eaa887456 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -208,7 +208,7 @@ class EMSESP { static uint16_t publish_id_; static bool tap_water_active_; static uint8_t publish_all_idx_; - + static uint8_t unique_id_count_; }; } // namespace emsesp From b51dfae718f856001d4c25d449d811b1ca66e58f Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 15:41:05 +0100 Subject: [PATCH 46/55] change queue size for standalone --- src/mqtt.cpp | 8 +++----- src/mqtt.h | 9 ++++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 3ab2ae3c3..28f8b0436 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -39,9 +39,9 @@ bool Mqtt::mqtt_enabled_; std::vector Mqtt::mqtt_subfunctions_; -uint16_t Mqtt::mqtt_publish_fails_ = 0; +uint16_t Mqtt::mqtt_publish_fails_ = 0; // size_t Mqtt::maximum_mqtt_messages_ = Mqtt::MAX_MQTT_MESSAGES; -uint16_t Mqtt::mqtt_message_id_ = 0; +uint16_t Mqtt::mqtt_message_id_ = 0; std::list Mqtt::mqtt_messages_; char will_topic_[Mqtt::MQTT_TOPIC_MAX_SIZE]; // because MQTT library keeps only char pointer @@ -181,7 +181,7 @@ void Mqtt::show_mqtt(uuid::console::Shell & shell) { return; } - shell.printfln(F("MQTT queue (%d messages):"), mqtt_messages_.size()); + shell.printfln(F("MQTT queue (%d/%d messages):"), mqtt_messages_.size(), MAX_MQTT_MESSAGES); for (const auto & message : mqtt_messages_) { auto content = message.content_; @@ -730,7 +730,6 @@ void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, cons // delay(MQTT_PUBLISH_WAIT); delay(50); - } // HA config for a normal 'sensor' type @@ -826,6 +825,5 @@ void Mqtt::register_mqtt_ha_sensor(const char * prefix, // delay(MQTT_PUBLISH_WAIT); // don't flood asynctcp delay(50); // enough time to send the short message out - } } // namespace emsesp diff --git a/src/mqtt.h b/src/mqtt.h index 8b987dbb4..ead5681d9 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -171,11 +171,14 @@ class Mqtt { static std::list mqtt_messages_; static AsyncMqttClient * mqttClient_; + static uint16_t mqtt_message_id_; - // static size_t maximum_mqtt_messages_; - static uint16_t mqtt_message_id_; +#if defined(EMSESP_STANDALONE) + static constexpr size_t MAX_MQTT_MESSAGES = 70; // size of queue +#else + static constexpr size_t MAX_MQTT_MESSAGES = 20; // size of queue +#endif - static constexpr size_t MAX_MQTT_MESSAGES = 20; // size of queue static constexpr uint32_t MQTT_PUBLISH_WAIT = 200; // delay between sending publishes, to account for large payloads static constexpr uint8_t MQTT_PUBLISH_MAX_RETRY = 3; // max retries for giving up on publishing From 992f325078072276671bdb41d4c427672fd5371e Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 15:41:24 +0100 Subject: [PATCH 47/55] prevent heartbeat with standalone --- src/system.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/system.cpp b/src/system.cpp index 9733834b2..d214e660d 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -245,10 +245,10 @@ void System::upload_status(bool in_progress) { // checks system health and handles LED flashing wizardry void System::loop() { #ifndef EMSESP_STANDALONE + if (syslog_enabled_) { syslog_.loop(); } -#endif led_monitor(); // check status and report back using the LED system_check(); // check system health @@ -272,6 +272,9 @@ void System::loop() { } #endif #endif + +#endif + } void System::show_mem(const char * note) { From 548c07f932726dc063b8927418e19fc7005b1471 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 14 Nov 2020 15:52:02 +0100 Subject: [PATCH 48/55] change json package size, min 384, max 1024 for static, 2048 for dynamic --- CHANGELOG_LATEST.md | 1 + src/WebAPIService.cpp | 6 +++--- src/mqtt.h | 9 ++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 4f49d423c..927d66944 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -14,6 +14,7 @@ - change syslog settings without reboot - HA-config split in smaller blocks - commands `fetch` and `publish [ha]` as call +- mqtt json package size ### Removed - old scripts diff --git a/src/WebAPIService.cpp b/src/WebAPIService.cpp index 499741713..94da9e153 100644 --- a/src/WebAPIService.cpp +++ b/src/WebAPIService.cpp @@ -71,7 +71,7 @@ void WebAPIService::webAPIService(AsyncWebServerRequest * request) { id = "-1"; } - DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_LARGE); + DynamicJsonDocument doc(EMSESP_MAX_JSON_SIZE_DYN); JsonObject json = doc.to(); bool ok = false; @@ -101,7 +101,7 @@ void WebAPIService::webAPIService(AsyncWebServerRequest * request) { ok ? PSTR("OK") : PSTR("Invalid")); EMSESP::logger().info(debug.c_str()); if (json.size()) { - char buffer2[EMSESP_MAX_JSON_SIZE_LARGE]; + char buffer2[EMSESP_MAX_JSON_SIZE_DYN]; serializeJson(doc, buffer2); EMSESP::logger().info("json (max 255 chars): %s", buffer2); } @@ -110,7 +110,7 @@ void WebAPIService::webAPIService(AsyncWebServerRequest * request) { // if we have returned data in JSON format, send this to the WEB if (json.size()) { doc.shrinkToFit(); - char buffer[EMSESP_MAX_JSON_SIZE_LARGE]; + char buffer[EMSESP_MAX_JSON_SIZE_DYN]; serializeJsonPretty(doc, buffer); request->send(200, "text/plain", buffer); } else { diff --git a/src/mqtt.h b/src/mqtt.h index ead5681d9..7e5080a79 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -38,11 +38,10 @@ using uuid::console::Shell; -#define EMSESP_MAX_JSON_SIZE_SMALL 256 // for smaller json docs when using StaticJsonDocument -#define EMSESP_MAX_JSON_SIZE_MEDIUM 768 // for smaller json docs from ems devices, when using StaticJsonDocument -// #define EMSESP_MAX_JSON_SIZE_LARGE 2048 // for large json docs from ems devices, like boiler or thermostat data. Using DynamicJsonDocument -// mqtt does not publish larger than 1570 on esp8266, boiler message is split and now smaller -#define EMSESP_MAX_JSON_SIZE_LARGE 1536 // for large json docs from ems devices, like boiler or thermostat data. Using StaticJsonDocument +#define EMSESP_MAX_JSON_SIZE_SMALL 384 // for smaller json docs when using StaticJsonDocument +#define EMSESP_MAX_JSON_SIZE_MEDIUM 768 // for medium json docs from ems devices, when using StaticJsonDocument +#define EMSESP_MAX_JSON_SIZE_LARGE 1024 // for large json docs from ems devices, like boiler or thermostat data. Using StaticJsonDocument +#define EMSESP_MAX_JSON_SIZE_DYN 2048 // for large json docs from web. Using DynamicJsonDocument namespace emsesp { From 57983c061d6d03bbc9345b253c76a2d93a7edf24 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 16:56:48 +0100 Subject: [PATCH 49/55] updated test --- src/test/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/test.cpp b/src/test/test.cpp index 35d8bbeea..81432182b 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -269,8 +269,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { shell.invoke_command("show devices"); shell.invoke_command("show"); - // shell.invoke_command("publish"); - // shell.invoke_command("show mqtt"); + shell.invoke_command("call system publish"); + shell.invoke_command("show mqtt"); } if (command == "fr120") { From 16dd1dab71ac9d6f595799873a22d96d903064e7 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 16:57:01 +0100 Subject: [PATCH 50/55] updated test --- src/devices/thermostat.cpp | 19 +++++++++++-------- src/system.cpp | 4 ++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 3a8605632..fd19f6acb 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -181,7 +181,7 @@ Thermostat::Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_i // prepare data for Web UI void Thermostat::device_info_web(JsonArray & root) { StaticJsonDocument doc_main; - JsonObject json_main = doc_main.to(); + JsonObject json_main = doc_main.to(); if (export_values_main(json_main)) { print_value_json(root, F("time"), nullptr, F_(time), nullptr, json_main); print_value_json(root, F("errorcode"), nullptr, F_(error), nullptr, json_main); @@ -817,7 +817,7 @@ std::shared_ptr Thermostat::heating_circuit(std::sha return heating_circuits_.back(); // even after sorting, this should still point back to the newly created HC } -// publish config topic for HA MQTT Discovery +// publish config topic for HA MQTT Discovery for main thermostat values // homeassistant/climate/ems-esp/thermostat/config void Thermostat::register_mqtt_ha_config() { StaticJsonDocument doc; @@ -871,7 +871,7 @@ void Thermostat::register_mqtt_ha_config() { } } -// publish config topic for HA MQTT Discovery +// publish config topic for HA MQTT Discovery for each of the heating circuit // e.g. homeassistant/climate/ems-esp/thermostat_hc1/config void Thermostat::register_mqtt_ha_config(uint8_t hc_num) { StaticJsonDocument doc; @@ -954,7 +954,7 @@ void Thermostat::register_mqtt_ha_config(uint8_t hc_num) { // for each of the heating circuits std::string topic2(100, '\0'); snprintf_P(&topic2[0], topic2.capacity() + 1, PSTR("thermostat_hc%d"), hc_num); - register_mqtt_topic(topic2, [=](const char * m) { return thermostat_ha_cmd(m, hc_num); }); + register_mqtt_topic(topic2, [&](const char * m) { return thermostat_ha_cmd(m, hc_num); }); char hc_name[10]; // hc{1-4} strlcpy(hc_name, "hc", 10); @@ -963,6 +963,9 @@ void Thermostat::register_mqtt_ha_config(uint8_t hc_num) { Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(mode), this->device_type(), "mode", nullptr, nullptr); + Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(seltemp), this->device_type(), "seltemp", F_(degrees), F_(icontemperature)); + Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(currtemp), this->device_type(), "currtemp", F_(degrees), F_(icontemperature)); + uint8_t model = this->model(); switch (model) { case EMS_DEVICE_FLAG_RC100: @@ -1455,10 +1458,10 @@ void Thermostat::process_RC35Set(std::shared_ptr telegram) { changed_ |= telegram->read_value(hc->flowtempoffset, 24); // is * 1, only in mixed circuits changed_ |= telegram->read_value(hc->minflowtemp, 16); if (hc->heatingtype == 3) { - changed_ |= telegram->read_value(hc->designtemp, 36); // is * 1 + changed_ |= telegram->read_value(hc->designtemp, 36); // is * 1 changed_ |= telegram->read_value(hc->maxflowtemp, 35); // is * 1 } else { - changed_ |= telegram->read_value(hc->designtemp, 17); // is * 1 + changed_ |= telegram->read_value(hc->designtemp, 17); // is * 1 changed_ |= telegram->read_value(hc->maxflowtemp, 15); // is * 1 } } @@ -2113,8 +2116,8 @@ bool Thermostat::set_temperature(const float temperature, const uint8_t mode, co case HeatingCircuit::Mode::MINFLOW: set_typeid = summer_typeids[hc->hc_num() - 1]; validate_typeid = set_typeid; - offset = 8; - factor = 1; + offset = 8; + factor = 1; break; case HeatingCircuit::Mode::MAXFLOW: set_typeid = curve_typeids[hc->hc_num() - 1]; diff --git a/src/system.cpp b/src/system.cpp index d214e660d..c89b4ca88 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -78,12 +78,12 @@ bool System::command_publish(const char * value, const int8_t id) { if (Helpers::value2string(value, ha)) { if (ha == "ha") { EMSESP::publish_all(true); // includes HA - LOG_INFO(F("Published all data to MQTT, including HA configs")); + LOG_INFO(F("Publishing all data to MQTT, including HA configs")); return true; } } EMSESP::publish_all(); // ignore value and id - LOG_INFO(F("Published all data to MQTT")); + LOG_INFO(F("Publishing all data to MQTT")); return true; } From cb9795ec82eab4fb408a49a2999eafae3ba8506a Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 17:31:17 +0100 Subject: [PATCH 51/55] increase mqtt size just in case --- src/devices/boiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index e4558e64f..ea1a053d0 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -80,7 +80,7 @@ void Boiler::register_mqtt_ha_config() { } // Create the Master device - StaticJsonDocument doc; + StaticJsonDocument doc; doc["name"] = F("Service Code"); doc["uniq_id"] = F("boiler"); doc["ic"] = F("mdi:home-thermometer-outline"); From ca0296e4540e34a3c2b7c310b02ade9f65aa94e0 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 17:31:28 +0100 Subject: [PATCH 52/55] mixing test --- src/test/test.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/test.cpp b/src/test/test.cpp index 81432182b..f0801dbb9 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -820,11 +820,9 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { uart_telegram({0xA0, 0x00, 0xFF, 0x00, 0x01, 0x55, 0x00, 0x1A}); shell.invoke_command("show"); - shell.invoke_command("call"); shell.invoke_command("call mixer info"); - shell.invoke_command("publish"); + shell.invoke_command("call system publish"); shell.invoke_command("show mqtt"); - shell.invoke_command("call mixer"); } } From bcac102bbdee4ff7a25cd7b29f231a300e725430 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 17:33:13 +0100 Subject: [PATCH 53/55] fix HA config for Mixing, #602 --- src/devices/mixer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/devices/mixer.cpp b/src/devices/mixer.cpp index 41c636c51..b399c9ffa 100644 --- a/src/devices/mixer.cpp +++ b/src/devices/mixer.cpp @@ -164,7 +164,7 @@ void Mixer::register_mqtt_ha_config() { } // Create the Master device - StaticJsonDocument doc; + StaticJsonDocument doc; char name[20]; snprintf_P(name, sizeof(name), PSTR("Mixer %02X"), device_id() - 0x20 + 1); @@ -192,7 +192,7 @@ void Mixer::register_mqtt_ha_config() { std::string topic(100, '\0'); if (this->type() == Type::HC) { - snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/climate/ems-esp/mixer_hc%d/config"), hc_); + snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/sensor/ems-esp/mixer_hc%d/config"), hc_); Mqtt::publish_retain(topic, doc.as(), true); // publish the config payload with retain flag char hc_name[10]; snprintf_P(hc_name, sizeof(hc_name), PSTR("hc%d"), hc_); @@ -202,7 +202,7 @@ void Mixer::register_mqtt_ha_config() { Mqtt::register_mqtt_ha_sensor(hc_name, nullptr, F_(valveStatus), this->device_type(), "valveStatus", nullptr, nullptr); } else { // WWC - snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/climate/ems-esp/mixer_wwc%d/config"), hc_); + snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/sensor/ems-esp/mixer_wwc%d/config"), hc_); Mqtt::publish_retain(topic, doc.as(), true); // publish the config payload with retain flag char wwc_name[10]; snprintf_P(wwc_name, sizeof(wwc_name), PSTR("wwc%d"), hc_); From 74012964ab579df4efd4ed2766c9092505f50f54 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 17:34:18 +0100 Subject: [PATCH 54/55] mixing name fixed in HA --- CHANGELOG_LATEST.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 927d66944..025954be5 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -8,6 +8,7 @@ ### Fixed - mixer IPM pumpstatus +- Mixing devices in HA were incorrectly named ### Changed - optimized MQTT for HA to reduce mem fragmentation issues From 956dda87ec624a9eb77b248ae3eaf76ddf1ea0a5 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 14 Nov 2020 22:10:06 +0100 Subject: [PATCH 55/55] added test command (console&web), to simulate adding devices. still experimental --- makefile | 2 +- platformio.ini | 1 + src/console.cpp | 24 ++-- src/locale_EN.h | 1 + src/system.cpp | 23 +++- src/system.h | 4 + src/test/test.cpp | 277 +++++++++++++++++++++++----------------------- src/test/test.h | 5 +- 8 files changed, 181 insertions(+), 156 deletions(-) diff --git a/makefile b/makefile index af6c3082b..c7e1da373 100644 --- a/makefile +++ b/makefile @@ -26,7 +26,7 @@ CXX_STANDARD := -std=c++11 #---------------------------------------------------------------------- # Defined Symbols #---------------------------------------------------------------------- -DEFINES += -DARDUINOJSON_ENABLE_STD_STRING=1 -DARDUINOJSON_ENABLE_ARDUINO_STRING -DEMSESP_DEBUG -DEMSESP_STANDALONE +DEFINES += -DARDUINOJSON_ENABLE_STD_STRING=1 -DARDUINOJSON_ENABLE_ARDUINO_STRING -DEMSESP_DEBUG -DEMSESP_STANDALONE -DEMSESP_TEST #---------------------------------------------------------------------- # Sources & Files diff --git a/platformio.ini b/platformio.ini index a5d8af090..051069d01 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,6 +13,7 @@ extra_configs = debug_flags = ; -D EMSESP_DEBUG ; -D EMSESP_UART_DEBUG + ; -D EMSESP_TEST ; -D EMSESP_FORCE_SERIAL ; -D ENABLE_CORS diff --git a/src/console.cpp b/src/console.cpp index 4e39942dd..ef81ffc88 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -20,7 +20,9 @@ #include "emsesp.h" #include "version.h" +#if defined(EMSESP_TEST) #include "test/test.h" +#endif namespace emsesp { @@ -426,11 +428,7 @@ void EMSESPShell::add_console_commands() { return {}; }); - /* - * add all the submenu contexts... - */ - - // System + // System context menu commands->add_command(ShellContext::MAIN, CommandFlags::USER, flash_string_vector{F_(system)}, @@ -471,26 +469,22 @@ 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) +#if defined(EMSESP_TEST) EMSESPShell::commands->add_command(context, CommandFlags::USER, - flash_string_vector{F("test")}, + 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"); + Test::run_test_shell(shell, "default"); } else { - Test::run_test(shell, arguments.front()); + Test::run_test_shell(shell, arguments.front()); } }); - EMSESPShell::commands->add_command(context, - CommandFlags::USER, - flash_string_vector{F("t")}, - [](Shell & shell, const std::vector & arguments __attribute__((unused))) { - Test::run_test(shell, "default"); - }); #endif + + EMSESPShell::commands->add_command( context, CommandFlags::USER, diff --git a/src/locale_EN.h b/src/locale_EN.h index b7abe921e..128809a94 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -78,6 +78,7 @@ MAKE_PSTR_WORD(command) MAKE_PSTR_WORD(commands) MAKE_PSTR_WORD(info) MAKE_PSTR_WORD(report) +MAKE_PSTR_WORD(test) // devices MAKE_PSTR_WORD(boiler) diff --git a/src/system.cpp b/src/system.cpp index c89b4ca88..072426316 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -21,6 +21,10 @@ #include "version.h" // firmware version of EMS-ESP +#if defined(EMSESP_TEST) +#include "test/test.h" +#endif + namespace emsesp { uuid::log::Logger System::logger_{F_(system), uuid::log::Facility::KERN}; @@ -47,7 +51,12 @@ String System::syslog_host_; // send on/off to a gpio pin // value: true = HIGH, false = LOW +// http://ems-esp/api?device=system&cmd=pin&data=1&id=2 bool System::command_pin(const char * value, const int8_t id) { + if (id < 0) { + return false; + } + bool v = false; if (Helpers::value2bool(value, v)) { pinMode(id, OUTPUT); @@ -191,6 +200,10 @@ void System::start() { Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(fetch), System::command_fetch); Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info); Command::add_with_json(EMSdevice::DeviceType::SYSTEM, F_(report), System::command_report); + +#if defined(EMSESP_TEST) + Command::add(EMSdevice::DeviceType::SYSTEM, settings.ems_bus_id, F_(test), System::command_test); +#endif }); @@ -274,7 +287,6 @@ void System::loop() { #endif #endif - } void System::show_mem(const char * note) { @@ -1073,4 +1085,13 @@ bool System::command_report(const char * value, const int8_t id, JsonObject & js return true; } +#if defined(EMSESP_TEST) +// run a test +// e.g. http://ems-esp/api?device=system&cmd=test&data=boiler +bool System::command_test(const char * value, const int8_t id) { + Test::run_test(value, id); + return true; +} +#endif + } // namespace emsesp diff --git a/src/system.h b/src/system.h index 0af8a8aae..7a5caad02 100644 --- a/src/system.h +++ b/src/system.h @@ -55,6 +55,10 @@ class System { static bool command_info(const char * value, const int8_t id, JsonObject & json); static bool command_report(const char * value, const int8_t id, JsonObject & json); +#if defined(EMSESP_TEST) + static bool command_test(const char * value, const int8_t id); +#endif + static uint8_t free_mem(); static void upload_status(bool in_progress); static bool upload_status(); diff --git a/src/test/test.cpp b/src/test/test.cpp index f0801dbb9..c1bce5695 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -17,24 +17,140 @@ * along with this program. If not, see . */ -#if defined(EMSESP_DEBUG) +#if defined(EMSESP_TEST) #include "test.h" +// create some fake test data + namespace emsesp { -// create some fake test data +// no shell +void Test::run_test(const char * command, int8_t id) { + if ((command == nullptr) || (strlen(command) == 0)) { + return; + } + + if (strcmp(command, "general") == 0) { + EMSESP::logger().info(F("Testing general...")); + + add_device(0x08, 123); // Nefit Trendline + add_device(0x18, 157); // Bosch CR100 + + // 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}); + + // Boiler -> Thermostat, UBAParameterWW(0x33), telegram: 08 97 33 00 23 24 (#data=2) + uart_telegram({0x08, 0x98, 0x33, 0x00, 0x23, 0x24}); + + // 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}); + + // 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}); + + return; + } + + if (strcmp(command, "gateway") == 0) { + EMSESP::logger().info(F("Testing gateway...")); + + // add 0x48 KM200, via a version command + rx_telegram({0x48, 0x0B, 0x02, 0x00, 0xBD, 0x04, 0x06, 00, 00, 00, 00, 00, 00, 00}); + + // Boiler(0x08) -> All(0x00), UBADevices(0x07), data: 09 01 00 00 00 00 00 00 01 00 00 00 00 + // check: make sure 0x48 is not detected again ! + rx_telegram({0x08, 0x00, 0x07, 0x00, 0x09, 01, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00, 00}); + + // add thermostat - Thermostat: RC300/RC310/Moduline 3000/CW400/Sense II (DeviceID:0x10, ProductID:158, Version:03.03) ** master device ** + add_device(0x10, 158); // Nefit Trendline + + // simulate incoming telegram + // Thermostat(0x10) -> 48(0x48), ?(0x26B), data: 6B 08 4F 00 00 00 02 00 00 00 02 00 03 00 03 00 03 + rx_telegram({0x10, 0x48, 0xFF, 00, 01, 0x6B, 00, 0x6B, 0x08, 0x4F, 00, 00, 00, 02, 00, 00, 00, 02, 00, 03, 00, 03, 00, 03}); + + return; + } + + if (strcmp(command, "boiler") == 0) { + // EMSESP::logger().info(F("Testing boiler...")); + add_device(0x08, 123); // Nefit Trendline + + // UBAuptime + uart_telegram({0x08, 0x0B, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70}); + + return; + } + + if (strcmp(command, "thermostat") == 0) { + EMSESP::logger().info(F("Testing thermostat...")); + add_device(0x10, 192); // FW120 + + // HC1 + uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x6F, 0x00, 0xCF, 0x21, 0x2E, 0x20, 0x00, 0x2E, 0x24, + 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); + + // HC2 + uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x70, 0x00, 0xCF, 0x22, 0x2F, 0x10, 0x00, 0x2E, 0x24, + 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); + + // HC3 + uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + + return; + } + + if (strcmp(command, "solar") == 0) { + EMSESP::logger().info(F("Testing solar...")); + EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); + + add_device(0x30, 163); // SM100 + + // 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, 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}); + + EMSESP::send_raw_telegram("B0 00 FF 18 02 62 80 00 B8"); + + return; + } + + if (strcmp(command, "heatpump") == 0) { + EMSESP::logger().info(F("Testing heatpump...")); + EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); + add_device(0x38, 200); // Enviline module + add_device(0x10, 192); // FW120 thermostat + + uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x6F, 0x00, 0xCF, 0x21, 0x2E, 0x20, 0x00, 0x2E, 0x24, + 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); // HC1 + + uart_telegram("38 0B FF 00 03 7B 0C 34 00 74"); + + return; + } +} + // used with the 'test' command, under su/admin -void Test::run_test(uuid::console::Shell & shell, const std::string & command) { +void Test::run_test_shell(uuid::console::Shell & shell, const std::string & command) { // switch to su shell.add_flags(CommandFlags::ADMIN); - if (command == "default") { - run_test(shell, "general"); // add the default test case here - } - - if (command.empty()) { - run_test(shell, "default"); + if ((command == "default") || (command == "general") || (command.empty())) { + shell.printfln(F("Testing adding a general boiler & thermostat...")); + run_test("general"); + shell.invoke_command("show devices"); + shell.invoke_command("show"); + shell.invoke_command("call system publish"); + shell.invoke_command("show mqtt"); } if (command == "render") { @@ -139,8 +255,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); // this is important otherwise nothing will be picked up! - //emsdevices.push_back(EMSFactory::add(EMSdevice::DeviceType::BOILER, EMSdevice::EMS_DEVICE_ID_BOILER, 0, "", "My Boiler", 0, 0)); - // A fake response - UBADevices(0x07) rx_telegram({0x08, 0x00, 0x07, 0x00, 0x0B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); } @@ -160,9 +274,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { if (command == "unknown") { shell.printfln(F("Testing unknown...")); - // question: do we need to set the mask? - std::string version("1.2.3"); - // add boiler add_device(0x08, 84); @@ -186,20 +297,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { if (command == "gateway") { shell.printfln(F("Testing Gateway...")); - - // add 0x48 KM200, via a version command - rx_telegram({0x48, 0x0B, 0x02, 0x00, 0xBD, 0x04, 0x06, 00, 00, 00, 00, 00, 00, 00}); - - // Boiler(0x08) -> All(0x00), UBADevices(0x07), data: 09 01 00 00 00 00 00 00 01 00 00 00 00 - // check: make sure 0x48 is not detected again ! - rx_telegram({0x08, 0x00, 0x07, 0x00, 0x09, 01, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00, 00}); - - // add thermostat - Thermostat: RC300/RC310/Moduline 3000/CW400/Sense II (DeviceID:0x10, ProductID:158, Version:03.03) ** master device ** - add_device(0x10, 158); // Nefit Trendline - - // simulate incoming telegram - // Thermostat(0x10) -> 48(0x48), ?(0x26B), data: 6B 08 4F 00 00 00 02 00 00 00 02 00 03 00 03 00 03 - rx_telegram({0x10, 0x48, 0xFF, 00, 01, 0x6B, 00, 0x6B, 0x08, 0x4F, 00, 00, 00, 02, 00, 00, 00, 02, 00, 03, 00, 03, 00, 03}); + run_test("gateway"); } if (command == "web") { @@ -227,8 +325,9 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { uart_telegram({0x98, 0x00, 0x06, 0x00, 0x00, 0x03, 0x04, 0x0C, 0x02, 0x33, 0x06, 00, 00, 00, 00, 00, 00}); shell.invoke_command("show"); - StaticJsonDocument<2000> doc; - JsonObject root = doc.to(); + + StaticJsonDocument<500> doc; + JsonObject root = doc.to(); EMSESP::device_info_web(2, root); // show thermostat. use 1 for boiler serializeJsonPretty(doc, shell); shell.println(); @@ -236,48 +335,15 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { if (command == "boiler") { shell.printfln(F("Testing boiler...")); - - add_device(0x08, 123); // Nefit Trendline - - // UBAuptime - uart_telegram({0x08, 0x0B, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70}); - + run_test("boiler"); shell.invoke_command("show"); shell.invoke_command("call boiler info"); } - if (command == "general") { - shell.printfln(F("Testing adding a general boiler & thermostat...")); - - add_device(0x08, 123); // Nefit Trendline - add_device(0x18, 157); // Bosch CR100 - - // 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}); - - // Boiler -> Thermostat, UBAParameterWW(0x33), telegram: 08 97 33 00 23 24 (#data=2) - uart_telegram({0x08, 0x98, 0x33, 0x00, 0x23, 0x24}); - - // 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}); - - // 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}); - - shell.invoke_command("show devices"); - shell.invoke_command("show"); - shell.invoke_command("call system publish"); - shell.invoke_command("show mqtt"); - } - if (command == "fr120") { shell.printfln(F("Testing adding a thermostat FR120...")); - // add a thermostat - add_device(0x10, 191); // FR120 + add_device(0x10, 191); // FR120 thermostat // HC1 uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x6F, 0x00, 0xCF, 0x21, 0x2E, 0x20, 0x00, 0x2E, 0x24, @@ -289,23 +355,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { if (command == "thermostat") { shell.printfln(F("Testing adding a thermostat FW120...")); - - // add a thermostat - add_device(0x10, 192); // FW120 - - // HC1 - uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x6F, 0x00, 0xCF, 0x21, 0x2E, 0x20, 0x00, 0x2E, 0x24, - 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); - - // HC2 - uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x70, 0x00, 0xCF, 0x22, 0x2F, 0x10, 0x00, 0x2E, 0x24, - 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); - - // HC3 - uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); - + run_test("thermostat"); shell.invoke_command("show"); - EMSESP::mqtt_.incoming("ems-esp/thermostat_hc1", "heat"); EMSESP::mqtt_.incoming("ems-esp/thermostat_hc2", "28.8"); EMSESP::mqtt_.incoming("ems-esp/thermostat", "{\"cmd\":\"temp\",\"id\":2,\"data\":22}"); @@ -324,50 +375,19 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { if (command == "solar") { shell.printfln(F("Testing Solar")); - - EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); - - add_device(0x30, 163); // SM100 - - // 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, 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}); - - EMSESP::send_raw_telegram("B0 00 FF 18 02 62 80 00 B8"); - + run_test("solar"); uart_telegram("30 00 FF 0A 02 6A 04"); // SM100 pump on 1 uart_telegram("30 00 FF 00 02 64 00 00 00 04 00 00 FF 00 00 1E 0B 09 64 00 00 00 00"); // SM100 modulation EMSESP::show_device_values(shell); - uart_telegram("30 00 FF 0A 02 6A 03"); // SM100 pump off 0 EMSESP::show_device_values(shell); } if (command == "heatpump") { shell.printfln(F("Testing Heat Pump")); - - EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); - - // add heatpump - add_device(0x38, 200); // Enviline module - - // add a thermostat - add_device(0x10, 192); // FW120 - - uart_telegram({0x90, 0x00, 0xFF, 0x00, 0x00, 0x6F, 0x00, 0xCF, 0x21, 0x2E, 0x20, 0x00, 0x2E, 0x24, - 0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03}); // HC1 - - uart_telegram("38 0B FF 00 03 7B 0C 34 00 74"); + run_test("heatpump"); shell.invoke_command("call"); shell.invoke_command("call heatpump info"); - - EMSESP::show_device_values(shell); } if (command == "solar200") { @@ -381,25 +401,20 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { // 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}); - EMSESP::show_device_values(shell); 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}); - EMSESP::show_device_values(shell); rx_telegram({0xB0, 00, 0xFF, 0x18, 02, 0x62, 0x80, 00, 0xB8}); - EMSESP::show_device_values(shell); EMSESP::send_raw_telegram("B0 00 FF 18 02 62 80 00 B8"); uart_telegram("30 00 FF 0A 02 6A 04"); // SM100 pump on 1 uart_telegram("30 00 FF 00 02 64 00 00 00 04 00 00 FF 00 00 1E 0B 09 64 00 00 00 00"); // SM100 modulation - EMSESP::show_device_values(shell); - uart_telegram("30 00 FF 0A 02 6A 03"); // SM100 pump off 0 - EMSESP::show_device_values(shell); + shell.invoke_command("show"); } if (command == "km") { @@ -558,12 +573,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { 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}); } - if (command == "send") { - shell.printfln(F("Sending to Tx...")); - EMSESP::show_ems(shell); - EMSESP::txservice_.send(); // send it to UART - } - if (command == "tx") { shell.printfln(F("Testing Tx...")); @@ -602,8 +611,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { EMSESP::txservice_.send(); // send it to UART } - shell.loop_all(); - EMSESP::txservice_.flush_tx_queue(); } @@ -654,9 +661,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { shell.invoke_command("call"); shell.invoke_command("call system info"); - char system_topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; - strcpy(system_topic, "ems-esp/system"); - EMSESP::mqtt_.incoming(system_topic, "{\"cmd\":\"info\"}"); // this should fail + EMSESP::mqtt_.incoming("ems-esp/system", "{\"cmd\":\"info\"}"); // this should fail shell.invoke_command("call thermostat wwmode"); // should do nothing shell.invoke_command("call thermostat mode auto 2"); // should error, no hc2 @@ -665,8 +670,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { if (command == "pin") { shell.printfln(F("Testing pin...")); - - shell.invoke_command("su"); shell.invoke_command("call system pin"); shell.invoke_command("call system pin 1 true"); } @@ -819,10 +822,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & command) { // check for error "No telegram type handler found for ID 0x255 (src 0x20)" uart_telegram({0xA0, 0x00, 0xFF, 0x00, 0x01, 0x55, 0x00, 0x1A}); - shell.invoke_command("show"); - shell.invoke_command("call mixer info"); - shell.invoke_command("call system publish"); - shell.invoke_command("show mqtt"); + // shell.invoke_command("show"); + // shell.invoke_command("call mixer info"); + // shell.invoke_command("call system publish"); + // shell.invoke_command("show mqtt"); } } diff --git a/src/test/test.h b/src/test/test.h index 4dcb75e41..90529ba38 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -#if defined(EMSESP_DEBUG) +#if defined(EMSESP_TEST) #ifndef EMSESP_TEST_H #define EMSESP_TEST_H @@ -40,7 +40,8 @@ namespace emsesp { class Test { public: - static void run_test(uuid::console::Shell & shell, const std::string & command); + static void run_test_shell(uuid::console::Shell & shell, const std::string & command); + static void run_test(const char * command, int8_t id = 0); static void dummy_mqtt_commands(const char * message); static void rx_telegram(const std::vector & data); static void uart_telegram(const std::vector & rx_data);