From 28068bdb9852dc4c54dd2f116e4a84217cda54e8 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 10 May 2021 14:13:37 +0200 Subject: [PATCH] add SM10 solar values and commands --- src/WebSettingsService.cpp | 4 +- src/WebSettingsService.h | 1 + src/default_settings.h | 4 + src/devices/solar.cpp | 225 +++++++++++++++++++++++++++++++------ src/devices/solar.h | 23 +++- src/emsdevice.cpp | 3 +- src/emsdevice.h | 2 +- src/locale_EN.h | 19 +++- 8 files changed, 239 insertions(+), 42 deletions(-) diff --git a/src/WebSettingsService.cpp b/src/WebSettingsService.cpp index 9302e88ff..c5b9a37c9 100644 --- a/src/WebSettingsService.cpp +++ b/src/WebSettingsService.cpp @@ -58,6 +58,7 @@ void WebSettings::read(WebSettings & settings, JsonObject & root) { root["notoken_api"] = settings.notoken_api; root["analog_enabled"] = settings.analog_enabled; root["pbutton_gpio"] = settings.pbutton_gpio; + root["solar_maxflow"] = settings.solar_maxflow; root["board_profile"] = settings.board_profile; } @@ -169,7 +170,8 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings) settings.master_thermostat = root["master_thermostat"] | EMSESP_DEFAULT_MASTER_THERMOSTAT; // doesn't need any follow-up actions - settings.notoken_api = root["notoken_api"] | EMSESP_DEFAULT_NOTOKEN_API; + settings.notoken_api = root["notoken_api"] | EMSESP_DEFAULT_NOTOKEN_API; + settings.solar_maxflow = root["solar_maxflow"] | EMSESP_DEFAULT_SOLAR_MAXFLOW; return StateUpdateResult::CHANGED; } diff --git a/src/WebSettingsService.h b/src/WebSettingsService.h index 38e7ae785..e90b30b6b 100644 --- a/src/WebSettingsService.h +++ b/src/WebSettingsService.h @@ -53,6 +53,7 @@ class WebSettings { bool notoken_api; bool analog_enabled; uint8_t pbutton_gpio; + uint8_t solar_maxflow; String board_profile; static void read(WebSettings & settings, JsonObject & root); diff --git a/src/default_settings.h b/src/default_settings.h index ab7520207..7f8dfd6ec 100644 --- a/src/default_settings.h +++ b/src/default_settings.h @@ -152,4 +152,8 @@ #define EMSESP_DEFAULT_SUBSCRIBE_FORMAT 0 #endif +#ifndef EMSESP_DEFAULT_SOLAR_MAXFLOW +#define EMSESP_DEFAULT_SOLAR_MAXFLOW 30 +#endif + #endif diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index c724b8c54..780a48b6f 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -30,7 +30,9 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s // telegram handlers if (flags == EMSdevice::EMS_DEVICE_FLAG_SM10) { - register_telegram_type(0x0097, F("SM10Monitor"), true, MAKE_PF_CB(process_SM10Monitor)); + register_telegram_type(0x97, F("SM10Monitor"), false, MAKE_PF_CB(process_SM10Monitor)); + register_telegram_type(0x96, F("SM10Config"), true, MAKE_PF_CB(process_SM10Config)); + EMSESP::send_read_request(0x97, device_id); } if (flags == EMSdevice::EMS_DEVICE_FLAG_SM100) { @@ -55,7 +57,7 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) { register_telegram_type(0x0103, F("ISM1StatusMessage"), true, MAKE_PF_CB(process_ISM1StatusMessage)); - register_telegram_type(0x0101, F("ISM1Set"), false, MAKE_PF_CB(process_ISM1Set)); + register_telegram_type(0x0101, F("ISM1Set"), true, MAKE_PF_CB(process_ISM1Set)); } // device values... @@ -78,24 +80,47 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s register_device_value(TAG_NONE, &collectorTemp_, DeviceValueType::SHORT, FL_(div10), FL_(collectorTemp), DeviceValueUOM::DEGREES); register_device_value(TAG_NONE, &tankBottomTemp_, DeviceValueType::SHORT, FL_(div10), FL_(tankBottomTemp), DeviceValueUOM::DEGREES); - register_device_value(TAG_NONE, &tankBottomTemp2_, DeviceValueType::SHORT, FL_(div10), FL_(tank2BottomTemp), DeviceValueUOM::DEGREES); - register_device_value(TAG_NONE, &heatExchangerTemp_, DeviceValueType::SHORT, FL_(div10), FL_(heatExchangerTemp), DeviceValueUOM::DEGREES); - - register_device_value( - TAG_NONE, &tankBottomMaxTemp_, DeviceValueType::UINT, nullptr, FL_(tankMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_SM100TankBottomMaxTemp)); - register_device_value(TAG_NONE, &solarPumpModulation_, DeviceValueType::UINT, nullptr, FL_(solarPumpModulation), DeviceValueUOM::PERCENT); - register_device_value(TAG_NONE, &cylinderPumpModulation_, DeviceValueType::UINT, nullptr, FL_(cylinderPumpModulation), DeviceValueUOM::PERCENT); - register_device_value(TAG_NONE, &solarPump_, DeviceValueType::BOOL, nullptr, FL_(solarPump), DeviceValueUOM::PUMP); - register_device_value(TAG_NONE, &valveStatus_, DeviceValueType::BOOL, nullptr, FL_(valveStatus), DeviceValueUOM::NONE); - register_device_value(TAG_NONE, &tankHeated_, DeviceValueType::BOOL, nullptr, FL_(tankHeated), DeviceValueUOM::NONE); - register_device_value(TAG_NONE, &collectorShutdown_, DeviceValueType::BOOL, nullptr, FL_(collectorShutdown), DeviceValueUOM::NONE); - register_device_value(TAG_NONE, &pumpWorkTime_, DeviceValueType::TIME, nullptr, FL_(pumpWorkTime), DeviceValueUOM::MINUTES); + register_device_value(TAG_NONE, &tankMaxTemp_, DeviceValueType::UINT, nullptr, FL_(tankMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_TankMaxTemp)); - register_device_value(TAG_NONE, &energyLastHour_, DeviceValueType::ULONG, FL_(div10), FL_(energyLastHour), DeviceValueUOM::WH); - register_device_value(TAG_NONE, &energyTotal_, DeviceValueType::ULONG, FL_(div10), FL_(energyTotal), DeviceValueUOM::KWH); - register_device_value(TAG_NONE, &energyToday_, DeviceValueType::ULONG, nullptr, FL_(energyToday), DeviceValueUOM::WH); + if (flags == EMSdevice::EMS_DEVICE_FLAG_SM10) { + // register_device_value(TAG_NONE, &collectorMaxTemp_, DeviceValueType::UINT, nullptr, FL_(collectorMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_CollectorMaxTemp)); + register_device_value(TAG_NONE, &solarPumpModulation_, DeviceValueType::UINT, nullptr, FL_(solarPumpModulation), DeviceValueUOM::PERCENT); + register_device_value(TAG_NONE, &solarPumpMinMod_, DeviceValueType::UINT, nullptr, FL_(pumpMinMod), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_PumpMinMod)); + register_device_value(TAG_NONE, &solarPumpTurnonDiff_, DeviceValueType::UINT, nullptr, FL_(solarPumpTurnonDiff), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_TurnonDiff)); + register_device_value(TAG_NONE, &solarPumpTurnoffDiff_, DeviceValueType::UINT, nullptr, FL_(solarPumpTurnoffDiff), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_TurnoffDiff)); + register_device_value(TAG_NONE, &collectorMaxTemp_, DeviceValueType::UINT, nullptr, FL_(collectorMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_CollectorMaxTemp)); + register_device_value(TAG_NONE, &collectorMinTemp_, DeviceValueType::UINT, nullptr, FL_(collectorMinTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_CollectorMinTemp)); + register_device_value(TAG_NONE, &collectorShutdown_, DeviceValueType::BOOL, nullptr, FL_(collectorShutdown), DeviceValueUOM::NONE); + // register_device_value(TAG_NONE, &tankHeated_, DeviceValueType::BOOL, nullptr, FL_(tankHeated), DeviceValueUOM::NONE); + register_device_value(TAG_NONE, &solarPower_, DeviceValueType::ULONG, nullptr, FL_(solarPower), DeviceValueUOM::W); + register_device_value(TAG_NONE, &energyLastHour_, DeviceValueType::ULONG, FL_(div10), FL_(energyLastHour), DeviceValueUOM::WH); + register_device_value(TAG_NONE, &maxFlow_, DeviceValueType::UINT, FL_(div10), FL_(maxFlow), DeviceValueUOM::LMIN, MAKE_CF_CB(set_SM10MaxFlow)); + register_device_value(TAG_DEVICE_DATA_WW, &wwMinTemp_, DeviceValueType::UINT, nullptr, FL_(wwMinTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMinTemp)); + } + if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) { + register_device_value(TAG_NONE, &collectorShutdown_, DeviceValueType::BOOL, nullptr, FL_(collectorShutdown), DeviceValueUOM::NONE); + register_device_value(TAG_NONE, &tankHeated_, DeviceValueType::BOOL, nullptr, FL_(tankHeated), DeviceValueUOM::NONE); + register_device_value(TAG_NONE, &energyLastHour_, DeviceValueType::ULONG, FL_(div10), FL_(energyLastHour), DeviceValueUOM::WH); + } + if (flags == EMSdevice::EMS_DEVICE_FLAG_SM100) { + register_device_value(TAG_NONE, &solarPumpModulation_, DeviceValueType::UINT, nullptr, FL_(solarPumpModulation), DeviceValueUOM::PERCENT); + register_device_value(TAG_NONE, &solarPumpMinMod_, DeviceValueType::UINT, nullptr, FL_(pumpMinMod), DeviceValueUOM::PERCENT, MAKE_CF_CB(set_PumpMinMod)); + register_device_value(TAG_NONE, &solarPumpTurnonDiff_, DeviceValueType::UINT, nullptr, FL_(solarPumpTurnonDiff), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_TurnonDiff)); + register_device_value(TAG_NONE, &solarPumpTurnoffDiff_, DeviceValueType::UINT, nullptr, FL_(solarPumpTurnoffDiff), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_TurnoffDiff)); + register_device_value(TAG_NONE, &tankBottomTemp2_, DeviceValueType::SHORT, FL_(div10), FL_(tank2BottomTemp), DeviceValueUOM::DEGREES); + register_device_value(TAG_NONE, &heatExchangerTemp_, DeviceValueType::SHORT, FL_(div10), FL_(heatExchangerTemp), DeviceValueUOM::DEGREES); + register_device_value(TAG_NONE, &cylinderPumpModulation_, DeviceValueType::UINT, nullptr, FL_(cylinderPumpModulation), DeviceValueUOM::PERCENT); + register_device_value(TAG_NONE, &valveStatus_, DeviceValueType::BOOL, nullptr, FL_(valveStatus), DeviceValueUOM::NONE); + register_device_value(TAG_NONE, &tankHeated_, DeviceValueType::BOOL, nullptr, FL_(tankHeated), DeviceValueUOM::NONE); + register_device_value(TAG_NONE, &collectorShutdown_, DeviceValueType::BOOL, nullptr, FL_(collectorShutdown), DeviceValueUOM::NONE); + register_device_value(TAG_NONE, &collectorMaxTemp_, DeviceValueType::UINT, nullptr, FL_(collectorMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_CollectorMaxTemp)); + register_device_value(TAG_NONE, &collectorMinTemp_, DeviceValueType::UINT, nullptr, FL_(collectorMinTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_CollectorMinTemp)); + register_device_value(TAG_NONE, &energyLastHour_, DeviceValueType::ULONG, FL_(div10), FL_(energyLastHour), DeviceValueUOM::WH); + register_device_value(TAG_NONE, &energyToday_, DeviceValueType::ULONG, nullptr, FL_(energyToday), DeviceValueUOM::WH); + register_device_value(TAG_NONE, &energyTotal_, DeviceValueType::ULONG, FL_(div10), FL_(energyTotal), DeviceValueUOM::KWH); + } } // publish HA config @@ -124,13 +149,60 @@ bool Solar::publish_ha_config() { return true; } +// SM10Monitor - type 0x96 +// Solar(0x30) -> All(0x00), (0x96), data: FF 18 19 0A 02 5A 27 0A 05 2D 1E 0F 64 28 0A +void Solar::process_SM10Config(std::shared_ptr telegram) { + uint8_t colmax = collectorMaxTemp_ / 10; + has_update(telegram->read_value(colmax, 3)); + collectorMaxTemp_ = colmax * 10; + uint8_t colmin = collectorMinTemp_ / 10; + has_update(telegram->read_value(colmin, 4)); + collectorMinTemp_ = colmin * 10; + has_update(telegram->read_value(solarPumpMinMod_, 2)); + has_update(telegram->read_value(solarPumpTurnonDiff_, 7)); + has_update(telegram->read_value(solarPumpTurnoffDiff_, 8)); + has_update(telegram->read_value(tankMaxTemp_, 5)); + has_update(telegram->read_value(wwMinTemp_, 6)); +} + // SM10Monitor - type 0x97 void Solar::process_SM10Monitor(std::shared_ptr telegram) { + uint8_t solarpumpmod = solarPumpModulation_; + + has_update(telegram->read_bitvalue(collectorShutdown_, 0, 3)); + // has_update(telegram->read_bitvalue(tankHeated_, 0, x)); // tank full, to be determined has_update(telegram->read_value(collectorTemp_, 2)); // collector temp from SM10, is *10 has_update(telegram->read_value(tankBottomTemp_, 5)); // tank bottom temp from SM10, is *10 has_update(telegram->read_value(solarPumpModulation_, 4)); // modulation solar pump has_update(telegram->read_bitvalue(solarPump_, 7, 1)); has_update(telegram->read_value(pumpWorkTime_, 8, 3)); + + // mask out pump-boosts + if (solarpumpmod == 0 && solarPumpModulation_ == 100) { + solarPumpModulation_ = solarPumpMinMod_; // set to minimum + } + + if (!Helpers::hasValue(maxFlow_)) { + EMSESP::webSettingsService.read([&](WebSettings & settings) { + maxFlow_ = settings.solar_maxflow; + }); + } + + // solar publishes every minute, do not count reads by other devices + if (telegram->dest == 0) { + // water 4.184 J/gK, glycol ~2.6-2.8 J/gK, no aceotrope + // solarPower_ = (collectorTemp_ - tankBottomTemp_) * solarPumpModulation_ * maxFlow_ * 10 / 1434; // water + solarPower_ = (collectorTemp_ - tankBottomTemp_) * solarPumpModulation_ * maxFlow_ * 10 / 1665; //40% glycol@40°C + if (energy.size() >= 60) { + energy.pop_front(); + } + energy.push_back(solarPower_); + uint32_t sum = 0; + for (auto e : energy) { + sum += e; + } + energyLastHour_ = sum / 6; // counts in 0.1 Wh + } } /* @@ -151,10 +223,10 @@ void Solar::process_SM100SystemConfig(std::shared_ptr telegram) */ void Solar::process_SM100SolarCircuitConfig(std::shared_ptr telegram) { has_update(telegram->read_value(collectorMaxTemp_, 0, 1)); - has_update(telegram->read_value(tankBottomMaxTemp_, 3, 1)); + has_update(telegram->read_value(tankMaxTemp_, 3, 1)); has_update(telegram->read_value(collectorMinTemp_, 4, 1)); has_update(telegram->read_value(solarPumpMode_, 5, 1)); - has_update(telegram->read_value(solarPumpMinRPM_, 6, 1)); + has_update(telegram->read_value(solarPumpMinMod_, 6, 1)); has_update(telegram->read_value(solarPumpTurnoffDiff_, 7, 1)); has_update(telegram->read_value(solarPumpTurnonDiff_, 8, 1)); has_update(telegram->read_value(solarPumpKick_, 9, 1)); @@ -263,11 +335,11 @@ void Solar::process_SM100Status(std::shared_ptr telegram) { has_update(telegram->read_value(solarPumpModulation_, 9)); if (solarpumpmod == 0 && solarPumpModulation_ == 100) { // mask out boosts - solarPumpModulation_ = 15; // set to minimum + solarPumpModulation_ = solarPumpMinMod_; // set to minimum } if (cylinderpumpmod == 0 && cylinderPumpModulation_ == 100) { // mask out boosts - cylinderPumpModulation_ = 15; // set to minimum + cylinderPumpModulation_ = solarPumpMinMod_; // set to minimum } has_update(telegram->read_bitvalue(tankHeated_, 3, 1)); // issue #422 has_update(telegram->read_bitvalue(collectorShutdown_, 3, 0)); // collector shutdown @@ -318,12 +390,9 @@ void Solar::process_SM100Time(std::shared_ptr telegram) { void Solar::process_ISM1StatusMessage(std::shared_ptr telegram) { has_update(telegram->read_value(collectorTemp_, 4)); // Collector Temperature has_update(telegram->read_value(tankBottomTemp_, 6)); // Temperature Bottom of Solar Boiler tank - uint16_t Wh = 0xFFFF; + uint16_t Wh = energyLastHour_ / 10; has_update(telegram->read_value(Wh, 2)); // Solar Energy produced in last hour only ushort, is not * 10 - - if (Wh != 0xFFFF) { - energyLastHour_ = Wh * 10; // set to *10 - } + energyLastHour_ = Wh * 10; // set to *10 has_update(telegram->read_bitvalue(solarPump_, 8, 0)); // PS1 Solar pump on (1) or off (0) has_update(telegram->read_value(pumpWorkTime_, 10, 3)); // force to 3 bytes @@ -335,21 +404,111 @@ void Solar::process_ISM1StatusMessage(std::shared_ptr telegram) * Junkers ISM1 Solar Module - type 0x0101 EMS+ for setting values */ void Solar::process_ISM1Set(std::shared_ptr telegram) { - has_update(telegram->read_value(setpoint_maxBottomTemp_, 6)); + has_update(telegram->read_value(tankMaxTemp_, 6)); } -// set temperature for tank -bool Solar::set_SM100TankBottomMaxTemp(const char * value, const int8_t id) { +/* + * Settings + */ +// collector shutdown temperature +bool Solar::set_CollectorMaxTemp(const char * value, const int8_t id) { int temperature; if (!Helpers::value2number(value, temperature)) { return false; } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_SM10) { + write_command(0x96, 3, (uint8_t)temperature / 10, 0x96); + } else { + write_command(0x35A, 0, (uint8_t)temperature, 0x35A); + } + return true; +} - // write value - // 90 30 FF 03 02 5A 59 B3 - // note: optionally add the validate to 0x035A which will pick up the adjusted tank1MaxTempCurrent_ - write_command(0x35A, 0x03, (uint8_t)temperature); +// collector shutdown temperature +bool Solar::set_CollectorMinTemp(const char * value, const int8_t id) { + int temperature; + if (!Helpers::value2number(value, temperature)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_SM10) { + write_command(0x96, 4, (uint8_t)temperature / 10, 0x96); + } else { + write_command(0x35A, 4, (uint8_t)temperature, 0x35A); + } + return true; +} +bool Solar::set_TankMaxTemp(const char * value, const int8_t id) { + int temperature; + if (!Helpers::value2number(value, temperature)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_SM10) { + write_command(0x96, 5, (uint8_t)temperature, 0x96); + } else if (flags() == EMSdevice::EMS_DEVICE_FLAG_ISM) { + write_command(0x101, 6, (uint8_t)temperature, 0x101); + } else { + // write value: 90 30 FF 03 02 5A 59 B3 + write_command(0x35A, 3, (uint8_t)temperature, 0x35A); + } + return true; +} +bool Solar::set_PumpMinMod(const char * value, const int8_t id) { + int modulation; + if (!Helpers::value2number(value, modulation)) { + return false; + } + write_command(0x96, 2, (uint8_t)modulation, 0x96); + return true; +} + +bool Solar::set_wwMinTemp(const char * value, const int8_t id) { + int temperature; + if (!Helpers::value2number(value, temperature)) { + return false; + } + write_command(0x96, 6, (uint8_t)temperature, 0x96); + return true; +} + +bool Solar::set_TurnoffDiff(const char * value, const int8_t id){ + int temperature; + if (!Helpers::value2number(value, temperature)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_SM10) { + write_command(0x96, 8, (uint8_t)temperature, 0x96); + } else { + write_command(0x35A, 7, (uint8_t)temperature, 0x35A); + } + return true; + +} + +bool Solar::set_TurnonDiff(const char * value, const int8_t id){ + int temperature; + if (!Helpers::value2number(value, temperature)) { + return false; + } + if (flags() == EMSdevice::EMS_DEVICE_FLAG_SM10) { + write_command(0x96, 7, (uint8_t)temperature, 0x96); + } else { + write_command(0x35A, 8, (uint8_t)temperature, 0x35A); + } + return true; +} + +// external value to calculate energy +bool Solar::set_SM10MaxFlow(const char * value, const int8_t id) { + float flow; + if (!Helpers::value2float(value, flow)) { + return false; + } + maxFlow_ = (flow * 10); + EMSESP::webSettingsService.update([&](WebSettings & settings) { + settings.solar_maxflow = maxFlow_; + return StateUpdateResult::CHANGED; + }, "local"); return true; } diff --git a/src/devices/solar.h b/src/devices/solar.h index 38631b427..2809f9e6b 100644 --- a/src/devices/solar.h +++ b/src/devices/solar.h @@ -40,7 +40,6 @@ class Solar : public EMSdevice { uint8_t cylinderPumpModulation_; // PS5: modulation cylinder pump uint8_t solarPump_; // PS1: solar pump active uint8_t valveStatus_; // VS2: status 3-way valve for cylinder 2 (solar thermal system) with valve - int16_t setpoint_maxBottomTemp_; // setpoint for maximum collector temp uint32_t energyLastHour_; uint32_t energyToday_; uint32_t energyTotal_; @@ -61,10 +60,10 @@ class Solar : public EMSdevice { // telegram 0x035A uint8_t collectorMaxTemp_; // maximum allowed collectorTemp array 1 - uint8_t tankBottomMaxTemp_; // Current value for max tank temp + uint8_t tankMaxTemp_; // Current value for max tank temp uint8_t collectorMinTemp_; // minimum allowed collectorTemp array 1 uint8_t solarPumpMode_; // 00=off, 01=PWM, 02=10V - uint8_t solarPumpMinRPM_; // minimum RPM setting, *5 % + uint8_t solarPumpMinMod_; // minimum modulation setting, *5 % uint8_t solarPumpTurnoffDiff_; // solar pump turnoff collector/tank diff uint8_t solarPumpTurnonDiff_; // solar pump turnon collector/tank diff uint8_t solarPumpKick_; // pump kick for vacuum collector, 00=off @@ -86,10 +85,18 @@ class Solar : public EMSdevice { // SM100wwStatus - 0x07AA uint8_t wwPump_; + // SM10Config - 0x96 + uint8_t wwMinTemp_; + uint8_t maxFlow_; // set this to caltulate power + uint32_t solarPower_; // calculated from maxFlow + + std::deque energy; + char type_[20]; // Solar of WWC uint8_t id_; void process_SM10Monitor(std::shared_ptr telegram); + void process_SM10Config(std::shared_ptr telegram); void process_SM100SystemConfig(std::shared_ptr telegram); void process_SM100SolarCircuitConfig(std::shared_ptr telegram); void process_SM100ParamCfg(std::shared_ptr telegram); @@ -112,7 +119,15 @@ class Solar : public EMSdevice { void process_ISM1Set(std::shared_ptr telegram); - bool set_SM100TankBottomMaxTemp(const char * value, const int8_t id); + bool set_CollectorMaxTemp(const char * value, const int8_t id); + bool set_CollectorMinTemp(const char * value, const int8_t id); + bool set_TankMaxTemp(const char * value, const int8_t id); + bool set_PumpMinMod(const char * value, const int8_t id); + bool set_wwMinTemp(const char * value, const int8_t id); + bool set_TurnonDiff(const char * value, const int8_t id); + bool set_TurnoffDiff(const char * value, const int8_t id); + + bool set_SM10MaxFlow(const char * value, const int8_t id); }; } // namespace emsesp diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 7abc3ce7c..6452baa8f 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -34,7 +34,8 @@ static const __FlashStringHelper * DeviceValueUOM_s[] __attribute__((__aligned__ F_(minutes), F_(ua), F_(bar), - F_(kw) + F_(kw), + F_(w) }; diff --git a/src/emsdevice.h b/src/emsdevice.h index 86bdf91d0..f27761672 100644 --- a/src/emsdevice.h +++ b/src/emsdevice.h @@ -57,7 +57,7 @@ enum DeviceValueType : uint8_t { // Unit Of Measurement mapping - maps to DeviceValueUOM_s in emsdevice.cpp // uom - also used with HA // sequence is important! -enum DeviceValueUOM : uint8_t { NONE = 0, DEGREES, PERCENT, LMIN, KWH, WH, HOURS, MINUTES, UA, BAR, KW, PUMP }; +enum DeviceValueUOM : uint8_t { NONE = 0, DEGREES, PERCENT, LMIN, KWH, WH, HOURS, MINUTES, UA, BAR, KW, W, PUMP }; // TAG mapping - maps to DeviceValueTAG_s in emsdevice.cpp enum DeviceValueTAG : uint8_t { diff --git a/src/locale_EN.h b/src/locale_EN.h index 7a2794e90..46ea039f6 100644 --- a/src/locale_EN.h +++ b/src/locale_EN.h @@ -80,6 +80,7 @@ MAKE_PSTR_WORD(command) MAKE_PSTR_WORD(commands) MAKE_PSTR_WORD(info) MAKE_PSTR_WORD(settings) +MAKE_PSTR_WORD(value) // devices MAKE_PSTR_WORD(boiler) @@ -94,6 +95,7 @@ MAKE_PSTR_WORD(heatpump) MAKE_PSTR_WORD(generic) MAKE_PSTR_WORD(dallassensor) MAKE_PSTR_WORD(unknown) +MAKE_PSTR_WORD(Dallassensor) // format strings MAKE_PSTR(EMSESP, "EMS-ESP") @@ -165,6 +167,7 @@ MAKE_PSTR(hours, "hours") MAKE_PSTR(ua, "uA") MAKE_PSTR(lmin, "l/min") MAKE_PSTR(kw, "kW") +MAKE_PSTR(w, "W") // TAG mapping - maps to DeviceValueTAG_s in emsdevice.cpp // use empty string if want to suppress showing tags @@ -329,6 +332,9 @@ MAKE_PSTR_LIST(enum_control, F_(off), F_(rc20), F_(rc3x)) MAKE_PSTR_LIST(enum_hamode, F_(off), F_(heat), F_(auto), F_(heat), F_(off), F_(heat), F_(auto), F_(auto), F_(auto), F_(auto)) +// solar list +MAKE_PSTR_LIST(enum_solarmode, F_(constant), F("pwm"), F("analog")) + /* * MQTT topics and full text for values and commands */ @@ -360,7 +366,7 @@ MAKE_PSTR_LIST(curFlowTemp, F("curflowtemp"), F("current flow temperature")) MAKE_PSTR_LIST(retTemp, F("rettemp"), F("return temperature")) MAKE_PSTR_LIST(switchTemp, F("switchtemp"), F("mixing switch temperature")) MAKE_PSTR_LIST(sysPress, F("syspress"), F("system pressure")) -MAKE_PSTR_LIST(boilTemp, F("boiltemp"), F("max boiler temperature")) +MAKE_PSTR_LIST(boilTemp, F("boiltemp"), F("boiler temperature")) MAKE_PSTR_LIST(exhaustTemp, F("exhausttemp"), F("exhaust temperature")) MAKE_PSTR_LIST(burnGas, F("burngas"), F("gas")) MAKE_PSTR_LIST(flameCurr, F("flamecurr"), F("flame current")) @@ -545,6 +551,8 @@ MAKE_PSTR_LIST(tankBottomTemp, F("tankbottomtemp"), F("tank bottom temperature ( MAKE_PSTR_LIST(tank2BottomTemp, F("tank2bottomtemp"), F("second tank bottom temperature (TS5)")) MAKE_PSTR_LIST(heatExchangerTemp, F("heatexchangertemp"), F("heat exchanger temperature (TS6)")) +MAKE_PSTR_LIST(collectorMaxTemp, F("collectormaxtemp"), F("maximum collector temperature")) +MAKE_PSTR_LIST(collectorMinTemp, F("collectormintemp"), F("minimum collector temperature")) MAKE_PSTR_LIST(tankMaxTemp, F("tankmaxtemp"), F("maximum tank temperature")) MAKE_PSTR_LIST(solarPumpModulation, F("solarpumpmodulation"), F("pump modulation (PS1)")) MAKE_PSTR_LIST(cylinderPumpModulation, F("cylinderpumpmodulation"), F("cylinder pump modulation (PS5)")) @@ -554,7 +562,7 @@ MAKE_PSTR_LIST(valveStatus, F("valvestatus"), F("valve status")) MAKE_PSTR_LIST(tankHeated, F("tankheated"), F("tank heated")) MAKE_PSTR_LIST(collectorShutdown, F("collectorshutdown"), F("collector shutdown")) -MAKE_PSTR_LIST(pumpWorkTime, F("pumpWorktime"), F("pump working time")) +MAKE_PSTR_LIST(pumpWorkTime, F("pumpworktime"), F("pump working time")) MAKE_PSTR_LIST(energyLastHour, F("energylasthour"), F("energy last hour")) MAKE_PSTR_LIST(energyTotal, F("energytotal"), F("energy total")) @@ -567,6 +575,13 @@ MAKE_PSTR_LIST(wwTemp5, F("wwtemp5"), F("temperature 5")) MAKE_PSTR_LIST(wwTemp7, F("wwtemp7"), F("temperature 7")) MAKE_PSTR_LIST(wwPump, F("wwpump"), F("pump")) +MAKE_PSTR_LIST(wwMinTemp, F("wwmintemp"), F("minimum temperature")) +MAKE_PSTR_LIST(pumpMinMod, F("pumpminmod"), F("minimum pump modulation")) +MAKE_PSTR_LIST(maxFlow, F("maxflow"), F("maximum solar flow")) +MAKE_PSTR_LIST(solarPower, F("solarpower"), F("actual solar power")) +MAKE_PSTR_LIST(solarPumpTurnonDiff, F("turnondiff"), F("pump turn on difference")) +MAKE_PSTR_LIST(solarPumpTurnoffDiff, F("turnoffdiff"), F("pump turn off difference")) + // switch MAKE_PSTR_LIST(activated, F("activated"), F("activated")) MAKE_PSTR_LIST(status, F("status"), F("status"))