mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
change show_info to read of json, updates to use HA MQTT Discovery
This commit is contained in:
@@ -87,7 +87,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
|||||||
void Boiler::register_mqtt_ha_config() {
|
void Boiler::register_mqtt_ha_config() {
|
||||||
// Create the Master device
|
// Create the Master device
|
||||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||||
doc["name"] = F("EMS-ESP");
|
doc["name"] = F("Service Code");
|
||||||
doc["uniq_id"] = F("boiler");
|
doc["uniq_id"] = F("boiler");
|
||||||
doc["ic"] = F("mdi:home-thermometer-outline");
|
doc["ic"] = F("mdi:home-thermometer-outline");
|
||||||
doc["stat_t"] = F("ems-esp/boiler_data");
|
doc["stat_t"] = F("ems-esp/boiler_data");
|
||||||
@@ -101,39 +101,160 @@ void Boiler::register_mqtt_ha_config() {
|
|||||||
ids.add("ems-esp-boiler");
|
ids.add("ems-esp-boiler");
|
||||||
Mqtt::publish_retain(F("homeassistant/sensor/ems-esp/boiler/config"), doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
Mqtt::publish_retain(F("homeassistant/sensor/ems-esp/boiler/config"), doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
||||||
|
|
||||||
Mqtt::register_mqtt_ha_binary_sensor(F("Boiler DHW"), this->device_type(), "tapwater_active");
|
Mqtt::register_mqtt_ha_binary_sensor(F_(tapwaterActive), this->device_type(), "tapwaterActive");
|
||||||
Mqtt::register_mqtt_ha_binary_sensor(F("Boiler Heating"), this->device_type(), "heating_active");
|
Mqtt::register_mqtt_ha_binary_sensor(F_(heatingActive), this->device_type(), "heatingActive");
|
||||||
|
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Service Code"), this->device_type(), "serviceCode", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(serviceCodeNumber), this->device_type(), "serviceCodeNumber", nullptr, nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Service Code number"), this->device_type(), "serviceCodeNumber", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wWSelTemp), this->device_type(), "wWSelTemp", F_(degrees), F_(icontemperature));
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Boiler WW Selected Temp"), this->device_type(), "wWSelTemp", "°C", "mdi:coolant-temperature");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wWSetTemp), this->device_type(), "wWSetTemp", F_(degrees), F_(icontemperature));
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Selected flow temperature"), this->device_type(), "selFlowTemp", "°C", "mdi:coolant-temperature");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wWDisinfectionTemp), this->device_type(), "wWDisinfectionTemp", F_(degrees), F_(icontemperature));
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Current flow temperature"), this->device_type(), "curFlowTemp", "°C", "mdi:coolant-temperature");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(selFlowTemp), this->device_type(), "selFlowTemp", F_(degrees), F_(icontemperature));
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Warm Water set temperature"), this->device_type(), "wWSetTemp", "°C", "mdi:coolant-temperature");
|
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Warm Water current temperature (intern)"), this->device_type(), "wWCurTmp", "°C", "mdi:coolant-temperature");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(selBurnPow), this->device_type(), "selBurnPow", F_(percent), nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Warm Water current temperature (extern)"), this->device_type(), "wWCurTmp2", "°C", "mdi:coolant-temperature");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(curBurnPow), this->device_type(), "curBurnPow", F_(percent), F_(iconpercent));
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Pump modulation"), this->device_type(), "pumpMod", "%", "mdi:sine-wave");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(pumpMod), this->device_type(), "pumpMod", F_(percent), F_(iconpercent));
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Heat Pump modulation"), this->device_type(), "pumpMod2", "%", "mdi:sine-wave");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(pumpMod2), this->device_type(), "pumpMod2", F_(percent), F_(iconpercent));
|
||||||
Mqtt::register_mqtt_ha_sensor(F("System Pressure"), this->device_type(), "sysPress", "bar", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wWType), this->device_type(), "wWType", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wWChargeType), this->device_type(), "wWChargeType", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wWCircPump), this->device_type(), "wWCircPump", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wWCiPuMode), this->device_type(), "wWCiPuMode", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wWCirc), this->device_type(), "wWCirc", nullptr, nullptr);
|
||||||
|
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(outdoorTemp), this->device_type(), "outdoorTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wWCurTmp), this->device_type(), "wWCurTmp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wWCurTmp2), this->device_type(), "wWCurTmp2", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wWCurFlow), this->device_type(), "wWCurFlow", F("l/min"), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(curFlowTemp), this->device_type(), "curFlowTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(retTemp), this->device_type(), "retTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(switchTemp), this->device_type(), "switchTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(sysPress), this->device_type(), "sysPress", F_(bar), nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(boilTemp), this->device_type(), "boilTemp", F_(degrees), nullptr);
|
||||||
|
|
||||||
|
// TODO add remaining values to MQTT
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(burnGas), this->device_type(), "burnGas", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(flameCurr), this->device_type(), "flameCurr", F_(uA), nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(heatPump), this->device_type(), "heatPump", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(fanWork), this->device_type(), "fanWork", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(ignWork), this->device_type(), "ignWork", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWHeat), this->device_type(), "wWHeat", nullptr, nullptr);
|
||||||
|
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wwStorageTemp1), this->device_type(), "wwStorageTemp1", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wwStorageTemp2), this->device_type(), "wwStorageTemp2", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(exhaustTemp), this->device_type(), "exhaustTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWActivated), this->device_type(), "wWActivated", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWOnetime), this->device_type(), "wWOnetime", nullptr, nullptr);
|
||||||
|
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWDisinfecting), this->device_type(), "wWDisinfecting", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWCharge), this->device_type(), "wWCharge", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWRecharge), this->device_type(), "wWRecharge", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWTempOK), this->device_type(), "wWTempOK", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWActive), this->device_type(), "wWActive", nullptr, nullptr);
|
||||||
|
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(heatingActivated), this->device_type(), "heatingActivated", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(heatingTemp), this->device_type(), "heatingTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(pumpModMax), this->device_type(), "pumpModMax", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(pumpModMin), this->device_type(), "pumpModMin", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(pumpDelay), this->device_type(), "pumpDelay", F_(min), nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(burnMinPeriod), this->device_type(), "burnMinPeriod", F_(min), nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(burnMinPower), this->device_type(), "burnMinPower", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(burnMaxPower), this->device_type(), "burnMaxPower", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(boilHystOn), this->device_type(), "boilHystOn", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(boilHystOff), this->device_type(), "boilHystOff", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(setFlowTemp), this->device_type(), "setFlowTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWSetPumpPower), this->device_type(), "wWSetPumpPower", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wwMixTemperature), this->device_type(), "wwMixTemperature", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wwBufferBoilerTemperature), this->device_type(), "wwBufferBoilerTemperature", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWStarts), this->device_type(), "wWStarts", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWWorkM), this->device_type(), "wWWorkM", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(setBurnPow), this->device_type(), "setBurnPow", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(burnStarts), this->device_type(), "burnStarts", nullptr, nullptr);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// send stuff to the Web UI
|
// send stuff to the Web UI
|
||||||
void Boiler::device_info_web(JsonArray & root) {
|
void Boiler::device_info_web(JsonArray & root) {
|
||||||
JsonObject dataElement;
|
JsonObject dataElement;
|
||||||
|
|
||||||
render_value_json(root, "", F("Service code"), serviceCodeChar_, nullptr);
|
render_value_json(root, "", F_(serviceCode), serviceCodeChar_, nullptr);
|
||||||
render_value_json(root, "", F("Service code number"), serviceCode_, nullptr);
|
render_value_json(root, "", F_(serviceCodeNumber), serviceCode_, nullptr);
|
||||||
render_value_json(root, "", F("Hot tap water"), tap_water_active_, nullptr, EMS_VALUE_BOOL);
|
render_value_json(root, "", F_(tapwaterActive), tap_water_active_, nullptr, EMS_VALUE_BOOL);
|
||||||
render_value_json(root, "", F("Central Heating"), heating_active_, nullptr, EMS_VALUE_BOOL);
|
render_value_json(root, "", F_(heatingActive), heating_active_, nullptr, EMS_VALUE_BOOL);
|
||||||
render_value_json(root, "", F("Selected flow temperature"), selFlowTemp_, F_(degrees));
|
render_value_json(root, "", F_(selFlowTemp), selFlowTemp_, F_(degrees));
|
||||||
render_value_json(root, "", F("Current flow temperature"), curFlowTemp_, F_(degrees), 10);
|
render_value_json(root, "", F_(curFlowTemp), curFlowTemp_, F_(degrees), 10);
|
||||||
render_value_json(root, "", F("Warm Water selected temperature"), wWSelTemp_, F_(degrees));
|
render_value_json(root, "", F_(wWSelTemp), wWSelTemp_, F_(degrees));
|
||||||
render_value_json(root, "", F("Warm Water set temperature"), wWSetTmp_, F_(degrees));
|
render_value_json(root, "", F_(wWSetTemp), wWSetTmp_, F_(degrees));
|
||||||
render_value_json(root, "", F("Warm Water current temperature (intern)"), wWCurTmp_, F_(degrees), 10);
|
render_value_json(root, "", F_(wWCurTmp), wWCurTmp_, F_(degrees), 10);
|
||||||
render_value_json(root, "", F("Warm Water current temperature (extern)"), wWCurTmp2_, F_(degrees), 10);
|
render_value_json(root, "", F_(wWCurTmp2), wWCurTmp2_, F_(degrees), 10);
|
||||||
render_value_json(root, "", F("Pump modulation"), pumpMod_, F_(percent));
|
render_value_json(root, "", F_(pumpMod), pumpMod_, F_(percent));
|
||||||
render_value_json(root, "", F("Heat Pump modulation"), pumpMod2_, F_(percent));
|
render_value_json(root, "", F_(pumpMod2), pumpMod2_, F_(percent));
|
||||||
render_value_json(root, "", F("System pressure"), sysPress_, F_(bar), 10);
|
render_value_json(root, "", F_(sysPress), sysPress_, F_(bar), 10);
|
||||||
|
|
||||||
|
// TODO add remaining values to web
|
||||||
|
/*
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(heatingActive), this->device_type(), "heatingActive", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(tapwaterActive), this->device_type(), "tapwaterActive", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(serviceCode), this->device_type(), "serviceCode", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(serviceCodeNumber), this->device_type(), "serviceCodeNumber", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWSelTemp), this->device_type(), "wWSelTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWSetTemp), this->device_type(), "wWSetTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWDisinfectionTemp), this->device_type(), "wWDisinfectionTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(selFlowTemp), this->device_type(), "selFlowTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(selBurnPow), this->device_type(), "selBurnPow", F_(percent), nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(curBurnPow), this->device_type(), "curBurnPow", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(pumpMod), this->device_type(), "pumpMod", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(pumpMod2), this->device_type(), "pumpMod2", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWType), this->device_type(), "wWType", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWChargeType), this->device_type(), "wWChargeType", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWCircPump), this->device_type(), "wWCircPump", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWCiPuMode), this->device_type(), "wWCiPuMode", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWCirc), this->device_type(), "wWCirc", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(outdoorTemp), this->device_type(), "outdoorTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWCurTmp), this->device_type(), "wWCurTmp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWCurTmp2), this->device_type(), "wWCurTmp2", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWCurFlow), this->device_type(), "wWCurFlow", F("l/min"), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(curFlowTemp), this->device_type(), "curFlowTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(retTemp), this->device_type(), "retTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(switchTemp), this->device_type(), "switchTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(sysPress), this->device_type(), "sysPress", F_(bar), nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(boilTemp), this->device_type(), "boilTemp", F_(degrees), nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wwStorageTemp1), this->device_type(), "wwStorageTemp1", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wwStorageTemp2), this->device_type(), "wwStorageTemp2", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(exhaustTemp), this->device_type(), "exhaustTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWActivated), this->device_type(), "wWActivated", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWOnetime), this->device_type(), "wWOnetime", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWDisinfecting), this->device_type(), "wWDisinfecting", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWCharge), this->device_type(), "wWCharge", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWRecharge), this->device_type(), "wWRecharge", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWTempOK), this->device_type(), "wWTempOK", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWActive), this->device_type(), "wWActive", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(burnGas), this->device_type(), "burnGas", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(flameCurr), this->device_type(), "flameCurr", F_(uA), nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(heatPump), this->device_type(), "heatPump", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(fanWork), this->device_type(), "fanWork", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(ignWork), this->device_type(), "ignWork", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWHeat), this->device_type(), "wWHeat", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(heatingActivated), this->device_type(), "heatingActivated", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(heatingTemp), this->device_type(), "heatingTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(pumpModMax), this->device_type(), "pumpModMax", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(pumpModMin), this->device_type(), "pumpModMin", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(pumpDelay), this->device_type(), "pumpDelay", F_(min), nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(burnMinPeriod), this->device_type(), "burnMinPeriod", F_(min), nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(burnMinPower), this->device_type(), "burnMinPower", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(burnMaxPower), this->device_type(), "burnMaxPower", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(boilHystOn), this->device_type(), "boilHystOn", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(boilHystOff), this->device_type(), "boilHystOff", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(setFlowTemp), this->device_type(), "setFlowTemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWSetPumpPower), this->device_type(), "wWSetPumpPower", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wwMixTemperature), this->device_type(), "wwMixTemperature", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wwBufferBoilerTemperature), this->device_type(), "wwBufferBoilerTemperature", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWStarts), this->device_type(), "wWStarts", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(wWWorkM), this->device_type(), "wWWorkM", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(setBurnPow), this->device_type(), "setBurnPow", F_(percent), F_(iconpercent));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(F_(burnStarts), this->device_type(), "burnStarts", nullptr, nullptr);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Boiler::command_info(const char * value, const int8_t id, JsonObject & output) {
|
bool Boiler::command_info(const char * value, const int8_t id, JsonObject & output) {
|
||||||
@@ -145,14 +266,17 @@ bool Boiler::command_info(const char * value, const int8_t id, JsonObject & outp
|
|||||||
bool Boiler::export_values(JsonObject & output) {
|
bool Boiler::export_values(JsonObject & output) {
|
||||||
char s[10]; // for formatting strings
|
char s[10]; // for formatting strings
|
||||||
|
|
||||||
|
// Hot tap water bool
|
||||||
if (Helpers::hasValue(heating_active_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(heating_active_, EMS_VALUE_BOOL)) {
|
||||||
output["heating_active"] = Helpers::render_value(s, heating_active_, EMS_VALUE_BOOL);
|
output["heatingActive"] = Helpers::render_value(s, heating_active_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Central heating bool
|
||||||
if (Helpers::hasValue(tap_water_active_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(tap_water_active_, EMS_VALUE_BOOL)) {
|
||||||
output["tap_water_active"] = Helpers::render_value(s, tap_water_active_, EMS_VALUE_BOOL);
|
output["tapwaterActive"] = Helpers::render_value(s, tap_water_active_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water comfort setting
|
||||||
if (Helpers::hasValue(wWComfort_)) {
|
if (Helpers::hasValue(wWComfort_)) {
|
||||||
if (wWComfort_ == 0x00) {
|
if (wWComfort_ == 0x00) {
|
||||||
output["wWComfort"] = "Hot";
|
output["wWComfort"] = "Hot";
|
||||||
@@ -163,30 +287,47 @@ bool Boiler::export_values(JsonObject & output) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water selected temperature
|
||||||
if (Helpers::hasValue(wWSelTemp_)) {
|
if (Helpers::hasValue(wWSelTemp_)) {
|
||||||
output["wWSelTemp"] = wWSelTemp_;
|
output["wWSelTemp"] = wWSelTemp_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water set temperature
|
||||||
if (Helpers::hasValue(wWSetTmp_)) {
|
if (Helpers::hasValue(wWSetTmp_)) {
|
||||||
output["wWSetTemp"] = wWSetTmp_;
|
output["wWSetTemp"] = wWSetTmp_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water disinfection temperature
|
||||||
if (Helpers::hasValue(wWDisinfectTemp_)) {
|
if (Helpers::hasValue(wWDisinfectTemp_)) {
|
||||||
output["wWDisinfectionTemp"] = wWDisinfectTemp_;
|
output["wWDisinfectionTemp"] = wWDisinfectTemp_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Selected flow temperature deg
|
||||||
if (Helpers::hasValue(selFlowTemp_)) {
|
if (Helpers::hasValue(selFlowTemp_)) {
|
||||||
output["selFlowTemp"] = selFlowTemp_;
|
output["selFlowTemp"] = selFlowTemp_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Burner selected max power %
|
||||||
if (Helpers::hasValue(selBurnPow_)) {
|
if (Helpers::hasValue(selBurnPow_)) {
|
||||||
output["selBurnPow"] = selBurnPow_;
|
output["selBurnPow"] = selBurnPow_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Burner current power %
|
||||||
if (Helpers::hasValue(curBurnPow_)) {
|
if (Helpers::hasValue(curBurnPow_)) {
|
||||||
output["curBurnPow"] = curBurnPow_;
|
output["curBurnPow"] = curBurnPow_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pump modulation %
|
||||||
if (Helpers::hasValue(pumpMod_)) {
|
if (Helpers::hasValue(pumpMod_)) {
|
||||||
output["pumpMod"] = pumpMod_;
|
output["pumpMod"] = pumpMod_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Heat Pump modulation %
|
||||||
if (Helpers::hasValue(pumpMod2_)) {
|
if (Helpers::hasValue(pumpMod2_)) {
|
||||||
output["pumpMod2"] = pumpMod2_;
|
output["pumpMod2"] = pumpMod2_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water type
|
||||||
if (wWType_ == 0) { // no output if not set
|
if (wWType_ == 0) { // no output if not set
|
||||||
output["wWType"] = F("off");
|
output["wWType"] = F("off");
|
||||||
} else if (wWType_ == 1) {
|
} else if (wWType_ == 1) {
|
||||||
@@ -198,147 +339,269 @@ bool Boiler::export_values(JsonObject & output) {
|
|||||||
} else if (wWType_ == 4) {
|
} else if (wWType_ == 4) {
|
||||||
output["wWType"] = F("layered buffer");
|
output["wWType"] = F("layered buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water charging type
|
||||||
if (Helpers::hasValue(wWChargeType_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(wWChargeType_, EMS_VALUE_BOOL)) {
|
||||||
output["wWChargeType"] = wWChargeType_ ? "valve" : "pump";
|
output["wWChargeType"] = wWChargeType_ ? "3-way valve" : "charge pump";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water circulation pump available bool
|
||||||
if (Helpers::hasValue(wWCircPump_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(wWCircPump_, EMS_VALUE_BOOL)) {
|
||||||
output["wWCircPump"] = Helpers::render_value(s, wWCircPump_, EMS_VALUE_BOOL);
|
output["wWCircPump"] = Helpers::render_value(s, wWCircPump_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water circulation pump freq
|
||||||
if (Helpers::hasValue(wWCircPumpMode_)) {
|
if (Helpers::hasValue(wWCircPumpMode_)) {
|
||||||
output["wWCiPuMode"] = wWCircPumpMode_;
|
if (wWCircPumpMode_ == 7) {
|
||||||
|
output["wWCiPuMode"] = F("continuous");
|
||||||
|
} else {
|
||||||
|
char s[7];
|
||||||
|
char buffer[2];
|
||||||
|
buffer[0] = (wWCircPumpMode_ % 10) + '0';
|
||||||
|
buffer[1] = '\0';
|
||||||
|
strlcpy(s, buffer, 7);
|
||||||
|
strlcat(s, "x3min", 7);
|
||||||
|
output["wWCiPuMode"] = s;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warm Water circulation active bool
|
||||||
if (Helpers::hasValue(wWCirc_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(wWCirc_, EMS_VALUE_BOOL)) {
|
||||||
output["wWCirc"] = Helpers::render_value(s, wWCirc_, EMS_VALUE_BOOL);
|
output["wWCirc"] = Helpers::render_value(s, wWCirc_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Outside temperature
|
||||||
if (Helpers::hasValue(extTemp_)) {
|
if (Helpers::hasValue(extTemp_)) {
|
||||||
output["outdoorTemp"] = (float)extTemp_ / 10;
|
output["outdoorTemp"] = (float)extTemp_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water current temperature (intern)
|
||||||
if (Helpers::hasValue(wWCurTmp_)) {
|
if (Helpers::hasValue(wWCurTmp_)) {
|
||||||
output["wWCurTmp"] = (float)wWCurTmp_ / 10;
|
output["wWCurTmp"] = (float)wWCurTmp_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water current temperature (extern)
|
||||||
if (Helpers::hasValue(wWCurTmp2_)) {
|
if (Helpers::hasValue(wWCurTmp2_)) {
|
||||||
output["wWCurTmp2"] = (float)wWCurTmp2_ / 10;
|
output["wWCurTmp2"] = (float)wWCurTmp2_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water current tap water flow l/min
|
||||||
if (Helpers::hasValue(wWCurFlow_)) {
|
if (Helpers::hasValue(wWCurFlow_)) {
|
||||||
output["wWCurFlow"] = (float)wWCurFlow_ / 10;
|
output["wWCurFlow"] = (float)wWCurFlow_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Current flow temperature
|
||||||
if (Helpers::hasValue(curFlowTemp_)) {
|
if (Helpers::hasValue(curFlowTemp_)) {
|
||||||
output["curFlowTemp"] = (float)curFlowTemp_ / 10;
|
output["curFlowTemp"] = (float)curFlowTemp_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return temperature
|
||||||
if (Helpers::hasValue(retTemp_)) {
|
if (Helpers::hasValue(retTemp_)) {
|
||||||
output["retTemp"] = (float)retTemp_ / 10;
|
output["retTemp"] = (float)retTemp_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mixing switch temperature
|
||||||
if (Helpers::hasValue(switchTemp_)) {
|
if (Helpers::hasValue(switchTemp_)) {
|
||||||
output["switchTemp"] = (float)switchTemp_ / 10;
|
output["switchTemp"] = (float)switchTemp_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// System pressure
|
||||||
if (Helpers::hasValue(sysPress_)) {
|
if (Helpers::hasValue(sysPress_)) {
|
||||||
output["sysPress"] = (float)sysPress_ / 10;
|
output["sysPress"] = (float)sysPress_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Max boiler temperature
|
||||||
if (Helpers::hasValue(boilTemp_)) {
|
if (Helpers::hasValue(boilTemp_)) {
|
||||||
output["boilTemp"] = (float)boilTemp_ / 10;
|
output["boilTemp"] = (float)boilTemp_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm water storage temperature (intern)
|
||||||
if (Helpers::hasValue(wwStorageTemp1_)) {
|
if (Helpers::hasValue(wwStorageTemp1_)) {
|
||||||
output["wwStorageTemp1"] = (float)wwStorageTemp1_ / 10;
|
output["wwStorageTemp1"] = (float)wwStorageTemp1_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm water storage temperature (extern)
|
||||||
if (Helpers::hasValue(wwStorageTemp2_)) {
|
if (Helpers::hasValue(wwStorageTemp2_)) {
|
||||||
output["wwStorageTemp2"] = (float)wwStorageTemp2_ / 10;
|
output["wwStorageTemp2"] = (float)wwStorageTemp2_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exhaust temperature
|
||||||
if (Helpers::hasValue(exhaustTemp_)) {
|
if (Helpers::hasValue(exhaustTemp_)) {
|
||||||
output["exhaustTemp"] = (float)exhaustTemp_ / 10;
|
output["exhaustTemp"] = (float)exhaustTemp_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water activated bool
|
||||||
if (Helpers::hasValue(wWActivated_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(wWActivated_, EMS_VALUE_BOOL)) {
|
||||||
output["wWActivated"] = Helpers::render_value(s, wWActivated_, EMS_VALUE_BOOL);
|
output["wWActivated"] = Helpers::render_value(s, wWActivated_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water one time charging bool
|
||||||
if (Helpers::hasValue(wWOneTime_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(wWOneTime_, EMS_VALUE_BOOL)) {
|
||||||
output["wWOnetime"] = Helpers::render_value(s, wWOneTime_, EMS_VALUE_BOOL);
|
output["wWOnetime"] = Helpers::render_value(s, wWOneTime_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water disinfecting bool
|
||||||
if (Helpers::hasValue(wWDisinfecting_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(wWDisinfecting_, EMS_VALUE_BOOL)) {
|
||||||
output["wWDisinfecting"] = Helpers::render_value(s, wWDisinfecting_, EMS_VALUE_BOOL);
|
output["wWDisinfecting"] = Helpers::render_value(s, wWDisinfecting_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm water charging bool
|
||||||
if (Helpers::hasValue(wWCharging_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(wWCharging_, EMS_VALUE_BOOL)) {
|
||||||
output["wWCharge"] = Helpers::render_value(s, wWCharging_, EMS_VALUE_BOOL);
|
output["wWCharge"] = Helpers::render_value(s, wWCharging_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm water recharge bool
|
||||||
if (Helpers::hasValue(wWRecharging_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(wWRecharging_, EMS_VALUE_BOOL)) {
|
||||||
output["wWRecharge"] = Helpers::render_value(s, wWRecharging_, EMS_VALUE_BOOL);
|
output["wWRecharge"] = Helpers::render_value(s, wWRecharging_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm water temperature ok bool
|
||||||
if (Helpers::hasValue(wWTemperatureOK_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(wWTemperatureOK_, EMS_VALUE_BOOL)) {
|
||||||
output["wWTempOK"] = Helpers::render_value(s, wWTemperatureOK_, EMS_VALUE_BOOL);
|
output["wWTempOK"] = Helpers::render_value(s, wWTemperatureOK_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm water active bool
|
||||||
if (Helpers::hasValue(wWActive_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(wWActive_, EMS_VALUE_BOOL)) {
|
||||||
output["wWActive"] = Helpers::render_value(s, wWActive_, EMS_VALUE_BOOL);
|
output["wWActive"] = Helpers::render_value(s, wWActive_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gas bool
|
||||||
if (Helpers::hasValue(burnGas_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(burnGas_, EMS_VALUE_BOOL)) {
|
||||||
output["burnGas"] = Helpers::render_value(s, burnGas_, EMS_VALUE_BOOL);
|
output["burnGas"] = Helpers::render_value(s, burnGas_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flame current uA
|
||||||
if (Helpers::hasValue(flameCurr_)) {
|
if (Helpers::hasValue(flameCurr_)) {
|
||||||
output["flameCurr"] = (float)(int16_t)flameCurr_ / 10;
|
output["flameCurr"] = (float)(int16_t)flameCurr_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boiler pump bool
|
||||||
if (Helpers::hasValue(heatPmp_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(heatPmp_, EMS_VALUE_BOOL)) {
|
||||||
output["heatPump"] = Helpers::render_value(s, heatPmp_, EMS_VALUE_BOOL);
|
output["heatPump"] = Helpers::render_value(s, heatPmp_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fan bool
|
||||||
if (Helpers::hasValue(fanWork_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(fanWork_, EMS_VALUE_BOOL)) {
|
||||||
output["fanWork"] = Helpers::render_value(s, fanWork_, EMS_VALUE_BOOL);
|
output["fanWork"] = Helpers::render_value(s, fanWork_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ignition bool
|
||||||
if (Helpers::hasValue(ignWork_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(ignWork_, EMS_VALUE_BOOL)) {
|
||||||
output["ignWork"] = Helpers::render_value(s, ignWork_, EMS_VALUE_BOOL);
|
output["ignWork"] = Helpers::render_value(s, ignWork_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water charging bool
|
||||||
if (Helpers::hasValue(wWHeat_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(wWHeat_, EMS_VALUE_BOOL)) {
|
||||||
output["wWHeat"] = Helpers::render_value(s, wWHeat_, EMS_VALUE_BOOL);
|
output["wWHeat"] = Helpers::render_value(s, wWHeat_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// heating activated bool
|
||||||
if (Helpers::hasValue(heating_activated_, EMS_VALUE_BOOL)) {
|
if (Helpers::hasValue(heating_activated_, EMS_VALUE_BOOL)) {
|
||||||
output["heatingActivated"] = Helpers::render_value(s, heating_activated_, EMS_VALUE_BOOL);
|
output["heatingActivated"] = Helpers::render_value(s, heating_activated_, EMS_VALUE_BOOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Heating temperature setting on the boiler
|
||||||
if (Helpers::hasValue(heating_temp_)) {
|
if (Helpers::hasValue(heating_temp_)) {
|
||||||
output["heatingTemp"] = heating_temp_;
|
output["heatingTemp"] = heating_temp_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boiler circuit pump modulation max power %
|
||||||
if (Helpers::hasValue(pump_mod_max_)) {
|
if (Helpers::hasValue(pump_mod_max_)) {
|
||||||
output["pumpModMax"] = pump_mod_max_;
|
output["pumpModMax"] = pump_mod_max_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boiler circuit pump modulation min power %
|
||||||
if (Helpers::hasValue(pump_mod_min_)) {
|
if (Helpers::hasValue(pump_mod_min_)) {
|
||||||
output["pumpModMin"] = pump_mod_min_;
|
output["pumpModMin"] = pump_mod_min_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boiler circuit pump delay time min
|
||||||
if (Helpers::hasValue(pumpDelay_)) {
|
if (Helpers::hasValue(pumpDelay_)) {
|
||||||
output["pumpDelay"] = pumpDelay_;
|
output["pumpDelay"] = pumpDelay_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boiler burner min period min
|
||||||
if (Helpers::hasValue(burnPeriod_)) {
|
if (Helpers::hasValue(burnPeriod_)) {
|
||||||
output["burnMinPeriod"] = burnPeriod_;
|
output["burnMinPeriod"] = burnPeriod_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boiler burner min power %
|
||||||
if (Helpers::hasValue(burnPowermin_)) {
|
if (Helpers::hasValue(burnPowermin_)) {
|
||||||
output["burnMinPower"] = burnPowermin_;
|
output["burnMinPower"] = burnPowermin_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boiler burner max power %
|
||||||
if (Helpers::hasValue(burnPowermax_)) {
|
if (Helpers::hasValue(burnPowermax_)) {
|
||||||
output["burnMaxPower"] = burnPowermax_;
|
output["burnMaxPower"] = burnPowermax_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boiler temp hysteresis on degrees
|
||||||
if (Helpers::hasValue(boilTemp_on_)) {
|
if (Helpers::hasValue(boilTemp_on_)) {
|
||||||
output["boilHystOn"] = boilTemp_on_;
|
output["boilHystOn"] = boilTemp_on_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boiler temp hysteresis off degrees
|
||||||
if (Helpers::hasValue(boilTemp_off_)) {
|
if (Helpers::hasValue(boilTemp_off_)) {
|
||||||
output["boilHystOff"] = boilTemp_off_;
|
output["boilHystOff"] = boilTemp_off_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set Flow temperature
|
||||||
if (Helpers::hasValue(setFlowTemp_)) {
|
if (Helpers::hasValue(setFlowTemp_)) {
|
||||||
output["setFlowTemp"] = setFlowTemp_;
|
output["setFlowTemp"] = setFlowTemp_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water pump set power %
|
||||||
if (Helpers::hasValue(setWWPumpPow_)) {
|
if (Helpers::hasValue(setWWPumpPow_)) {
|
||||||
output["wWSetPumpPower"] = setWWPumpPow_;
|
output["wWSetPumpPower"] = setWWPumpPow_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm water mix temperature
|
||||||
|
if (Helpers::hasValue(wwMixTemperature_)) {
|
||||||
|
output["wwMixTemperature"] = wwMixTemperature_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warm water buffer boiler temperature
|
||||||
|
if (Helpers::hasValue(wwBufferBoilerTemperature_)) {
|
||||||
|
output["wwBufferBoilerTemperature"] = wwBufferBoilerTemperature_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warm Water # starts
|
||||||
if (Helpers::hasValue(wWStarts_)) {
|
if (Helpers::hasValue(wWStarts_)) {
|
||||||
output["wWStarts"] = wWStarts_;
|
output["wWStarts"] = wWStarts_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water active time
|
||||||
if (Helpers::hasValue(wWWorkM_)) {
|
if (Helpers::hasValue(wWWorkM_)) {
|
||||||
output["wWWorkM"] = wWWorkM_;
|
output["wWWorkM"] = wWWorkM_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Total UBA working time
|
||||||
if (Helpers::hasValue(UBAuptime_)) {
|
if (Helpers::hasValue(UBAuptime_)) {
|
||||||
output["UBAuptime"] = UBAuptime_;
|
output["UBAuptime"] = UBAuptime_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Boiler burner set power %
|
||||||
|
if (Helpers::hasValue(setBurnPow_)) {
|
||||||
|
output["setBurnPow_"] = setBurnPow_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Burner # starts
|
||||||
if (Helpers::hasValue(burnStarts_)) {
|
if (Helpers::hasValue(burnStarts_)) {
|
||||||
output["burnStarts"] = burnStarts_;
|
output["burnStarts"] = burnStarts_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Total burner operating time
|
||||||
if (Helpers::hasValue(burnWorkMin_)) {
|
if (Helpers::hasValue(burnWorkMin_)) {
|
||||||
output["burnWorkMin"] = burnWorkMin_;
|
output["burnWorkMin"] = burnWorkMin_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Total heat operating time
|
||||||
if (Helpers::hasValue(heatWorkMin_)) {
|
if (Helpers::hasValue(heatWorkMin_)) {
|
||||||
output["heatWorkMin"] = heatWorkMin_;
|
output["heatWorkMin"] = heatWorkMin_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Service Code
|
||||||
|
// Service Code Number
|
||||||
if (Helpers::hasValue(serviceCode_)) {
|
if (Helpers::hasValue(serviceCode_)) {
|
||||||
output["serviceCode"] = serviceCodeChar_;
|
output["serviceCode"] = serviceCodeChar_;
|
||||||
output["serviceCodeNumber"] = serviceCode_;
|
output["serviceCodeNumber"] = serviceCode_;
|
||||||
@@ -372,113 +635,78 @@ bool Boiler::updated_values() {
|
|||||||
void Boiler::show_values(uuid::console::Shell & shell) {
|
void Boiler::show_values(uuid::console::Shell & shell) {
|
||||||
EMSdevice::show_values(shell); // for showing the header
|
EMSdevice::show_values(shell); // for showing the header
|
||||||
|
|
||||||
print_value(shell, 2, F("Hot tap water"), tap_water_active_, nullptr, EMS_VALUE_BOOL);
|
// fetch the values into a JSON document
|
||||||
print_value(shell, 2, F("Central heating"), heating_active_, nullptr, EMS_VALUE_BOOL);
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_LARGE> doc;
|
||||||
|
JsonObject output = doc.to<JsonObject>();
|
||||||
print_value(shell, 2, F("Warm Water activated"), wWActivated_, nullptr, EMS_VALUE_BOOL);
|
if (!export_values(output)) {
|
||||||
if (wWType_ == 0) {
|
return; // empty
|
||||||
print_value(shell, 2, F("Warm Water type"), F("off"));
|
|
||||||
} else if (wWType_ == 1) {
|
|
||||||
print_value(shell, 2, F("Warm Water type"), F("flow"));
|
|
||||||
} else if (wWType_ == 2) {
|
|
||||||
print_value(shell, 2, F("Warm Water type"), F("buffered flow"));
|
|
||||||
} else if (wWType_ == 3) {
|
|
||||||
print_value(shell, 2, F("Warm Water type"), F("buffer"));
|
|
||||||
} else if (wWType_ == 4) {
|
|
||||||
print_value(shell, 2, F("Warm Water type"), F("layered buffer"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Helpers::hasValue(wWChargeType_, EMS_VALUE_BOOL)) {
|
print_value_json(shell, F("heatingActive"), F_(heatingActive), nullptr, output);
|
||||||
print_value(shell, 2, F("Warm Water charging type"), wWChargeType_ ? F("3-way valve") : F("charge pump"));
|
print_value_json(shell, F("tapwaterActive"), F_(tapwaterActive), nullptr, output);
|
||||||
}
|
print_value_json(shell, F("serviceCode"), F_(serviceCode), nullptr, output);
|
||||||
|
print_value_json(shell, F("serviceCodeNumber"), F_(serviceCodeNumber), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWSelTemp"), F_(wWSelTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("wWSetTemp"), F_(wWSetTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("wWDisinfectionTemp"), F_(wWDisinfectionTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("selFlowTemp"), F_(selFlowTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("selBurnPow"), F_(selBurnPow), F_(percent), output);
|
||||||
|
print_value_json(shell, F("curBurnPow"), F_(curBurnPow), F_(percent), output);
|
||||||
|
print_value_json(shell, F("pumpMod"), F_(pumpMod), F_(percent), output);
|
||||||
|
print_value_json(shell, F("pumpMod2"), F_(pumpMod2), F_(percent), output);
|
||||||
|
print_value_json(shell, F("wWType"), F_(wWType), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWChargeType"), F_(wWChargeType), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWCircPump"), F_(wWCircPump), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWCiPuMode"), F_(wWCiPuMode), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWCirc"), F_(wWCirc), nullptr, output);
|
||||||
|
print_value_json(shell, F("outdoorTemp"), F_(outdoorTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("wWCurTmp"), F_(wWCurTmp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("wWCurTmp2"), F_(wWCurTmp2), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("wWCurFlow"), F_(wWCurFlow), F("l/min"), output);
|
||||||
|
print_value_json(shell, F("curFlowTemp"), F_(curFlowTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("retTemp"), F_(retTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("switchTemp"), F_(switchTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("sysPress"), F_(sysPress), nullptr, output);
|
||||||
|
print_value_json(shell, F("boilTemp"), F_(boilTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("wwStorageTemp1"), F_(wwStorageTemp1), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("wwStorageTemp2"), F_(wwStorageTemp2), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("exhaustTemp"), F_(exhaustTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("wWActivated"), F_(wWActivated), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWOnetime"), F_(wWOnetime), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWDisinfecting"), F_(wWDisinfecting), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWCharge"), F_(wWCharge), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWRecharge"), F_(wWRecharge), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWTempOK"), F_(wWTempOK), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWActive"), F_(wWActive), nullptr, output);
|
||||||
|
print_value_json(shell, F("burnGas"), F_(burnGas), nullptr, output);
|
||||||
|
print_value_json(shell, F("flameCurr"), F_(flameCurr), F_(uA), output);
|
||||||
|
print_value_json(shell, F("heatPump"), F_(heatPump), nullptr, output);
|
||||||
|
print_value_json(shell, F("fanWork"), F_(fanWork), nullptr, output);
|
||||||
|
print_value_json(shell, F("ignWork"), F_(ignWork), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWHeat"), F_(wWHeat), nullptr, output);
|
||||||
|
print_value_json(shell, F("heatingActivated"), F_(heatingActivated), nullptr, output);
|
||||||
|
print_value_json(shell, F("heatingTemp"), F_(heatingTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("pumpModMax"), F_(pumpModMax), F_(percent), output);
|
||||||
|
print_value_json(shell, F("pumpModMin"), F_(pumpModMin), F_(percent), output);
|
||||||
|
print_value_json(shell, F("pumpDelay"), F_(pumpDelay), F_(min), output);
|
||||||
|
print_value_json(shell, F("burnMinPeriod"), F_(burnMinPeriod), F_(min), output);
|
||||||
|
print_value_json(shell, F("burnMinPower"), F_(burnMinPower), F_(percent), output);
|
||||||
|
print_value_json(shell, F("burnMaxPower"), F_(burnMaxPower), F_(percent), output);
|
||||||
|
print_value_json(shell, F("boilHystOn"), F_(boilHystOn), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("boilHystOff"), F_(boilHystOff), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("setFlowTemp"), F_(setFlowTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("wWSetPumpPower"), F_(wWSetPumpPower), F_(percent), output);
|
||||||
|
print_value_json(shell, F("wwMixTemperature"), F_(wwMixTemperature), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("wwBufferBoilerTemperature"), F_(wwBufferBoilerTemperature), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("wWStarts"), F_(wWStarts), nullptr, output);
|
||||||
|
print_value_json(shell, F("wWWorkM"), F_(wWWorkM), nullptr, output);
|
||||||
|
print_value_json(shell, F("setBurnPow"), F_(setBurnPow), F_(percent), output);
|
||||||
|
print_value_json(shell, F("burnStarts"), F_(burnStarts), nullptr, output);
|
||||||
|
|
||||||
print_value(shell, 2, F("Warm Water circulation pump available"), wWCircPump_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
|
|
||||||
if (Helpers::hasValue(wWCircPumpMode_)) {
|
|
||||||
if (wWCircPumpMode_ == 7) {
|
|
||||||
print_value(shell, 2, F("Warm Water circulation pump freq"), F("continuous"));
|
|
||||||
} else {
|
|
||||||
char s[7];
|
|
||||||
char buffer[2];
|
|
||||||
buffer[0] = (wWCircPumpMode_ % 10) + '0';
|
|
||||||
buffer[1] = '\0';
|
|
||||||
strlcpy(s, buffer, 7);
|
|
||||||
strlcat(s, "x3min", 7);
|
|
||||||
print_value(shell, 2, F("Warm Water circulation pump freq"), s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print_value(shell, 2, F("Warm Water circulation active"), wWCirc_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
|
|
||||||
if (wWComfort_ == 0x00) {
|
|
||||||
print_value(shell, 2, F("Warm Water comfort setting"), F("Hot"));
|
|
||||||
} else if (wWComfort_ == 0xD8) {
|
|
||||||
print_value(shell, 2, F("Warm Water comfort setting"), F("Eco"));
|
|
||||||
} else if (wWComfort_ == 0xEC) {
|
|
||||||
print_value(shell, 2, F("Warm Water comfort setting"), F("Intelligent"));
|
|
||||||
}
|
|
||||||
|
|
||||||
print_value(shell, 2, F("Warm water mix temperature"), wwMixTemperature_, F_(degrees), 10);
|
|
||||||
print_value(shell, 2, F("Warm water buffer boiler temperature"), wwBufferBoilerTemperature_, F_(degrees), 10);
|
|
||||||
print_value(shell, 2, F("Warm Water disinfection temperature"), wWDisinfectTemp_, F_(degrees));
|
|
||||||
print_value(shell, 2, F("Warm Water selected temperature"), wWSelTemp_, F_(degrees));
|
|
||||||
print_value(shell, 2, F("Warm Water set temperature"), wWSetTmp_, F_(degrees));
|
|
||||||
print_value(shell, 2, F("Warm Water current temperature (intern)"), wWCurTmp_, F_(degrees), 10);
|
|
||||||
print_value(shell, 2, F("Warm water storage temperature (intern)"), wwStorageTemp1_, F_(degrees), 10);
|
|
||||||
print_value(shell, 2, F("Warm Water current temperature (extern)"), wWCurTmp2_, F_(degrees), 10);
|
|
||||||
print_value(shell, 2, F("Warm water storage temperature (extern)"), wwStorageTemp2_, F_(degrees), 10);
|
|
||||||
print_value(shell, 2, F("Warm Water current tap water flow"), wWCurFlow_, F("l/min"), 10);
|
|
||||||
print_value(shell, 2, F("Warm Water # starts"), wWStarts_, nullptr);
|
|
||||||
if (Helpers::hasValue(wWWorkM_)) {
|
if (Helpers::hasValue(wWWorkM_)) {
|
||||||
shell.printfln(F(" Warm Water active time: %d days %d hours %d minutes"), wWWorkM_ / 1440, (wWWorkM_ % 1440) / 60, wWWorkM_ % 60);
|
shell.printfln(F(" Warm Water active time: %d days %d hours %d minutes"), wWWorkM_ / 1440, (wWWorkM_ % 1440) / 60, wWWorkM_ % 60);
|
||||||
}
|
}
|
||||||
print_value(shell, 2, F("Warm Water one time charging"), wWOneTime_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
print_value(shell, 2, F("Warm Water charging"), wWHeat_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
print_value(shell, 2, F("Warm Water disinfecting"), wWDisinfecting_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
print_value(shell, 2, F("Selected flow temperature"), selFlowTemp_, F_(degrees));
|
|
||||||
print_value(shell, 2, F("Current flow temperature"), curFlowTemp_, F_(degrees), 10);
|
|
||||||
print_value(shell, 2, F("Max boiler temperature"), boilTemp_, F_(degrees), 10);
|
|
||||||
print_value(shell, 2, F("Return temperature"), retTemp_, F_(degrees), 10);
|
|
||||||
print_value(shell, 2, F("Gas"), burnGas_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
print_value(shell, 2, F("Boiler pump"), heatPmp_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
print_value(shell, 2, F("Fan"), fanWork_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
print_value(shell, 2, F("Ignition"), ignWork_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
|
|
||||||
print_value(shell, 2, F("Burner selected max power"), selBurnPow_, F_(percent));
|
|
||||||
print_value(shell, 2, F("Burner current power"), curBurnPow_, F_(percent));
|
|
||||||
print_value(shell, 2, F("Flame current"), flameCurr_, F_(uA), 10);
|
|
||||||
print_value(shell, 2, F("System pressure"), sysPress_, F_(bar), 10);
|
|
||||||
if (Helpers::hasValue(serviceCode_)) {
|
|
||||||
shell.printfln(F(" System service code: %s (%d)"), serviceCodeChar_, serviceCode_);
|
|
||||||
} else if (serviceCodeChar_[0] != '\0') {
|
|
||||||
print_value(shell, 2, F("System service code"), serviceCodeChar_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// UBAParameters
|
|
||||||
print_value(shell, 2, F("Heating activated"), heating_activated_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
print_value(shell, 2, F("Heating temperature setting on the boiler"), heating_temp_, F_(degrees));
|
|
||||||
print_value(shell, 2, F("Boiler circuit pump modulation max power"), pump_mod_max_, F_(percent));
|
|
||||||
print_value(shell, 2, F("Boiler circuit pump modulation min power"), pump_mod_min_, F_(percent));
|
|
||||||
print_value(shell, 2, F("Boiler circuit pump delay time"), pumpDelay_, F_(min));
|
|
||||||
print_value(shell, 2, F("Boiler temp hysteresis on"), boilTemp_on_, F_(degrees));
|
|
||||||
print_value(shell, 2, F("Boiler temp hysteresis off"), boilTemp_off_, F_(degrees));
|
|
||||||
print_value(shell, 2, F("Boiler burner min period"), burnPeriod_, F_(min));
|
|
||||||
print_value(shell, 2, F("Boiler burner min power"), burnPowermin_, F_(percent));
|
|
||||||
print_value(shell, 2, F("Boiler burner max power"), burnPowermax_, F_(percent));
|
|
||||||
|
|
||||||
// UBASetPoint - these may differ from the above
|
|
||||||
print_value(shell, 2, F("Set Flow temperature"), setFlowTemp_, F_(degrees));
|
|
||||||
print_value(shell, 2, F("Boiler burner set power"), setBurnPow_, F_(percent));
|
|
||||||
print_value(shell, 2, F("Warm Water pump set power"), setWWPumpPow_, F_(percent));
|
|
||||||
|
|
||||||
// UBAMonitorSlow
|
|
||||||
if (Helpers::hasValue(extTemp_)) {
|
|
||||||
print_value(shell, 2, F("Outside temperature"), extTemp_, F_(degrees), 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
print_value(shell, 2, F("Exhaust temperature"), exhaustTemp_, F_(degrees), 10);
|
|
||||||
print_value(shell, 2, F("Pump modulation"), pumpMod_, F_(percent));
|
|
||||||
print_value(shell, 2, F("Heat Pump modulation"), pumpMod2_, F_(percent));
|
|
||||||
print_value(shell, 2, F("Burner # starts"), burnStarts_, nullptr);
|
|
||||||
if (Helpers::hasValue(burnWorkMin_)) {
|
if (Helpers::hasValue(burnWorkMin_)) {
|
||||||
shell.printfln(F(" Total burner operating time: %d days %d hours %d minutes"), burnWorkMin_ / 1440, (burnWorkMin_ % 1440) / 60, burnWorkMin_ % 60);
|
shell.printfln(F(" Total burner operating time: %d days %d hours %d minutes"), burnWorkMin_ / 1440, (burnWorkMin_ % 1440) / 60, burnWorkMin_ % 60);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,11 +47,11 @@ class Boiler : public EMSdevice {
|
|||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
void register_mqtt_ha_config();
|
void register_mqtt_ha_config();
|
||||||
void register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, const char * entity);
|
|
||||||
void register_mqtt_ha_sensor(const __FlashStringHelper * name, const char * entity, const char * uom, const char * icon);
|
|
||||||
void check_active();
|
void check_active();
|
||||||
bool export_values(JsonObject & doc);
|
bool export_values(JsonObject & doc);
|
||||||
|
|
||||||
|
void print_value2(uuid::console::Shell & shell, const char * param, const __FlashStringHelper * name, const __FlashStringHelper * suffix, JsonObject & json);
|
||||||
|
|
||||||
uint8_t last_boilerState = 0xFF; // remember last state of heating and warm water on/off
|
uint8_t last_boilerState = 0xFF; // remember last state of heating and warm water on/off
|
||||||
bool changed_ = false;
|
bool changed_ = false;
|
||||||
|
|
||||||
|
|||||||
@@ -98,17 +98,24 @@ void Mixing::show_values(uuid::console::Shell & shell) {
|
|||||||
return; // don't have any values yet
|
return; // don't have any values yet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fetch the values into a JSON document
|
||||||
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||||
|
JsonObject output = doc.to<JsonObject>();
|
||||||
|
if (!export_values(output)) {
|
||||||
|
return; // empty
|
||||||
|
}
|
||||||
|
|
||||||
if (type() == Type::WWC) {
|
if (type() == Type::WWC) {
|
||||||
print_value(shell, 2, F("Warm Water Circuit"), hc_, nullptr);
|
shell.println(F_(ww_hc));
|
||||||
print_value(shell, 4, F("Current warm water temperature"), flowTemp_, F_(degrees), 10);
|
print_value_json(shell, F("wwTemp"), F_(wwTemp), F_(degrees), output);
|
||||||
print_value(shell, 4, F("Current pump status"), pump_, nullptr, EMS_VALUE_BOOL);
|
print_value_json(shell, F("pumpStatus"), F_(pumpStatus), nullptr, output);
|
||||||
print_value(shell, 4, F("Current temperature status"), status_, nullptr);
|
print_value_json(shell, F("tempStatus"), F_(tempStatus), nullptr, output);
|
||||||
} else {
|
} else {
|
||||||
print_value(shell, 2, F("Heating Circuit"), hc_, nullptr);
|
shell.println(F_(hc));
|
||||||
print_value(shell, 4, F("Current flow temperature"), flowTemp_, F_(degrees), 10);
|
print_value_json(shell, F("flowTemp"), F_(flowTemp), F_(degrees), output);
|
||||||
print_value(shell, 4, F("Setpoint flow temperature"), flowSetTemp_, F_(degrees));
|
print_value_json(shell, F("flowSetTemp"), F_(flowSetTemp), F_(degrees), output);
|
||||||
print_value(shell, 4, F("Current pump status"), pump_, nullptr, EMS_VALUE_BOOL);
|
print_value_json(shell, F("pumpStatus"), F_(pumpStatus), nullptr, output);
|
||||||
print_value(shell, 4, F("Current valve status"), status_, F_(percent));
|
print_value_json(shell, F("valveStatus"), F_(valveStatus), F_(percent), output);
|
||||||
}
|
}
|
||||||
|
|
||||||
shell.println();
|
shell.println();
|
||||||
@@ -119,7 +126,7 @@ bool Mixing::command_info(const char * value, const int8_t id, JsonObject & outp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// publish values via MQTT
|
// publish values via MQTT
|
||||||
// ideally we should group up all the mixing units together into a nested JSON but for now we'll send them individually
|
// topic is mixing_data<id>
|
||||||
void Mixing::publish_values() {
|
void Mixing::publish_values() {
|
||||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_SMALL> doc;
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_SMALL> doc;
|
||||||
JsonObject output = doc.to<JsonObject>();
|
JsonObject output = doc.to<JsonObject>();
|
||||||
@@ -127,24 +134,28 @@ void Mixing::publish_values() {
|
|||||||
char topic[30];
|
char topic[30];
|
||||||
char s[5];
|
char s[5];
|
||||||
strlcpy(topic, "mixing_data", 30);
|
strlcpy(topic, "mixing_data", 30);
|
||||||
strlcat(topic, Helpers::itoa(s, device_id() - 0x20 + 1), 30); // append hc to topic
|
strlcat(topic, Helpers::itoa(s, device_id() - 0x20 + 1), 30); // append device_id to topic
|
||||||
Mqtt::publish(topic, doc.as<JsonObject>());
|
Mqtt::publish(topic, doc.as<JsonObject>());
|
||||||
|
|
||||||
// if we're using Home Assistant and haven't created the MQTT Discovery topics, do it now
|
// if we're using Home Assistant and haven't created the MQTT Discovery topics, do it now
|
||||||
if ((Mqtt::mqtt_format() == Mqtt::Format::HA) && (!ha_created_)) {
|
if ((Mqtt::mqtt_format() == Mqtt::Format::HA) && (!ha_created_)) {
|
||||||
register_mqtt_ha_config();
|
register_mqtt_ha_config(topic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish config topic for HA MQTT Discovery
|
// publish config topic for HA MQTT Discovery
|
||||||
void Mixing::register_mqtt_ha_config() {
|
void Mixing::register_mqtt_ha_config(const char * topic) {
|
||||||
// Create the Master device
|
// Create the Master device
|
||||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||||
doc["name"] = F("EMS-ESP");
|
doc["name"] = F("EMS-ESP");
|
||||||
doc["uniq_id"] = F("mixing");
|
doc["uniq_id"] = F("mixing");
|
||||||
doc["ic"] = F("mdi:home-thermometer-outline");
|
doc["ic"] = F("mdi:home-thermometer-outline");
|
||||||
doc["stat_t"] = F("ems-esp/mixing_data");
|
|
||||||
|
std::string stat_t(50, '\0');
|
||||||
|
snprintf_P(&stat_t[0], stat_t.capacity() + 1, PSTR("%s/%s"), System::hostname().c_str(), topic);
|
||||||
|
doc["stat_t"] = stat_t;
|
||||||
|
|
||||||
doc["val_tpl"] = F("{{value_json.pumpStatus}}");
|
doc["val_tpl"] = F("{{value_json.pumpStatus}}");
|
||||||
JsonObject dev = doc.createNestedObject("dev");
|
JsonObject dev = doc.createNestedObject("dev");
|
||||||
dev["name"] = F("EMS-ESP Mixing");
|
dev["name"] = F("EMS-ESP Mixing");
|
||||||
@@ -156,15 +167,15 @@ void Mixing::register_mqtt_ha_config() {
|
|||||||
Mqtt::publish_retain(F("homeassistant/sensor/ems-esp/mixing/config"), doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
Mqtt::publish_retain(F("homeassistant/sensor/ems-esp/mixing/config"), doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
||||||
|
|
||||||
if (this->type() == Type::HC) {
|
if (this->type() == Type::HC) {
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Current flow temperature"), this->device_type(), "flowTemp", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(flowTemp), this->device_type(), "flowTemp", F_(degrees), nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Setpoint flow temperature"), this->device_type(), "flowSetTemp", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(flowSetTemp), this->device_type(), "flowSetTemp", F_(degrees), nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Current pump status"), this->device_type(), "pumpStatus", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(pumpStatus), this->device_type(), "pumpStatus", nullptr, nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Current valve status"), this->device_type(), "valveStatus", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(valveStatus), this->device_type(), "valveStatus", nullptr, nullptr);
|
||||||
} else {
|
} else {
|
||||||
// WWC
|
// WWC
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Current flow temperature"), this->device_type(), "wwTemp", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(wwTemp), this->device_type(), "wwTemp", F_(degrees), nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Current pump status"), this->device_type(), "pumpStatus", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(pumpStatus), this->device_type(), "pumpStatus", nullptr, nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Current temperature status"), this->device_type(), "tempStatus", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(tempStatus), this->device_type(), "tempStatus", nullptr, nullptr);
|
||||||
}
|
}
|
||||||
ha_created_ = true;
|
ha_created_ = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class Mixing : public EMSdevice {
|
|||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
bool export_values(JsonObject & doc);
|
bool export_values(JsonObject & doc);
|
||||||
void register_mqtt_ha_config();
|
void register_mqtt_ha_config(const char * topic);
|
||||||
bool command_info(const char * value, const int8_t id, JsonObject & output);
|
bool command_info(const char * value, const int8_t id, JsonObject & output);
|
||||||
|
|
||||||
void process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> telegram);
|
void process_MMPLUSStatusMessage_HC(std::shared_ptr<const Telegram> telegram);
|
||||||
|
|||||||
@@ -90,25 +90,30 @@ void Solar::device_info_web(JsonArray & root) {
|
|||||||
void Solar::show_values(uuid::console::Shell & shell) {
|
void Solar::show_values(uuid::console::Shell & shell) {
|
||||||
EMSdevice::show_values(shell); // always call this to show header
|
EMSdevice::show_values(shell); // always call this to show header
|
||||||
|
|
||||||
print_value(shell, 2, F("Collector temperature (TS1)"), collectorTemp_, F_(degrees), 10);
|
// fetch the values into a JSON document
|
||||||
print_value(shell, 2, F("Bottom temperature (TS2)"), tankBottomTemp_, F_(degrees), 10);
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||||
print_value(shell, 2, F("Bottom temperature (TS5)"), tankBottomTemp2_, F_(degrees), 10);
|
JsonObject output = doc.to<JsonObject>();
|
||||||
print_value(shell, 2, F("Heat exchanger temperature (TS6)"), heatExchangerTemp_, F_(degrees), 10);
|
if (!export_values(output)) {
|
||||||
print_value(shell, 2, F("Solar pump modulation (PS1)"), solarPumpModulation_, F_(percent));
|
return; // empty
|
||||||
print_value(shell, 2, F("Cylinder pump modulation (PS5)"), cylinderPumpModulation_, F_(percent));
|
}
|
||||||
print_value(shell, 2, F("Valve (VS2) status"), valveStatus_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
print_value(shell, 2, F("Solar Pump (PS1) active"), solarPump_, nullptr, EMS_VALUE_BOOL);
|
print_value_json(shell, F("collectorTemp"), F_(collectorTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("tankBottomTemp"), F_(tankBottomTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("tankBottomTemp2"), F_(tankBottomTemp2), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("heatExchangerTemp"), F_(heatExchangerTemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("solarPumpModulation"), F_(solarPumpModulation), F_(percent), output);
|
||||||
|
print_value_json(shell, F("cylinderPumpModulation"), F_(cylinderPumpModulation), F_(percent), output);
|
||||||
|
print_value_json(shell, F("valveStatus"), F_(valveStatus), nullptr, output);
|
||||||
|
print_value_json(shell, F("solarPump"), F_(solarPump), nullptr, output);
|
||||||
|
print_value_json(shell, F("tankHeated"), F_(tankHeated), nullptr, output);
|
||||||
|
print_value_json(shell, F("collectorShutdown"), F_(collectorShutdown), nullptr, output);
|
||||||
|
print_value_json(shell, F("energyLastHour"), F_(energyLastHour), F_(wh), output);
|
||||||
|
print_value_json(shell, F("energyToday"), F_(energyToday), F_(wh), output);
|
||||||
|
print_value_json(shell, F("energyTotal"), F_(energyTotal), F_(kwh), output);
|
||||||
|
|
||||||
if (Helpers::hasValue(pumpWorkMin_)) {
|
if (Helpers::hasValue(pumpWorkMin_)) {
|
||||||
shell.printfln(F(" Pump working time: %d days %d hours %d minutes"), pumpWorkMin_ / 1440, (pumpWorkMin_ % 1440) / 60, pumpWorkMin_ % 60);
|
shell.printfln(F(" Pump working time: %d days %d hours %d minutes"), pumpWorkMin_ / 1440, (pumpWorkMin_ % 1440) / 60, pumpWorkMin_ % 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
print_value(shell, 2, F("Tank Heated"), tankHeated_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
print_value(shell, 2, F("Collector shutdown"), collectorShutdown_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
|
|
||||||
print_value(shell, 2, F("Energy last hour"), energyLastHour_, F_(wh), 10);
|
|
||||||
print_value(shell, 2, F("Energy today"), energyToday_, F_(wh));
|
|
||||||
print_value(shell, 2, F("Energy total"), energyTotal_, F_(kwh), 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish values via MQTT
|
// publish values via MQTT
|
||||||
@@ -143,20 +148,20 @@ void Solar::register_mqtt_ha_config() {
|
|||||||
ids.add("ems-esp-solar");
|
ids.add("ems-esp-solar");
|
||||||
Mqtt::publish_retain(F("homeassistant/sensor/ems-esp/solar/config"), doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
Mqtt::publish_retain(F("homeassistant/sensor/ems-esp/solar/config"), doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
||||||
|
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Collector temperature (TS1)"), this->device_type(), "collectorTemp", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(collectorTemp), this->device_type(), "collectorTemp", F_(degrees), nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Bottom temperature (TS2)"), this->device_type(), "tankBottomTemp", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(tankBottomTemp), this->device_type(), "tankBottomTemp", F_(degrees), nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Bottom temperature (TS5)"), this->device_type(), "tankBottomTemp2", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(tankBottomTemp2), this->device_type(), "tankBottomTemp2", F_(degrees), nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Heat exchanger temperature (TS6)"), this->device_type(), "heatExchangerTemp", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(heatExchangerTemp), this->device_type(), "heatExchangerTemp", F_(degrees), nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Solar pump modulation (PS1)"), this->device_type(), "solarPumpModulation", "%", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(solarPumpModulation), this->device_type(), "solarPumpModulation", F_(percent), nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Cylinder pump modulation (PS5)"), this->device_type(), "cylinderPumpModulation", "%", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(cylinderPumpModulation), this->device_type(), "cylinderPumpModulation", F_(percent), nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Pump working time"), this->device_type(), "pumpWorkMin", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(pumpWorkMin), this->device_type(), "pumpWorkMin", nullptr, nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Energy last hour"), this->device_type(), "energyLastHour", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(energyLastHour), this->device_type(), "energyLastHour", nullptr, nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Energy today"), this->device_type(), "energyToday", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(energyToday), this->device_type(), "energyToday", nullptr, nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Energy total"), this->device_type(), "energyTotal", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(energyTotal), this->device_type(), "energyTotal", nullptr, nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Solar Pump (PS1) active"), this->device_type(), "solarPump", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(solarPump), this->device_type(), "solarPump", nullptr, nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Valve (VS2) status"), this->device_type(), "valveStatus", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(valveStatus), this->device_type(), "valveStatus", nullptr, nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Tank Heated"), this->device_type(), "tankHeated", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(tankHeated), this->device_type(), "tankHeated", nullptr, nullptr);
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Collector shutdown"), this->device_type(), "collectorShutdown", "", "");
|
Mqtt::register_mqtt_ha_sensor(nullptr, F_(collectorShutdown), this->device_type(), "collectorShutdown", nullptr, nullptr);
|
||||||
|
|
||||||
ha_created_ = true;
|
ha_created_ = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,14 +194,16 @@ void Thermostat::device_info_web(JsonArray & root) {
|
|||||||
std::string hc_str(5, '\0');
|
std::string hc_str(5, '\0');
|
||||||
snprintf_P(&hc_str[0], hc_str.capacity() + 1, PSTR("hc%d: "), hc->hc_num());
|
snprintf_P(&hc_str[0], hc_str.capacity() + 1, PSTR("hc%d: "), hc->hc_num());
|
||||||
|
|
||||||
render_value_json(root, hc_str, F("Current room temperature"), hc->curr_roomTemp, F_(degrees), format_curr);
|
render_value_json(root, hc_str, F_(currtemp), hc->curr_roomTemp, F_(degrees), format_curr);
|
||||||
render_value_json(root, hc_str, F("Setpoint room temperature"), hc->setpoint_roomTemp, F_(degrees), format_setpoint);
|
render_value_json(root, hc_str, F_(seltemp), hc->setpoint_roomTemp, F_(degrees), format_setpoint);
|
||||||
if (Helpers::hasValue(hc->mode)) {
|
if (Helpers::hasValue(hc->mode)) {
|
||||||
JsonObject dataElement;
|
JsonObject dataElement;
|
||||||
dataElement = root.createNestedObject();
|
dataElement = root.createNestedObject();
|
||||||
|
|
||||||
std::string mode_str(15, '\0');
|
std::string mode_str(15, '\0');
|
||||||
snprintf_P(&mode_str[0], mode_str.capacity() + 1, PSTR("%sMode"), hc_str.c_str());
|
snprintf_P(&mode_str[0], mode_str.capacity() + 1, PSTR("%sMode"), hc_str.c_str());
|
||||||
dataElement["name"] = mode_str;
|
dataElement["name"] = mode_str;
|
||||||
|
|
||||||
std::string modetype_str(20, '\0');
|
std::string modetype_str(20, '\0');
|
||||||
if (Helpers::hasValue(hc->summer_mode) && hc->summer_mode) {
|
if (Helpers::hasValue(hc->summer_mode) && hc->summer_mode) {
|
||||||
snprintf_P(&modetype_str[0], modetype_str.capacity() + 1, PSTR("%s - summer"), mode_tostring(hc->get_mode(flags)).c_str());
|
snprintf_P(&modetype_str[0], modetype_str.capacity() + 1, PSTR("%s - summer"), mode_tostring(hc->get_mode(flags)).c_str());
|
||||||
@@ -238,7 +240,66 @@ bool Thermostat::updated_values() {
|
|||||||
// info API command
|
// info API command
|
||||||
// returns the same MQTT publish payload in Nested format
|
// returns the same MQTT publish payload in Nested format
|
||||||
bool Thermostat::command_info(const char * value, const int8_t id, JsonObject & output) {
|
bool Thermostat::command_info(const char * value, const int8_t id, JsonObject & output) {
|
||||||
return (export_values(Mqtt::Format::NESTED, output));
|
return (export_values_hc(Mqtt::Format::NESTED, output));
|
||||||
|
}
|
||||||
|
|
||||||
|
// display all thermostat values into the shell console
|
||||||
|
void Thermostat::show_values(uuid::console::Shell & shell) {
|
||||||
|
EMSdevice::show_values(shell); // always call this to show header
|
||||||
|
|
||||||
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_SMALL> doc_main;
|
||||||
|
JsonObject output_main = doc_main.to<JsonObject>();
|
||||||
|
if (export_values_main(output_main)) {
|
||||||
|
print_value_json(shell, F("display"), F_(display), nullptr, output_main);
|
||||||
|
print_value_json(shell, F("language"), F_(language), nullptr, output_main);
|
||||||
|
print_value_json(shell, F("offsetclock"), F_(offsetclock), nullptr, output_main);
|
||||||
|
print_value_json(shell, F("dampedtemp"), F_(dampedtemp), F_(degrees), output_main);
|
||||||
|
print_value_json(shell, F("inttemp1"), F_(inttemp1), F_(degrees), output_main);
|
||||||
|
print_value_json(shell, F("inttemp2"), F_(inttemp2), F_(degrees), output_main);
|
||||||
|
print_value_json(shell, F("intoffset"), F_(intoffset), nullptr, output_main);
|
||||||
|
print_value_json(shell, F("minexttemp"), F_(minexttemp), F_(degrees), output_main);
|
||||||
|
print_value_json(shell, F("building"), F_(building), nullptr, output_main);
|
||||||
|
print_value_json(shell, F("wwmode"), F_(wwmode), nullptr, output_main);
|
||||||
|
print_value_json(shell, F("wwcircmode"), F_(wwcircmode), nullptr, output_main);
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc_hc;
|
||||||
|
JsonObject output_hc = doc_hc.to<JsonObject>();
|
||||||
|
// e.g. {"hc1":{"seltemp":849.4,"currtemp":819.2,"mode":"unknown","modetype":"day"},"hc2":{"seltemp":875.1,"currtemp":409.6,"mode":"unknown","modetype":"day"},"hc3":{"seltemp":0,"currtemp":0,"mode":"unknown","modetype":"day"}}
|
||||||
|
|
||||||
|
if (export_values_hc(Mqtt::Format::NESTED, output_hc)) {
|
||||||
|
// display for each active heating circuit
|
||||||
|
for (const auto & hc : heating_circuits_) {
|
||||||
|
if (hc->is_active()) {
|
||||||
|
shell.printfln("Heating Circuit %d:", hc->hc_num());
|
||||||
|
|
||||||
|
char hc_name[10]; // hc{1-4}
|
||||||
|
strlcpy(hc_name, "hc", 10);
|
||||||
|
char s[3];
|
||||||
|
strlcat(hc_name, Helpers::itoa(s, hc->hc_num()), 10);
|
||||||
|
JsonObject output = output_hc[hc_name];
|
||||||
|
|
||||||
|
print_value_json(shell, F("seltemp"), F_(seltemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("currtemp"), F_(currtemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("heattemp"), F_(heattemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("comforttemp"), F_(comforttemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("daytemp"), F_(daytemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("ecotemp"), F_(ecotemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("nighttemp"), F_(nighttemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("manualtemp"), F_(manualtemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("holidaytemp"), F_(holidaytemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("nofrosttemp"), F_(nofrosttemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("targetflowtemp"), F_(targetflowtemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("offsettemp"), F_(offsettemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("designtemp"), F_(designtemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("summertemp"), F_(summertemp), F_(degrees), output);
|
||||||
|
print_value_json(shell, F("mode"), F_(mode), nullptr, output);
|
||||||
|
print_value_json(shell, F("modetype"), F_(modetype), nullptr, output);
|
||||||
|
|
||||||
|
shell.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish values via MQTT
|
// publish values via MQTT
|
||||||
@@ -247,52 +308,108 @@ void Thermostat::publish_values() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_SMALL> doc_main;
|
||||||
JsonObject output = doc.to<JsonObject>();
|
JsonObject output_main = doc_main.to<JsonObject>();
|
||||||
|
if (export_values_main(output_main)) {
|
||||||
export_values(Mqtt::mqtt_format(), output);
|
Mqtt::publish(F("thermostat_system_data"), output_main);
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc_hc;
|
||||||
|
JsonObject output_hc = doc_hc.to<JsonObject>();
|
||||||
|
if (export_values_hc(Mqtt::mqtt_format(), output_hc)) {
|
||||||
// if we're in SINGLE mode the MQTT would have been published on the export_values() function for each hc
|
// if we're in SINGLE mode the MQTT would have been published on the export_values() function for each hc
|
||||||
if (Mqtt::mqtt_format() != Mqtt::Format::SINGLE) {
|
if (Mqtt::mqtt_format() != Mqtt::Format::SINGLE) {
|
||||||
Mqtt::publish(F("thermostat_data"), output);
|
Mqtt::publish(F("thermostat_data"), output_hc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates JSON doc from values
|
// creates JSON doc from values
|
||||||
// returns false if empty
|
// returns false if empty
|
||||||
bool Thermostat::export_values(uint8_t mqtt_format, JsonObject & rootThermostat) {
|
bool Thermostat::export_values_main(JsonObject & rootThermostat) {
|
||||||
uint8_t flags = this->model();
|
// Clock time
|
||||||
JsonObject dataThermostat;
|
|
||||||
|
|
||||||
// add external temp and other stuff specific to the RC30 and RC35
|
|
||||||
if (flags == EMS_DEVICE_FLAG_RC35 || flags == EMS_DEVICE_FLAG_RC30_1) {
|
|
||||||
if (datetime_.size()) {
|
if (datetime_.size()) {
|
||||||
rootThermostat["time"] = datetime_.c_str();
|
rootThermostat["time"] = datetime_.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Display
|
||||||
|
if (Helpers::hasValue(ibaMainDisplay_)) {
|
||||||
|
if (ibaMainDisplay_ == 0) {
|
||||||
|
rootThermostat["display"] = F("internal temperature");
|
||||||
|
} else if (ibaMainDisplay_ == 1) {
|
||||||
|
rootThermostat["display"] = F("internal setpoint");
|
||||||
|
} else if (ibaMainDisplay_ == 2) {
|
||||||
|
rootThermostat["display"] = F("external temperature");
|
||||||
|
} else if (ibaMainDisplay_ == 3) {
|
||||||
|
rootThermostat["display"] = F("burner temperature");
|
||||||
|
} else if (ibaMainDisplay_ == 4) {
|
||||||
|
rootThermostat["display"] = F("WW temperature");
|
||||||
|
} else if (ibaMainDisplay_ == 5) {
|
||||||
|
rootThermostat["display"] = F("functioning mode");
|
||||||
|
} else if (ibaMainDisplay_ == 6) {
|
||||||
|
rootThermostat["display"] = F("time");
|
||||||
|
} else if (ibaMainDisplay_ == 7) {
|
||||||
|
rootThermostat["display"] = F("date");
|
||||||
|
} else if (ibaMainDisplay_ == 8) {
|
||||||
|
rootThermostat["display"] = F("smoke temperature");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Language
|
||||||
|
if (Helpers::hasValue(ibaLanguage_)) {
|
||||||
|
if (ibaLanguage_ == 0) {
|
||||||
|
rootThermostat["language"] = F("German");
|
||||||
|
} else if (ibaLanguage_ == 1) {
|
||||||
|
rootThermostat["language"] = F("Dutch");
|
||||||
|
} else if (ibaLanguage_ == 2) {
|
||||||
|
rootThermostat["language"] = F("French");
|
||||||
|
} else if (ibaLanguage_ == 3) {
|
||||||
|
rootThermostat["language"] = F("Italian");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offset clock
|
||||||
|
if (Helpers::hasValue(ibaClockOffset_)) {
|
||||||
|
rootThermostat["offsetclock"] = ibaClockOffset_; // offset (in sec) to clock, 0xff=-1s, 0x02=2s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Damped outdoor temperature
|
||||||
if (Helpers::hasValue(dampedoutdoortemp_)) {
|
if (Helpers::hasValue(dampedoutdoortemp_)) {
|
||||||
rootThermostat["dampedtemp"] = dampedoutdoortemp_;
|
rootThermostat["dampedtemp"] = dampedoutdoortemp_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temp sensor 1
|
||||||
if (Helpers::hasValue(tempsensor1_)) {
|
if (Helpers::hasValue(tempsensor1_)) {
|
||||||
rootThermostat["inttemp1"] = (float)tempsensor1_ / 10;
|
rootThermostat["inttemp1"] = (float)tempsensor1_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temp sensor 2
|
||||||
if (Helpers::hasValue(tempsensor2_)) {
|
if (Helpers::hasValue(tempsensor2_)) {
|
||||||
rootThermostat["inttemp2"] = (float)tempsensor2_ / 10;
|
rootThermostat["inttemp2"] = (float)tempsensor2_ / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Offset int. temperature
|
||||||
if (Helpers::hasValue(ibaCalIntTemperature_)) {
|
if (Helpers::hasValue(ibaCalIntTemperature_)) {
|
||||||
rootThermostat["intoffset"] = (float)ibaCalIntTemperature_ / 2;
|
rootThermostat["intoffset"] = (float)ibaCalIntTemperature_ / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Min ext. temperature
|
||||||
if (Helpers::hasValue(ibaMinExtTemperature_)) {
|
if (Helpers::hasValue(ibaMinExtTemperature_)) {
|
||||||
rootThermostat["minexttemp"] = (float)ibaMinExtTemperature_; // min ext temp for heating curve, in deg.
|
rootThermostat["minexttemp"] = (float)ibaMinExtTemperature_; // min ext temp for heating curve, in deg.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Building
|
||||||
if (Helpers::hasValue(ibaBuildingType_)) {
|
if (Helpers::hasValue(ibaBuildingType_)) {
|
||||||
if (ibaBuildingType_ == 0) {
|
if (ibaBuildingType_ == 0) {
|
||||||
rootThermostat["building"] = "light";
|
rootThermostat["building"] = F("light");
|
||||||
} else if (ibaBuildingType_ == 1) {
|
} else if (ibaBuildingType_ == 1) {
|
||||||
rootThermostat["building"] = "medium";
|
rootThermostat["building"] = F("medium");
|
||||||
} else if (ibaBuildingType_ == 2) {
|
} else if (ibaBuildingType_ == 2) {
|
||||||
rootThermostat["building"] = "heavy";
|
rootThermostat["building"] = F("heavy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm water mode
|
||||||
if (Helpers::hasValue(wwMode_)) {
|
if (Helpers::hasValue(wwMode_)) {
|
||||||
if (wwMode_ == 2) {
|
if (wwMode_ == 2) {
|
||||||
rootThermostat["wwmode"] = "auto";
|
rootThermostat["wwmode"] = "auto";
|
||||||
@@ -302,6 +419,7 @@ bool Thermostat::export_values(uint8_t mqtt_format, JsonObject & rootThermostat)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warm Water circulation mode
|
||||||
if (Helpers::hasValue(wwCircMode_)) {
|
if (Helpers::hasValue(wwCircMode_)) {
|
||||||
if (wwCircMode_ == 2) {
|
if (wwCircMode_ == 2) {
|
||||||
rootThermostat["wwcircmode"] = "auto";
|
rootThermostat["wwcircmode"] = "auto";
|
||||||
@@ -311,12 +429,15 @@ bool Thermostat::export_values(uint8_t mqtt_format, JsonObject & rootThermostat)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// send this specific data using the thermostat_data topic
|
return (rootThermostat.size());
|
||||||
if (mqtt_format != Mqtt::Format::NESTED) {
|
}
|
||||||
Mqtt::publish(F("thermostat_data"), rootThermostat);
|
|
||||||
rootThermostat.clear(); // clear object
|
// creates JSON doc from values, for each heating circuit
|
||||||
}
|
// if the mqtt_format is 0 then it will not perform the MQTT publish
|
||||||
}
|
// returns false if empty
|
||||||
|
bool Thermostat::export_values_hc(uint8_t mqtt_format, JsonObject & rootThermostat) {
|
||||||
|
uint8_t flags = this->model();
|
||||||
|
JsonObject dataThermostat;
|
||||||
|
|
||||||
// go through all the heating circuits
|
// go through all the heating circuits
|
||||||
bool has_data = false;
|
bool has_data = false;
|
||||||
@@ -349,64 +470,80 @@ bool Thermostat::export_values(uint8_t mqtt_format, JsonObject & rootThermostat)
|
|||||||
curr_temp_divider = 10;
|
curr_temp_divider = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setpoint room temperature
|
||||||
if (Helpers::hasValue(hc->setpoint_roomTemp)) {
|
if (Helpers::hasValue(hc->setpoint_roomTemp)) {
|
||||||
dataThermostat["seltemp"] = Helpers::round2((float)hc->setpoint_roomTemp / setpoint_temp_divider);
|
dataThermostat["seltemp"] = Helpers::round2((float)hc->setpoint_roomTemp / setpoint_temp_divider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Current room temperature
|
||||||
if (Helpers::hasValue(hc->curr_roomTemp)) {
|
if (Helpers::hasValue(hc->curr_roomTemp)) {
|
||||||
dataThermostat["currtemp"] = Helpers::round2((float)hc->curr_roomTemp / curr_temp_divider);
|
dataThermostat["currtemp"] = Helpers::round2((float)hc->curr_roomTemp / curr_temp_divider);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Helpers::hasValue(hc->daytemp)) {
|
if (Helpers::hasValue(hc->daytemp)) {
|
||||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
if (flags == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
||||||
|
// Heat temperature
|
||||||
dataThermostat["heattemp"] = (float)hc->daytemp / 2;
|
dataThermostat["heattemp"] = (float)hc->daytemp / 2;
|
||||||
} else if (flags == EMSdevice::EMS_DEVICE_FLAG_RC300 || flags == EMSdevice::EMS_DEVICE_FLAG_RC100) {
|
} else if (flags == EMSdevice::EMS_DEVICE_FLAG_RC300 || flags == EMSdevice::EMS_DEVICE_FLAG_RC100) {
|
||||||
|
// Comfort temperature
|
||||||
dataThermostat["comforttemp"] = (float)hc->daytemp / 2;
|
dataThermostat["comforttemp"] = (float)hc->daytemp / 2;
|
||||||
} else {
|
} else {
|
||||||
|
// Day temperature
|
||||||
dataThermostat["daytemp"] = (float)hc->daytemp / 2;
|
dataThermostat["daytemp"] = (float)hc->daytemp / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Helpers::hasValue(hc->nighttemp)) {
|
if (Helpers::hasValue(hc->nighttemp)) {
|
||||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_JUNKERS || flags == EMSdevice::EMS_DEVICE_FLAG_RC300 || flags == EMSdevice::EMS_DEVICE_FLAG_RC100) {
|
if (flags == EMSdevice::EMS_DEVICE_FLAG_JUNKERS || flags == EMSdevice::EMS_DEVICE_FLAG_RC300 || flags == EMSdevice::EMS_DEVICE_FLAG_RC100) {
|
||||||
|
// Eco temperature
|
||||||
dataThermostat["ecotemp"] = (float)hc->nighttemp / 2;
|
dataThermostat["ecotemp"] = (float)hc->nighttemp / 2;
|
||||||
} else {
|
} else {
|
||||||
|
// Night temperature
|
||||||
dataThermostat["nighttemp"] = (float)hc->nighttemp / 2;
|
dataThermostat["nighttemp"] = (float)hc->nighttemp / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Manual temperature
|
||||||
if (Helpers::hasValue(hc->manualtemp)) {
|
if (Helpers::hasValue(hc->manualtemp)) {
|
||||||
dataThermostat["manualtemp"] = (float)hc->manualtemp / 2;
|
dataThermostat["manualtemp"] = (float)hc->manualtemp / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Holiday temperature
|
||||||
if (Helpers::hasValue(hc->holidaytemp)) {
|
if (Helpers::hasValue(hc->holidaytemp)) {
|
||||||
dataThermostat["holidaytemp"] = (float)hc->holidaytemp / 2;
|
dataThermostat["holidaytemp"] = (float)hc->holidaytemp / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Nofrost temperature
|
||||||
if (Helpers::hasValue(hc->nofrosttemp)) {
|
if (Helpers::hasValue(hc->nofrosttemp)) {
|
||||||
dataThermostat["nofrosttemp"] = (float)hc->nofrosttemp / 2;
|
dataThermostat["nofrosttemp"] = (float)hc->nofrosttemp / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Heating Type
|
||||||
if (Helpers::hasValue(hc->heatingtype)) {
|
if (Helpers::hasValue(hc->heatingtype)) {
|
||||||
dataThermostat["heatingtype"] = hc->heatingtype;
|
dataThermostat["heatingtype"] = hc->heatingtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Target flow temperature
|
||||||
if (Helpers::hasValue(hc->targetflowtemp)) {
|
if (Helpers::hasValue(hc->targetflowtemp)) {
|
||||||
dataThermostat["targetflowtemp"] = hc->targetflowtemp;
|
dataThermostat["targetflowtemp"] = hc->targetflowtemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Offset temperature
|
||||||
if (Helpers::hasValue(hc->offsettemp)) {
|
if (Helpers::hasValue(hc->offsettemp)) {
|
||||||
dataThermostat["offsettemp"] = hc->offsettemp / 2;
|
dataThermostat["offsettemp"] = hc->offsettemp / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Design temperature
|
||||||
if (Helpers::hasValue(hc->designtemp)) {
|
if (Helpers::hasValue(hc->designtemp)) {
|
||||||
dataThermostat["designtemp"] = hc->designtemp;
|
dataThermostat["designtemp"] = hc->designtemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Summer temperature
|
||||||
if (Helpers::hasValue(hc->summertemp)) {
|
if (Helpers::hasValue(hc->summertemp)) {
|
||||||
dataThermostat["summertemp"] = hc->summertemp;
|
dataThermostat["summertemp"] = hc->summertemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Summer mode
|
||||||
if (Helpers::hasValue(hc->summer_setmode)) {
|
if (Helpers::hasValue(hc->summer_setmode)) {
|
||||||
if (hc->summer_setmode == 1) {
|
if (hc->summer_setmode == 1) {
|
||||||
dataThermostat["summermode"] = "auto";
|
dataThermostat["summermode"] = "auto";
|
||||||
@@ -429,11 +566,13 @@ bool Thermostat::export_values(uint8_t mqtt_format, JsonObject & rootThermostat)
|
|||||||
hc_mode = HeatingCircuit::Mode::AUTO;
|
hc_mode = HeatingCircuit::Mode::AUTO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Mode
|
||||||
dataThermostat["mode"] = mode_tostring(hc_mode);
|
dataThermostat["mode"] = mode_tostring(hc_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// special handling of mode type, for the RC35 replace with summer/holiday if set
|
// special handling of mode type, for the RC35 replace with summer/holiday if set
|
||||||
// https://github.com/proddy/EMS-ESP/issues/373#issuecomment-619810209
|
// https://github.com/proddy/EMS-ESP/issues/373#issuecomment-619810209
|
||||||
|
// Mode Type
|
||||||
if (Helpers::hasValue(hc->summer_mode) && hc->summer_mode) {
|
if (Helpers::hasValue(hc->summer_mode) && hc->summer_mode) {
|
||||||
dataThermostat["modetype"] = F("summer");
|
dataThermostat["modetype"] = F("summer");
|
||||||
} else if (Helpers::hasValue(hc->holiday_mode) && hc->holiday_mode) {
|
} else if (Helpers::hasValue(hc->holiday_mode) && hc->holiday_mode) {
|
||||||
@@ -444,7 +583,7 @@ bool Thermostat::export_values(uint8_t mqtt_format, JsonObject & rootThermostat)
|
|||||||
|
|
||||||
// if format is single, send immediately and clear object for next hc
|
// if format is single, send immediately and clear object for next hc
|
||||||
// the topic will have the hc number appended
|
// the topic will have the hc number appended
|
||||||
if ((mqtt_format == Mqtt::Format::SINGLE) || (mqtt_format == Mqtt::Format::CUSTOM)) {
|
if (mqtt_format == Mqtt::Format::SINGLE) {
|
||||||
char topic[30];
|
char topic[30];
|
||||||
char s[3];
|
char s[3];
|
||||||
strlcpy(topic, "thermostat_data", 30);
|
strlcpy(topic, "thermostat_data", 30);
|
||||||
@@ -633,6 +772,45 @@ void Thermostat::register_mqtt_ha_config(uint8_t hc_num) {
|
|||||||
|
|
||||||
// enable the thermostat topic to take both mode strings and floats
|
// enable the thermostat topic to take both mode strings and floats
|
||||||
register_mqtt_topic("thermostat", [&](const char * m) { return thermostat_ha_cmd(m); });
|
register_mqtt_topic("thermostat", [&](const char * m) { return thermostat_ha_cmd(m); });
|
||||||
|
|
||||||
|
char hc_name[10]; // hc{1-4}
|
||||||
|
strlcpy(hc_name, "hc", 10);
|
||||||
|
char s[3];
|
||||||
|
strlcat(hc_name, Helpers::itoa(s, hc_num), 10);
|
||||||
|
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(mode), this->device_type(), "mode", nullptr, nullptr);
|
||||||
|
|
||||||
|
uint8_t model = this->model();
|
||||||
|
switch (model) {
|
||||||
|
case EMS_DEVICE_FLAG_RC100:
|
||||||
|
case EMS_DEVICE_FLAG_RC300:
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(modetype), this->device_type(), "modetype", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(ecotemp), this->device_type(), "ecotemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(manualtemp), this->device_type(), "manualtemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(comforttemp), this->device_type(), "comforttemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(summertemp), this->device_type(), "summertemp", F_(degrees), F_(icontemperature));
|
||||||
|
break;
|
||||||
|
case EMS_DEVICE_FLAG_RC20_2:
|
||||||
|
case EMS_DEVICE_FLAG_RC35:
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(modetype), this->device_type(), "modetype", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(nighttemp), this->device_type(), "nighttemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(daytemp), this->device_type(), "daytemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(designtemp), this->device_type(), "designtemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(offsettemp), this->device_type(), "offsettemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(holidaytemp), this->device_type(), "holidaytemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(targetflowtemp), this->device_type(), "targetflowtemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(summertemp), this->device_type(), "summertemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(nofrosttemp), this->device_type(), "nofrosttemp", F_(degrees), F_(icontemperature));
|
||||||
|
break;
|
||||||
|
case EMS_DEVICE_FLAG_JUNKERS:
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(modetype), this->device_type(), "modetype", nullptr, nullptr);
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(heattemp), this->device_type(), "heattemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(ecotemp), this->device_type(), "ecotemp", F_(degrees), F_(icontemperature));
|
||||||
|
Mqtt::register_mqtt_ha_sensor(hc_name, F_(nofrosttemp), this->device_type(), "nofrosttemp", F_(degrees), F_(icontemperature));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for HA specifically when receiving over MQTT in the thermostat topic
|
// for HA specifically when receiving over MQTT in the thermostat topic
|
||||||
@@ -780,187 +958,6 @@ std::string Thermostat::mode_tostring(uint8_t mode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// display all thermostat values into the shell console
|
|
||||||
void Thermostat::show_values(uuid::console::Shell & shell) {
|
|
||||||
EMSdevice::show_values(shell); // always call this to show header
|
|
||||||
|
|
||||||
uint8_t flags = this->model();
|
|
||||||
|
|
||||||
if (datetime_.size()) {
|
|
||||||
shell.printfln(F(" Clock: %s"), datetime_.c_str());
|
|
||||||
if (Helpers::hasValue(ibaClockOffset_) && flags == EMS_DEVICE_FLAG_RC30_1) {
|
|
||||||
print_value(shell, 2, F("Offset clock"), ibaClockOffset_, nullptr); // offset (in sec) to clock, 0xff = -1 s, 0x02 = 2 s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Helpers::hasValue(wwMode_)) {
|
|
||||||
if (wwMode_ == 2) {
|
|
||||||
print_value(shell, 2, F("Warm Water mode"), F("auto"));
|
|
||||||
} else {
|
|
||||||
print_value(shell, 2, F("Warm Water mode"), wwMode_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Helpers::hasValue(wwCircMode_)) {
|
|
||||||
if (wwCircMode_ == 2) {
|
|
||||||
print_value(shell, 2, F("Warm Water circulation mode"), F("auto"));
|
|
||||||
} else {
|
|
||||||
print_value(shell, 2, F("Warm Water circulation mode"), wwCircMode_, nullptr, EMS_VALUE_BOOL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags == EMS_DEVICE_FLAG_RC35) {
|
|
||||||
print_value(shell, 2, F("Damped Outdoor temperature"), dampedoutdoortemp_, F_(degrees));
|
|
||||||
print_value(shell, 2, F("Temp sensor 1"), tempsensor1_, F_(degrees), 10);
|
|
||||||
print_value(shell, 2, F("Temp sensor 2"), tempsensor2_, F_(degrees), 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags == EMS_DEVICE_FLAG_RC30_1) {
|
|
||||||
// settings parameters
|
|
||||||
if (Helpers::hasValue(ibaMainDisplay_)) {
|
|
||||||
if (ibaMainDisplay_ == 0) {
|
|
||||||
shell.printfln(F(" Display: internal temperature"));
|
|
||||||
} else if (ibaMainDisplay_ == 1) {
|
|
||||||
shell.printfln(F(" Display: internal setpoint"));
|
|
||||||
} else if (ibaMainDisplay_ == 2) {
|
|
||||||
shell.printfln(F(" Display: external temperature"));
|
|
||||||
} else if (ibaMainDisplay_ == 3) {
|
|
||||||
shell.printfln(F(" Display: burner temperature"));
|
|
||||||
} else if (ibaMainDisplay_ == 4) {
|
|
||||||
shell.printfln(F(" Display: WW temperature"));
|
|
||||||
} else if (ibaMainDisplay_ == 5) {
|
|
||||||
shell.printfln(F(" Display: functioning mode"));
|
|
||||||
} else if (ibaMainDisplay_ == 6) {
|
|
||||||
shell.printfln(F(" Display: time"));
|
|
||||||
} else if (ibaMainDisplay_ == 7) {
|
|
||||||
shell.printfln(F(" Display: date"));
|
|
||||||
} else if (ibaMainDisplay_ == 8) {
|
|
||||||
shell.printfln(F(" Display: smoke temperature"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Helpers::hasValue(ibaLanguage_)) {
|
|
||||||
if (ibaLanguage_ == 0) {
|
|
||||||
shell.printfln(F(" Language: German"));
|
|
||||||
} else if (ibaLanguage_ == 1) {
|
|
||||||
shell.printfln(F(" Language: Dutch"));
|
|
||||||
} else if (ibaLanguage_ == 2) {
|
|
||||||
shell.printfln(F(" Language: French"));
|
|
||||||
} else if (ibaLanguage_ == 3) {
|
|
||||||
shell.printfln(F(" Language: Italian"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags == EMS_DEVICE_FLAG_RC35 || flags == EMS_DEVICE_FLAG_RC30_1) {
|
|
||||||
if (Helpers::hasValue(ibaCalIntTemperature_)) {
|
|
||||||
print_value(shell, 2, F("Offset int. temperature"), ibaCalIntTemperature_, F_(degrees), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Helpers::hasValue(ibaMinExtTemperature_)) {
|
|
||||||
print_value(shell, 2, F("Min ext. temperature"), ibaMinExtTemperature_, F_(degrees)); // min ext temp for heating curve, in deg.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Helpers::hasValue(ibaBuildingType_)) {
|
|
||||||
if (ibaBuildingType_ == 0) {
|
|
||||||
shell.printfln(F(" Building: light"));
|
|
||||||
} else if (ibaBuildingType_ == 1) {
|
|
||||||
shell.printfln(F(" Building: medium"));
|
|
||||||
} else if (ibaBuildingType_ == 2) {
|
|
||||||
shell.printfln(F(" Building: heavy"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto & hc : heating_circuits_) {
|
|
||||||
if (!hc->is_active()) {
|
|
||||||
break; // skip this HC
|
|
||||||
}
|
|
||||||
|
|
||||||
shell.printfln(F(" Heating Circuit %d:"), hc->hc_num());
|
|
||||||
|
|
||||||
// different thermostat types store their temperature values differently
|
|
||||||
uint8_t format_setpoint, format_curr;
|
|
||||||
switch (flags) {
|
|
||||||
case EMS_DEVICE_FLAG_EASY:
|
|
||||||
format_setpoint = 100; // *100
|
|
||||||
format_curr = 100; // *100
|
|
||||||
break;
|
|
||||||
case EMS_DEVICE_FLAG_JUNKERS:
|
|
||||||
format_setpoint = 10; // *10
|
|
||||||
format_curr = 10; // *10
|
|
||||||
break;
|
|
||||||
default: // RC30, RC35 etc...
|
|
||||||
format_setpoint = 2; // *2
|
|
||||||
format_curr = 10; // *10
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_value(shell, 4, F("Current room temperature"), hc->curr_roomTemp, F_(degrees), format_curr);
|
|
||||||
print_value(shell, 4, F("Setpoint room temperature"), hc->setpoint_roomTemp, F_(degrees), format_setpoint);
|
|
||||||
if (Helpers::hasValue(hc->mode)) {
|
|
||||||
print_value(shell, 4, F("Mode"), mode_tostring(hc->get_mode(flags)).c_str());
|
|
||||||
}
|
|
||||||
if (Helpers::hasValue(hc->mode_type)) {
|
|
||||||
print_value(shell, 4, F("Mode Type"), mode_tostring(hc->get_mode_type(flags)).c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Helpers::hasValue(hc->summer_mode) && hc->summer_mode) {
|
|
||||||
shell.printfln(F(" Program is set to Summer mode"));
|
|
||||||
} else if (Helpers::hasValue(hc->holiday_mode) && hc->holiday_mode) {
|
|
||||||
shell.printfln(F(" Program is set to Holiday mode"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Helpers::hasValue(hc->daytemp)) {
|
|
||||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_JUNKERS) {
|
|
||||||
print_value(shell, 4, F("Heat temperature"), hc->daytemp, F_(degrees), 2);
|
|
||||||
} else if (flags == EMSdevice::EMS_DEVICE_FLAG_RC300 || flags == EMSdevice::EMS_DEVICE_FLAG_RC100) {
|
|
||||||
print_value(shell, 4, F("Comfort temperature"), hc->daytemp, F_(degrees), 2);
|
|
||||||
} else {
|
|
||||||
print_value(shell, 4, F("Day temperature"), hc->daytemp, F_(degrees), 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Helpers::hasValue(hc->nighttemp)) {
|
|
||||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_JUNKERS || flags == EMSdevice::EMS_DEVICE_FLAG_RC300 || flags == EMSdevice::EMS_DEVICE_FLAG_RC100) {
|
|
||||||
print_value(shell, 4, F("Eco temperature"), hc->nighttemp, F_(degrees), 2);
|
|
||||||
} else {
|
|
||||||
print_value(shell, 4, F("Night temperature"), hc->nighttemp, F_(degrees), 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Helpers::hasValue(hc->manualtemp)) {
|
|
||||||
print_value(shell, 4, F("Manual temperature"), hc->manualtemp, F_(degrees), 2);
|
|
||||||
}
|
|
||||||
if (Helpers::hasValue(hc->nofrosttemp)) {
|
|
||||||
print_value(shell, 4, F("Nofrost temperature"), hc->nofrosttemp, F_(degrees), 2);
|
|
||||||
}
|
|
||||||
if (Helpers::hasValue(hc->holidaytemp)) {
|
|
||||||
print_value(shell, 4, F("Holiday temperature"), hc->holidaytemp, F_(degrees), 2);
|
|
||||||
}
|
|
||||||
if (Helpers::hasValue(hc->offsettemp)) {
|
|
||||||
print_value(shell, 4, F("Offset temperature"), hc->offsettemp, F_(degrees), 2);
|
|
||||||
}
|
|
||||||
if (Helpers::hasValue(hc->designtemp)) {
|
|
||||||
print_value(shell, 4, F("Design temperature"), hc->designtemp, F_(degrees));
|
|
||||||
}
|
|
||||||
if (Helpers::hasValue(hc->summertemp)) {
|
|
||||||
print_value(shell, 4, F("Summer temperature"), hc->summertemp, F_(degrees));
|
|
||||||
}
|
|
||||||
if (Helpers::hasValue(hc->summer_setmode)) {
|
|
||||||
if (hc->summer_setmode == 1) {
|
|
||||||
print_value(shell, 4, F("Summer mode"), F("auto"));
|
|
||||||
} else {
|
|
||||||
char s[7];
|
|
||||||
print_value(shell, 4, F("Summer mode"), Helpers::render_boolean(s, (hc->summer_setmode == 0)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Helpers::hasValue(hc->targetflowtemp)) {
|
|
||||||
print_value(shell, 4, F("Target flow temperature"), hc->targetflowtemp, F_(degrees));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shell.println();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0xA8 - for reading the mode from the RC20 thermostat (0x17)
|
// 0xA8 - for reading the mode from the RC20 thermostat (0x17)
|
||||||
void Thermostat::process_RC20Set(std::shared_ptr<const Telegram> telegram) {
|
void Thermostat::process_RC20Set(std::shared_ptr<const Telegram> telegram) {
|
||||||
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
|
std::shared_ptr<Thermostat::HeatingCircuit> hc = heating_circuit(telegram);
|
||||||
@@ -1026,6 +1023,9 @@ void Thermostat::process_JunkersSet2(std::shared_ptr<const Telegram> telegram) {
|
|||||||
// type 0xA3 - for external temp settings from the the RC* thermostats (e.g. RC35)
|
// type 0xA3 - for external temp settings from the the RC* thermostats (e.g. RC35)
|
||||||
void Thermostat::process_RCOutdoorTemp(std::shared_ptr<const Telegram> telegram) {
|
void Thermostat::process_RCOutdoorTemp(std::shared_ptr<const Telegram> telegram) {
|
||||||
changed_ |= telegram->read_value(dampedoutdoortemp_, 0);
|
changed_ |= telegram->read_value(dampedoutdoortemp_, 0);
|
||||||
|
if (dampedoutdoortemp_ == 0) {
|
||||||
|
dampedoutdoortemp_ = EMS_VALUE_INT_NOTSET; // special case for RC20's where the value is always 0
|
||||||
|
}
|
||||||
changed_ |= telegram->read_value(tempsensor1_, 3); // sensor 1 - is * 10
|
changed_ |= telegram->read_value(tempsensor1_, 3); // sensor 1 - is * 10
|
||||||
changed_ |= telegram->read_value(tempsensor2_, 5); // sensor 2 - is * 10
|
changed_ |= telegram->read_value(tempsensor2_, 5); // sensor 2 - is * 10
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,8 @@ class Thermostat : public EMSdevice {
|
|||||||
static uuid::log::Logger logger_;
|
static uuid::log::Logger logger_;
|
||||||
|
|
||||||
void add_commands();
|
void add_commands();
|
||||||
bool export_values(uint8_t mqtt_format, JsonObject & doc);
|
bool export_values_main(JsonObject & doc);
|
||||||
|
bool export_values_hc(uint8_t mqtt_format, JsonObject & doc);
|
||||||
|
|
||||||
// specific thermostat characteristics, stripping the option bits at pos 6 and 7
|
// specific thermostat characteristics, stripping the option bits at pos 6 and 7
|
||||||
inline uint8_t model() const {
|
inline uint8_t model() const {
|
||||||
|
|||||||
65
src/mqtt.cpp
65
src/mqtt.cpp
@@ -35,6 +35,7 @@ uint32_t Mqtt::publish_time_mixing_;
|
|||||||
uint32_t Mqtt::publish_time_other_;
|
uint32_t Mqtt::publish_time_other_;
|
||||||
uint32_t Mqtt::publish_time_sensor_;
|
uint32_t Mqtt::publish_time_sensor_;
|
||||||
uint8_t Mqtt::mqtt_format_;
|
uint8_t Mqtt::mqtt_format_;
|
||||||
|
bool Mqtt::mqtt_enabled_;
|
||||||
|
|
||||||
std::vector<Mqtt::MQTTSubFunction> Mqtt::mqtt_subfunctions_;
|
std::vector<Mqtt::MQTTSubFunction> Mqtt::mqtt_subfunctions_;
|
||||||
|
|
||||||
@@ -49,6 +50,10 @@ uuid::log::Logger Mqtt::logger_{F_(mqtt), uuid::log::Facility::DAEMON};
|
|||||||
// subscribe to an MQTT topic, and store the associated callback function
|
// subscribe to an MQTT topic, and store the associated callback function
|
||||||
// only if it already hasn't been added
|
// only if it already hasn't been added
|
||||||
void Mqtt::subscribe(const uint8_t device_type, const std::string & topic, mqtt_subfunction_p cb) {
|
void Mqtt::subscribe(const uint8_t device_type, const std::string & topic, mqtt_subfunction_p cb) {
|
||||||
|
if (!enabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// check if we already have the topic subscribed, if so don't add it again
|
// check if we already have the topic subscribed, if so don't add it again
|
||||||
if (!mqtt_subfunctions_.empty()) {
|
if (!mqtt_subfunctions_.empty()) {
|
||||||
for (auto & mqtt_subfunction : mqtt_subfunctions_) {
|
for (auto & mqtt_subfunction : mqtt_subfunctions_) {
|
||||||
@@ -159,8 +164,6 @@ void Mqtt::loop() {
|
|||||||
void Mqtt::show_mqtt(uuid::console::Shell & shell) {
|
void Mqtt::show_mqtt(uuid::console::Shell & shell) {
|
||||||
shell.printfln(F("MQTT is %s"), connected() ? uuid::read_flash_string(F_(connected)).c_str() : uuid::read_flash_string(F_(disconnected)).c_str());
|
shell.printfln(F("MQTT is %s"), connected() ? uuid::read_flash_string(F_(connected)).c_str() : uuid::read_flash_string(F_(disconnected)).c_str());
|
||||||
|
|
||||||
EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & settings) { shell.printfln(F_(mqtt_format_fmt), settings.mqtt_format); });
|
|
||||||
|
|
||||||
shell.printfln(F("MQTT publish fails count: %lu"), mqtt_publish_fails_);
|
shell.printfln(F("MQTT publish fails count: %lu"), mqtt_publish_fails_);
|
||||||
shell.println();
|
shell.println();
|
||||||
|
|
||||||
@@ -352,6 +355,7 @@ void Mqtt::start() {
|
|||||||
mqtt_qos_ = mqttSettings.mqtt_qos;
|
mqtt_qos_ = mqttSettings.mqtt_qos;
|
||||||
mqtt_retain_ = mqttSettings.mqtt_retain;
|
mqtt_retain_ = mqttSettings.mqtt_retain;
|
||||||
mqtt_format_ = mqttSettings.mqtt_format;
|
mqtt_format_ = mqttSettings.mqtt_format;
|
||||||
|
mqtt_enabled_ = mqttSettings.enabled;
|
||||||
});
|
});
|
||||||
|
|
||||||
mqttClient_->onConnect([this](bool sessionPresent) { on_connect(); });
|
mqttClient_->onConnect([this](bool sessionPresent) { on_connect(); });
|
||||||
@@ -476,6 +480,7 @@ void Mqtt::on_connect() {
|
|||||||
|
|
||||||
// Home Assistant Discovery - the main master Device
|
// Home Assistant Discovery - the main master Device
|
||||||
// homeassistant/sensor/ems-esp/status/config
|
// homeassistant/sensor/ems-esp/status/config
|
||||||
|
// all the values from the heartbeat payload will be added as attributes to the entity state
|
||||||
void Mqtt::ha_status() {
|
void Mqtt::ha_status() {
|
||||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||||
doc["name"] = F("EMS-ESP status");
|
doc["name"] = F("EMS-ESP status");
|
||||||
@@ -500,7 +505,7 @@ void Mqtt::ha_status() {
|
|||||||
// add sub or pub task to the queue.
|
// add sub or pub task to the queue.
|
||||||
// a fully-qualified topic is created by prefixing the hostname, unless it's HA
|
// a fully-qualified topic is created by prefixing the hostname, unless it's HA
|
||||||
// returns a pointer to the message created
|
// returns a pointer to the message created
|
||||||
std::shared_ptr<const MqttMessage> Mqtt::queue_message(const uint8_t operation, const std::string & topic, const std::string & payload, const bool retain) {
|
std::shared_ptr<const MqttMessage> Mqtt::queue_message(const uint8_t operation, const std::string & topic, const std::string & payload, bool retain) {
|
||||||
if (topic.empty()) {
|
if (topic.empty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -509,16 +514,14 @@ std::shared_ptr<const MqttMessage> Mqtt::queue_message(const uint8_t operation,
|
|||||||
std::shared_ptr<MqttMessage> message;
|
std::shared_ptr<MqttMessage> message;
|
||||||
if ((strncmp(topic.c_str(), "homeassistant/", 13) == 0)) {
|
if ((strncmp(topic.c_str(), "homeassistant/", 13) == 0)) {
|
||||||
// leave topic as it is
|
// leave topic as it is
|
||||||
// message = std::make_shared<MqttMessage>(operation, topic, std::move(payload), retain);
|
|
||||||
message = std::make_shared<MqttMessage>(operation, topic, std::move(payload), retain);
|
message = std::make_shared<MqttMessage>(operation, topic, std::move(payload), retain);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// prefix the hostname
|
// prefix the hostname
|
||||||
std::string full_topic(100, '\0');
|
std::string full_topic(100, '\0');
|
||||||
snprintf_P(&full_topic[0], full_topic.capacity() + 1, PSTR("%s/%s"), hostname_.c_str(), topic.c_str());
|
snprintf_P(&full_topic[0], full_topic.capacity() + 1, PSTR("%s/%s"), hostname_.c_str(), topic.c_str());
|
||||||
// message = std::make_shared<MqttMessage>(operation, full_topic, std::move(payload), retain);
|
|
||||||
message = std::make_shared<MqttMessage>(operation, full_topic, std::move(payload), retain);
|
message = std::make_shared<MqttMessage>(operation, full_topic, std::move(payload), retain);
|
||||||
}
|
}
|
||||||
|
// TODO use && and resize() to fix mem defrag issues
|
||||||
|
|
||||||
// if the queue is full, make room but removing the last one
|
// if the queue is full, make room but removing the last one
|
||||||
if (mqtt_messages_.size() >= maximum_mqtt_messages_) {
|
if (mqtt_messages_.size() >= maximum_mqtt_messages_) {
|
||||||
@@ -530,7 +533,10 @@ std::shared_ptr<const MqttMessage> Mqtt::queue_message(const uint8_t operation,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add MQTT message to queue, payload is a string
|
// add MQTT message to queue, payload is a string
|
||||||
std::shared_ptr<const MqttMessage> Mqtt::queue_publish_message(const std::string & topic, const std::string & payload, const bool retain) {
|
std::shared_ptr<const MqttMessage> Mqtt::queue_publish_message(const std::string & topic, const std::string & payload, bool retain) {
|
||||||
|
if (!enabled()) {
|
||||||
|
return nullptr;
|
||||||
|
};
|
||||||
return queue_message(Operation::PUBLISH, topic, payload, retain);
|
return queue_message(Operation::PUBLISH, topic, payload, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -549,7 +555,6 @@ void Mqtt::publish(const __FlashStringHelper * topic, const char * payload) {
|
|||||||
queue_publish_message(uuid::read_flash_string(topic), payload, mqtt_retain_);
|
queue_publish_message(uuid::read_flash_string(topic), payload, mqtt_retain_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MQTT Publish, using a specific retain flag, topic is a flash string
|
// MQTT Publish, using a specific retain flag, topic is a flash string
|
||||||
void Mqtt::publish(const __FlashStringHelper * topic, const std::string & payload) {
|
void Mqtt::publish(const __FlashStringHelper * topic, const std::string & payload) {
|
||||||
queue_publish_message(uuid::read_flash_string(topic), payload, mqtt_retain_);
|
queue_publish_message(uuid::read_flash_string(topic), payload, mqtt_retain_);
|
||||||
@@ -561,7 +566,7 @@ void Mqtt::publish(const __FlashStringHelper * topic, const JsonObject & payload
|
|||||||
|
|
||||||
// publish json doc, only if its not empty
|
// publish json doc, only if its not empty
|
||||||
void Mqtt::publish(const std::string & topic, const JsonObject & payload) {
|
void Mqtt::publish(const std::string & topic, const JsonObject & payload) {
|
||||||
if (payload.size()) {
|
if (enabled() && payload.size()) {
|
||||||
std::string payload_text;
|
std::string payload_text;
|
||||||
serializeJson(payload, payload_text); // convert json to string
|
serializeJson(payload, payload_text); // convert json to string
|
||||||
queue_publish_message(topic, payload_text, mqtt_retain_);
|
queue_publish_message(topic, payload_text, mqtt_retain_);
|
||||||
@@ -569,11 +574,11 @@ void Mqtt::publish(const std::string & topic, const JsonObject & payload) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for booleans, which get converted to string values 1 and 0
|
// for booleans, which get converted to string values 1 and 0
|
||||||
void Mqtt::publish(const std::string & topic, const bool value) {
|
void Mqtt::publish(const std::string & topic, bool value) {
|
||||||
queue_publish_message(topic, value ? "1" : "0", false);
|
queue_publish_message(topic, value ? "1" : "0", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mqtt::publish(const __FlashStringHelper * topic, const bool value) {
|
void Mqtt::publish(const __FlashStringHelper * topic, bool value) {
|
||||||
queue_publish_message(uuid::read_flash_string(topic), value ? "1" : "0", false);
|
queue_publish_message(uuid::read_flash_string(topic), value ? "1" : "0", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,7 +594,7 @@ void Mqtt::publish_retain(const __FlashStringHelper * topic, const std::string &
|
|||||||
|
|
||||||
// publish json doc, only if its not empty, using the retain flag
|
// publish json doc, only if its not empty, using the retain flag
|
||||||
void Mqtt::publish_retain(const std::string & topic, const JsonObject & payload, bool retain) {
|
void Mqtt::publish_retain(const std::string & topic, const JsonObject & payload, bool retain) {
|
||||||
if (payload.size()) {
|
if (enabled() && payload.size()) {
|
||||||
std::string payload_text;
|
std::string payload_text;
|
||||||
serializeJson(payload, payload_text); // convert json to string
|
serializeJson(payload, payload_text); // convert json to string
|
||||||
queue_publish_message(topic, payload_text, retain);
|
queue_publish_message(topic, payload_text, retain);
|
||||||
@@ -721,41 +726,61 @@ void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HA config for a normal 'sensor' type
|
// HA config for a normal 'sensor' type
|
||||||
void Mqtt::register_mqtt_ha_sensor(const __FlashStringHelper * name, const uint8_t device_type, const char * entity, const char * uom, const char * icon) {
|
// entity must match the key/value pair in the _data topic
|
||||||
|
void Mqtt::register_mqtt_ha_sensor(const char * prefix,
|
||||||
|
const __FlashStringHelper * name,
|
||||||
|
const uint8_t device_type,
|
||||||
|
const char * entity,
|
||||||
|
const __FlashStringHelper * uom,
|
||||||
|
const __FlashStringHelper * icon) {
|
||||||
if (mqtt_format() != Format::HA) {
|
if (mqtt_format() != Format::HA) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||||
|
|
||||||
|
std::string device_name = EMSdevice::device_type_2_device_name(device_type);
|
||||||
|
|
||||||
|
char new_entity[20];
|
||||||
|
// add prefix to entity if its specified
|
||||||
|
if (prefix != nullptr) {
|
||||||
|
snprintf_P(&new_entity[0], 20, PSTR("%s.%s"), prefix, entity);
|
||||||
|
} else {
|
||||||
|
strcpy(new_entity, entity);
|
||||||
|
}
|
||||||
|
|
||||||
doc["name"] = name;
|
doc["name"] = name;
|
||||||
|
|
||||||
|
// build unique identifier, replacing all . with _ as not to break HA
|
||||||
std::string uniq(50, '\0');
|
std::string uniq(50, '\0');
|
||||||
snprintf_P(&uniq[0], uniq.capacity() + 1, PSTR("%s"), entity);
|
snprintf_P(&uniq[0], uniq.capacity() + 1, PSTR("%s_%s"), device_name.c_str(), new_entity);
|
||||||
|
std::replace(uniq.begin(), uniq.end(), '.', '_');
|
||||||
doc["uniq_id"] = uniq;
|
doc["uniq_id"] = uniq;
|
||||||
|
|
||||||
|
if (uom != nullptr) {
|
||||||
doc["unit_of_meas"] = uom;
|
doc["unit_of_meas"] = uom;
|
||||||
|
}
|
||||||
|
|
||||||
std::string state_t(50, '\0');
|
std::string state_t(50, '\0');
|
||||||
snprintf_P(&state_t[0], state_t.capacity() + 1, PSTR("%s/%s_data"), hostname_.c_str(), EMSdevice::device_type_2_device_name(device_type).c_str());
|
snprintf_P(&state_t[0], state_t.capacity() + 1, PSTR("%s/%s_data"), hostname_.c_str(), device_name.c_str());
|
||||||
doc["stat_t"] = state_t;
|
doc["stat_t"] = state_t;
|
||||||
|
|
||||||
std::string tpl(50, '\0');
|
std::string tpl(50, '\0');
|
||||||
snprintf_P(&tpl[0], tpl.capacity() + 1, PSTR("{{value_json.%s}}"), entity);
|
snprintf_P(&tpl[0], tpl.capacity() + 1, PSTR("{{value_json.%s}}"), new_entity);
|
||||||
doc["val_tpl"] = tpl;
|
doc["val_tpl"] = tpl;
|
||||||
|
|
||||||
if (strlen(icon)) {
|
if (icon != nullptr) {
|
||||||
doc["ic"] = icon;
|
doc["ic"] = icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject dev = doc.createNestedObject(F("dev"));
|
JsonObject dev = doc.createNestedObject(F("dev"));
|
||||||
JsonArray ids = dev.createNestedArray(F("ids"));
|
JsonArray ids = dev.createNestedArray(F("ids"));
|
||||||
std::string ha_device(40, '\0');
|
std::string ha_device(40, '\0');
|
||||||
snprintf_P(&ha_device[0], ha_device.capacity() + 1, PSTR("ems-esp-%s"), EMSdevice::device_type_2_device_name(device_type).c_str());
|
snprintf_P(&ha_device[0], ha_device.capacity() + 1, PSTR("ems-esp-%s"), device_name.c_str());
|
||||||
ids.add(ha_device);
|
ids.add(ha_device);
|
||||||
|
|
||||||
std::string topic(100, '\0');
|
std::string topic(100, '\0');
|
||||||
snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/sensor/ems-esp/%s/config"), entity);
|
snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/sensor/ems-esp/%s/config"), uniq.c_str());
|
||||||
|
|
||||||
Mqtt::publish_retain(topic, doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
Mqtt::publish_retain(topic, doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/mqtt.h
28
src/mqtt.h
@@ -81,7 +81,7 @@ class Mqtt {
|
|||||||
|
|
||||||
enum Operation { PUBLISH, SUBSCRIBE };
|
enum Operation { PUBLISH, SUBSCRIBE };
|
||||||
|
|
||||||
enum Format : uint8_t { SINGLE = 1, NESTED, HA, CUSTOM };
|
enum Format : uint8_t { NONE = 0, SINGLE, NESTED, HA };
|
||||||
|
|
||||||
static constexpr uint8_t MQTT_TOPIC_MAX_SIZE = 100;
|
static constexpr uint8_t MQTT_TOPIC_MAX_SIZE = 100;
|
||||||
|
|
||||||
@@ -96,8 +96,8 @@ class Mqtt {
|
|||||||
static void publish(const std::string & topic, const JsonObject & payload);
|
static void publish(const std::string & topic, const JsonObject & payload);
|
||||||
static void publish(const __FlashStringHelper * topic, const JsonObject & payload);
|
static void publish(const __FlashStringHelper * topic, const JsonObject & payload);
|
||||||
static void publish(const __FlashStringHelper * topic, const std::string & payload);
|
static void publish(const __FlashStringHelper * topic, const std::string & payload);
|
||||||
static void publish(const std::string & topic, const bool value);
|
static void publish(const std::string & topic, bool value);
|
||||||
static void publish(const __FlashStringHelper * topi, const bool value);
|
static void publish(const __FlashStringHelper * topic, bool value);
|
||||||
static void publish(const std::string & topic);
|
static void publish(const std::string & topic);
|
||||||
|
|
||||||
static void publish_retain(const std::string & topic, const JsonObject & payload, bool retain);
|
static void publish_retain(const std::string & topic, const JsonObject & payload, bool retain);
|
||||||
@@ -105,7 +105,12 @@ class Mqtt {
|
|||||||
static void publish_retain(const __FlashStringHelper * topic, const JsonObject & payload, bool retain);
|
static void publish_retain(const __FlashStringHelper * topic, const JsonObject & payload, bool retain);
|
||||||
|
|
||||||
static void register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, const uint8_t device_type, const char * entity);
|
static void register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, const uint8_t device_type, const char * entity);
|
||||||
static void register_mqtt_ha_sensor(const __FlashStringHelper * name, const uint8_t device_type, const char * entity, const char * uom, const char * icon);
|
static void register_mqtt_ha_sensor(const char * prefix,
|
||||||
|
const __FlashStringHelper * name,
|
||||||
|
const uint8_t device_type,
|
||||||
|
const char * entity,
|
||||||
|
const __FlashStringHelper * uom,
|
||||||
|
const __FlashStringHelper * icon);
|
||||||
|
|
||||||
static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type);
|
static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type);
|
||||||
static void show_mqtt(uuid::console::Shell & shell);
|
static void show_mqtt(uuid::console::Shell & shell);
|
||||||
@@ -122,7 +127,15 @@ class Mqtt {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool connected() {
|
static bool connected() {
|
||||||
|
#if defined(EMSESP_STANDALONE)
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
return mqttClient_->connected();
|
return mqttClient_->connected();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool enabled() {
|
||||||
|
return mqtt_enabled_;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t publish_fails() {
|
static uint32_t publish_fails() {
|
||||||
@@ -163,11 +176,11 @@ class Mqtt {
|
|||||||
static uint16_t mqtt_message_id_;
|
static uint16_t mqtt_message_id_;
|
||||||
|
|
||||||
static constexpr size_t MAX_MQTT_MESSAGES = 70; // size of queue
|
static constexpr size_t MAX_MQTT_MESSAGES = 70; // size of queue
|
||||||
static constexpr uint32_t MQTT_PUBLISH_WAIT = 200; // delay between sending publishes, to account for large payloads
|
static constexpr uint32_t MQTT_PUBLISH_WAIT = 100; // delay between sending publishes, to account for large payloads
|
||||||
static constexpr uint8_t MQTT_PUBLISH_MAX_RETRY = 3; // max retries for giving up on publishing
|
static constexpr uint8_t MQTT_PUBLISH_MAX_RETRY = 3; // max retries for giving up on publishing
|
||||||
|
|
||||||
static std::shared_ptr<const MqttMessage> queue_message(const uint8_t operation, const std::string & topic, const std::string & payload, const bool retain);
|
static std::shared_ptr<const MqttMessage> queue_message(const uint8_t operation, const std::string & topic, const std::string & payload, bool retain);
|
||||||
static std::shared_ptr<const MqttMessage> queue_publish_message(const std::string & topic, const std::string & payload, const bool retain);
|
static std::shared_ptr<const MqttMessage> queue_publish_message(const std::string & topic, const std::string & payload, bool retain);
|
||||||
static std::shared_ptr<const MqttMessage> queue_subscribe_message(const std::string & topic);
|
static std::shared_ptr<const MqttMessage> queue_subscribe_message(const std::string & topic);
|
||||||
|
|
||||||
void on_publish(uint16_t packetId);
|
void on_publish(uint16_t packetId);
|
||||||
@@ -213,6 +226,7 @@ class Mqtt {
|
|||||||
static uint32_t publish_time_other_;
|
static uint32_t publish_time_other_;
|
||||||
static uint32_t publish_time_sensor_;
|
static uint32_t publish_time_sensor_;
|
||||||
static uint8_t mqtt_format_;
|
static uint8_t mqtt_format_;
|
||||||
|
static bool mqtt_enabled_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
Reference in New Issue
Block a user