mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 16:29:51 +03:00
Added all known solar config items and implemented 0xF9 telegram correctly
This commit is contained in:
@@ -39,22 +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(0x035A, F("SM100Tank1MaxTemp"), false, [&](std::shared_ptr<const Telegram> t) { process_SM100Tank1MaxTemp(t); });
|
||||
}
|
||||
// EMSESP::send_read_request(0x035A, device_id);
|
||||
// This is a hack right now, need to update TXService to support sending F9 packets
|
||||
//uint8_t msg[]="8B B0 F9 00 11 FF 02 5A 03 00";
|
||||
//msg[sizeof(msg)-2] = EMSESP::rxservice_.calculate_crc(msg, sizeof(msg)-2);
|
||||
//EMSESP::send_raw_telegram((const char*)msg);
|
||||
|
||||
uint8_t msg[]={0x11, 0xFF, 0x02, 0x5A, 0x03};
|
||||
EMSdevice::write_command(EMS_TYPE_RegRead, 0x00, msg, sizeof(msg), EMS_TYPE_RegRead);
|
||||
register_mqtt_cmd(F("SM100Tank1MaxTemp"), [&](const char * value, const int8_t id) { return set_SM100Tank1MaxTemp(value, id); });
|
||||
}
|
||||
}
|
||||
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_ISM) {
|
||||
@@ -75,7 +72,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("tank1MaxTemp"), nullptr, F_(tank1MaxTempCurrent), 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);
|
||||
@@ -110,7 +107,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("tank1MaxTemp"), nullptr, F_(tank1MaxTempCurrent), 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);
|
||||
@@ -182,7 +179,7 @@ void Solar::register_mqtt_ha_config(bool force) {
|
||||
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(), "tank1MaxTemp", 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);
|
||||
@@ -216,7 +213,7 @@ bool Solar::export_values(JsonObject & json) {
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(tank1MaxTempCurrent_)) {
|
||||
json["tankMaximumTemp"] = tank1MaxTempCurrent_;
|
||||
json["tank1MaxTempCurrent"] = tank1MaxTempCurrent_;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(heatExchangerTemp_)) {
|
||||
@@ -285,26 +282,60 @@ void Solar::process_SM10Monitor(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
|
||||
/*
|
||||
* process_SM100Tank1MaxTemp - type 0x035A EMS+ - for MS/SM100 and MS/SM200
|
||||
* 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
|
||||
* bytes 0-1 = packet format designator
|
||||
* bytes 2..5 = minimum value
|
||||
* bytes 6..9 = default value
|
||||
* bytes 10..13 = maximum value
|
||||
* bytes 14..17 = current value
|
||||
* e.g, FD 3F - requested with 90 B0 F7 00 FF FF 02 5A B0
|
||||
* process_SM100SystemConfig - type 0x0358 EMS+ - for MS/SM100 and MS/SM200
|
||||
*/
|
||||
void Solar::process_SM100Tank1MaxTemp(std::shared_ptr<const Telegram> telegram) {
|
||||
int16_t designator;
|
||||
telegram->read_value(designator, 0);
|
||||
LOG_DEBUG(F("SM100Tank1MaxTemp designator 0x%02X"), designator);
|
||||
if(designator==0x0317) // The telegram has the right form
|
||||
{
|
||||
changed_ |= telegram->read_value(tank1MaxTempMinimum_, 2);
|
||||
changed_ |= telegram->read_value(tank1MaxTempDefault_, 6);
|
||||
changed_ |= telegram->read_value(tank1MaxTempMaximum_, 10);
|
||||
changed_ |= telegram->read_value(tank1MaxTempCurrent_, 14);
|
||||
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
|
||||
*/
|
||||
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 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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -399,6 +430,16 @@ 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
|
||||
*/
|
||||
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
|
||||
@@ -436,4 +477,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 temp;
|
||||
if(! Helpers::value2number(value, temp)) return false;
|
||||
tank1MaxTempCurrent_=temp;
|
||||
unsigned char transport_temp=(unsigned char) temp;
|
||||
// 90 30 FF 03 02 5A 59 B3
|
||||
EMSdevice::write_command(0x35A, 0x03, &transport_temp, sizeof(transport_temp), 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -46,10 +46,6 @@ class Solar : public EMSdevice {
|
||||
static uuid::log::Logger logger_;
|
||||
void register_mqtt_ha_config(bool force);
|
||||
|
||||
uint32_t tank1MaxTempMinimum_ = EMS_VALUE_ULONG_NOTSET; // Min value for max tank temp
|
||||
uint32_t tank1MaxTempDefault_ = EMS_VALUE_ULONG_NOTSET; // Default value for max tank temp
|
||||
uint32_t tank1MaxTempMaximum_ = EMS_VALUE_ULONG_NOTSET; // Max value for max tank temp
|
||||
uint32_t tank1MaxTempCurrent_ = EMS_VALUE_ULONG_NOTSET; // Current value for max tank temp
|
||||
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)
|
||||
int16_t tankBottomTemp2_ = EMS_VALUE_SHORT_NOTSET; // TS5: Temperature sensor 2 cylinder, bottom, or swimming pool (solar thermal system)
|
||||
@@ -70,11 +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_SM100Tank1MaxTemp(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);
|
||||
|
||||
@@ -82,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_SM100wwTemperature(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -90,6 +113,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
|
||||
|
||||
@@ -241,7 +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_RegRead = 0xF9; // EMS register read
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user