Merge pull request #613 from hpanther/dev

Updates to the solar device to handle configuration-related telegrams
This commit is contained in:
Proddy
2020-11-17 17:50:00 +01:00
committed by GitHub
4 changed files with 127 additions and 0 deletions

View File

@@ -39,13 +39,19 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
register_telegram_type(0x07AA, F("SM100wwStatus"), false, [&](std::shared_ptr<const Telegram> t) { process_SM100wwStatus(t); });
register_telegram_type(0x07AB, F("SM100wwCommand"), false, [&](std::shared_ptr<const Telegram> t) { process_SM100wwCommand(t); });
} else {
register_telegram_type(EMS_TYPE_ParamCfg, F("ParamCfg"), false, [&](std::shared_ptr<const Telegram> t) { process_SM100ParamCfg(t); });
register_telegram_type(0x0358, F("SM100SystemConfig"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100SystemConfig(t); });
register_telegram_type(0x035A, F("SM100SolarCircuitConfig"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100SolarCircuitConfig(t); });
register_telegram_type(0x0362, F("SM100Monitor"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100Monitor(t); });
register_telegram_type(0x0363, F("SM100Monitor2"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100Monitor2(t); });
register_telegram_type(0x0366, F("SM100Config"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100Config(t); });
register_telegram_type(0x0364, F("SM100Status"), false, [&](std::shared_ptr<const Telegram> t) { process_SM100Status(t); });
register_telegram_type(0x036A, F("SM100Status2"), false, [&](std::shared_ptr<const Telegram> t) { process_SM100Status2(t); });
register_telegram_type(0x0380, F("SM100CollectorConfig"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100CollectorConfig(t); });
register_telegram_type(0x038E, F("SM100Energy"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100Energy(t); });
register_telegram_type(0x0391, F("SM100Time"), true, [&](std::shared_ptr<const Telegram> t) { process_SM100Time(t); });
register_mqtt_cmd(F("SM100Tank1MaxTemp"), [&](const char * value, const int8_t id) { return set_SM100Tank1MaxTemp(value, id); });
}
}
@@ -67,6 +73,7 @@ void Solar::device_info_web(JsonArray & root) {
print_value_json(root, F("collectorTemp"), nullptr, F_(collectorTemp), F_(degrees), json);
print_value_json(root, F("tankBottomTemp"), nullptr, F_(tankBottomTemp), F_(degrees), json);
print_value_json(root, F("tankBottomTemp2"), nullptr, F_(tankBottomTemp2), F_(degrees), json);
print_value_json(root, F("tank1MaxTempCurrent"), nullptr, F_(tank1MaxTempCurrent), F_(degrees), json);
print_value_json(root, F("heatExchangerTemp"), nullptr, F_(heatExchangerTemp), F_(degrees), json);
print_value_json(root, F("solarPumpModulation"), nullptr, F_(solarPumpModulation), F_(percent), json);
print_value_json(root, F("cylinderPumpModulation"), nullptr, F_(cylinderPumpModulation), F_(percent), json);
@@ -102,6 +109,7 @@ void Solar::show_values(uuid::console::Shell & shell) {
print_value_json(shell, F("collectorTemp"), nullptr, F_(collectorTemp), F_(degrees), json);
print_value_json(shell, F("tankBottomTemp"), nullptr, F_(tankBottomTemp), F_(degrees), json);
print_value_json(shell, F("tankBottomTemp2"), nullptr, F_(tankBottomTemp2), F_(degrees), json);
print_value_json(shell, F("tank1MaxTempCurrent"), nullptr, F_(tank1MaxTempCurrent), F_(degrees), json);
print_value_json(shell, F("heatExchangerTemp"), nullptr, F_(heatExchangerTemp), F_(degrees), json);
print_value_json(shell, F("solarPumpModulation"), nullptr, F_(solarPumpModulation), F_(percent), json);
print_value_json(shell, F("cylinderPumpModulation"), nullptr, F_(cylinderPumpModulation), F_(percent), json);
@@ -173,6 +181,7 @@ void Solar::register_mqtt_ha_config() {
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(collectorTemp), this->device_type(), "collectorTemp", F_(degrees), nullptr);
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(tankBottomTemp), this->device_type(), "tankBottomTemp", F_(degrees), nullptr);
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(tankBottomTemp2), this->device_type(), "tankBottomTemp2", F_(degrees), nullptr);
Mqtt::register_mqtt_ha_sensor(nullptr, nullptr, F_(tank1MaxTempCurrent), this->device_type(), "tank1MaxTempCurrent", F_(degrees), nullptr);
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);
@@ -205,6 +214,10 @@ bool Solar::export_values(JsonObject & json) {
json["tankBottomTemp2"] = (float)tankBottomTemp2_ / 10;
}
if (Helpers::hasValue(tank1MaxTempCurrent_)) {
json["tank1MaxTempCurrent"] = tank1MaxTempCurrent_;
}
if (Helpers::hasValue(heatExchangerTemp_)) {
json["heatExchangerTemp"] = (float)heatExchangerTemp_ / 10;
}
@@ -270,6 +283,65 @@ void Solar::process_SM10Monitor(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_value(pumpWorkMin_, 8, 3);
}
/*
* process_SM100SystemConfig - type 0x0358 EMS+ - for MS/SM100 and MS/SM200
* e.g. B0 0B FF 00 02 58 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 00 FF 01 00 00
*/
void Solar::process_SM100SystemConfig(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_value(heatTransferSystem_ , 5, 1);
changed_ |= telegram->read_value(externalTank_ , 9, 1);
changed_ |= telegram->read_value(thermalDisinfect_ , 10, 1);
changed_ |= telegram->read_value(heatMetering_ , 14, 1);
changed_ |= telegram->read_value(solarIsEnabled_ , 19, 1);
}
/*
* process_SM100SolarCircuitConfig - type 0x035A EMS+ - for MS/SM100 and MS/SM200
* e.g. B0 0B FF 00 02 5A 64 05 00 58 14 01 01 32 64 00 00 00 5A 0C
*/
void Solar::process_SM100SolarCircuitConfig(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_value(collectorTempMax_ , 0, 1);
changed_ |= telegram->read_value(tank1MaxTempCurrent_ , 3, 1);
changed_ |= telegram->read_value(collectorTempMin_ , 4, 1);
changed_ |= telegram->read_value(solarPumpMode_ , 5, 1);
changed_ |= telegram->read_value(solarPumpMinRPM_ , 6, 1);
changed_ |= telegram->read_value(solarPumpTurnoffDiff_, 7, 1);
changed_ |= telegram->read_value(solarPumpTurnonDiff_ , 8, 1);
changed_ |= telegram->read_value(solarPumpKick_ , 9, 1);
changed_ |= telegram->read_value(plainWaterMode_ , 10, 1);
changed_ |= telegram->read_value(doubleMatchFlow_ , 11, 1);
}
/* process_SM100ParamCfg - type 0xF9 EMS 1.0
* This telegram is used to inquire the min, default, max, and current values of a value that is usually read and written with another telegram ID
* The CS200 uses this method extensively to find out which values may be set in the SM100
* e.g. B0 10 F9 00 FF 02 5A 03 17 00 00 00 14 00 00 00 3C 00 00 00 5A 00 00 00 59 29 - requested with 90 B0 F9 00 11 FF 02 5A 03 AF
* byte 0 = 0xFF
* byte 1-2 = telegram ID used to write this value
* byte 3 = offset in telegram used to write this value
* byte 4 = unknown
* bytes 5..8 = minimum value
* bytes 9..12 = default value
* bytes 13..16 = maximum value
* bytes 17..20 = current value
*
* e.g. B0 0B F9 00 00 02 5A 00 00 6E
*/
void Solar::process_SM100ParamCfg(std::shared_ptr<const Telegram> telegram) {
uint16_t t_id;
uint8_t of;
int32_t min,def,max,cur;
telegram->read_value(t_id, 1);
telegram->read_value(of, 3);
telegram->read_value(min, 5);
telegram->read_value(def, 9);
telegram->read_value(max, 13);
telegram->read_value(cur, 17);
LOG_DEBUG(F("SM100ParamCfg param=0x%04X, offset=%d, min=%d, default=%d, max=%d, current=%d"),
t_id, of, min, def, max, cur);
}
/*
* SM100Monitor - type 0x0362 EMS+ - for MS/SM100 and MS/SM200
* e.g. B0 0B FF 00 02 62 00 77 01 D4 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 00 F9 80 00 80 9E - for heat exchanger temp
@@ -362,6 +434,17 @@ void Solar::process_SM100Status2(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_bitvalue(solarPump_, 10, 2); // on if bit 2 set
}
/*
* SM100CollectorConfig - type 0x0380 EMS+ - for SM100 and SM200
* e.g. B0 0B FF 00 02 80 50 64 00 00 29 01 00 00 01
*/
void Solar::process_SM100CollectorConfig(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_value(climateZone_, 0, 1);
changed_ |= telegram->read_value(collector1Area_, 3, 2);
changed_ |= telegram->read_value(collector1Type_, 5, 1);
}
/*
* SM100Energy - type 0x038E EMS+ for energy readings
* e.g. 30 00 FF 00 02 8E 00 00 00 00 00 00 06 C5 00 00 76 35
@@ -406,4 +489,15 @@ void Solar::process_ISM1Set(std::shared_ptr<const Telegram> telegram) {
changed_ |= telegram->read_value(setpoint_maxBottomTemp_, 6);
}
bool Solar::set_SM100Tank1MaxTemp(const char * value, const int8_t id) {
int temperature;
if(! Helpers::value2number(value, temperature)) return false;
tank1MaxTempCurrent_=temperature;
uint8_t data=(uint8_t) temperature;
// 90 30 FF 03 02 5A 59 B3
EMSdevice::write_command(0x35A, 0x03, &data, sizeof(data), 0);
return true;
}
} // namespace emsesp

View File

@@ -66,10 +66,37 @@ class Solar : public EMSdevice {
uint8_t configFlag_ = EMS_VALUE_BOOL_NOTSET;
uint8_t userFlag_ = EMS_VALUE_BOOL_NOTSET;
// telegram 0x0358
uint8_t heatTransferSystem_ = EMS_VALUE_UINT_NOTSET; // Umladesystem, 00=no
uint8_t externalTank_ = EMS_VALUE_UINT_NOTSET; // Heat exchanger, 00=no
uint8_t thermalDisinfect_ = EMS_VALUE_UINT_NOTSET; // Daily heatup for disinfection, 00=no
uint8_t heatMetering_ = EMS_VALUE_UINT_NOTSET; // Wärmemengenzählung, 00=no
uint8_t solarIsEnabled_ = EMS_VALUE_UINT_NOTSET; // System enable, 00=no
// telegram 0x035A
uint8_t collectorTempMax_ = EMS_VALUE_UINT_NOTSET; // maximum allowable temperature for collector
uint8_t tank1MaxTempCurrent_ = EMS_VALUE_UINT_NOTSET; // Current value for max tank temp
uint8_t collectorTempMin_ = EMS_VALUE_UINT_NOTSET; // minimum allowable temperature for collector
uint8_t solarPumpMode_ = EMS_VALUE_UINT_NOTSET; // 00=off, 01=PWM, 02=10V
uint8_t solarPumpMinRPM_ = EMS_VALUE_UINT_NOTSET; // minimum RPM setting, *5 %
uint8_t solarPumpTurnoffDiff_ = EMS_VALUE_UINT_NOTSET; // solar pump turnoff collector/tank diff
uint8_t solarPumpTurnonDiff_ = EMS_VALUE_UINT_NOTSET; // solar pump turnon collector/tank diff
uint8_t solarPumpKick_ = EMS_VALUE_UINT_NOTSET; // pump kick for vacuum collector, 00=off
uint8_t plainWaterMode_ = EMS_VALUE_UINT_NOTSET; // system does not use antifreeze, 00=off
uint8_t doubleMatchFlow_ = EMS_VALUE_UINT_NOTSET; // double Match Flow, 00=off
// telegram 0x380
uint8_t climateZone_ = EMS_VALUE_UINT_NOTSET; // climate zone identifier
uint16_t collector1Area_ = EMS_VALUE_USHORT_NOTSET;// Area of collector field 1
uint8_t collector1Type_ = EMS_VALUE_UINT_NOTSET; // Type of collector field 1, 01=flat, 02=vacuum
bool changed_ = false;
bool mqtt_ha_config_ = false; // for HA MQTT Discovery
void process_SM10Monitor(std::shared_ptr<const Telegram> telegram);
void process_SM100SystemConfig(std::shared_ptr<const Telegram> telegram);
void process_SM100SolarCircuitConfig(std::shared_ptr<const Telegram> telegram);
void process_SM100ParamCfg(std::shared_ptr<const Telegram> telegram);
void process_SM100Monitor(std::shared_ptr<const Telegram> telegram);
void process_SM100Monitor2(std::shared_ptr<const Telegram> telegram);
@@ -77,6 +104,7 @@ class Solar : public EMSdevice {
void process_SM100Status(std::shared_ptr<const Telegram> telegram);
void process_SM100Status2(std::shared_ptr<const Telegram> telegram);
void process_SM100CollectorConfig(std::shared_ptr<const Telegram> telegram);
void process_SM100Energy(std::shared_ptr<const Telegram> telegram);
void process_SM100Time(std::shared_ptr<const Telegram> telegram);
@@ -86,6 +114,9 @@ class Solar : public EMSdevice {
void process_ISM1StatusMessage(std::shared_ptr<const Telegram> telegram);
void process_ISM1Set(std::shared_ptr<const Telegram> telegram);
bool set_SM100Tank1MaxTemp(const char * value, const int8_t id);
};
} // namespace emsesp

View File

@@ -241,6 +241,7 @@ class EMSdevice {
// type IDs
static constexpr uint16_t EMS_TYPE_VERSION = 0x02; // type ID for Version information. Generic across all EMS devices.
static constexpr uint16_t EMS_TYPE_UBADevices = 0x07; // EMS connected devices
static constexpr uint16_t EMS_TYPE_ParamCfg = 0xF9; // EMS parameter min/default/max/current
// device flags: The lower 4 bits hold the unique identifier, the upper 4 bits are used for specific flags
static constexpr uint8_t EMS_DEVICE_FLAG_NONE = 0;

View File

@@ -203,6 +203,7 @@ MAKE_PSTR(UBAuptime, "Boiler total uptime")
MAKE_PSTR(collectorTemp, "Collector temperature (TS1)")
MAKE_PSTR(tankBottomTemp, "Bottom temperature (TS2)")
MAKE_PSTR(tankBottomTemp2, "Bottom temperature (TS5)")
MAKE_PSTR(tank1MaxTempCurrent, "Maximum Tank temperature")
MAKE_PSTR(heatExchangerTemp, "Heat exchanger temperature (TS6)")
MAKE_PSTR(solarPumpModulation, "Solar pump modulation (PS1)")
MAKE_PSTR(cylinderPumpModulation, "Cylinder pump modulation (PS5)")