diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 26f804142..680ffd317 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -63,15 +63,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_telegram_type(0x16, F("UBAParameters"), true, std::bind(&Boiler::process_UBAParameters, this, _1)); register_telegram_type(0x1A, F("UBASetPoints"), false, std::bind(&Boiler::process_UBASetPoints, this, _1)); register_telegram_type(0xD1, F("UBAOutdoorTemp"), false, std::bind(&Boiler::process_UBAOutdoorTemp, this, _1)); + register_telegram_type(0xE3, F("UBAMonitorSlowPlus"), false, std::bind(&Boiler::process_UBAMonitorSlowPlus2, this, _1)); register_telegram_type(0xE4, F("UBAMonitorFastPlus"), false, std::bind(&Boiler::process_UBAMonitorFastPlus, this, _1)); register_telegram_type(0xE5, F("UBAMonitorSlowPlus"), false, std::bind(&Boiler::process_UBAMonitorSlowPlus, this, _1)); register_telegram_type(0xE9, F("UBADHWStatus"), false, std::bind(&Boiler::process_UBADHWStatus, this, _1)); - // HeatPump specific - register_telegram_type(0xE3, F("HeatPumpMonitor1"), false, std::bind(&Boiler::process_HPMonitor1, this, _1)); - register_telegram_type(0xE5, F("HeatPumpMonitor2"), false, std::bind(&Boiler::process_HPMonitor2, this, _1)); - // MQTT callbacks register_mqtt_topic("boiler_cmd", std::bind(&Boiler::boiler_cmd, this, _1)); register_mqtt_topic("boiler_cmd_wwactivated", std::bind(&Boiler::boiler_cmd_wwactivated, this, _1)); @@ -195,6 +192,9 @@ void Boiler::publish_values() { if (Helpers::hasValue(pumpMod_)) { doc["pumpMod"] = pumpMod_; } + if (Helpers::hasValue(pumpMod2_)) { + doc["pumpMod2"] = pumpMod2_; + } if (Helpers::hasValue(wWCircPump_, true)) { doc["wWCircPump"] = Helpers::render_value(s, wWCircPump_, EMS_VALUE_BOOL); } @@ -312,15 +312,6 @@ void Boiler::publish_values() { doc["serviceCodeNumber"] = serviceCode_; } - // heatpump specific - if (Helpers::hasValue(hpModulation_)) { - doc["pumpmodulation"] = hpModulation_; - } - - if (Helpers::hasValue(hpSpeed_)) { - doc["pumpspeed"] = hpSpeed_; - } - #ifdef EMSESP_DEBUG LOG_DEBUG(F("[DEBUG] Performing a boiler publish")); #endif @@ -340,21 +331,19 @@ bool Boiler::updated_values() { void Boiler::show_values(uuid::console::Shell & shell) { EMSdevice::show_values(shell); // for showing the header - char buffer[10]; // used for formatting - if (Helpers::hasValue(tap_water_active_, true)) { - print_value(shell, 2, F("Hot tap water"), tap_water_active_ ? "running" : "off"); + print_value(shell, 2, F("Hot tap water"), tap_water_active_ ? F("running") : F("off")); } if (Helpers::hasValue(heating_active_, true)) { - print_value(shell, 2, F("Central heating"), heating_active_ ? "active" : "off"); + print_value(shell, 2, F("Central heating"), heating_active_ ? F("active") : F("off")); } - print_value(shell, 2, F("Warm Water activated"), Helpers::render_value(buffer, wWActivated_, EMS_VALUE_BOOL)); - print_value(shell, 2, F("Warm Water charging type"), wWCircPumpType_ ? "3-way valve" : "charge pump"); - print_value(shell, 2, F("Warm Water circulation pump available"), Helpers::render_value(buffer, wWCircPump_, EMS_VALUE_BOOL)); + print_value(shell, 2, F("Warm Water activated"), wWActivated_, nullptr, EMS_VALUE_BOOL); + print_value(shell, 2, F("Warm Water charging type"), wWCircPumpType_ ? F("3-way valve") : F("charge pump")); + print_value(shell, 2, F("Warm Water circulation pump available"), wWCircPump_, nullptr, EMS_VALUE_BOOL); if (wWCircPumpMode_ == 7) { - print_value(shell, 2, F("Warm Water circulation pump freq"), "continuous"); + print_value(shell, 2, F("Warm Water circulation pump freq"), F("continuous")); } else { char s[7]; char buffer[2]; @@ -362,67 +351,67 @@ void Boiler::show_values(uuid::console::Shell & shell) { buffer[1] = '\0'; strlcpy(s, buffer, 7); strlcat(s, "x3min", 7); - print_value(shell, 2, F("Warm Water circulation pump freq"), s); + print_value(shell, 2, F("Warm Water circulation pump freq"), FPSTR(s)); // TODO check } - print_value(shell, 2, F("Warm Water circulation active"), Helpers::render_value(buffer, wWCirc_, EMS_VALUE_BOOL)); + print_value(shell, 2, F("Warm Water circulation active"), wWCirc_, nullptr, EMS_VALUE_BOOL); if (wWComfort_ == 0x00) { - print_value(shell, 2, F("Warm Water comfort setting"), "Hot"); + print_value(shell, 2, F("Warm Water comfort setting"), F("Hot")); } else if (wWComfort_ == 0xD8) { - print_value(shell, 2, F("Warm Water comfort setting"), "Eco"); + print_value(shell, 2, F("Warm Water comfort setting"), F("Eco")); } else if (wWComfort_ == 0xEC) { - print_value(shell, 2, F("Warm Water comfort setting"), "Intelligent"); + print_value(shell, 2, F("Warm Water comfort setting"), F("Intelligent")); } - print_value(shell, 2, F("Warm water mix temperature"), F_(degrees), Helpers::render_value(buffer, wwMixTemperature_, 10)); - print_value(shell, 2, F("Warm water buffer boiler temperature"), F_(degrees), Helpers::render_value(buffer, wwBufferBoilerTemperature_, 10)); - - print_value(shell, 2, F("Warm Water disinfection temperature"), F_(degrees), Helpers::render_value(buffer, wWDisinfectTemp_, 1)); - print_value(shell, 2, F("Warm Water selected temperature"), F_(degrees), Helpers::render_value(buffer, wWSelTemp_, 1)); - print_value(shell, 2, F("Warm Water set temperature"), F_(degrees), Helpers::render_value(buffer, wWSetTmp_, 1)); - print_value(shell, 2, F("Warm Water current temperature (intern)"), F_(degrees), Helpers::render_value(buffer, wWCurTmp_, 10)); - print_value(shell, 2, F("Warm water storage temperature (intern)"), F_(degrees), Helpers::render_value(buffer, wwStorageTemp1_, 10)); - print_value(shell, 2, F("Warm Water current temperature (extern)"), F_(degrees), Helpers::render_value(buffer, wWCurTmp2_, 10)); - print_value(shell, 2, F("Warm water storage temperature (extern)"), F_(degrees), Helpers::render_value(buffer, wwStorageTemp2_, 10)); - print_value(shell, 2, F("Warm Water current tap water flow"), F("l/min"), Helpers::render_value(buffer, wWCurFlow_, 10)); - print_value(shell, 2, F("Warm Water # starts"), Helpers::render_value(buffer, wWStarts_, 1)); + print_value(shell, 2, F("Warm water mix temperature"), wwMixTemperature_, F_(degrees), 10); + print_value(shell, 2, F("Warm water buffer boiler temperature"), wwBufferBoilerTemperature_, F_(degrees), 10); + print_value(shell, 2, F("Warm Water disinfection temperature"), wWDisinfectTemp_, F_(degrees), 1); + print_value(shell, 2, F("Warm Water selected temperature"), wWSelTemp_, F_(degrees), 1); + print_value(shell, 2, F("Warm Water set temperature"), wWSetTmp_, F_(degrees), 1); + print_value(shell, 2, F("Warm Water current temperature (intern)"), wWCurTmp_, F_(degrees), 10); + print_value(shell, 2, F("Warm water storage temperature (intern)"), wwStorageTemp1_, F_(degrees), 10); + print_value(shell, 2, F("Warm Water current temperature (extern)"), wWCurTmp2_, F_(degrees), 10); + print_value(shell, 2, F("Warm water storage temperature (extern)"), wwStorageTemp2_, F_(degrees), 10); + print_value(shell, 2, F("Warm Water current tap water flow"), wWCurFlow_, F("l/min"), 10); + print_value(shell, 2, F("Warm Water # starts"), wWStarts_, nullptr, 1); if (Helpers::hasValue(wWWorkM_)) { shell.printfln(F(" Warm Water active time: %d days %d hours %d minutes"), wWWorkM_ / 1440, (wWWorkM_ % 1440) / 60, wWWorkM_ % 60); } - print_value(shell, 2, F("Warm Water charging"), Helpers::render_value(buffer, wWHeat_, EMS_VALUE_BOOL)); - print_value(shell, 2, F("Warm Water disinfecting"), Helpers::render_value(buffer, wWDesinfecting_, EMS_VALUE_BOOL)); - print_value(shell, 2, F("Selected flow temperature"), F_(degrees), Helpers::render_value(buffer, selFlowTemp_, 1)); - print_value(shell, 2, F("Current flow temperature"), F_(degrees), Helpers::render_value(buffer, curFlowTemp_, 10)); - print_value(shell, 2, F("Max boiler temperature"), F_(degrees), Helpers::render_value(buffer, boilTemp_, 10)); - print_value(shell, 2, F("Return temperature"), F_(degrees), Helpers::render_value(buffer, retTemp_, 10)); - print_value(shell, 2, F("Gas"), Helpers::render_value(buffer, burnGas_, EMS_VALUE_BOOL)); - print_value(shell, 2, F("Boiler pump"), Helpers::render_value(buffer, heatPmp_, EMS_VALUE_BOOL)); - print_value(shell, 2, F("Fan"), Helpers::render_value(buffer, fanWork_, EMS_VALUE_BOOL)); - print_value(shell, 2, F("Ignition"), Helpers::render_value(buffer, ignWork_, EMS_VALUE_BOOL)); + print_value(shell, 2, F("Warm Water charging"), wWHeat_, nullptr, EMS_VALUE_BOOL); + print_value(shell, 2, F("Warm Water disinfecting"), wWDesinfecting_, nullptr, EMS_VALUE_BOOL); + print_value(shell, 2, F("Selected flow temperature"), selFlowTemp_, F_(degrees), 1); + print_value(shell, 2, F("Current flow temperature"), curFlowTemp_, F_(degrees), 10); + print_value(shell, 2, F("Max boiler temperature"), boilTemp_, F_(degrees), 10); + print_value(shell, 2, F("Return temperature"), retTemp_, F_(degrees), 10); + print_value(shell, 2, F("Gas"), burnGas_, nullptr, EMS_VALUE_BOOL); + print_value(shell, 2, F("Boiler pump"), heatPmp_, nullptr, EMS_VALUE_BOOL); + print_value(shell, 2, F("Fan"), fanWork_, nullptr, EMS_VALUE_BOOL); + print_value(shell, 2, F("Ignition"), ignWork_, nullptr, EMS_VALUE_BOOL); - print_value(shell, 2, F("Burner selected max power"), F_(percent), Helpers::render_value(buffer, selBurnPow_, 1)); - print_value(shell, 2, F("Burner current power"), F_(percent), Helpers::render_value(buffer, curBurnPow_, 1)); - print_value(shell, 2, F("Flame current"), F("uA"), Helpers::render_value(buffer, flameCurr_, 10)); - print_value(shell, 2, F("System pressure"), F("bar"), Helpers::render_value(buffer, sysPress_, 10)); + print_value(shell, 2, F("Burner selected max power"), selBurnPow_, F_(percent), 1); + print_value(shell, 2, F("Burner current power"), curBurnPow_, F_(percent), 1); + print_value(shell, 2, F("Flame current"), flameCurr_, F("uA"), 10); + print_value(shell, 2, F("System pressure"), sysPress_, F("bar"), 10); if (Helpers::hasValue(serviceCode_)) { shell.printfln(F(" System service code: %s (%d)"), serviceCodeChar_, serviceCode_); } else if (serviceCodeChar_[0] != '\0') { - shell.printfln(F(" System service code: %s"), serviceCodeChar_); + print_value(shell, 2, F("System service code"), FPSTR(serviceCodeChar_)); // TODO check } // UBAParameters - print_value(shell, 2, F("Heating temperature setting on the boiler"), F_(degrees), Helpers::render_value(buffer, heating_temp_, 1)); - print_value(shell, 2, F("Boiler circuit pump modulation max power"), F_(percent), Helpers::render_value(buffer, pump_mod_max_, 1)); - print_value(shell, 2, F("Boiler circuit pump modulation min power"), F_(percent), Helpers::render_value(buffer, pump_mod_min_, 1)); + print_value(shell, 2, F("Heating temperature setting on the boiler"), heating_temp_, F_(degrees), 1); + print_value(shell, 2, F("Boiler circuit pump modulation max power"), pump_mod_max_, F_(percent), 1); + print_value(shell, 2, F("Boiler circuit pump modulation min power"), pump_mod_min_, F_(percent), 1); // UBAMonitorSlow if (Helpers::hasValue(extTemp_)) { - print_value(shell, 2, F("Outside temperature"), F_(degrees), Helpers::render_value(buffer, extTemp_, 10)); + print_value(shell, 2, F("Outside temperature"), extTemp_, F_(degrees), 10); } - print_value(shell, 2, F("Exhaust temperature"), F_(degrees), Helpers::render_value(buffer, exhaustTemp_, 10)); - print_value(shell, 2, F("Pump modulation"), F_(percent), Helpers::render_value(buffer, pumpMod_, 1)); - print_value(shell, 2, F("Burner # starts"), Helpers::render_value(buffer, burnStarts_, 1)); + print_value(shell, 2, F("Exhaust temperature"), exhaustTemp_, F_(degrees), 10); + print_value(shell, 2, F("Pump modulation"), pumpMod_, F_(percent), 1); + print_value(shell, 2, F("Pump modulation2"), pumpMod2_, F_(percent), 1); + print_value(shell, 2, F("Burner # starts"), burnStarts_, nullptr, 1); if (Helpers::hasValue(burnWorkMin_)) { shell.printfln(F(" Total burner operating time: %d days %d hours %d minutes"), burnWorkMin_ / 1440, (burnWorkMin_ % 1440) / 60, burnWorkMin_ % 60); } @@ -432,14 +421,6 @@ void Boiler::show_values(uuid::console::Shell & shell) { if (Helpers::hasValue(UBAuptime_)) { shell.printfln(F(" Total UBA working time: %d days %d hours %d minutes"), UBAuptime_ / 1440, (UBAuptime_ % 1440) / 60, UBAuptime_ % 60); } - - if (Helpers::hasValue(hpModulation_)) { - print_value(shell, 2, F("Heat Pump modulation"), F_(percent), Helpers::render_value(buffer, hpModulation_, 1)); - } - - if (Helpers::hasValue(hpSpeed_)) { - print_value(shell, 2, F("Heat Pump speed"), F_(percent), Helpers::render_value(buffer, hpSpeed_, 1)); - } } /* @@ -597,6 +578,13 @@ void Boiler::process_UBAMonitorSlow(std::shared_ptr telegram) { telegram->read_value(heatWorkMin_, 19); } +/* + * UBAMonitorSlowPlus2 - type 0xE3 + */ +void Boiler::process_UBAMonitorSlowPlus2(std::shared_ptr telegram) { + telegram->read_value(pumpMod2_, 13); +} + /* * UBAMonitorSlowPlus - type 0xE5 - central heating monitor EMS+ */ @@ -608,21 +596,7 @@ void Boiler::process_UBAMonitorSlowPlus(std::shared_ptr telegram telegram->read_value(burnStarts_, 10); telegram->read_value(burnWorkMin_, 13); telegram->read_value(heatWorkMin_, 19); - telegram->read_value(pumpMod_, 25); // or is it switchTemp ? -} - -/* - * Type 0xE3 - HeatPump Monitor 1 - */ -void Boiler::process_HPMonitor1(std::shared_ptr telegram) { - telegram->read_value(hpModulation_, 13); -} - -/* - * Type 0xE5 - HeatPump Monitor 2 - */ -void Boiler::process_HPMonitor2(std::shared_ptr telegram) { - telegram->read_value(hpSpeed_, 25); + telegram->read_value(pumpMod_, 25); } // 0xE9 - DHW Status diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 9dc36c8c3..41f7e8160 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -123,9 +123,7 @@ class Boiler : public EMSdevice { uint8_t tap_water_active_ = EMS_VALUE_BOOL_NOTSET; // Hot tap water is on/off uint8_t heating_active_ = EMS_VALUE_BOOL_NOTSET; // Central heating is on/off - // heatpump boilers - uint8_t hpModulation_ = EMS_VALUE_UINT_NOTSET; // heatpump modulation in % - uint8_t hpSpeed_ = EMS_VALUE_UINT_NOTSET; // speed 0-100 % + uint8_t pumpMod2_ = EMS_VALUE_UINT_NOTSET; // heatpump modulation from 0xE3 (heatpumps) void process_UBAParameterWW(std::shared_ptr telegram); void process_UBAMonitorFast(std::shared_ptr telegram); @@ -135,6 +133,8 @@ class Boiler : public EMSdevice { void process_UBAMonitorFastPlus(std::shared_ptr telegram); void process_UBAMonitorSlow(std::shared_ptr telegram); void process_UBAMonitorSlowPlus(std::shared_ptr telegram); + void process_UBAMonitorSlowPlus2(std::shared_ptr telegram); + void process_UBAOutdoorTemp(std::shared_ptr telegram); void process_UBASetPoints(std::shared_ptr telegram); void process_UBAFlags(std::shared_ptr telegram); @@ -144,8 +144,6 @@ class Boiler : public EMSdevice { void process_UBAErrorMessage(std::shared_ptr telegram); void process_UBADHWStatus(std::shared_ptr telegram); - void process_HPMonitor1(std::shared_ptr telegram); - void process_HPMonitor2(std::shared_ptr telegram); void check_active(); diff --git a/src/devices/mixing.cpp b/src/devices/mixing.cpp index c8516f086..05d1cff48 100644 --- a/src/devices/mixing.cpp +++ b/src/devices/mixing.cpp @@ -70,17 +70,15 @@ void Mixing::show_values(uuid::console::Shell & shell) { return; // don't have any values yet } - char buffer[10]; // used for formatting - if (type_ == Type::WWC) { - shell.printfln(F(" Warm Water Circuit #: %d"), hc_); + print_value(shell, 2, F("Warm Water Circuit"), hc_, nullptr, 1); } else { - shell.printfln(F(" Heating Circuit #: %d"), hc_); + print_value(shell, 2, F("Heating Circuit"), hc_, nullptr, 1); } - print_value(shell, 4, F("Current flow temperature"), F_(degrees), Helpers::render_value(buffer, flowTemp_, 10)); - print_value(shell, 4, F("Setpoint flow temperature"), F_(degrees), Helpers::render_value(buffer, flowSetTemp_, 1)); - print_value(shell, 4, F("Current pump modulation"), Helpers::render_value(buffer, pumpMod_, 1)); - print_value(shell, 4, F("Current valve status"), Helpers::render_value(buffer, status_, 1)); + print_value(shell, 4, F("Current flow temperature"), flowTemp_, F_(degrees), 10); + print_value(shell, 4, F("Setpoint flow temperature"), flowSetTemp_, F_(degrees), 1); + print_value(shell, 4, F("Current pump modulation"), pumpMod_, F_(percent), 1); + print_value(shell, 4, F("Current valve status"), status_, nullptr, 1); } // publish values via MQTT diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index 68cd990e0..7a9381d67 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -56,22 +56,20 @@ void Solar::add_context_menu() { void Solar::show_values(uuid::console::Shell & shell) { EMSdevice::show_values(shell); // always call this to show header - char buffer[10]; // used for formatting - - print_value(shell, 2, F("Collector temperature (TS1)"), F_(degrees), Helpers::render_value(buffer, collectorTemp_, 10)); - print_value(shell, 2, F("Bottom temperature (TS2)"), F_(degrees), Helpers::render_value(buffer, bottomTemp_, 10)); - print_value(shell, 2, F("Bottom temperature (TS5)"), F_(degrees), Helpers::render_value(buffer, bottomTemp2_, 10)); - print_value(shell, 2, F("Pump modulation"), F_(percent), Helpers::render_value(buffer, pumpModulation_, 1)); - print_value(shell, 2, F("Valve (VS2) status"), Helpers::render_value(buffer, valveStatus_, EMS_VALUE_BOOL)); - print_value(shell, 2, F("Pump (PS1) active"), Helpers::render_value(buffer, pump_, EMS_VALUE_BOOL)); + print_value(shell, 2, F("Collector temperature (TS1)"), collectorTemp_, F_(degrees), 10); + print_value(shell, 2, F("Bottom temperature (TS2)"), bottomTemp_, F_(degrees), 10); + print_value(shell, 2, F("Bottom temperature (TS5)"), bottomTemp2_, F_(degrees), 10); + print_value(shell, 2, F("Pump modulation"), pumpModulation_, F_(percent), 1); + print_value(shell, 2, F("Valve (VS2) status"), valveStatus_, nullptr, EMS_VALUE_BOOL); + print_value(shell, 2, F("Pump (PS1) active"), pump_, nullptr, EMS_VALUE_BOOL); if (Helpers::hasValue(pumpWorkMin_)) { shell.printfln(F(" Pump working time: %d days %d hours %d minutes"), pumpWorkMin_ / 1440, (pumpWorkMin_ % 1440) / 60, pumpWorkMin_ % 60); } - print_value(shell, 2, F("Energy last hour"), F_(wh), Helpers::render_value(buffer, energyLastHour_, 10)); - print_value(shell, 2, F("Energy today"), F_(wh), Helpers::render_value(buffer, energyToday_, 0)); // no division - print_value(shell, 2, F("Energy total"), F_(kwh), Helpers::render_value(buffer, energyTotal_, 10)); + print_value(shell, 2, F("Energy last hour"), energyLastHour_, F_(wh), 10); + print_value(shell, 2, F("Energy today"), energyToday_, F_(wh), 0); + print_value(shell, 2, F("Energy total"), energyTotal_, F_(kwh), 10); } // publish values via MQTT diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 46fb8ca8b..f0bd83f6a 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -804,20 +804,19 @@ std::string Thermostat::mode_tostring(uint8_t mode) const { void Thermostat::show_values(uuid::console::Shell & shell) { EMSdevice::show_values(shell); // always call this to show header - char buffer[10]; // for formatting only uint8_t flags = (this->flags() & 0x0F); // specific thermostat characteristics, strip the option bits if (datetime_.size()) { shell.printfln(F(" Clock: %s"), datetime_.c_str()); if (Helpers::hasValue(ibaClockOffset_) && flags == EMS_DEVICE_FLAG_RC30_1) { - print_value(shell, 2, F("Offset clock"), Helpers::render_value(buffer, ibaClockOffset_, 1)); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s + print_value(shell, 2, F("Offset clock"), ibaClockOffset_, nullptr, 1); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s } } if (flags == EMS_DEVICE_FLAG_RC35) { - print_value(shell, 2, F("Damped Outdoor temperature"), F_(degrees), Helpers::render_value(buffer, dampedoutdoortemp_, 1)); - print_value(shell, 2, F("Temp sensor 1"), F_(degrees), Helpers::render_value(buffer, tempsensor1_, 10)); - print_value(shell, 2, F("Temp sensor 2"), F_(degrees), Helpers::render_value(buffer, tempsensor2_, 10)); + print_value(shell, 2, F("Damped Outdoor temperature"), dampedoutdoortemp_, F_(degrees), 1); + print_value(shell, 2, F("Temp sensor 1"), tempsensor1_, F_(degrees), 10); + print_value(shell, 2, F("Temp sensor 2"), tempsensor2_, F_(degrees), 10); } if (flags == EMS_DEVICE_FLAG_RC30_1) { // settings parameters @@ -857,11 +856,11 @@ void Thermostat::show_values(uuid::console::Shell & shell) { } if (flags == EMS_DEVICE_FLAG_RC35 || flags == EMS_DEVICE_FLAG_RC30_1) { if (Helpers::hasValue(ibaCalIntTemperature_)) { - print_value(shell, 2, F("Offset int. temperature"), F_(degrees), Helpers::render_value(buffer, ibaCalIntTemperature_, 2)); + print_value(shell, 2, F("Offset int. temperature"), ibaCalIntTemperature_, F_(degrees), 2); } if (Helpers::hasValue(ibaMinExtTemperature_)) { - print_value(shell, 2, F("Min ext. temperature"), F_(degrees), Helpers::render_value(buffer, ibaMinExtTemperature_, 0)); // min ext temp for heating curve, in deg. + print_value(shell, 2, F("Min ext. temperature"), ibaMinExtTemperature_, F_(degrees), 0); // min ext temp for heating curve, in deg. } if (Helpers::hasValue(ibaBuildingType_)) { @@ -895,8 +894,8 @@ void Thermostat::show_values(uuid::console::Shell & shell) { break; } - print_value(shell, 4, F("Current room temperature"), F_(degrees), Helpers::render_value(buffer, hc->curr_roomTemp, format_curr)); - print_value(shell, 4, F("Setpoint room temperature"), F_(degrees), Helpers::render_value(buffer, hc->setpoint_roomTemp, format_setpoint)); + print_value(shell, 4, F("Current room temperature"), hc->curr_roomTemp, F_(degrees), format_curr); + print_value(shell, 4, F("Setpoint room temperature"), hc->setpoint_roomTemp, F_(degrees), format_setpoint); if (Helpers::hasValue(hc->mode)) { print_value(shell, 4, F("Mode"), mode_tostring(hc->get_mode(flags)).c_str()); } @@ -911,18 +910,18 @@ void Thermostat::show_values(uuid::console::Shell & shell) { shell.printfln(F(" Program is set to Holiday mode")); } - print_value(shell, 4, F("Day temperature"), F_(degrees), Helpers::render_value(buffer, hc->daytemp, 2)); - print_value(shell, 4, F("Night temperature"), F_(degrees), Helpers::render_value(buffer, hc->nighttemp, 2)); - print_value(shell, 4, F("Holiday temperature"), F_(degrees), Helpers::render_value(buffer, hc->holidaytemp, 2)); + print_value(shell, 4, F("Day temperature"), hc->daytemp, F_(degrees), 2); + print_value(shell, 4, F("Night temperature"), hc->nighttemp, F_(degrees), 2); + print_value(shell, 4, F("Holiday temperature"), hc->holidaytemp, F_(degrees), 2); - print_value(shell, 4, F("Offset temperature"), F_(degrees), Helpers::render_value(buffer, hc->offsettemp, 2)); - print_value(shell, 4, F("Design temperature"), F_(degrees), Helpers::render_value(buffer, hc->designtemp, 0)); - print_value(shell, 4, F("Summer temperature"), F_(degrees), Helpers::render_value(buffer, hc->summertemp, 0)); + print_value(shell, 4, F("Offset temperature"), hc->offsettemp, F_(degrees), 2); + print_value(shell, 4, F("Design temperature"), hc->designtemp, F_(degrees), 0); + print_value(shell, 4, F("Summer temperature"), hc->summertemp, F_(degrees), 0); } // show flow temp if we have it if (Helpers::hasValue(hc->circuitcalctemp)) { - print_value(shell, 4, F("Calculated flow temperature"), F_(degrees), Helpers::render_value(buffer, hc->circuitcalctemp, 1)); + print_value(shell, 4, F("Calculated flow temperature"), hc->circuitcalctemp, F_(degrees), 1); } } } diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 1db79d3d2..9ca502f29 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -279,22 +279,18 @@ void EMSdevice::read_command(const uint16_t type_id) { EMSESP::send_read_request(type_id, device_id()); } -// prints a value to the console -void EMSdevice::print_value(uuid::console::Shell & shell, uint8_t padding, const __FlashStringHelper * name, const __FlashStringHelper * suffix, const char * value) { +// prints a string value to the console +void EMSdevice::print_value(uuid::console::Shell & shell, uint8_t padding, const __FlashStringHelper * name, const __FlashStringHelper * value) { + print_value(shell, padding, name, uuid::read_flash_string(value).c_str()); +} + +void EMSdevice::print_value(uuid::console::Shell & shell, uint8_t padding, const __FlashStringHelper * name, const char * value) { uint8_t i = padding; while (i-- > 0) { shell.print(F(" ")); } - shell.printf(PSTR("%s: %s"), uuid::read_flash_string(name).c_str(), value); - if (suffix != nullptr) { - shell.print(uuid::read_flash_string(suffix).c_str()); - } - shell.println(); -} -// prints a value to the console - with no prefix -void EMSdevice::print_value(uuid::console::Shell & shell, uint8_t padding, const __FlashStringHelper * name, const char * value) { - print_value(shell, padding, name, nullptr, value); + shell.printfln(PSTR("%s: %s"), uuid::read_flash_string(name).c_str(), value); } } // namespace emsesp diff --git a/src/emsdevice.h b/src/emsdevice.h index 405a1d3ad..b0259e590 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -120,8 +120,30 @@ class EMSdevice { void fetch_values(); void toggle_fetch(uint16_t telegram_id, bool toggle); - void print_value(uuid::console::Shell & shell, uint8_t padding, const __FlashStringHelper * name, const __FlashStringHelper * prefix, const char * value); - void print_value(uuid::console::Shell & shell, uint8_t padding, const __FlashStringHelper * name, const char * value); + template + static void + print_value(uuid::console::Shell & shell, uint8_t padding, const __FlashStringHelper * name, Value & value, const __FlashStringHelper * suffix, const uint8_t p) { + char buffer[15]; + if (Helpers::render_value(buffer, value, p) == nullptr) { + return; + } + + uint8_t i = padding; + while (i-- > 0) { + shell.print(F(" ")); + } + + shell.printf(PSTR("%s: %s"), uuid::read_flash_string(name).c_str(), buffer); + + if (suffix != nullptr) { + shell.println(uuid::read_flash_string(suffix).c_str()); + } else { + shell.println(); + } + } + + static void print_value(uuid::console::Shell & shell, uint8_t padding, const __FlashStringHelper * name, const __FlashStringHelper * value); + static void print_value(uuid::console::Shell & shell, uint8_t padding, const __FlashStringHelper * name, const char * value); enum Brand : uint8_t { NO_BRAND, // 0 diff --git a/src/helpers.cpp b/src/helpers.cpp index bd9c3a9ea..4b46acb89 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -32,8 +32,45 @@ char * Helpers::hextoa(char * result, const uint8_t value) { return result; } +#ifdef EMSESP_STANDALONE +char * Helpers::ultostr(char * ptr, uint32_t value, const uint8_t base) { + unsigned long t = 0, res = 0; + unsigned long tmp = value; + int count = 0; + + if (NULL == ptr) { + return NULL; + } + + if (tmp == 0) { + count++; + } + + while (tmp > 0) { + tmp = tmp / base; + count++; + } + + ptr += count; + + *ptr = '\0'; + + do { + res = value - base * (t = value / base); + if (res < 10) { + *--ptr = '0' + res; + } else if ((res >= 10) && (res < 16)) { + *--ptr = 'A' - 10 + res; + } + } while ((value = t) != 0); + + return (ptr); +} +#endif + + /* - * itoa for 2 byte integers + * itoa for 2 byte signed (short) integers * written by Lukás Chmela, Released under GPLv3. http://www.strudel.org.uk/itoa/ version 0.4 */ char * Helpers::itoa(char * result, int16_t value, const uint8_t base) { @@ -56,12 +93,14 @@ char * Helpers::itoa(char * result, int16_t value, const uint8_t base) { if (tmp_value < 0) { *ptr++ = '-'; } + *ptr-- = '\0'; while (ptr1 < ptr) { tmp_char = *ptr; *ptr-- = *ptr1; *ptr1++ = tmp_char; } + return result; } @@ -92,7 +131,7 @@ char * Helpers::render_value(char * result, uint8_t value, uint8_t format) { if (value == EMS_VALUE_BOOL_OFF) { strlcpy(result, "off", 5); } else if (value == EMS_VALUE_BOOL_NOTSET) { - strlcpy(result, "?", 5); + return nullptr; } else { strlcpy(result, "on", 5); // assume on. could have value 0x01 or 0xFF } @@ -100,8 +139,7 @@ char * Helpers::render_value(char * result, uint8_t value, uint8_t format) { } if (value == EMS_VALUE_UINT_NOTSET) { - strlcpy(result, "?", 5); - return (result); + return nullptr; } char s2[5] = {0}; @@ -153,8 +191,7 @@ char * Helpers::render_value(char * result, const int16_t value, const uint8_t f // remove errors or invalid values, 0x7D00 and higher if ((value == EMS_VALUE_SHORT_NOTSET) || (value == EMS_VALUE_SHORT_INVALID) || (value == EMS_VALUE_USHORT_NOTSET)) { - strlcpy(result, "?", 10); - return result; + return nullptr; } // just print it if mo conversion required @@ -196,8 +233,7 @@ char * Helpers::render_value(char * result, const uint16_t value, const uint8_t result[0] = '\0'; if ((value == EMS_VALUE_USHORT_NOTSET) || (value == EMS_VALUE_USHORT_INVALID)) { - strlcpy(result, "?", 10); - return result; + return nullptr; } return (render_value(result, (int16_t)value, format)); // use same code, force it to a signed int @@ -209,8 +245,7 @@ char * Helpers::render_value(char * result, const int8_t value, const uint8_t fo result[0] = '\0'; if (value == EMS_VALUE_INT_NOTSET) { - strlcpy(result, "?", 10); - return result; + return nullptr; } return (render_value(result, (int16_t)value, format)); // use same code, force it to a signed int @@ -222,8 +257,7 @@ char * Helpers::render_value(char * result, const uint32_t value, const uint8_t result[0] = '\0'; if ((value == EMS_VALUE_ULONG_NOTSET) || (value == EMS_VALUE_ULONG_INVALID)) { - strlcpy(result, "?", 10); - return (result); + return nullptr; } char s[20] = {0}; @@ -238,7 +272,13 @@ char * Helpers::render_value(char * result, const uint32_t value, const uint8_t } #else - strncat(result, itoa(s, value / format, 10), 20); + if (format <= 1) { + strlcat(result, ultostr(s, value, 10), 20); + } else { + strncat(result, ultostr(s, value / format, 10), 20); + strlcat(result, ".", 20); + strncat(result, ultostr(s, value % format, 10), 20); + } #endif return result; @@ -264,7 +304,6 @@ std::string Helpers::data_to_hex(const uint8_t * data, const uint8_t length) { return str; } - // takes a hex string and convert it to an unsigned 32bit number (max 8 hex digits) // works with only positive numbers uint32_t Helpers::hextoint(const char * hex) { @@ -331,5 +370,4 @@ bool Helpers::hasValue(const uint32_t v) { return (v != EMS_VALUE_ULONG_NOTSET); } - } // namespace emsesp diff --git a/src/helpers.h b/src/helpers.h index e7d4867c7..33fcc13a5 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -44,6 +44,10 @@ class Helpers { static bool check_abs(const int32_t i); static double round2(double value); +#ifdef EMSESP_STANDALONE + static char * ultostr(char * ptr, uint32_t value, const uint8_t base); +#endif + static bool hasValue(const uint8_t v, bool isBool = false); // use isBool=true for bool's static bool hasValue(const int8_t v); static bool hasValue(const int16_t v); diff --git a/src/test/test.cpp b/src/test/test.cpp index 61c6e3e58..eea81961b 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -25,6 +25,62 @@ 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) { + if (command == "render") { + /* +static constexpr uint8_t EMS_VALUE_BOOL = 0xFF; // boolean +static constexpr uint8_t EMS_VALUE_BOOL_OFF = 0x00; // boolean false. True can be 0x01 or 0xFF sometimes. + +static constexpr uint8_t EMS_VALUE_BOOL_NOTSET = 0xFE; // random number for booleans, that's not 0, 1 or FF +static constexpr uint8_t EMS_VALUE_UINT_NOTSET = 0xFF; // for 8-bit unsigned ints/bytes +static constexpr int8_t EMS_VALUE_INT_NOTSET = 0x7F; // for signed 8-bit ints/bytes +static constexpr int16_t EMS_VALUE_SHORT_NOTSET = 0x8300; // -32000: for 2-byte signed shorts +static constexpr uint16_t EMS_VALUE_USHORT_NOTSET = 0x7D00; // 32000: for 2-byte unsigned shorts +static constexpr uint16_t EMS_VALUE_USHORT_INVALID = 0x8000; +static constexpr int16_t EMS_VALUE_SHORT_INVALID = 0x8000; +static constexpr uint32_t EMS_VALUE_ULONG_NOTSET = 0xFFFFFFFF; // for 3-byte and 4-byte longs +static constexpr uint32_t EMS_VALUE_ULONG_INVALID = 0x80000000; +*/ + + uint8_t test1 = 12; + int8_t test2 = -12; + uint16_t test3 = 456; + int16_t test4 = -456; + uint8_t test5 = 1; // bool = on + uint32_t test6 = 305419896; + float test7 = 89.43; + + uint8_t test1u = EMS_VALUE_UINT_NOTSET; + int8_t test2u = EMS_VALUE_INT_NOTSET; + uint16_t test3u = EMS_VALUE_USHORT_NOTSET; + int16_t test4u = EMS_VALUE_USHORT_NOTSET; + uint8_t test5u = EMS_VALUE_BOOL_NOTSET; + uint32_t test6u = EMS_VALUE_ULONG_NOTSET; + + EMSdevice::print_value(shell, 2, F("Selected flow temperature1"), test1, F_(degrees), 1); // 12 + EMSdevice::print_value(shell, 2, F("Selected flow temperature2"), test2, F_(degrees), 1); // -12 + EMSdevice::print_value(shell, 2, F("Selected flow temperature3"), test3, F_(degrees), 10); // 45.6 + EMSdevice::print_value(shell, 2, F("Selected flow temperature4"), test4, F_(degrees), 10); // -45.6 + EMSdevice::print_value(shell, 2, F("Selected flow temperature5"), test5, nullptr, EMS_VALUE_BOOL); // on + EMSdevice::print_value(shell, 2, F("Selected flow temperature6"), test6, F_(degrees), 1); // + EMSdevice::print_value(shell, 2, F("Selected flow temperature7"), test7, F_(degrees), 2); // 89.43 + EMSdevice::print_value(shell, 2, F("Warm Water comfort setting"), F("Intelligent")); + char s[100]; + strcpy(s, "Not very intelligent"); + EMSdevice::print_value(shell, 2, F("Warm Water comfort setting2"), s); + + shell.println(); + + EMSdevice::print_value(shell, 2, F("Selected flow temperature1u"), test1u, F_(degrees), 1); + EMSdevice::print_value(shell, 2, F("Selected flow temperature2u"), test2u, F_(degrees), 1); + EMSdevice::print_value(shell, 2, F("Selected flow temperature3u"), test3u, F_(degrees), 10); + EMSdevice::print_value(shell, 2, F("Selected flow temperature4u"), test4u, F_(degrees), 10); + EMSdevice::print_value(shell, 2, F("Selected flow temperature5u"), test5u, F_(degrees), EMS_VALUE_BOOL); + EMSdevice::print_value(shell, 2, F("Selected flow temperature6u"), test6u, F_(degrees), 100); + + shell.loop_all(); + return; + } + if (command == "devices") { EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); // this is important otherwise nothing will be picked up! @@ -101,6 +157,17 @@ 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_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_values(shell); + + rx_telegram({0xB0, 00, 0xFF, 0x18, 02, 0x62, 0x80, 00, 0xB8}); + EMSESP::show_values(shell); + + EMSESP::send_raw_telegram("B0 00 FF 18 02 62 80 00 B8"); + EMSESP::show_values(shell); } if (command == "cr100") { diff --git a/src/version.h b/src/version.h index b7aeef83f..8f4a11059 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "2.0.0a20" +#define EMSESP_APP_VERSION "2.0.0a21"