From b64c392c586b4ba07cf1e9d3455296177ff363ab Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 9 Jan 2026 17:21:26 +0100 Subject: [PATCH 1/4] rename uom::HZ to HERTZ, avoids compile error on ESP32C3 --- interface/src/app/main/types.ts | 2 +- src/core/emsdevicevalue.h | 2 +- src/core/mqtt.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/app/main/types.ts b/interface/src/app/main/types.ts index 67b88d10e..492ccc532 100644 --- a/interface/src/app/main/types.ts +++ b/interface/src/app/main/types.ts @@ -196,7 +196,7 @@ export enum DeviceValueUOM { MBAR, LH, CTKWH, - HZ + HERTZ } export const DeviceValueUOM_s = [ diff --git a/src/core/emsdevicevalue.h b/src/core/emsdevicevalue.h index 04d28809c..01eb461c2 100644 --- a/src/core/emsdevicevalue.h +++ b/src/core/emsdevicevalue.h @@ -76,7 +76,7 @@ class DeviceValue { MBAR, // 24 - mbar - atmospheric pressure LH, // 25 - l/h - volume flow rate CTKWH, // 26 - ct/kWh - monetary - HZ, // 27 - Hz - frequency + HERTZ, // 27 - Hz - frequency CONNECTIVITY // 28 - used in HA - connectivity }; diff --git a/src/core/mqtt.cpp b/src/core/mqtt.cpp index 03d9b2eb5..2e43c2f6b 100644 --- a/src/core/mqtt.cpp +++ b/src/core/mqtt.cpp @@ -1268,7 +1268,7 @@ void Mqtt::add_ha_classes(JsonObject doc, const uint8_t device_type, const uint8 doc[sc_ha] = sc_ha_total_increasing; doc[dc_ha] = "monetary"; break; - case DeviceValueUOM::HZ: + case DeviceValueUOM::HERTZ: doc[sc_ha] = sc_ha_measurement; doc[dc_ha] = "frequency"; break; From fb77b455be3c20c272cda9b270eb59c65d3b2653 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 9 Jan 2026 17:21:44 +0100 Subject: [PATCH 2/4] testdata without decimals --- test/test_api/test_api.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/test_api/test_api.h b/test/test_api/test_api.h index 9d07e4f34..fcd00d560 100644 --- a/test/test_api/test_api.h +++ b/test/test_api/test_api.h @@ -5,10 +5,10 @@ void test_1() { "[{\"reset\":\"\",\"chimneysweeper\":\"\",\"heatingoff\":\"off\",\"heatingactive\":\"off\",\"tapwateractive\":\"on\",\"selflowtemp\":0,\"curflowtemp\":" "60.2,\"rettemp\":48.1,\"syspress\":1.4,\"burngas\":\"on\",\"burngas2\":\"off\",\"flamecurr\":37.4,\"fanwork\":\"on\",\"ignwork\":\"off\"," "\"oilpreheat\":\"off\",\"heatingpump\":\"on\",\"selburnpow\":115,\"curburnpow\":61,\"ubauptime\":3940268,\"servicecode\":\"=H\",\"servicecodenumber\":" - "201,\"nompower\":0,\"nrgtotal\":0.0,\"nrgheat\":0.0,\"dhw\":{\"seltemp\":52,\"comfort\":\"hot\",\"flowtempoffset\":40,\"chargeoptimization\":\"off\"," + "201,\"nompower\":0,\"nrgtotal\":0,\"nrgheat\":0,\"dhw\":{\"seltemp\":52,\"comfort\":\"hot\",\"flowtempoffset\":40,\"chargeoptimization\":\"off\"," "\"circpump\":\"off\",\"chargetype\":\"3-way " "valve\",\"hyston\":-5,\"disinfectiontemp\":70,\"circmode\":\"off\",\"circ\":\"off\",\"storagetemp1\":53.8,\"activated\":\"on\",\"3wayvalve\":\"on\"," - "\"chargepump\":\"off\",\"nrg\":0.0}}]"; + "\"chargepump\":\"off\",\"nrg\":0}}]"; TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/boiler")); } @@ -42,10 +42,10 @@ void test_3() { "[{\"reset\":\"\",\"chimneysweeper\":\"\",\"heatingoff\":\"off\",\"heatingactive\":\"off\",\"tapwateractive\":\"on\",\"selflowtemp\":0,\"curflowtemp\":" "60.2,\"rettemp\":48.1,\"syspress\":1.4,\"burngas\":\"on\",\"burngas2\":\"off\",\"flamecurr\":37.4,\"fanwork\":\"on\",\"ignwork\":\"off\"," "\"oilpreheat\":\"off\",\"heatingpump\":\"on\",\"selburnpow\":115,\"curburnpow\":61,\"ubauptime\":3940268,\"servicecode\":\"=H\",\"servicecodenumber\":" - "201,\"nompower\":0,\"nrgtotal\":0.0,\"nrgheat\":0.0,\"dhw\":{\"seltemp\":52,\"comfort\":\"hot\",\"flowtempoffset\":40,\"chargeoptimization\":\"off\"," + "201,\"nompower\":0,\"nrgtotal\":0,\"nrgheat\":0,\"dhw\":{\"seltemp\":52,\"comfort\":\"hot\",\"flowtempoffset\":40,\"chargeoptimization\":\"off\"," "\"circpump\":\"off\",\"chargetype\":\"3-way " "valve\",\"hyston\":-5,\"disinfectiontemp\":70,\"circmode\":\"off\",\"circ\":\"off\",\"storagetemp1\":53.8,\"activated\":\"on\",\"3wayvalve\":\"on\"," - "\"chargepump\":\"off\",\"nrg\":0.0}}]"; + "\"chargepump\":\"off\",\"nrg\":0}}]"; TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/boiler/values")); } @@ -62,7 +62,7 @@ void test_4() { "type (chargetype)\":\"3-way valve\",\"dhw hysteresis on temperature (hyston)\":-5,\"dhw disinfection temperature (disinfectiontemp)\":70,\"dhw " "circulation pump mode (circmode)\":\"off\",\"dhw circulation active (circ)\":\"off\",\"dhw storage intern temperature (storagetemp1)\":53.8,\"dhw " "activated (activated)\":\"on\",\"dhw 3-way valve active (3wayvalve)\":\"on\",\"dhw charge pump (chargepump)\":\"off\",\"nominal Power " - "(nompower)\":0,\"total energy (nrgtotal)\":0.0,\"energy heating (nrgheat)\":0.0,\"dhw energy (nrg)\":0.0}]"; + "(nompower)\":0,\"total energy (nrgtotal)\":0,\"energy heating (nrgheat)\":0,\"dhw energy (nrg)\":0}]"; TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/boiler/info")); } @@ -150,7 +150,7 @@ void test_12() { void test_13() { auto expected_response = "[{\"hc1\":{\"seltemp\":20.5,\"currtemp\":22.8,\"haclimate\":\"roomTemp\",\"modetype\":\"heat\",\"remotetemp\":null},\"hc2\":{" "\"seltemp\":20.6,\"currtemp\":22.9,\"haclimate\":\"roomTemp\",\"modetype\":\"eco\",\"remotetemp\":null},\"hc3\":{\"seltemp\":20." - "7,\"currtemp\":23.0,\"haclimate\":\"roomTemp\",\"modetype\":\"nofrost\",\"remotetemp\":null},\"dhw\":{}}]"; + "7,\"currtemp\":23,\"haclimate\":\"roomTemp\",\"modetype\":\"nofrost\",\"remotetemp\":null},\"dhw\":{}}]"; TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/thermostat")); } @@ -187,12 +187,12 @@ void test_17() { } void test_18() { - auto expected_response = "[{\"test_custom\":0.00,\"test_read_only\":70.00,\"test_ram\":\"14\",\"test_seltemp\":\"14\"}]"; + auto expected_response = "[{\"test_custom\":0,\"test_read_only\":70,\"test_ram\":\"14\",\"test_seltemp\":\"14\"}]"; TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/custom")); } void test_19() { - auto expected_response = "[{\"test_custom\":0.00,\"test_read_only\":70.00,\"test_ram\":\"14\",\"test_seltemp\":\"14\"}]"; + auto expected_response = "[{\"test_custom\":0,\"test_read_only\":70,\"test_ram\":\"14\",\"test_seltemp\":\"14\"}]"; TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/custom/info")); } @@ -210,7 +210,7 @@ void test_21() { void test_22() { auto expected_response = "[{\"name\":\"test_custom\",\"fullname\":\"test_custom\",\"storage\":\"ems\",\"type\":\"number\",\"readable\":true,\"writeable\":" "true,\"visible\":true,\"device_id\":\"0x08\",\"type_id\":\"0x18\",\"offset\":0,\"factor\":1,\"ent_cat\":\"diagnostic\",\"uom\":" - "\"°C\",\"state_class\":\"measurement\",\"device_class\":\"temperature\",\"value\":0.00}]"; + "\"°C\",\"state_class\":\"measurement\",\"device_class\":\"temperature\",\"value\":0}]"; TEST_ASSERT_EQUAL_STRING(expected_response, call_url("/api/custom/test_custom")); } From debe90eb8de1cbb2400e716fdb25a7bd1efb2cb2 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 9 Jan 2026 18:57:25 +0100 Subject: [PATCH 3/4] formatting, update gpios for C3, S2 --- src/core/system.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/core/system.cpp b/src/core/system.cpp index 62972bc55..56feb57fa 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -2399,21 +2399,21 @@ bool System::load_board_profile(std::vector & data, const std::string & if (board_profile == "default") { return false; // unknown, return false } else if (board_profile == "S32") { - data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0, 0}; // BBQKees Gateway S32 + data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0, 0}; // BBQKees Gateway S32 valid_system_gpios_ = {0, 2, 5, 18, 23}; } else if (board_profile == "E32") { - data = {2, 4, 5, 17, 33, PHY_type::PHY_TYPE_LAN8720, 16, 1, 0, 0}; // BBQKees Gateway E32 + data = {2, 4, 5, 17, 33, PHY_type::PHY_TYPE_LAN8720, 16, 1, 0, 0}; // BBQKees Gateway E32 valid_system_gpios_ = {0, 2, 4, 5, 16, 17, 33}; } else if (board_profile == "E32V2") { - data = {2, 14, 4, 5, 34, PHY_type::PHY_TYPE_LAN8720, 15, 0, 1, 0}; // BBQKees Gateway E32 V2 + data = {2, 14, 4, 5, 34, PHY_type::PHY_TYPE_LAN8720, 15, 0, 1, 0}; // BBQKees Gateway E32 V2 valid_system_gpios_ = {0, 2, 4, 5, 14, 15, 34}; } else if (board_profile == "E32V2_2") { - data = {32, 14, 4, 5, 34, PHY_type::PHY_TYPE_LAN8720, 15, 0, 1, 1}; // BBQKees Gateway E32 V2.2, rgb led - valid_system_gpios_ = {0, 2, 4, 5, 14, 15, 32, 34, 36, 39}; // system analogs 36, 39, led 2 + data = {32, 14, 4, 5, 34, PHY_type::PHY_TYPE_LAN8720, 15, 0, 1, 1}; // BBQKees Gateway E32 V2.2, rgb led + valid_system_gpios_ = {0, 2, 4, 5, 14, 15, 32, 34, 36, 39}; // system analogs 36, 39, led 2 } else if (board_profile == "MH-ET") { data = {2, 18, 23, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0, 0}; // MH-ET Live D1 Mini // allow only pins that are marked as `can always be used` - valid_system_gpios_ = {0, 2, 5, 18, 23, 12 ,13, 14, 15, 16, 17, 26, 27, 33}; + valid_system_gpios_ = {0, 2, 5, 18, 23, 12, 13, 14, 15, 16, 17, 26, 27, 33}; // can always be used: 12, 13 ,14, 15, 16, 17, 26, 27, 33 // can be used if no other function 2, 4, 5, 9, 10, 18, 19, 21, 22, 23, 25, 34, 35, 36, 39 } else if (board_profile == "NODEMCU") { @@ -2442,12 +2442,16 @@ bool System::load_board_profile(std::vector & data, const std::string & #else data = {7, 1, 4, 5, 9, PHY_type::PHY_TYPE_NONE, 0, 0, 0, 1}; // Lolin C3 Mini with RGB Led #endif + // https://www.wemos.cc/en/latest/c3/c3_mini.html + valid_system_gpios_ = {0, 1, 3, 4, 5, 6, 7, 9, 10, 20, 21}; } else if (board_profile == "S2MINI") { data = {15, 7, 11, 12, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0, 0}; // Lolin S2 Mini + // https://www.wemos.cc/en/latest/s2/s2_mini.html } else if (board_profile == "S3MINI") { data = {17, 18, 8, 5, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0, 0}; // Liligo S3 + // https://lilygo.cc/products/t7-s3 } else if (board_profile == "S32S3") { - data = {2, 18, 5, 17, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0, 0}; // BBQKees Gateway S3 + data = {2, 18, 5, 17, 0, PHY_type::PHY_TYPE_NONE, 0, 0, 0, 0}; // BBQKees Gateway S3 valid_system_gpios_ = {0, 2, 5, 17, 18}; } else { return false; // unknown, return false @@ -2924,8 +2928,9 @@ void System::set_valid_system_gpios() { // GPIO18 - GPIO19 = USB-JTAG // // notes on what is allowed: - // GPIO10 = button on BOARD_C3_MINI_V1 - valid_system_gpios_ = string_range_to_vector("0-21", "2, 8-9, 12-17, 18-19"); + // GPIO09 = button on BOARD_C3_MINI_V1 + // GPIO20 - GPIO21 = UART0, , no chip connected because native USB + valid_system_gpios_ = string_range_to_vector("0-21", "2, 8, 12-17, 18-19"); #elif CONFIG_IDF_TARGET_ESP32S2 // https://docs.espressif.com/projects/esp-idf/en/stable/esp32s2/api-reference/peripherals/gpio.html @@ -2934,9 +2939,11 @@ void System::set_valid_system_gpios() { // GPIO45 - GPIO46 = strapping pins // GPIO39 - GPIO42 = USB-JTAG // GPIO22 - GPIO25 = don't exist + // GPIO19 - GPIO20 = USB // // notes on what is allowed: - valid_system_gpios_ = string_range_to_vector("0-46", "26-32, 45-46, 39-42, 22-25"); + // GPIO43, GPIO44 = UART0, no chip connected because native USB + valid_system_gpios_ = string_range_to_vector("0-46", "19, 20, 26-32, 45-46, 39-42, 22-25"); #elif CONFIG_IDF_TARGET_ESP32S3 // https://docs.espressif.com/projects/esp-idf/en/stable/esp32s3/api-reference/peripherals/gpio.html From 12ce7365801e7e682d75a9b4b8d035488ae4abc8 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 9 Jan 2026 21:03:23 +0100 Subject: [PATCH 4/4] remove eth fixed pins --- src/web/WebSettingsService.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 1de3875fb..f5dc9d831 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -133,6 +133,13 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { // remove the ethernet pins from valid list, regardless of whether the GPIOs are valid or not EMSESP::system_.remove_gpio(23, true); // MDC EMSESP::system_.remove_gpio(18, true); // MDIO + EMSESP::system_.remove_gpio(19, true); // TXD0 + EMSESP::system_.remove_gpio(22, true); // TXD1 + EMSESP::system_.remove_gpio(21, true); // TXEN + EMSESP::system_.remove_gpio(25, true); // RXD0 + EMSESP::system_.remove_gpio(26, true); // RXD1 + EMSESP::system_.remove_gpio(27, true); // CRS + if (settings.eth_clock_mode < 2) { EMSESP::system_.remove_gpio(0, true); // ETH.clock input } else if (settings.eth_clock_mode == 2) {