mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-10 17:59:53 +03:00
Merge remote-tracking branch 'origin/v3.4' into dev
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -25,9 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Boiler : public EMSdevice {
|
||||
public:
|
||||
Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
virtual bool publish_ha_device_config();
|
||||
Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
@@ -52,50 +50,46 @@ class Boiler : public EMSdevice {
|
||||
static constexpr uint16_t EMS_TYPE_UBAInformation = 0x495;
|
||||
static constexpr uint16_t EMS_TYPE_UBAEnergySupplied = 0x494;
|
||||
|
||||
static constexpr uint8_t EMS_BOILER_SELFLOWTEMP_HEATING = 20; // was originally 70, changed to 30 for issue #193, then to 20 with issue #344
|
||||
|
||||
// ww
|
||||
uint8_t wwSetTemp_; // Warm Water set temperature
|
||||
uint8_t wwSelTemp_; // Warm Water selected temperature
|
||||
uint8_t wwSelTempLow_; // Warm Water lower selected temperature
|
||||
uint8_t wwSelTempOff_; // Warm Water selected temperature for off position
|
||||
uint8_t wwSelTempSingle_; // Warm Water single charge temperature
|
||||
uint8_t wwSetTemp_; // DHW set temperature
|
||||
uint8_t wwSelTemp_; // DHW selected temperature
|
||||
uint8_t wwSelTempLow_; // DHW lower selected temperature
|
||||
uint8_t wwSelTempOff_; // DHW selected temperature for off position
|
||||
uint8_t wwSelTempSingle_; // DHW single charge temperature
|
||||
uint8_t wwType_; // 0-off, 1-flow, 2-flowbuffer, 3-buffer, 4-layered buffer
|
||||
uint8_t wwComfort_; // WW comfort mode
|
||||
uint8_t wwCircPump_; // Warm Water circulation pump available
|
||||
uint8_t wwChargeType_; // Warm Water charge type (pump or 3-way-valve)
|
||||
uint8_t wwDisinfectionTemp_; // Warm Water disinfection temperature to prevent infection
|
||||
uint8_t wwCircMode_; // Warm Water circulation pump mode
|
||||
uint8_t wwCircPump_; // DHW circulation pump available
|
||||
uint8_t wwChargeType_; // DHW charge type (pump or 3-way-valve)
|
||||
uint8_t wwDisinfectionTemp_; // DHW disinfection temperature to prevent infection
|
||||
uint8_t wwCircMode_; // DHW circulation pump mode
|
||||
uint8_t wwCirc_; // Circulation on/off
|
||||
uint16_t wwCurTemp_; // Warm Water current temperature
|
||||
uint16_t wwCurTemp2_; // Warm Water current temperature storage
|
||||
uint8_t wwCurFlow_; // Warm Water current flow temp in l/min
|
||||
uint16_t wwStorageTemp1_; // warm water storage temp 1
|
||||
uint16_t wwStorageTemp2_; // warm water storage temp 2
|
||||
uint8_t wwActivated_; // Warm Water activated
|
||||
uint8_t wwOneTime_; // Warm Water one time function on/off
|
||||
uint8_t wwDisinfect_; // Warm Water disinfection on/off
|
||||
uint8_t wwCharging_; // Warm Water charging on/off
|
||||
uint8_t wwRecharging_; // Warm Water recharge on/off
|
||||
uint8_t wwTempOK_; // Warm Water temperature ok on/off
|
||||
uint16_t wwCurTemp_; // DHW current temperature
|
||||
uint16_t wwCurTemp2_; // DHW current temperature storage
|
||||
uint8_t wwCurFlow_; // DHW current flow temp in l/min
|
||||
uint16_t wwStorageTemp1_; // DHW storage temp 1
|
||||
uint16_t wwStorageTemp2_; // DHW storage temp 2
|
||||
uint8_t wwActivated_; // DHW activated
|
||||
uint8_t wwOneTime_; // DHW one time function on/off
|
||||
uint8_t wwDisinfect_; // DHW disinfection on/off
|
||||
uint8_t wwCharging_; // DHW charging on/off
|
||||
uint8_t wwRecharging_; // DHW recharge on/off
|
||||
uint8_t wwTempOK_; // DHW temperature ok on/off
|
||||
uint8_t wwActive_; //
|
||||
uint8_t wwHeat_; // 3-way valve on WW
|
||||
uint8_t ww3wayValve_; // 3-way valve on WW
|
||||
uint8_t wwSetPumpPower_; // ww pump speed/power?
|
||||
uint8_t wwFlowTempOffset_; // Boiler offset for ww heating
|
||||
uint8_t wwMaxPower_; // Warm Water maximum power
|
||||
uint32_t wwStarts_; // Warm Water starts
|
||||
uint32_t wwStarts2_; // Warm water control starts
|
||||
uint32_t wwWorkM_; // Warm Water minutes
|
||||
uint8_t wwMaxPower_; // DHW maximum power
|
||||
uint32_t wwStarts_; // DHW starts
|
||||
uint32_t wwStarts2_; // DHW control starts
|
||||
uint32_t wwWorkM_; // DHW minutes
|
||||
int8_t wwHystOn_;
|
||||
int8_t wwHystOff_;
|
||||
uint8_t wwTapActivated_; // maintenance-mode to switch DHW off
|
||||
uint16_t wwMixerTemp_; // mixing temperature
|
||||
uint16_t wwTankMiddleTemp_; // Tank middle temperature (TS3)
|
||||
uint8_t wwTapActivated_; // maintenance-mode to switch DHW off
|
||||
uint16_t wwMixerTemp_; // mixing temperature
|
||||
uint16_t wwCylMiddleTemp_; // Cyl middle temperature (TS3)
|
||||
|
||||
// main
|
||||
uint8_t id_; // product id
|
||||
uint8_t dummy8u_; // for commands with no output
|
||||
uint8_t dummybool_; // for commands with no output
|
||||
uint8_t reset_; // for reset command
|
||||
uint8_t heatingActive_; // Central heating is on/off
|
||||
uint8_t tapwaterActive_; // Hot tap water is on/off
|
||||
uint8_t selFlowTemp_; // Selected flow temperature
|
||||
@@ -110,10 +104,12 @@ class Boiler : public EMSdevice {
|
||||
uint16_t boilTemp_; // Boiler temperature
|
||||
uint16_t exhaustTemp_; // Exhaust temperature
|
||||
uint8_t burnGas_; // Gas on/off
|
||||
uint8_t burnGas2_; // Gas stage 2 on/off
|
||||
uint16_t flameCurr_; // Flame current in micro amps
|
||||
uint8_t heatingPump_; // Boiler heating pump on/off
|
||||
uint8_t fanWork_; // Fan on/off
|
||||
uint8_t ignWork_; // Ignition on/off
|
||||
uint8_t oilPreHeat_; // oil preheating on
|
||||
uint8_t heatingActivated_; // Heating activated on the boiler
|
||||
uint8_t heatingTemp_; // Heating temperature setting on the boiler
|
||||
uint8_t pumpModMax_; // Boiler circuit pump modulation max. power %
|
||||
@@ -131,7 +127,7 @@ class Boiler : public EMSdevice {
|
||||
uint32_t burnWorkMin_; // Total burner operating time
|
||||
uint32_t heatWorkMin_; // Total heat operating time
|
||||
uint32_t UBAuptime_; // Total UBA working hours
|
||||
char lastCode_[60]; // last error code
|
||||
char lastCode_[75]; // last error code
|
||||
char serviceCode_[4]; // 3 character status/service code
|
||||
uint16_t serviceCodeNumber_; // error/service code
|
||||
|
||||
@@ -139,21 +135,21 @@ class Boiler : public EMSdevice {
|
||||
uint32_t upTimeControl_; // Operating time control
|
||||
uint32_t upTimeCompHeating_; // Operating time compressor heating
|
||||
uint32_t upTimeCompCooling_; // Operating time compressor cooling
|
||||
uint32_t upTimeCompWw_; // Operating time compressor warm water
|
||||
uint32_t upTimeCompWw_; // Operating time compressor DHW
|
||||
uint32_t upTimeCompPool_; // Operating time compressor pool
|
||||
uint32_t totalCompStarts_; // Total Commpressor control starts
|
||||
uint32_t heatingStarts_; // Heating control starts
|
||||
uint32_t coolingStarts_; // Cooling control starts
|
||||
uint32_t poolStarts_; // Warm water control starts
|
||||
uint32_t poolStarts_; // DHW control starts
|
||||
uint32_t nrgConsTotal_; // Energy consumption total
|
||||
uint32_t nrgConsCompTotal_; // Energy consumption compressor total
|
||||
uint32_t nrgConsCompHeating_; // Energy consumption compressor heating
|
||||
uint32_t nrgConsCompWw_; // Energy consumption compressor warm water
|
||||
uint32_t nrgConsCompWw_; // Energy consumption compressor DHW
|
||||
uint32_t nrgConsCompCooling_; // Energy consumption compressor cooling
|
||||
uint32_t nrgConsCompPool_; // Energy consumption compressor pool
|
||||
uint32_t nrgSuppTotal_; // Energy supplied total
|
||||
uint32_t nrgSuppHeating_; // Energy supplied heating
|
||||
uint32_t nrgSuppWw_; // Energy supplied warm water
|
||||
uint32_t nrgSuppWw_; // Energy supplied DHW
|
||||
uint32_t nrgSuppCooling_; // Energy supplied cooling
|
||||
uint32_t nrgSuppPool_; // Energy supplied pool
|
||||
uint32_t auxElecHeatNrgConsTotal_; // Auxiliary electrical heater energy consumption total
|
||||
|
||||
@@ -22,15 +22,8 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Connect, EMSdevice::DeviceType::CONNECT);
|
||||
|
||||
uuid::log::Logger Connect::logger_{F_(connect), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Connect::Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Connect::Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
}
|
||||
|
||||
// publish HA config
|
||||
bool Connect::publish_ha_device_config() {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
@@ -25,12 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Connect : public EMSdevice {
|
||||
public:
|
||||
Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
virtual bool publish_ha_device_config();
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -22,15 +22,8 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Controller, EMSdevice::DeviceType::CONTROLLER);
|
||||
|
||||
uuid::log::Logger Controller::logger_{F_(controller), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Controller::Controller(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Controller::Controller(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
}
|
||||
|
||||
// publish HA config
|
||||
bool Controller::publish_ha_device_config() {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
@@ -25,12 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Controller : public EMSdevice {
|
||||
public:
|
||||
Controller(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
virtual bool publish_ha_device_config();
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
Controller(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -22,15 +22,8 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Gateway, EMSdevice::DeviceType::GATEWAY);
|
||||
|
||||
uuid::log::Logger Gateway::logger_{F_(gateway), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Gateway::Gateway(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Gateway::Gateway(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
}
|
||||
|
||||
// publish HA config
|
||||
bool Gateway::publish_ha_device_config() {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
@@ -25,12 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Gateway : public EMSdevice {
|
||||
public:
|
||||
Gateway(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
virtual bool publish_ha_device_config();
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
Gateway(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -24,23 +24,18 @@ REGISTER_FACTORY(Generic, EMSdevice::DeviceType::GENERIC);
|
||||
|
||||
uuid::log::Logger Generic::logger_{F_(generic), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Generic::Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Generic::Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// RF-Sensor 0x40 sending temperature in telegram 0x435, see https://github.com/emsesp/EMS-ESP32/issues/103
|
||||
if (device_id == 0x40) {
|
||||
register_telegram_type(0x435, F("RFSensorMessage"), false, MAKE_PF_CB(process_RFSensorMessage));
|
||||
register_device_value(TAG_NONE, &rfTemp_, DeviceValueType::SHORT, FL_(div10), FL_(RFTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_NONE, &rfTemp_, DeviceValueType::SHORT, FL_(div10), FL_(RFTemp), DeviceValueUOM::DEGREES);
|
||||
}
|
||||
}
|
||||
|
||||
// publish HA config
|
||||
bool Generic::publish_ha_device_config() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// type 0x435 rf remote sensor
|
||||
void Generic::process_RFSensorMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(rfTemp_, 0)); // is * 10
|
||||
has_update(telegram, rfTemp_, 0); // is * 10
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -25,9 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Generic : public EMSdevice {
|
||||
public:
|
||||
Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
virtual bool publish_ha_device_config();
|
||||
Generic(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
@@ -22,50 +22,15 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Heatpump, EMSdevice::DeviceType::HEATPUMP);
|
||||
|
||||
uuid::log::Logger Heatpump::logger_{F_(heatpump), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Heatpump::Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// telegram handlers
|
||||
register_telegram_type(0x042B, F("HP1"), true, MAKE_PF_CB(process_HPMonitor1));
|
||||
register_telegram_type(0x047B, F("HP2"), true, MAKE_PF_CB(process_HPMonitor2));
|
||||
|
||||
// device values
|
||||
register_device_value(TAG_NONE, &id_, DeviceValueType::UINT, nullptr, FL_(ID), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_NONE, &airHumidity_, DeviceValueType::UINT, FL_(div2), FL_(airHumidity), DeviceValueUOM::PERCENT);
|
||||
register_device_value(TAG_NONE, &dewTemperature_, DeviceValueType::UINT, nullptr, FL_(dewTemperature), DeviceValueUOM::DEGREES);
|
||||
|
||||
id_ = product_id;
|
||||
}
|
||||
|
||||
// publish HA config
|
||||
bool Heatpump::publish_ha_device_config() {
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_HA_CONFIG> doc;
|
||||
doc["uniq_id"] = F_(heatpump);
|
||||
doc["ic"] = F_(icondevice);
|
||||
|
||||
char stat_t[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s", Mqtt::base().c_str(), Mqtt::tag_to_topic(device_type(), DeviceValueTAG::TAG_NONE).c_str());
|
||||
doc["stat_t"] = stat_t;
|
||||
|
||||
char name_s[40];
|
||||
snprintf(name_s, sizeof(name_s), FSTR_(productid_fmt), device_type_name().c_str());
|
||||
doc["name"] = name_s;
|
||||
|
||||
doc["val_tpl"] = FJSON("{{value_json.id}}");
|
||||
JsonObject dev = doc.createNestedObject("dev");
|
||||
dev["name"] = FJSON("EMS-ESP Heat Pump");
|
||||
dev["sw"] = EMSESP_APP_VERSION;
|
||||
dev["mf"] = brand_to_string();
|
||||
dev["mdl"] = this->name();
|
||||
JsonArray ids = dev.createNestedArray("ids");
|
||||
ids.add("ems-esp-heatpump");
|
||||
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/heatpump/config", Mqtt::base().c_str());
|
||||
Mqtt::publish_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
|
||||
|
||||
return true;
|
||||
register_device_value(DeviceValueTAG::TAG_NONE, &airHumidity_, DeviceValueType::UINT, FL_(div2), FL_(airHumidity), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_NONE, &dewTemperature_, DeviceValueType::UINT, nullptr, FL_(dewTemperature), DeviceValueUOM::DEGREES);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -73,8 +38,8 @@ bool Heatpump::publish_ha_device_config() {
|
||||
* e.g. "38 10 FF 00 03 7B 08 24 00 4B"
|
||||
*/
|
||||
void Heatpump::process_HPMonitor2(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(dewTemperature_, 0));
|
||||
has_update(telegram->read_value(airHumidity_, 1));
|
||||
has_update(telegram, dewTemperature_, 0);
|
||||
has_update(telegram, airHumidity_, 1);
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
@@ -90,4 +55,4 @@ void Heatpump::process_HPMonitor1(std::shared_ptr<const Telegram> telegram) {
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
} // namespace emsesp
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -25,16 +25,11 @@ namespace emsesp {
|
||||
|
||||
class Heatpump : public EMSdevice {
|
||||
public:
|
||||
Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
virtual bool publish_ha_device_config();
|
||||
Heatpump(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
uint8_t airHumidity_;
|
||||
uint8_t dewTemperature_;
|
||||
uint8_t id_;
|
||||
|
||||
void process_HPMonitor1(std::shared_ptr<const Telegram> telegram);
|
||||
void process_HPMonitor2(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
@@ -24,41 +24,59 @@ REGISTER_FACTORY(Mixer, EMSdevice::DeviceType::MIXER);
|
||||
|
||||
uuid::log::Logger Mixer::logger_{F_(mixer), uuid::log::Facility::CONSOLE};
|
||||
|
||||
Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
// Pool module
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_MP) {
|
||||
register_telegram_type(0x5BA, F("HpPoolStatus"), true, MAKE_PF_CB(process_HpPoolStatus));
|
||||
type_ = Type::MP;
|
||||
register_device_value(TAG_NONE, &id_, DeviceValueType::UINT, nullptr, FL_(ID), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_NONE, &poolTemp_, DeviceValueType::SHORT, FL_(div10), FL_(poolTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_NONE, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_NONE, &poolShunt_, DeviceValueType::UINT, nullptr, FL_(poolShunt), DeviceValueUOM::PERCENT);
|
||||
register_device_value(DeviceValueTAG::TAG_NONE, &poolTemp_, DeviceValueType::SHORT, FL_(div10), FL_(poolTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_NONE, &poolShuntStatus_, DeviceValueType::ENUM, FL_(enum_shunt), FL_(poolShuntStatus), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_NONE, &poolShunt_, DeviceValueType::UINT, nullptr, FL_(poolShunt), DeviceValueUOM::PERCENT);
|
||||
}
|
||||
|
||||
// EMS+
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_MMPLUS) {
|
||||
if (device_id >= 0x20 && device_id <= 0x27) {
|
||||
register_telegram_type(device_id - 0x20 + 0x02D7, F("MMPLUSStatusMessage_HC"), true, MAKE_PF_CB(process_MMPLUSStatusMessage_HC));
|
||||
register_telegram_type(device_id - 0x20 + 0x02D7, F("MMPLUSStatusMessage_HC"), false, MAKE_PF_CB(process_MMPLUSStatusMessage_HC));
|
||||
// register_telegram_type(device_id - 0x20 + 0x02E1, F("MMPLUSStetMessage_HC"), true, MAKE_PF_CB(process_MMPLUSSetMessage_HC));
|
||||
type_ = Type::HC;
|
||||
hc_ = device_id - 0x20 + 1;
|
||||
uint8_t tag = TAG_HC1 + hc_ - 1;
|
||||
register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, FL_(ID), DeviceValueUOM::NONE);
|
||||
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
|
||||
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(mixerStatus), DeviceValueUOM::PERCENT);
|
||||
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, nullptr, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp));
|
||||
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump));
|
||||
} else if (device_id >= 0x28 && device_id <= 0x29) {
|
||||
register_telegram_type(device_id - 0x28 + 0x0331, F("MMPLUSStatusMessage_WWC"), true, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC));
|
||||
register_telegram_type(device_id - 0x28 + 0x0331, F("MMPLUSStatusMessage_WWC"), false, MAKE_PF_CB(process_MMPLUSStatusMessage_WWC));
|
||||
register_telegram_type(device_id - 0x28 + 0x0313, F("MMPLUSConfigMessage_WWC"), true, MAKE_PF_CB(process_MMPLUSConfigMessage_WWC));
|
||||
// register_telegram_type(device_id - 0x28 + 0x033B, F("MMPLUSSetMessage_WWC"), true, MAKE_PF_CB(process_MMPLUSSetMessage_WWC));
|
||||
type_ = Type::WWC;
|
||||
hc_ = device_id - 0x28 + 1;
|
||||
uint8_t tag = TAG_WWC1 + hc_ - 1;
|
||||
register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, FL_(ID), DeviceValueUOM::NONE);
|
||||
uint8_t tag = DeviceValueTAG::TAG_WWC1 + hc_ - 1;
|
||||
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(wwTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(wwPumpStatus), DeviceValueUOM::NONE);
|
||||
register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(wwTempStatus), DeviceValueUOM::NONE);
|
||||
|
||||
register_device_value(tag, &wwMaxTemp_, DeviceValueType::UINT, nullptr, FL_(wwMaxTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwMaxTemp));
|
||||
register_device_value(tag, &wwDiffTemp_, DeviceValueType::INT, nullptr, FL_(wwDiffTemp), DeviceValueUOM::DEGREES_R, MAKE_CF_CB(set_wwDiffTemp));
|
||||
register_device_value(tag,
|
||||
&wwDisinfectionTemp_,
|
||||
DeviceValueType::UINT,
|
||||
nullptr,
|
||||
FL_(wwDisinfectionTemp),
|
||||
DeviceValueUOM::DEGREES,
|
||||
MAKE_CF_CB(set_wwDisinfectionTemp));
|
||||
register_device_value(tag, &wwReducedTemp_, DeviceValueType::UINT, nullptr, FL_(wwRedTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwReducedTemp));
|
||||
register_device_value(tag, &wwRequiredTemp_, DeviceValueType::UINT, nullptr, FL_(wwRequiredTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_wwRequiredTemp));
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA_WW,
|
||||
&wwCircPump_,
|
||||
DeviceValueType::BOOL,
|
||||
nullptr,
|
||||
FL_(wwCircPump),
|
||||
DeviceValueUOM::NONE,
|
||||
MAKE_CF_CB(set_wwCircPump));
|
||||
register_device_value(tag, &wwCircMode_, DeviceValueType::ENUM, FL_(enum_wwCircMode), FL_(wwCircMode), DeviceValueUOM::NONE, MAKE_CF_CB(set_wwCircMode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,17 +85,16 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
||||
register_telegram_type(0x00AA, F("MMConfigMessage"), true, MAKE_PF_CB(process_MMConfigMessage));
|
||||
register_telegram_type(0x00AB, F("MMStatusMessage"), false, MAKE_PF_CB(process_MMStatusMessage));
|
||||
register_telegram_type(0x00AC, F("MMSetMessage"), false, MAKE_PF_CB(process_MMSetMessage));
|
||||
// EMSESP::send_read_request(0xAA, device_id);
|
||||
type_ = Type::HC;
|
||||
hc_ = device_id - 0x20 + 1;
|
||||
uint8_t tag = TAG_HC1 + hc_ - 1;
|
||||
register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, FL_(ID), DeviceValueUOM::NONE);
|
||||
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
|
||||
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(mixerStatus), DeviceValueUOM::PERCENT);
|
||||
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, nullptr, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp));
|
||||
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump));
|
||||
register_device_value(tag, &activated_, DeviceValueType::BOOL, nullptr, FL_(activated), DeviceValueUOM::NONE, MAKE_CF_CB(set_activated));
|
||||
register_device_value(tag, &setValveTime_, DeviceValueType::UINT, FL_(mul10), FL_(mixerSetTime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_setValveTime), 1, 12);
|
||||
register_device_value(
|
||||
tag, &setValveTime_, DeviceValueType::UINT, FL_(mul10), FL_(mixerSetTime), DeviceValueUOM::SECONDS, MAKE_CF_CB(set_setValveTime), 10, 120);
|
||||
}
|
||||
|
||||
// HT3
|
||||
@@ -87,99 +104,32 @@ Mixer::Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
||||
// register_telegram_type(0x0123, F("IPMSetMessage"), false, MAKE_PF_CB(process_IPMSetMessage));
|
||||
type_ = Type::HC;
|
||||
hc_ = device_id - 0x20 + 1;
|
||||
uint8_t tag = TAG_HC1 + hc_ - 1;
|
||||
register_device_value(tag, &id_, DeviceValueType::UINT, nullptr, FL_(ID), DeviceValueUOM::NONE);
|
||||
uint8_t tag = DeviceValueTAG::TAG_HC1 + hc_ - 1;
|
||||
register_device_value(tag, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES);
|
||||
register_device_value(tag, &status_, DeviceValueType::INT, nullptr, FL_(mixerStatus), DeviceValueUOM::PERCENT);
|
||||
register_device_value(tag, &flowSetTemp_, DeviceValueType::UINT, nullptr, FL_(flowSetTemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_flowSetTemp));
|
||||
register_device_value(tag, &pumpStatus_, DeviceValueType::BOOL, nullptr, FL_(pumpStatus), DeviceValueUOM::NONE, MAKE_CF_CB(set_pump));
|
||||
register_device_value(tag, &flowTempVf_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempVf), DeviceValueUOM::DEGREES);
|
||||
}
|
||||
|
||||
id_ = product_id;
|
||||
}
|
||||
|
||||
// publish HA config
|
||||
bool Mixer::publish_ha_device_config() {
|
||||
// if we don't have valid values for this HC don't add it ever again
|
||||
if (!Helpers::hasValue(pumpStatus_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_HA_CONFIG> doc;
|
||||
|
||||
char uniq_id[20];
|
||||
if (type_ == Type::MP) {
|
||||
snprintf(uniq_id, sizeof(uniq_id), "MixerMP");
|
||||
} else {
|
||||
snprintf(uniq_id, sizeof(uniq_id), "Mixer%02X", device_id() - 0x20 + 1);
|
||||
}
|
||||
doc["uniq_id"] = uniq_id;
|
||||
|
||||
doc["ic"] = F_(icondevice);
|
||||
|
||||
char stat_t[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s", Mqtt::base().c_str(), Mqtt::tag_to_topic(device_type(), DeviceValueTAG::TAG_NONE).c_str());
|
||||
doc["stat_t"] = stat_t;
|
||||
|
||||
char name[20];
|
||||
if (type_ == Type::MP) {
|
||||
snprintf(name, sizeof(name), "Mixer MP");
|
||||
} else {
|
||||
snprintf(name, sizeof(name), "Mixer %02X", device_id() - 0x20 + 1);
|
||||
}
|
||||
doc["name"] = name;
|
||||
|
||||
char tpl[30];
|
||||
if (type_ == Type::HC) {
|
||||
snprintf(tpl, sizeof(tpl), "{{value_json.hc%d.id}}", device_id() - 0x20 + 1);
|
||||
} else if (type_ == Type::WWC) {
|
||||
snprintf(tpl, sizeof(tpl), "{{value_json.wwc%d.id}}", device_id() - 0x28 + 1);
|
||||
} else {
|
||||
snprintf(tpl, sizeof(tpl), "{{value_json.id}}");
|
||||
}
|
||||
doc["val_tpl"] = tpl;
|
||||
|
||||
JsonObject dev = doc.createNestedObject("dev");
|
||||
dev["name"] = FJSON("EMS-ESP Mixer");
|
||||
dev["sw"] = EMSESP_APP_VERSION;
|
||||
dev["mf"] = brand_to_string();
|
||||
dev["mdl"] = this->name();
|
||||
JsonArray ids = dev.createNestedArray("ids");
|
||||
ids.add("ems-esp-mixer");
|
||||
|
||||
// determine the topic, if its HC and WWC. This is determined by the incoming telegram types.
|
||||
std::string topic(Mqtt::MQTT_TOPIC_MAX_SIZE, '\0');
|
||||
if (type_ == Type::HC) {
|
||||
snprintf(&topic[0], topic.capacity() + 1, "sensor/%s/mixer_hc%d/config", Mqtt::base().c_str(), hc_);
|
||||
} else if (type_ == Type::WWC) {
|
||||
snprintf(&topic[0], topic.capacity() + 1, "sensor/%s/mixer_wwc%d/config", Mqtt::base().c_str(), hc_); // WWC
|
||||
} else if (type_ == Type::MP) {
|
||||
snprintf(&topic[0], topic.capacity() + 1, "sensor/%s/mixer_mp/config", Mqtt::base().c_str());
|
||||
}
|
||||
|
||||
Mqtt::publish_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// heating circuits 0x02D7, 0x02D8 etc...
|
||||
// e.g. A0 00 FF 00 01 D7 00 00 00 80 00 00 00 00 03 C5
|
||||
// A0 0B FF 00 01 D7 00 00 00 80 00 00 00 00 03 80
|
||||
void Mixer::process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(flowTempHc_, 3)); // is * 10
|
||||
has_update(telegram->read_value(flowSetTemp_, 5));
|
||||
has_update(telegram->read_bitvalue(pumpStatus_, 0, 0));
|
||||
has_update(telegram->read_value(status_, 2)); // valve status
|
||||
has_update(telegram, flowTempHc_, 3); // is * 10
|
||||
has_update(telegram, flowSetTemp_, 5);
|
||||
has_bitupdate(telegram, pumpStatus_, 0, 0);
|
||||
has_update(telegram, status_, 2); // valve status
|
||||
}
|
||||
|
||||
// Mixer warm water loading/DHW - 0x0331, 0x0332
|
||||
// e.g. A9 00 FF 00 02 32 02 6C 00 3C 00 3C 3C 46 02 03 03 00 3C // on 0x28
|
||||
// A8 00 FF 00 02 31 02 35 00 3C 00 3C 3C 46 02 03 03 00 3C // in 0x29
|
||||
void Mixer::process_MMPLUSStatusMessage_WWC(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(flowTempHc_, 0)); // is * 10
|
||||
has_update(telegram->read_bitvalue(pumpStatus_, 2, 0));
|
||||
has_update(telegram->read_value(status_, 11)); // temp status
|
||||
has_update(telegram, flowTempHc_, 0); // is * 10
|
||||
has_bitupdate(telegram, pumpStatus_, 2, 0);
|
||||
has_update(telegram, status_, 11); // temp status
|
||||
}
|
||||
|
||||
// Mixer IPM - 0x010C
|
||||
@@ -195,18 +145,27 @@ void Mixer::process_IPMStatusMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
|
||||
// do we have a mixed circuit
|
||||
if (ismixed == 2) {
|
||||
has_update(telegram->read_value(flowTempHc_, 3)); // is * 10
|
||||
has_update(telegram->read_value(status_, 2)); // valve status
|
||||
has_update(telegram, flowTempHc_, 3); // is * 10
|
||||
has_update(telegram, status_, 2); // valve status
|
||||
}
|
||||
|
||||
has_update(telegram->read_bitvalue(pumpStatus_, 1, 0)); // pump is also in unmixed circuits
|
||||
has_update(telegram->read_value(flowSetTemp_, 5)); // flowSettemp is also in unmixed circuits, see #711
|
||||
has_bitupdate(telegram, pumpStatus_, 1, 0); // pump is also in unmixed circuits
|
||||
has_update(telegram, flowSetTemp_, 5); // flowSettemp is also in unmixed circuits, see #711
|
||||
}
|
||||
|
||||
// Mixer IPM - 0x001E Temperature Message in unmixed circuits
|
||||
// in unmixed circuits FlowTemp in 10C is zero, this is the measured flowtemp in header
|
||||
void Mixer::process_IPMTempMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(flowTempVf_, 0)); // TC1, is * 10
|
||||
has_update(telegram, flowTempVf_, 0); // TC1, is * 10
|
||||
}
|
||||
|
||||
// Mixer MP100 for pools - 0x5BA
|
||||
void Mixer::process_HpPoolStatus(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, poolTemp_, 0);
|
||||
has_update(telegram, poolShunt_, 3); // 0-100% how much is the shunt open?
|
||||
telegram->read_value(poolShuntStatus__, 2);
|
||||
uint8_t pss = poolShunt_ == 100 ? 3 : (poolShunt_ == 0 ? 4 : poolShuntStatus__);
|
||||
has_update(poolShuntStatus_, pss);
|
||||
}
|
||||
|
||||
// Mixer on a MM10 - 0xAB
|
||||
@@ -217,41 +176,67 @@ void Mixer::process_MMStatusMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
// 0x21 is position 2. 0x20 is typically reserved for the WM10 switch module
|
||||
// see https://github.com/emsesp/EMS-ESP/issues/270 and https://github.com/emsesp/EMS-ESP/issues/386#issuecomment-629610918
|
||||
|
||||
has_update(telegram->read_value(flowTempHc_, 1)); // is * 10
|
||||
has_update(telegram->read_bitvalue(pumpStatus_, 3, 2)); // is 0 or 0x64 (100%), check only bit 2
|
||||
has_update(telegram->read_value(flowSetTemp_, 0));
|
||||
has_update(telegram->read_value(status_, 4)); // valve status -100 to 100
|
||||
has_update(telegram, flowTempHc_, 1); // is * 10
|
||||
has_bitupdate(telegram, pumpStatus_, 3, 2); // is 0 or 0x64 (100%), check only bit 2
|
||||
has_update(telegram, flowSetTemp_, 0);
|
||||
has_update(telegram, status_, 4); // valve status -100 to 100
|
||||
}
|
||||
|
||||
// Pool mixer MP100, - 0x5BA
|
||||
void Mixer::process_HpPoolStatus(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(poolTemp_, 0));
|
||||
has_update(telegram->read_value(poolShuntStatus__, 2));
|
||||
has_update(telegram->read_value(poolShunt_, 3)); // 0-100% how much is the shunt open?
|
||||
poolShuntStatus_ = poolShunt_ == 100 ? 3 : (poolShunt_ == 0 ? 4 : poolShuntStatus__);
|
||||
}
|
||||
/*
|
||||
* The set-messages are not broadcasted and send from thermostat to mixer,
|
||||
* we have to fetch for processing
|
||||
*/
|
||||
|
||||
// Mixer on a MM10 - 0xAA
|
||||
// e.g. Thermostat -> Mixer Module, type 0xAA, telegram: 10 21 AA 00 FF 0C 0A 11 0A 32 xx
|
||||
void Mixer::process_MMConfigMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(activated_, 0)); // on = 0xFF
|
||||
has_update(telegram->read_value(setValveTime_, 1)); // valve runtime in 10 sec, max 120 s
|
||||
has_update(telegram, activated_, 0); // on = 0xFF
|
||||
has_update(telegram, setValveTime_, 1); // valve runtime in 10 sec, max 120 s
|
||||
}
|
||||
|
||||
// Config message 0x313, has to be fetched
|
||||
void Mixer::process_MMPLUSConfigMessage_WWC(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram, wwRequiredTemp_, 4);
|
||||
has_update(telegram, wwReducedTemp_, 5);
|
||||
has_update(telegram, wwDiffTemp_, 7);
|
||||
has_update(telegram, wwDisinfectionTemp_, 9);
|
||||
has_update(telegram, wwMaxTemp_, 10);
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
// Thermostat(0x10) -> Mixer(0x20), ?(0x2E1), data: 01 1C 64 00 01
|
||||
// Thermostat(0x10) -> Mixing Module(0x20), (0x2E1), data: 01 00 00 00 01
|
||||
// Thermostat(0x10) -> Mixing Module(0x20), (0x2EB), data: 00
|
||||
void Mixer::process_MMPLUSSetMessage_HC(std::shared_ptr<const Telegram> telegram) {
|
||||
// pos 1: setpoint
|
||||
// pos2: pump
|
||||
}
|
||||
|
||||
// unknown, 2 examples from older threads
|
||||
// Thermostat(0x10) -> Mixer(0x28), ?(0x33B), data: 01 01 00
|
||||
// Thermostat -> Mixing Module, type 0x023B, telegram: 90 28 FF 00 02 3B 00 02 00 (CRC=68)
|
||||
void Mixer::process_MMPLUSSetMessage_WWC(std::shared_ptr<const Telegram> telegram) {
|
||||
}
|
||||
|
||||
// MMPLUS telegram 0x345 unknown
|
||||
// Solar Module -> Mixing Module, type 0x0245, telegram: B0 28 FF 00 02 45 64 01 01 (CRC=36)
|
||||
// ?
|
||||
|
||||
// Mixer on a MM10 - 0xAC
|
||||
// e.g. Thermostat -> Mixer Module, type 0xAC, telegram: 10 21 AC 00 1E 64 01 AB
|
||||
void Mixer::process_MMSetMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
// pos 0: flowtemp setpoint 1E = 30°C
|
||||
// pos 1: position in %
|
||||
// pos 1: pump in %
|
||||
// pos 2 flags (mostly 01)
|
||||
// LOG_INFO("MM10 SetMessage received");
|
||||
}
|
||||
|
||||
// Thermostat(0x10) -> Mixer(0x21), ?(0x23), data: 1A 64 00 90 21 23 00 1A 64 00 89
|
||||
void Mixer::process_IPMSetMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
// pos 0: flowtemp setpoint 1A = 26°C
|
||||
// pos 1: position in %?
|
||||
// pos 1: pump in %?
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
@@ -261,7 +246,6 @@ bool Mixer::set_flowSetTemp(const char * value, const int8_t id) {
|
||||
if (!Helpers::value2number(value, v)) {
|
||||
return false;
|
||||
}
|
||||
LOG_INFO(F("Setting mixer flow set temperature to %d"), v);
|
||||
if (flags() == EMSdevice::EMS_DEVICE_FLAG_MM10) {
|
||||
write_command(0xAC, 0, v, 0xAB);
|
||||
return true;
|
||||
@@ -283,7 +267,6 @@ bool Mixer::set_pump(const char * value, const int8_t id) {
|
||||
if (!Helpers::value2bool(value, b)) {
|
||||
return false;
|
||||
}
|
||||
LOG_INFO(F("Setting mixer pump %s"), b ? "on" : "off");
|
||||
if (flags() == EMSdevice::EMS_DEVICE_FLAG_MM10) {
|
||||
write_command(0xAC, 1, b ? 0x64 : 0, 0xAB);
|
||||
return true;
|
||||
@@ -306,7 +289,6 @@ bool Mixer::set_activated(const char * value, const int8_t id) {
|
||||
return false;
|
||||
}
|
||||
if (flags() == EMSdevice::EMS_DEVICE_FLAG_MM10) {
|
||||
LOG_INFO(F("Setting mixer %s"), value);
|
||||
write_command(0xAA, 0, b ? 0xFF : 0, 0xAA);
|
||||
return true;
|
||||
}
|
||||
@@ -320,11 +302,81 @@ bool Mixer::set_setValveTime(const char * value, const int8_t id) {
|
||||
}
|
||||
if (flags() == EMSdevice::EMS_DEVICE_FLAG_MM10) {
|
||||
v = (v + 5) / 10;
|
||||
LOG_INFO(F("Setting mixer valve time to %ds"), v * 10);
|
||||
write_command(0xAA, 1, v, 0xAA);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Mixer::set_wwMaxTemp(const char * value, const int8_t id) {
|
||||
uint8_t wwc = device_id() - 0x28;
|
||||
float v = 0;
|
||||
if (!Helpers::value2temperature(value, v)) {
|
||||
return false;
|
||||
}
|
||||
write_command(0x313 + wwc, 10, (uint8_t)v, 0x313 + wwc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mixer::set_wwDiffTemp(const char * value, const int8_t id) {
|
||||
uint8_t wwc = device_id() - 0x28;
|
||||
float v = 0;
|
||||
if (!Helpers::value2temperature(value, v)) {
|
||||
return false;
|
||||
}
|
||||
write_command(0x313 + wwc, 7, (int8_t)(v * 10), 0x313 + wwc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mixer::set_wwReducedTemp(const char * value, const int8_t id) {
|
||||
uint8_t wwc = device_id() - 0x28;
|
||||
float v = 0;
|
||||
if (!Helpers::value2temperature(value, v)) {
|
||||
return false;
|
||||
}
|
||||
write_command(0x313 + wwc, 5, (uint8_t)v, 0x313 + wwc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mixer::set_wwRequiredTemp(const char * value, const int8_t id) {
|
||||
uint8_t wwc = device_id() - 0x28;
|
||||
float v = 0;
|
||||
if (!Helpers::value2temperature(value, v)) {
|
||||
return false;
|
||||
}
|
||||
write_command(0x313 + wwc, 4, (uint8_t)v, 0x313 + wwc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mixer::set_wwDisinfectionTemp(const char * value, const int8_t id) {
|
||||
uint8_t wwc = device_id() - 0x28;
|
||||
float v = 0;
|
||||
if (!Helpers::value2temperature(value, v)) {
|
||||
return false;
|
||||
}
|
||||
write_command(0x313 + wwc, 9, (uint8_t)v, 0x313 + wwc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mixer::set_wwCircPump(const char * value, const int8_t id) {
|
||||
uint8_t wwc = device_id() - 0x28;
|
||||
bool v = false;
|
||||
if (!Helpers::value2bool(value, v)) {
|
||||
return false;
|
||||
}
|
||||
write_command(0x33B + wwc, 0, v ? 0x01 : 0x00, 0x33B + wwc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mixer::set_wwCircMode(const char * value, const int8_t id) {
|
||||
uint8_t wwc = device_id() - 0x28;
|
||||
uint8_t n;
|
||||
if (!Helpers::value2enum(value, n, FL_(enum_wwCircMode))) {
|
||||
return false;
|
||||
}
|
||||
write_command(0x313 + wwc, 0, n, 0x313 + wwc);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -25,15 +25,16 @@ namespace emsesp {
|
||||
|
||||
class Mixer : public EMSdevice {
|
||||
public:
|
||||
Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
virtual bool publish_ha_device_config();
|
||||
Mixer(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
void process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> telegram);
|
||||
void process_MMPLUSSetMessage_HC(std::shared_ptr<const Telegram> telegram);
|
||||
void process_MMPLUSStatusMessage_WWC(std::shared_ptr<const Telegram> telegram);
|
||||
void process_MMPLUSSetMessage_WWC(std::shared_ptr<const Telegram> telegram);
|
||||
void process_MMPLUSConfigMessage_WWC(std::shared_ptr<const Telegram> telegram);
|
||||
void process_IPMStatusMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_IPMTempMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_IPMSetMessage(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -47,12 +48,20 @@ class Mixer : public EMSdevice {
|
||||
bool set_activated(const char * value, const int8_t id);
|
||||
bool set_setValveTime(const char * value, const int8_t id);
|
||||
|
||||
bool set_wwMaxTemp(const char * value, const int8_t id);
|
||||
bool set_wwDiffTemp(const char * value, const int8_t id);
|
||||
bool set_wwReducedTemp(const char * value, const int8_t id);
|
||||
bool set_wwRequiredTemp(const char * value, const int8_t id);
|
||||
bool set_wwDisinfectionTemp(const char * value, const int8_t id);
|
||||
bool set_wwCircPump(const char * value, const int8_t id);
|
||||
bool set_wwCircMode(const char * value, const int8_t id);
|
||||
|
||||
|
||||
enum class Type {
|
||||
NONE,
|
||||
HC, // heating circuit
|
||||
WWC, // warm water circuit
|
||||
MP // pool
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -64,14 +73,23 @@ class Mixer : public EMSdevice {
|
||||
uint8_t activated_;
|
||||
uint8_t setValveTime_;
|
||||
|
||||
// MM100wwParam - 0x0313, 0x033B
|
||||
uint8_t wwMaxTemp_;
|
||||
uint8_t wwRequiredTemp_;
|
||||
uint8_t wwReducedTemp_;
|
||||
uint8_t wwDiffTemp_;
|
||||
uint8_t wwDisinfectionTemp_;
|
||||
uint8_t wwCircPump_;
|
||||
uint8_t wwCircMode_;
|
||||
|
||||
// MP100 pool
|
||||
int16_t poolTemp_;
|
||||
int8_t poolShuntStatus_;
|
||||
int8_t poolShunt_;
|
||||
uint8_t poolShuntStatus_;
|
||||
uint8_t poolShunt_;
|
||||
|
||||
Type type_ = Type::NONE;
|
||||
uint16_t hc_ = EMS_VALUE_USHORT_NOTSET;
|
||||
int8_t poolShuntStatus__ = EMS_VALUE_INT_NOTSET; // temp value
|
||||
uint8_t id_;
|
||||
uint8_t poolShuntStatus__ = EMS_VALUE_UINT_NOTSET; // temp value
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,26 +25,42 @@ namespace emsesp {
|
||||
|
||||
class Solar : public EMSdevice {
|
||||
public:
|
||||
Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
virtual bool publish_ha_device_config();
|
||||
Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
int16_t collectorTemp_; // TS1: Temperature sensor for collector array 1
|
||||
int16_t tankBottomTemp_; // TS2: Temperature sensor 1 cylinder, bottom tank (solar thermal system)
|
||||
int16_t tankBottomTemp2_; // TS5: Temperature sensor 2 cylinder, bottom tank, or swimming pool (solar thermal system)
|
||||
int16_t heatExchangerTemp_; // TS6: Heat exchanger temperature sensor
|
||||
uint8_t solarPumpModulation_; // PS1: modulation solar pump
|
||||
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 collectorTemp_; // TS1: Temperature sensor for collector array 1
|
||||
int16_t cylBottomTemp_; // TS2: Temperature sensor 1 cylinder, bottom cyl (solar thermal system)
|
||||
int16_t cylBottomTemp2_; // TS5: Temperature sensor 2 cylinder, bottom cyl, or swimming pool (solar thermal system)
|
||||
int16_t heatExchangerTemp_; // TS6: Heat exchanger temperature sensor
|
||||
int16_t collector2Temp_; // TS7: Temperature sensor for collector array 2
|
||||
int16_t cylMiddleTemp_; // TS14: Cylinder middle temp
|
||||
int16_t retHeatAssist_; // TS15: return temperature heating assistance
|
||||
uint8_t solarPumpMod_; // PS1: modulation solar pump
|
||||
uint8_t cylPumpMod_; // 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
|
||||
uint8_t solarPump2_; // PS4: solar pump 2 active
|
||||
uint8_t solarPump2Mod_; // PS4: modulation solar pump
|
||||
uint8_t m1Valve_; // M1: heat assistance valve
|
||||
uint8_t m1Power_; // M1: heat assistance valve
|
||||
|
||||
// 0x363 heat counter
|
||||
uint16_t heatCntFlowTemp_;
|
||||
uint16_t heatCntRetTemp_;
|
||||
uint8_t heatCnt_;
|
||||
uint16_t swapFlowTemp_;
|
||||
uint16_t swapRetTemp_;
|
||||
|
||||
// 0x38E
|
||||
uint32_t energyLastHour_;
|
||||
uint32_t energyToday_;
|
||||
uint32_t energyTotal_;
|
||||
uint32_t pumpWorkTime_; // Total solar pump operating time
|
||||
uint8_t tankHeated_;
|
||||
uint32_t pumpWorkTime_; // Total solar pump operating time
|
||||
uint32_t pump2WorkTime_; // Total solar pump 2 operating time
|
||||
uint32_t m1WorkTime_; // differential control work time
|
||||
uint8_t cylHeated_;
|
||||
uint8_t collectorShutdown_; // Collector shutdown on/off
|
||||
|
||||
uint8_t availabilityFlag_;
|
||||
@@ -53,57 +69,104 @@ class Solar : public EMSdevice {
|
||||
|
||||
// telegram 0x0358
|
||||
uint8_t heatTransferSystem_; // Umladesystem, 00=no
|
||||
uint8_t externalTank_; // Heat exchanger, 00=no
|
||||
uint8_t externalCyl_; // Heat exchanger, 00=no
|
||||
uint8_t thermalDisinfect_; // Daily heatup for disinfection, 00=no
|
||||
uint8_t heatMetering_; // Wärmemengenzählung, 00=no
|
||||
uint8_t heatMetering_; // Heat quantity metering, 00=no
|
||||
uint8_t solarIsEnabled_; // System enable, 00=no
|
||||
|
||||
// telegram 0x035A
|
||||
uint8_t collectorMaxTemp_; // maximum allowed collectorTemp array 1
|
||||
uint8_t tankMaxTemp_; // Current value for max tank temp
|
||||
uint8_t collectorMaxTemp_; // maximum allowed collectorTemp array 1
|
||||
uint8_t cylMaxTemp_; // Current value for max cyl temp
|
||||
// uint8_t cyl2MaxTemp_; // Current value for max cyl temp
|
||||
uint8_t collectorMinTemp_; // minimum allowed collectorTemp array 1
|
||||
uint8_t solarPumpMode_; // 00=off, 01=PWM, 02=10V
|
||||
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 solarPumpMinMod_; // minimum modulation setting
|
||||
uint8_t solarPumpTurnoffDiff_; // solar pump turnoff collector/cyl diff
|
||||
uint8_t solarPumpTurnonDiff_; // solar pump turnon collector/cyl diff
|
||||
uint8_t solarPumpKick_; // pump kick for vacuum collector, 00=off
|
||||
uint8_t plainWaterMode_; // system does not use antifreeze, 00=off
|
||||
uint8_t doubleMatchFlow_; // double Match Flow, 00=off
|
||||
|
||||
// telegram 0x035D
|
||||
uint8_t collector2MaxTemp_; // maximum allowed collectorTemp array 1
|
||||
uint8_t collector2MinTemp_; // minimum allowed collectorTemp array 1
|
||||
uint8_t solarPump2MinMod_; // minimum modulation setting
|
||||
uint8_t solarPump2TurnoffDiff_; // solar pump turnoff collector/cyl diff
|
||||
uint8_t solarPump2TurnonDiff_; // solar pump turnon collector/cyl diff
|
||||
uint8_t solarPump2Kick_; // pump kick for vacuum collector, 00=off
|
||||
uint8_t solarPump2Mode_; // 00=off, 01=PWM, 02=10V
|
||||
|
||||
// telegram 0x35C Heat assistance
|
||||
uint8_t solarHeatAssist_; // is *10
|
||||
|
||||
// telegram 0x035F
|
||||
uint8_t cylPriority_; // 0 or 1
|
||||
|
||||
// telegram 0x361 Differential control
|
||||
uint8_t diffControl_; // is *10
|
||||
|
||||
|
||||
// telegram 0x380
|
||||
uint8_t climateZone_; // climate zone identifier
|
||||
uint16_t collector1Area_; // Area of collector field 1
|
||||
uint8_t collector1Type_; // Type of collector field 1, 01=flat, 02=vacuum
|
||||
uint16_t collector2Area_; // Area of collector field 2
|
||||
uint8_t collector2Type_; // Type of collector field 2, 01=flat, 02=vacuum
|
||||
|
||||
// SM100wwTemperature - 0x07D6
|
||||
uint8_t wwTemp_1_;
|
||||
uint8_t wwTemp_3_;
|
||||
uint8_t wwTemp_4_;
|
||||
uint8_t wwTemp_5_;
|
||||
uint8_t wwTemp_7_;
|
||||
uint16_t wwTemp_1_;
|
||||
uint16_t wwTemp_3_;
|
||||
uint16_t wwTemp_4_;
|
||||
uint16_t wwTemp_5_;
|
||||
uint16_t wwTemp_7_;
|
||||
|
||||
// SM100wwStatus - 0x07AA
|
||||
uint8_t wwPump_;
|
||||
|
||||
// SM100wwParam - 0x07A6
|
||||
uint8_t wwMaxTemp_;
|
||||
uint8_t wwTemp_;
|
||||
uint8_t wwRedTemp_;
|
||||
uint8_t wwDailyTemp_;
|
||||
uint8_t wwDisinfectionTemp_;
|
||||
|
||||
// SM100wwKeepWarm - 0x07AE
|
||||
uint8_t wwKeepWarm_;
|
||||
|
||||
// SM100wwCirc - 0x07A5
|
||||
uint8_t wwCirc_;
|
||||
uint8_t wwCircMode_;
|
||||
|
||||
// SM100wwStatus2 - 0x07E0
|
||||
uint8_t wwFlow_;
|
||||
uint8_t wwPumpMod_;
|
||||
uint8_t wwStatus2_;
|
||||
|
||||
// SM10Config - 0x96
|
||||
uint8_t wwMinTemp_;
|
||||
uint8_t maxFlow_; // set this to calculate power
|
||||
uint32_t solarPower_; // calculated from maxFlow
|
||||
uint8_t wwMinTemp_;
|
||||
uint8_t maxFlow_; // set this to calculate power
|
||||
int16_t solarPower_; // calculated from maxFlow
|
||||
|
||||
std::deque<uint16_t> energy;
|
||||
uint8_t data0_;
|
||||
uint8_t data1_;
|
||||
uint8_t data11_;
|
||||
uint8_t data12_;
|
||||
uint8_t setting3_;
|
||||
uint8_t setting4_;
|
||||
|
||||
char type_[20]; // Solar of WWC
|
||||
uint8_t id_;
|
||||
std::deque<int16_t> energy;
|
||||
|
||||
void process_SM10Monitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM10Config(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_SM100CircuitConfig(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100Circuit2Config(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);
|
||||
|
||||
void process_SM100Config(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100Config1(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_SM100Status(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100Status2(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -111,9 +174,16 @@ class Solar : public EMSdevice {
|
||||
void process_SM100Energy(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100Time(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_SM100HeatAssist(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100Differential(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_SM100wwTemperature(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100wwStatus(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100wwStatus2(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100wwCommand(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100wwCirc(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100wwParam(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100wwKeepWarm(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
void process_ISM1StatusMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_ISM1Set(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -121,26 +191,47 @@ class Solar : public EMSdevice {
|
||||
|
||||
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_cylMaxTemp(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_Collector2MaxTemp(const char * value, const int8_t id);
|
||||
bool set_Collector2MinTemp(const char * value, const int8_t id);
|
||||
bool set_Pump2MinMod(const char * value, const int8_t id);
|
||||
bool set_TurnonDiff2(const char * value, const int8_t id);
|
||||
bool set_TurnoffDiff2(const char * value, const int8_t id);
|
||||
|
||||
bool set_SM10MaxFlow(const char * value, const int8_t id);
|
||||
// SM100
|
||||
bool set_heatTransferSystem(const char * value, const int8_t id);
|
||||
bool set_externalTank(const char * value, const int8_t id);
|
||||
bool set_externalCyl(const char * value, const int8_t id);
|
||||
bool set_thermalDisinfect(const char * value, const int8_t id);
|
||||
bool set_heatMetering(const char * value, const int8_t id);
|
||||
bool set_solarEnabled(const char * value, const int8_t id);
|
||||
bool set_solarMode(const char * value, const int8_t id);
|
||||
bool set_solarPumpKick(const char * value, const int8_t id);
|
||||
bool set_solarPump2Kick(const char * value, const int8_t id);
|
||||
bool set_plainWaterMode(const char * value, const int8_t id);
|
||||
bool set_doubleMatchFlow(const char * value, const int8_t id);
|
||||
bool set_climateZone(const char * value, const int8_t id);
|
||||
bool set_collector1Area(const char * value, const int8_t id);
|
||||
bool set_collector1Type(const char * value, const int8_t id);
|
||||
bool set_collector2Area(const char * value, const int8_t id);
|
||||
bool set_collector2Type(const char * value, const int8_t id);
|
||||
bool set_cylPriority(const char * value, const int8_t id);
|
||||
bool set_heatAssist(const char * value, const int8_t id);
|
||||
bool set_diffControl(const char * value, const int8_t id);
|
||||
|
||||
bool set_wwTemp(const char * value, const int8_t id);
|
||||
bool set_wwMaxTemp(const char * value, const int8_t id);
|
||||
bool set_wwRedTemp(const char * value, const int8_t id);
|
||||
bool set_wwCirc(const char * value, const int8_t id);
|
||||
bool set_wwCircMode(const char * value, const int8_t id);
|
||||
bool set_wwKeepWarm(const char * value, const int8_t id);
|
||||
bool set_wwDisinfectionTemp(const char * value, const int8_t id);
|
||||
bool set_wwDailyTemp(const char * value, const int8_t id);
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -22,76 +22,35 @@ namespace emsesp {
|
||||
|
||||
REGISTER_FACTORY(Switch, EMSdevice::DeviceType::SWITCH);
|
||||
|
||||
uuid::log::Logger Switch::logger_ {
|
||||
F_(switch), uuid::log::Facility::CONSOLE
|
||||
};
|
||||
|
||||
Switch::Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
Switch::Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
register_telegram_type(0x9C, F("WM10MonitorMessage"), false, MAKE_PF_CB(process_WM10MonitorMessage));
|
||||
register_telegram_type(0x9D, F("WM10SetMessage"), false, MAKE_PF_CB(process_WM10SetMessage));
|
||||
register_telegram_type(0x1E, F("WM10TempMessage"), false, MAKE_PF_CB(process_WM10TempMessage));
|
||||
|
||||
register_device_value(TAG_NONE, &id_, DeviceValueType::UINT, nullptr, FL_(ID), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_NONE, &activated_, DeviceValueType::BOOL, nullptr, FL_(activated), DeviceValueUOM::NONE);
|
||||
register_device_value(TAG_NONE, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES);
|
||||
register_device_value(TAG_NONE, &status_, DeviceValueType::INT, nullptr, FL_(status), DeviceValueUOM::NONE);
|
||||
id_ = product_id;
|
||||
}
|
||||
|
||||
// publish HA config
|
||||
bool Switch::publish_ha_device_config() {
|
||||
// if we don't have valid values don't add it ever again
|
||||
if (!Helpers::hasValue(flowTempHc_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_HA_CONFIG> doc;
|
||||
doc["uniq_id"] = F_(switch);
|
||||
doc["ic"] = F_(icondevice);
|
||||
|
||||
char stat_t[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s", Mqtt::base().c_str(), Mqtt::tag_to_topic(device_type(), DeviceValueTAG::TAG_NONE).c_str());
|
||||
doc["stat_t"] = stat_t;
|
||||
|
||||
char name_s[40];
|
||||
snprintf(name_s, sizeof(name_s), FSTR_(productid_fmt), device_type_name().c_str());
|
||||
doc["name"] = name_s;
|
||||
|
||||
doc["val_tpl"] = FJSON("{{value_json.id}}");
|
||||
JsonObject dev = doc.createNestedObject("dev");
|
||||
dev["name"] = FJSON("EMS-ESP Switch");
|
||||
dev["sw"] = EMSESP_APP_VERSION;
|
||||
dev["mf"] = brand_to_string();
|
||||
dev["mdl"] = this->name();
|
||||
JsonArray ids = dev.createNestedArray("ids");
|
||||
ids.add("ems-esp-switch");
|
||||
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(topic, sizeof(topic), "sensor/%s/switch/config", Mqtt::base().c_str());
|
||||
Mqtt::publish_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
|
||||
|
||||
return true;
|
||||
register_device_value(DeviceValueTAG::TAG_NONE, &activated_, DeviceValueType::BOOL, nullptr, FL_(activated), DeviceValueUOM::NONE);
|
||||
register_device_value(DeviceValueTAG::TAG_NONE, &flowTempHc_, DeviceValueType::USHORT, FL_(div10), FL_(flowTempHc), DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_NONE, &status_, DeviceValueType::INT, nullptr, FL_(status), DeviceValueUOM::NONE);
|
||||
}
|
||||
|
||||
// message 0x9D switch on/off
|
||||
// Thermostat(0x10) -> Switch(0x11), ?(0x9D), data: 00
|
||||
void Switch::process_WM10SetMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(activated_, 0));
|
||||
has_update(telegram, activated_, 0);
|
||||
}
|
||||
|
||||
// message 0x9C holds flowtemp and unknown status value
|
||||
// Switch(0x11) -> All(0x00), ?(0x9C), data: 01 BA 00 01 00
|
||||
void Switch::process_WM10MonitorMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(flowTempHc_, 0)); // is * 10
|
||||
has_update(telegram->read_value(status_, 2));
|
||||
// has_update(telegram->read_value(status2_, 3)); // unknown
|
||||
has_update(telegram, flowTempHc_, 0); // is * 10
|
||||
has_update(telegram, status_, 2);
|
||||
// has_update(telegram, status2_, 3)); // unknown
|
||||
}
|
||||
|
||||
// message 0x1E flow temperature, same as in 9C, published often, republished also by boiler UBAFast 0x18
|
||||
// Switch(0x11) -> Boiler(0x08), ?(0x1E), data: 01 BA
|
||||
void Switch::process_WM10TempMessage(std::shared_ptr<const Telegram> telegram) {
|
||||
has_update(telegram->read_value(flowTempHc_, 0)); // is * 10
|
||||
has_update(telegram, flowTempHc_, 0); // is * 10
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -25,13 +25,9 @@ namespace emsesp {
|
||||
|
||||
class Switch : public EMSdevice {
|
||||
public:
|
||||
Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
virtual bool publish_ha_device_config();
|
||||
Switch(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
void process_WM10SetMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_WM10MonitorMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_WM10TempMessage(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -39,7 +35,6 @@ class Switch : public EMSdevice {
|
||||
uint16_t flowTempHc_;
|
||||
uint8_t status_;
|
||||
uint8_t activated_;
|
||||
uint8_t id_;
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@ namespace emsesp {
|
||||
|
||||
class Thermostat : public EMSdevice {
|
||||
public:
|
||||
Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_id, const std::string & version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
Thermostat(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const std::string & name, uint8_t flags, uint8_t brand);
|
||||
class HeatingCircuit {
|
||||
public:
|
||||
HeatingCircuit(const uint8_t hc_num, const uint8_t model)
|
||||
@@ -34,12 +34,11 @@ class Thermostat : public EMSdevice {
|
||||
}
|
||||
~HeatingCircuit() = default;
|
||||
|
||||
int16_t setpoint_roomTemp;
|
||||
int16_t curr_roomTemp;
|
||||
int16_t selTemp;
|
||||
int16_t roomTemp;
|
||||
int16_t remotetemp; // for readback
|
||||
uint8_t tempautotemp;
|
||||
uint8_t mode;
|
||||
uint8_t hamode; // special mode for HA. See https://github.com/emsesp/EMS-ESP32/issues/66
|
||||
uint8_t modetype;
|
||||
uint8_t summermode;
|
||||
uint8_t holidaymode;
|
||||
@@ -68,8 +67,11 @@ class Thermostat : public EMSdevice {
|
||||
int8_t noreducetemp; // signed -20°C to +10°C
|
||||
uint8_t wwprio;
|
||||
uint8_t fastHeatup;
|
||||
char holiday[22];
|
||||
char vacation[22];
|
||||
char holiday[26];
|
||||
char vacation[26];
|
||||
char switchtime1[16];
|
||||
char switchtime2[16];
|
||||
|
||||
// RC 10
|
||||
uint8_t reducehours; // night reduce duration
|
||||
uint16_t reduceminutes; // remaining minutes to night->day
|
||||
@@ -78,13 +80,25 @@ class Thermostat : public EMSdevice {
|
||||
return hc_num_;
|
||||
}
|
||||
|
||||
uint8_t hc() const {
|
||||
return hc_num_ - 1;
|
||||
}
|
||||
|
||||
uint8_t get_model() const {
|
||||
return model_;
|
||||
}
|
||||
|
||||
// determines if the heating circuit is actually present and has data
|
||||
bool is_active() {
|
||||
return Helpers::hasValue(setpoint_roomTemp);
|
||||
return Helpers::hasValue(selTemp);
|
||||
}
|
||||
|
||||
bool ha_climate_created() {
|
||||
return ha_climate_created_;
|
||||
}
|
||||
|
||||
void ha_climate_created(bool ha_climate_created) {
|
||||
ha_climate_created_ = ha_climate_created;
|
||||
}
|
||||
|
||||
uint8_t get_mode() const;
|
||||
@@ -116,19 +130,18 @@ class Thermostat : public EMSdevice {
|
||||
};
|
||||
|
||||
// for sorting based on hc number
|
||||
friend inline bool operator<(const std::shared_ptr<HeatingCircuit> & lhs, const std::shared_ptr<HeatingCircuit> & rhs) {
|
||||
return (lhs->hc_num_ < rhs->hc_num_);
|
||||
friend inline bool operator<(const std::shared_ptr<HeatingCircuit> & a, const std::shared_ptr<HeatingCircuit> & b) {
|
||||
return (a->hc_num_ < b->hc_num_);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t hc_num_; // heating circuit number 1..10
|
||||
uint8_t model_; // the model type
|
||||
uint8_t hc_num_; // heating circuit number 1..10
|
||||
uint8_t model_; // the model type
|
||||
bool ha_climate_created_; // if we need to create the HA climate control
|
||||
};
|
||||
|
||||
static std::string mode_tostring(uint8_t mode);
|
||||
|
||||
virtual bool publish_ha_device_config();
|
||||
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
@@ -144,18 +157,17 @@ class Thermostat : public EMSdevice {
|
||||
std::vector<uint16_t> monitor_typeids;
|
||||
std::vector<uint16_t> set_typeids;
|
||||
std::vector<uint16_t> timer_typeids;
|
||||
std::vector<uint16_t> timer2_typeids;
|
||||
std::vector<uint16_t> summer_typeids;
|
||||
std::vector<uint16_t> summer2_typeids;
|
||||
std::vector<uint16_t> curve_typeids;
|
||||
|
||||
// standard for all thermostats
|
||||
uint8_t id_; // product id
|
||||
char status_[20]; // online or offline
|
||||
char dateTime_[25]; // date and time stamp
|
||||
char errorCode_[15]; // code from 0xA2 as string i.e. "A22(816)"
|
||||
uint16_t errorNumber_; // used internally to build error code
|
||||
char lastCode_[30]; // error log
|
||||
uint8_t dummy_; // for commands with no output
|
||||
char lastCode_[50]; // error log
|
||||
|
||||
// Installation parameters
|
||||
uint8_t ibaMainDisplay_; // display on Thermostat: 0 int temp, 1 int setpoint, 2 ext temp, 3 burner temp, 4 ww temp, 5 functioning mode, 6 time, 7 data, 9 smoke temp
|
||||
@@ -184,13 +196,17 @@ class Thermostat : public EMSdevice {
|
||||
uint8_t wwSetTempLow_;
|
||||
uint8_t wwCharge_;
|
||||
uint8_t wwChargeDuration_;
|
||||
uint8_t wwDisinfect_;
|
||||
uint8_t wwDisinfecting_;
|
||||
uint8_t wwDisinfectDay_;
|
||||
uint8_t wwDisinfectHour_;
|
||||
uint8_t wwMaxTemp_;
|
||||
uint8_t wwOneTimeKey_;
|
||||
uint8_t wwProgMode_;
|
||||
uint8_t wwCircProg_;
|
||||
char wwSwitchTime_[16];
|
||||
char wwCircSwitchTime_[16];
|
||||
uint8_t wwDailyHeating_;
|
||||
uint8_t wwDailyHeatTime_;
|
||||
|
||||
std::vector<std::shared_ptr<HeatingCircuit>> heating_circuits_; // each thermostat can have multiple heating circuits
|
||||
|
||||
@@ -208,7 +224,8 @@ class Thermostat : public EMSdevice {
|
||||
static constexpr uint8_t EMS_OFFSET_RC20StatusMessage_setpoint = 1; // setpoint temp
|
||||
static constexpr uint8_t EMS_OFFSET_RC20StatusMessage_curr = 2; // current temp
|
||||
static constexpr uint8_t EMS_OFFSET_RC20Set_mode = 23; // position of thermostat mode
|
||||
static constexpr uint8_t EMS_OFFSET_RC20Set_temp = 28; // position of thermostat setpoint temperature
|
||||
static constexpr uint8_t EMS_OFFSET_RC20Set_temp_auto = 28; // position of thermostat setpoint temperature
|
||||
static constexpr uint8_t EMS_OFFSET_RC20Set_temp_manual = 29; // position of thermostat setpoint temperature
|
||||
|
||||
static constexpr uint8_t EMS_OFFSET_RC20_2_Set_mode = 3; // ES72 - see https://github.com/emsesp/EMS-ESP/issues/334
|
||||
static constexpr uint8_t EMS_OFFSET_RC20_2_Set_temp_night = 1; // ES72
|
||||
@@ -280,6 +297,7 @@ class Thermostat : public EMSdevice {
|
||||
void register_device_values_hc(std::shared_ptr<Thermostat::HeatingCircuit> hc);
|
||||
|
||||
bool thermostat_ha_cmd(const char * message, uint8_t hc_num);
|
||||
void add_ha_climate(std::shared_ptr<HeatingCircuit> hc);
|
||||
|
||||
void process_RCOutdoorTemp(std::shared_ptr<const Telegram> telegram);
|
||||
void process_IBASettings(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -287,6 +305,7 @@ class Thermostat : public EMSdevice {
|
||||
void process_RCError(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RCErrorMessage(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC35wwSettings(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC35wwTimer(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC35Monitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC35Set(std::shared_ptr<const Telegram> telegram);
|
||||
void process_RC35Timer(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -316,12 +335,14 @@ class Thermostat : public EMSdevice {
|
||||
void process_JunkersSet(std::shared_ptr<const Telegram> telegram);
|
||||
void process_JunkersSet2(std::shared_ptr<const Telegram> telegram);
|
||||
void process_EasyMonitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_JunkersRemoteMonitor(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
// internal helper functions
|
||||
bool set_mode_n(const uint8_t mode, const uint8_t hc_num);
|
||||
|
||||
bool set_temperature_value(const char * value, const int8_t id, const uint8_t mode);
|
||||
bool set_temperature_value(const char * value, const int8_t id, const uint8_t mode, bool relative = false);
|
||||
bool set_temperature(const float temperature, const uint8_t mode, const uint8_t hc_num);
|
||||
bool set_switchtime(const char * value, const uint16_t type_id, char * out, size_t len);
|
||||
|
||||
// set functions - these use the id/hc
|
||||
bool set_mode(const char * value, const int8_t id);
|
||||
@@ -354,7 +375,8 @@ class Thermostat : public EMSdevice {
|
||||
bool set_minflowtemp(const char * value, const int8_t id);
|
||||
bool set_maxflowtemp(const char * value, const int8_t id);
|
||||
bool set_reducemode(const char * value, const int8_t id);
|
||||
bool set_switchtime(const char * value, const int8_t id);
|
||||
bool set_switchtime1(const char * value, const int8_t id);
|
||||
bool set_switchtime2(const char * value, const int8_t id);
|
||||
bool set_program(const char * value, const int8_t id);
|
||||
bool set_controlmode(const char * value, const int8_t id);
|
||||
bool set_wwprio(const char * value, const int8_t id);
|
||||
@@ -374,6 +396,10 @@ class Thermostat : public EMSdevice {
|
||||
bool set_wwOneTimeKey(const char * value, const int8_t id);
|
||||
bool set_wwProgMode(const char * value, const int8_t id);
|
||||
bool set_wwCircProg(const char * value, const int8_t id);
|
||||
bool set_wwSwitchTime(const char * value, const int8_t id);
|
||||
bool set_wwCircSwitchTime(const char * value, const int8_t id);
|
||||
bool set_wwDailyHeating(const char * value, const int8_t id);
|
||||
bool set_wwDailyHeatTime(const char * value, const int8_t id);
|
||||
|
||||
bool set_datetime(const char * value, const int8_t id);
|
||||
bool set_minexttemp(const char * value, const int8_t id);
|
||||
|
||||
Reference in New Issue
Block a user