mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-01-29 10:09:11 +03:00
added all devices - API: HTTP read/write #506
This commit is contained in:
@@ -69,6 +69,12 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
||||
register_mqtt_cmd(F("burnperiod"), [&](const char * value, const int8_t id) { return set_burn_period(value, id); });
|
||||
register_mqtt_cmd(F("pumpdelay"), [&](const char * value, const int8_t id) { return set_pump_delay(value, id); });
|
||||
|
||||
// API call
|
||||
// Command::add_with_json(this->device_type(), F("info"), Boiler::command_info);
|
||||
Command::add_with_json(this->device_type(), F("info"), [&](const char * value, const int8_t id, JsonObject & object) {
|
||||
return command_info(value, id, object);
|
||||
});
|
||||
|
||||
EMSESP::esp8266React.getMqttSettingsService()->read([&](MqttSettings & settings) {
|
||||
mqtt_format_ = settings.mqtt_format; // single, nested or ha
|
||||
|
||||
@@ -140,208 +146,217 @@ void Boiler::device_info_web(JsonArray & root) {
|
||||
render_value_json(root, "", F("Heat Pump modulation"), pumpMod2_, F_(percent));
|
||||
}
|
||||
|
||||
bool Boiler::command_info(const char * value, const int8_t id, JsonObject & output) {
|
||||
return (export_values(output));
|
||||
}
|
||||
|
||||
// creates JSON doc from values
|
||||
// returns false if empty
|
||||
bool Boiler::export_values(JsonObject & output) {
|
||||
char s[10]; // for formatting strings
|
||||
|
||||
if (Helpers::hasValue(wWComfort_)) {
|
||||
if (wWComfort_ == 0x00) {
|
||||
output["wWComfort"] = "Hot";
|
||||
} else if (wWComfort_ == 0xD8) {
|
||||
output["wWComfort"] = "Eco";
|
||||
} else if (wWComfort_ == 0xEC) {
|
||||
output["wWComfort"] = "Intelligent";
|
||||
}
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(wWSelTemp_)) {
|
||||
output["wWSelTemp"] = wWSelTemp_;
|
||||
}
|
||||
if (Helpers::hasValue(wWSetTmp_)) {
|
||||
output["wWSetTemp"] = wWSetTmp_;
|
||||
}
|
||||
if (Helpers::hasValue(wWDisinfectTemp_)) {
|
||||
output["wWDisinfectionTemp"] = wWDisinfectTemp_;
|
||||
}
|
||||
if (Helpers::hasValue(selFlowTemp_)) {
|
||||
output["selFlowTemp"] = selFlowTemp_;
|
||||
}
|
||||
if (Helpers::hasValue(selBurnPow_)) {
|
||||
output["selBurnPow"] = selBurnPow_;
|
||||
}
|
||||
if (Helpers::hasValue(curBurnPow_)) {
|
||||
output["curBurnPow"] = curBurnPow_;
|
||||
}
|
||||
if (Helpers::hasValue(pumpMod_)) {
|
||||
output["pumpMod"] = pumpMod_;
|
||||
}
|
||||
if (Helpers::hasValue(pumpMod2_)) {
|
||||
output["pumpMod2"] = pumpMod2_;
|
||||
}
|
||||
if (wWType_ == 0) { // no output if not set
|
||||
output["wWType"] = F("off");
|
||||
} else if (wWType_ == 1) {
|
||||
output["wWType"] = F("flow");
|
||||
} else if (wWType_ == 2) {
|
||||
output["wWType"] = F("buffered flow");
|
||||
} else if (wWType_ == 3) {
|
||||
output["wWType"] = F("buffer");
|
||||
} else if (wWType_ == 4) {
|
||||
output["wWType"] = F("layered buffer");
|
||||
}
|
||||
if (Helpers::hasValue(wWChargeType_, EMS_VALUE_BOOL)) {
|
||||
output["wWChargeType"] = wWChargeType_ ? "valve" : "pump";
|
||||
}
|
||||
if (Helpers::hasValue(wWCircPump_, EMS_VALUE_BOOL)) {
|
||||
output["wWCircPump"] = Helpers::render_value(s, wWCircPump_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWCircPumpMode_)) {
|
||||
output["wWCiPuMode"] = wWCircPumpMode_;
|
||||
}
|
||||
if (Helpers::hasValue(wWCirc_, EMS_VALUE_BOOL)) {
|
||||
output["wWCirc"] = Helpers::render_value(s, wWCirc_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(extTemp_)) {
|
||||
output["outdoorTemp"] = (float)extTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wWCurTmp_)) {
|
||||
output["wWCurTmp"] = (float)wWCurTmp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wWCurTmp2_)) {
|
||||
output["wWCurTmp2"] = (float)wWCurTmp2_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wWCurFlow_)) {
|
||||
output["wWCurFlow"] = (float)wWCurFlow_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(curFlowTemp_)) {
|
||||
output["curFlowTemp"] = (float)curFlowTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(retTemp_)) {
|
||||
output["retTemp"] = (float)retTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(switchTemp_)) {
|
||||
output["switchTemp"] = (float)switchTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(sysPress_)) {
|
||||
output["sysPress"] = (float)sysPress_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(boilTemp_)) {
|
||||
output["boilTemp"] = (float)boilTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wwStorageTemp1_)) {
|
||||
output["wwStorageTemp1"] = (float)wwStorageTemp1_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wwStorageTemp2_)) {
|
||||
output["wwStorageTemp2"] = (float)wwStorageTemp2_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(exhaustTemp_)) {
|
||||
output["exhaustTemp"] = (float)exhaustTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wWActivated_, EMS_VALUE_BOOL)) {
|
||||
output["wWActivated"] = Helpers::render_value(s, wWActivated_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWOneTime_, EMS_VALUE_BOOL)) {
|
||||
output["wWOnetime"] = Helpers::render_value(s, wWOneTime_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWDisinfecting_, EMS_VALUE_BOOL)) {
|
||||
output["wWDisinfecting"] = Helpers::render_value(s, wWDisinfecting_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWReadiness_, EMS_VALUE_BOOL)) {
|
||||
output["wWReady"] = Helpers::render_value(s, wWReadiness_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWRecharging_, EMS_VALUE_BOOL)) {
|
||||
output["wWRecharge"] = Helpers::render_value(s, wWRecharging_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWTemperatureOK_, EMS_VALUE_BOOL)) {
|
||||
output["wWTempOK"] = Helpers::render_value(s, wWTemperatureOK_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWCirc_, EMS_VALUE_BOOL)) {
|
||||
output["wWCirc"] = Helpers::render_value(s, wWCirc_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(burnGas_, EMS_VALUE_BOOL)) {
|
||||
output["burnGas"] = Helpers::render_value(s, burnGas_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(flameCurr_)) {
|
||||
output["flameCurr"] = (float)(int16_t)flameCurr_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(heatPmp_, EMS_VALUE_BOOL)) {
|
||||
output["heatPump"] = Helpers::render_value(s, heatPmp_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(fanWork_, EMS_VALUE_BOOL)) {
|
||||
output["fanWork"] = Helpers::render_value(s, fanWork_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(ignWork_, EMS_VALUE_BOOL)) {
|
||||
output["ignWork"] = Helpers::render_value(s, ignWork_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWHeat_, EMS_VALUE_BOOL)) {
|
||||
output["wWHeat"] = Helpers::render_value(s, wWHeat_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(heating_activated_, EMS_VALUE_BOOL)) {
|
||||
output["heatingActivated"] = Helpers::render_value(s, heating_activated_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(heating_temp_)) {
|
||||
output["heatingTemp"] = heating_temp_;
|
||||
}
|
||||
if (Helpers::hasValue(pump_mod_max_)) {
|
||||
output["pumpModMax"] = pump_mod_max_;
|
||||
}
|
||||
if (Helpers::hasValue(pump_mod_min_)) {
|
||||
output["pumpModMin"] = pump_mod_min_;
|
||||
}
|
||||
if (Helpers::hasValue(pumpDelay_)) {
|
||||
output["pumpDelay"] = pumpDelay_;
|
||||
}
|
||||
if (Helpers::hasValue(burnPeriod_)) {
|
||||
output["burnMinPeriod"] = burnPeriod_;
|
||||
}
|
||||
if (Helpers::hasValue(burnPowermin_)) {
|
||||
output["burnMinPower"] = burnPowermin_;
|
||||
}
|
||||
if (Helpers::hasValue(burnPowermax_)) {
|
||||
output["burnMaxPower"] = burnPowermax_;
|
||||
}
|
||||
if (Helpers::hasValue(boilTemp_on_)) {
|
||||
output["boilHystOn"] = boilTemp_on_;
|
||||
}
|
||||
if (Helpers::hasValue(boilTemp_off_)) {
|
||||
output["boilHystOff"] = boilTemp_off_;
|
||||
}
|
||||
if (Helpers::hasValue(setFlowTemp_)) {
|
||||
output["setFlowTemp"] = setFlowTemp_;
|
||||
}
|
||||
if (Helpers::hasValue(setWWPumpPow_)) {
|
||||
output["wWSetPumpPower"] = setWWPumpPow_;
|
||||
}
|
||||
if (Helpers::hasValue(wWStarts_)) {
|
||||
output["wWStarts"] = wWStarts_;
|
||||
}
|
||||
if (Helpers::hasValue(wWWorkM_)) {
|
||||
output["wWWorkM"] = wWWorkM_;
|
||||
}
|
||||
if (Helpers::hasValue(UBAuptime_)) {
|
||||
output["UBAuptime"] = UBAuptime_;
|
||||
}
|
||||
if (Helpers::hasValue(burnStarts_)) {
|
||||
output["burnStarts"] = burnStarts_;
|
||||
}
|
||||
if (Helpers::hasValue(burnWorkMin_)) {
|
||||
output["burnWorkMin"] = burnWorkMin_;
|
||||
}
|
||||
if (Helpers::hasValue(heatWorkMin_)) {
|
||||
output["heatWorkMin"] = heatWorkMin_;
|
||||
}
|
||||
if (Helpers::hasValue(serviceCode_)) {
|
||||
output["serviceCode"] = serviceCodeChar_;
|
||||
output["serviceCodeNumber"] = serviceCode_;
|
||||
}
|
||||
|
||||
return (output.size());
|
||||
}
|
||||
|
||||
// publish values via MQTT
|
||||
void Boiler::publish_values() {
|
||||
// const size_t capacity = JSON_OBJECT_SIZE(56); // must recalculate if more objects addded https://arduinojson.org/v6/assistant/
|
||||
// DynamicJsonDocument doc(capacity);
|
||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_LARGE> doc;
|
||||
|
||||
char s[10]; // for formatting strings
|
||||
|
||||
if (Helpers::hasValue(wWComfort_)) {
|
||||
if (wWComfort_ == 0x00) {
|
||||
doc["wWComfort"] = "Hot";
|
||||
} else if (wWComfort_ == 0xD8) {
|
||||
doc["wWComfort"] = "Eco";
|
||||
} else if (wWComfort_ == 0xEC) {
|
||||
doc["wWComfort"] = "Intelligent";
|
||||
}
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(wWSelTemp_)) {
|
||||
doc["wWSelTemp"] = wWSelTemp_;
|
||||
}
|
||||
if (Helpers::hasValue(wWSetTmp_)) {
|
||||
doc["wWSetTemp"] = wWSetTmp_;
|
||||
}
|
||||
if (Helpers::hasValue(wWDisinfectTemp_)) {
|
||||
doc["wWDisinfectionTemp"] = wWDisinfectTemp_;
|
||||
}
|
||||
if (Helpers::hasValue(selFlowTemp_)) {
|
||||
doc["selFlowTemp"] = selFlowTemp_;
|
||||
}
|
||||
if (Helpers::hasValue(selBurnPow_)) {
|
||||
doc["selBurnPow"] = selBurnPow_;
|
||||
}
|
||||
if (Helpers::hasValue(curBurnPow_)) {
|
||||
doc["curBurnPow"] = curBurnPow_;
|
||||
}
|
||||
if (Helpers::hasValue(pumpMod_)) {
|
||||
doc["pumpMod"] = pumpMod_;
|
||||
}
|
||||
if (Helpers::hasValue(pumpMod2_)) {
|
||||
doc["pumpMod2"] = pumpMod2_;
|
||||
}
|
||||
if (wWType_ == 0) { // no output if not set
|
||||
doc["wWType"] = F("off");
|
||||
} else if (wWType_ == 1) {
|
||||
doc["wWType"] = F("flow");
|
||||
} else if (wWType_ == 2) {
|
||||
doc["wWType"] = F("buffered flow");
|
||||
} else if (wWType_ == 3) {
|
||||
doc["wWType"] = F("buffer");
|
||||
} else if (wWType_ == 4) {
|
||||
doc["wWType"] = F("layered buffer");
|
||||
}
|
||||
if (Helpers::hasValue(wWChargeType_, EMS_VALUE_BOOL)) {
|
||||
doc["wWChargeType"] = wWChargeType_ ? "valve" : "pump";
|
||||
}
|
||||
if (Helpers::hasValue(wWCircPump_, EMS_VALUE_BOOL)) {
|
||||
doc["wWCircPump"] = Helpers::render_value(s, wWCircPump_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWCircPumpMode_)) {
|
||||
doc["wWCiPuMode"] = wWCircPumpMode_;
|
||||
}
|
||||
if (Helpers::hasValue(wWCirc_, EMS_VALUE_BOOL)) {
|
||||
doc["wWCirc"] = Helpers::render_value(s, wWCirc_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(extTemp_)) {
|
||||
doc["outdoorTemp"] = (float)extTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wWCurTmp_)) {
|
||||
doc["wWCurTmp"] = (float)wWCurTmp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wWCurTmp2_)) {
|
||||
doc["wWCurTmp2"] = (float)wWCurTmp2_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wWCurFlow_)) {
|
||||
doc["wWCurFlow"] = (float)wWCurFlow_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(curFlowTemp_)) {
|
||||
doc["curFlowTemp"] = (float)curFlowTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(retTemp_)) {
|
||||
doc["retTemp"] = (float)retTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(switchTemp_)) {
|
||||
doc["switchTemp"] = (float)switchTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(sysPress_)) {
|
||||
doc["sysPress"] = (float)sysPress_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(boilTemp_)) {
|
||||
doc["boilTemp"] = (float)boilTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wwStorageTemp1_)) {
|
||||
doc["wwStorageTemp1"] = (float)wwStorageTemp1_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wwStorageTemp2_)) {
|
||||
doc["wwStorageTemp2"] = (float)wwStorageTemp2_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(exhaustTemp_)) {
|
||||
doc["exhaustTemp"] = (float)exhaustTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(wWActivated_, EMS_VALUE_BOOL)) {
|
||||
doc["wWActivated"] = Helpers::render_value(s, wWActivated_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWOneTime_, EMS_VALUE_BOOL)) {
|
||||
doc["wWOnetime"] = Helpers::render_value(s, wWOneTime_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWDisinfecting_, EMS_VALUE_BOOL)) {
|
||||
doc["wWDisinfecting"] = Helpers::render_value(s, wWDisinfecting_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWReadiness_, EMS_VALUE_BOOL)) {
|
||||
doc["wWReady"] = Helpers::render_value(s, wWReadiness_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWRecharging_, EMS_VALUE_BOOL)) {
|
||||
doc["wWRecharge"] = Helpers::render_value(s, wWRecharging_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWTemperatureOK_, EMS_VALUE_BOOL)) {
|
||||
doc["wWTempOK"] = Helpers::render_value(s, wWTemperatureOK_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWCirc_, EMS_VALUE_BOOL)) {
|
||||
doc["wWCirc"] = Helpers::render_value(s, wWCirc_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(burnGas_, EMS_VALUE_BOOL)) {
|
||||
doc["burnGas"] = Helpers::render_value(s, burnGas_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(flameCurr_)) {
|
||||
doc["flameCurr"] = (float)(int16_t)flameCurr_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(heatPmp_, EMS_VALUE_BOOL)) {
|
||||
doc["heatPump"] = Helpers::render_value(s, heatPmp_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(fanWork_, EMS_VALUE_BOOL)) {
|
||||
doc["fanWork"] = Helpers::render_value(s, fanWork_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(ignWork_, EMS_VALUE_BOOL)) {
|
||||
doc["ignWork"] = Helpers::render_value(s, ignWork_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(wWHeat_, EMS_VALUE_BOOL)) {
|
||||
doc["wWHeat"] = Helpers::render_value(s, wWHeat_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(heating_activated_, EMS_VALUE_BOOL)) {
|
||||
doc["heatingActivated"] = Helpers::render_value(s, heating_activated_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(heating_temp_)) {
|
||||
doc["heatingTemp"] = heating_temp_;
|
||||
}
|
||||
if (Helpers::hasValue(pump_mod_max_)) {
|
||||
doc["pumpModMax"] = pump_mod_max_;
|
||||
}
|
||||
if (Helpers::hasValue(pump_mod_min_)) {
|
||||
doc["pumpModMin"] = pump_mod_min_;
|
||||
}
|
||||
if (Helpers::hasValue(pumpDelay_)) {
|
||||
doc["pumpDelay"] = pumpDelay_;
|
||||
}
|
||||
if (Helpers::hasValue(burnPeriod_)) {
|
||||
doc["burnMinPeriod"] = burnPeriod_;
|
||||
}
|
||||
if (Helpers::hasValue(burnPowermin_)) {
|
||||
doc["burnMinPower"] = burnPowermin_;
|
||||
}
|
||||
if (Helpers::hasValue(burnPowermax_)) {
|
||||
doc["burnMaxPower"] = burnPowermax_;
|
||||
}
|
||||
if (Helpers::hasValue(boilTemp_on_)) {
|
||||
doc["boilHystOn"] = boilTemp_on_;
|
||||
}
|
||||
if (Helpers::hasValue(boilTemp_off_)) {
|
||||
doc["boilHystOff"] = boilTemp_off_;
|
||||
}
|
||||
if (Helpers::hasValue(setFlowTemp_)) {
|
||||
doc["setFlowTemp"] = setFlowTemp_;
|
||||
}
|
||||
if (Helpers::hasValue(setWWPumpPow_)) {
|
||||
doc["wWSetPumpPower"] = setWWPumpPow_;
|
||||
}
|
||||
if (Helpers::hasValue(wWStarts_)) {
|
||||
doc["wWStarts"] = wWStarts_;
|
||||
}
|
||||
if (Helpers::hasValue(wWWorkM_)) {
|
||||
doc["wWWorkM"] = wWWorkM_;
|
||||
}
|
||||
if (Helpers::hasValue(UBAuptime_)) {
|
||||
doc["UBAuptime"] = UBAuptime_;
|
||||
}
|
||||
if (Helpers::hasValue(burnStarts_)) {
|
||||
doc["burnStarts"] = burnStarts_;
|
||||
}
|
||||
if (Helpers::hasValue(burnWorkMin_)) {
|
||||
doc["burnWorkMin"] = burnWorkMin_;
|
||||
}
|
||||
if (Helpers::hasValue(heatWorkMin_)) {
|
||||
doc["heatWorkMin"] = heatWorkMin_;
|
||||
}
|
||||
if (Helpers::hasValue(serviceCode_)) {
|
||||
doc["serviceCode"] = serviceCodeChar_;
|
||||
doc["serviceCodeNumber"] = serviceCode_;
|
||||
}
|
||||
|
||||
// if we have data, publish it
|
||||
if (!doc.isNull()) {
|
||||
Mqtt::publish(F("boiler_data"), doc);
|
||||
JsonObject output = doc.to<JsonObject>();
|
||||
if (export_values(output)) {
|
||||
Mqtt::publish(F("boiler_data"), doc.as<JsonObject>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -801,6 +816,7 @@ bool Boiler::set_heating_activated(const char * value, const int8_t id) {
|
||||
if (!Helpers::value2bool(value, v)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO(F("Setting boiler heating "), v ? "on" : "off");
|
||||
if (get_toggle_fetch(EMS_TYPE_UBAParametersPlus)) {
|
||||
write_command(EMS_TYPE_UBAParametersPlus, 0, v ? 0x01 : 0, EMS_TYPE_UBAParametersPlus);
|
||||
|
||||
@@ -50,6 +50,7 @@ class Boiler : public EMSdevice {
|
||||
void console_commands(Shell & shell, unsigned int context);
|
||||
void register_mqtt_ha_config();
|
||||
void check_active();
|
||||
bool export_values(JsonObject & doc);
|
||||
|
||||
uint8_t last_boilerState = 0xFF; // remember last state of heating and warm water on/off
|
||||
uint8_t mqtt_format_; // single, nested or ha
|
||||
@@ -76,7 +77,7 @@ class Boiler : public EMSdevice {
|
||||
|
||||
// MC10Status
|
||||
uint16_t wwMixTemperature_ = EMS_VALUE_USHORT_NOTSET; // mengertemperatuur
|
||||
uint16_t wwBufferBoilerTemperature_ = EMS_VALUE_USHORT_NOTSET; // bufferboilertemperatuur
|
||||
uint16_t wwBufferBoilerTemperature_ = EMS_VALUE_USHORT_NOTSET; // bufferboilertemperature
|
||||
|
||||
// UBAMonitorFast - 0x18 on EMS1
|
||||
uint8_t selFlowTemp_ = EMS_VALUE_UINT_NOTSET; // Selected flow temperature
|
||||
@@ -146,6 +147,8 @@ class Boiler : public EMSdevice {
|
||||
uint8_t heating_active_ = EMS_VALUE_BOOL_NOTSET; // Central heating is on/off
|
||||
uint8_t pumpMod2_ = EMS_VALUE_UINT_NOTSET; // heatpump modulation from 0xE3 (heatpumps)
|
||||
|
||||
bool command_info(const char * value, const int8_t id, JsonObject & output);
|
||||
|
||||
void process_UBAParameterWW(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBAMonitorFast(std::shared_ptr<const Telegram> telegram);
|
||||
void process_UBATotalUptime(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
@@ -53,10 +53,24 @@ Mixing::Mixing(uint8_t device_type, uint8_t device_id, uint8_t product_id, const
|
||||
if (flags == EMSdevice::EMS_DEVICE_FLAG_IPM) {
|
||||
register_telegram_type(0x010C, F("IPMSetMessage"), false, [&](std::shared_ptr<const Telegram> t) { process_IPMStatusMessage(t); });
|
||||
}
|
||||
|
||||
// API call
|
||||
Command::add_with_json(this->device_type(), F("info"), [&](const char * value, const int8_t id, JsonObject & object) {
|
||||
return command_info(value, id, object);
|
||||
});
|
||||
}
|
||||
|
||||
// add context submenu
|
||||
void Mixing::add_context_menu() {
|
||||
// TODO support for multiple mixing units from a single menu, similar to set master with thermostat
|
||||
/*
|
||||
EMSESPShell::commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(mixing)},
|
||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
Mixing::console_commands(shell, ShellContext::MIXING);
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
// output json to web UI
|
||||
@@ -89,7 +103,24 @@ bool Mixing::updated_values() {
|
||||
}
|
||||
|
||||
// add console commands
|
||||
void Mixing::console_commands() {
|
||||
void Mixing::console_commands(Shell & shell, unsigned int context) {
|
||||
EMSESPShell::commands->add_command(ShellContext::MIXING,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(read)},
|
||||
flash_string_vector{F_(typeid_mandatory)},
|
||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||
uint16_t type_id = Helpers::hextoint(arguments.front().c_str());
|
||||
EMSESP::set_read_id(type_id);
|
||||
EMSESP::send_read_request(type_id, device_id());
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(ShellContext::MIXING,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(show)},
|
||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { show_values(shell); });
|
||||
|
||||
// enter the context
|
||||
Console::enter_custom_context(shell, context);
|
||||
}
|
||||
|
||||
// display all values into the shell console
|
||||
@@ -117,49 +148,66 @@ void Mixing::show_values(uuid::console::Shell & shell) {
|
||||
shell.println();
|
||||
}
|
||||
|
||||
bool Mixing::command_info(const char * value, const int8_t id, JsonObject & output) {
|
||||
return (export_values(output));
|
||||
}
|
||||
|
||||
// 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
|
||||
void Mixing::publish_values() {
|
||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_SMALL> doc;
|
||||
char s[5]; // for formatting strings
|
||||
JsonObject output = doc.to<JsonObject>();
|
||||
if (export_values(output)) {
|
||||
char topic[30];
|
||||
char s[5];
|
||||
strlcpy(topic, "mixing_data", 30);
|
||||
strlcat(topic, Helpers::itoa(s, device_id() - 0x20 + 1), 30); // append hc to topic
|
||||
Mqtt::publish(topic, doc.as<JsonObject>());
|
||||
}
|
||||
}
|
||||
|
||||
// creates JSON doc from values
|
||||
// returns false if empty
|
||||
bool Mixing::export_values(JsonObject & output) {
|
||||
char s[5]; // for formatting strings
|
||||
|
||||
switch (type_) {
|
||||
case Type::HC:
|
||||
doc["type"] = "hc";
|
||||
output["type"] = "hc";
|
||||
if (Helpers::hasValue(flowTemp_)) {
|
||||
doc["flowTemp"] = (float)flowTemp_ / 10;
|
||||
output["flowTemp"] = (float)flowTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(flowSetTemp_)) {
|
||||
doc["flowSetTemp"] = flowSetTemp_;
|
||||
output["flowSetTemp"] = flowSetTemp_;
|
||||
}
|
||||
if (Helpers::hasValue(pump_)) {
|
||||
doc["pumpStatus"] = Helpers::render_value(s, pump_, EMS_VALUE_BOOL);
|
||||
output["pumpStatus"] = Helpers::render_value(s, pump_, EMS_VALUE_BOOL);
|
||||
}
|
||||
if (Helpers::hasValue(status_)) {
|
||||
doc["valveStatus"] = status_;
|
||||
output["valveStatus"] = status_;
|
||||
}
|
||||
break;
|
||||
|
||||
case Type::WWC:
|
||||
doc["type"] = "wwc";
|
||||
output["type"] = "wwc";
|
||||
if (Helpers::hasValue(flowTemp_)) {
|
||||
doc["wwTemp"] = (float)flowTemp_ / 10;
|
||||
output["wwTemp"] = (float)flowTemp_ / 10;
|
||||
}
|
||||
if (Helpers::hasValue(pump_)) {
|
||||
doc["pumpStatus"] = pump_;
|
||||
output["pumpStatus"] = pump_;
|
||||
}
|
||||
if (Helpers::hasValue(status_)) {
|
||||
doc["tempStatus"] = status_;
|
||||
output["tempStatus"] = status_;
|
||||
}
|
||||
break;
|
||||
|
||||
case Type::NONE:
|
||||
default:
|
||||
return;
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
char topic[30];
|
||||
strlcpy(topic, "mixing_data", 30);
|
||||
strlcat(topic, Helpers::itoa(s, device_id() - 0x20 + 1), 30); // append hc to topic
|
||||
Mqtt::publish(topic, doc);
|
||||
return output.size();
|
||||
}
|
||||
|
||||
// heating circuits 0x02D7, 0x02D8 etc...
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <uuid/log.h>
|
||||
|
||||
#include "emsdevice.h"
|
||||
#include "emsesp.h"
|
||||
#include "telegram.h"
|
||||
#include "helpers.h"
|
||||
#include "mqtt.h"
|
||||
@@ -44,7 +45,9 @@ class Mixing : public EMSdevice {
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
void console_commands();
|
||||
void console_commands(Shell & shell, unsigned int context);
|
||||
bool export_values(JsonObject & doc);
|
||||
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_WWC(std::shared_ptr<const Telegram> telegram);
|
||||
@@ -66,7 +69,8 @@ class Mixing : public EMSdevice {
|
||||
int8_t status_ = EMS_VALUE_UINT_NOTSET;
|
||||
uint8_t flowSetTemp_ = EMS_VALUE_UINT_NOTSET;
|
||||
Type type_ = Type::NONE;
|
||||
bool changed_ = false;
|
||||
|
||||
bool changed_ = false;
|
||||
};
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -47,10 +47,28 @@ Solar::Solar(uint8_t device_type, uint8_t device_id, uint8_t product_id, const s
|
||||
register_telegram_type(0x0103, F("ISM1StatusMessage"), true, [&](std::shared_ptr<const Telegram> t) { process_ISM1StatusMessage(t); });
|
||||
register_telegram_type(0x0101, F("ISM1Set"), false, [&](std::shared_ptr<const Telegram> t) { process_ISM1Set(t); });
|
||||
}
|
||||
|
||||
// API call
|
||||
Command::add_with_json(this->device_type(), F("info"), [&](const char * value, const int8_t id, JsonObject & object) {
|
||||
return command_info(value, id, object);
|
||||
});
|
||||
}
|
||||
|
||||
bool Solar::command_info(const char * value, const int8_t id, JsonObject & output) {
|
||||
return (export_values(output));
|
||||
}
|
||||
|
||||
// context submenu
|
||||
void Solar::add_context_menu() {
|
||||
// TODO support for multiple solar units from a single menu, similar to set master with thermostat
|
||||
/*
|
||||
EMSESPShell::commands->add_command(ShellContext::MAIN,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(solar)},
|
||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) {
|
||||
Solar::console_commands(shell, ShellContext::SOLAR);
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
// print to web
|
||||
@@ -109,69 +127,74 @@ void Solar::show_values(uuid::console::Shell & shell) {
|
||||
// publish values via MQTT
|
||||
void Solar::publish_values() {
|
||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||
JsonObject output = doc.to<JsonObject>();
|
||||
if (export_values(output)) {
|
||||
Mqtt::publish(F("sm_data"), doc.as<JsonObject>());
|
||||
}
|
||||
}
|
||||
|
||||
// creates JSON doc from values
|
||||
// returns false if empty
|
||||
bool Solar::export_values(JsonObject & output) {
|
||||
char s[10]; // for formatting strings
|
||||
|
||||
if (Helpers::hasValue(collectorTemp_)) {
|
||||
doc["collectorTemp"] = (float)collectorTemp_ / 10;
|
||||
output["collectorTemp"] = (float)collectorTemp_ / 10;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(tankBottomTemp_)) {
|
||||
doc["tankBottomTemp"] = (float)tankBottomTemp_ / 10;
|
||||
output["tankBottomTemp"] = (float)tankBottomTemp_ / 10;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(tankBottomTemp2_)) {
|
||||
doc["tankBottomTemp2"] = (float)tankBottomTemp2_ / 10;
|
||||
output["tankBottomTemp2"] = (float)tankBottomTemp2_ / 10;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(heatExchangerTemp_)) {
|
||||
doc["heatExchangerTemp"] = (float)heatExchangerTemp_ / 10;
|
||||
output["heatExchangerTemp"] = (float)heatExchangerTemp_ / 10;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(solarPumpModulation_)) {
|
||||
doc["solarPumpModulation"] = solarPumpModulation_;
|
||||
output["solarPumpModulation"] = solarPumpModulation_;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(cylinderPumpModulation_)) {
|
||||
doc["cylinderPumpModulation"] = cylinderPumpModulation_;
|
||||
output["cylinderPumpModulation"] = cylinderPumpModulation_;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(solarPump_, EMS_VALUE_BOOL)) {
|
||||
doc["solarPump"] = Helpers::render_value(s, solarPump_, EMS_VALUE_BOOL);
|
||||
output["solarPump"] = Helpers::render_value(s, solarPump_, EMS_VALUE_BOOL);
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(valveStatus_, EMS_VALUE_BOOL)) {
|
||||
doc["valveStatus"] = Helpers::render_value(s, valveStatus_, EMS_VALUE_BOOL);
|
||||
output["valveStatus"] = Helpers::render_value(s, valveStatus_, EMS_VALUE_BOOL);
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(pumpWorkMin_)) {
|
||||
doc["pumpWorkMin"] = pumpWorkMin_;
|
||||
output["pumpWorkMin"] = pumpWorkMin_;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(tankHeated_, EMS_VALUE_BOOL)) {
|
||||
doc["tankHeated"] = Helpers::render_value(s, tankHeated_, EMS_VALUE_BOOL);
|
||||
output["tankHeated"] = Helpers::render_value(s, tankHeated_, EMS_VALUE_BOOL);
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(collectorShutdown_, EMS_VALUE_BOOL)) {
|
||||
doc["collectorShutdown"] = Helpers::render_value(s, collectorShutdown_, EMS_VALUE_BOOL);
|
||||
output["collectorShutdown"] = Helpers::render_value(s, collectorShutdown_, EMS_VALUE_BOOL);
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(energyLastHour_)) {
|
||||
doc["energyLastHour"] = (float)energyLastHour_ / 10;
|
||||
output["energyLastHour"] = (float)energyLastHour_ / 10;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(energyToday_)) {
|
||||
doc["energyToday"] = energyToday_;
|
||||
output["energyToday"] = energyToday_;
|
||||
}
|
||||
|
||||
if (Helpers::hasValue(energyTotal_)) {
|
||||
doc["energyTotal"] = (float)energyTotal_ / 10;
|
||||
output["energyTotal"] = (float)energyTotal_ / 10;
|
||||
}
|
||||
|
||||
// if we have data, publish it
|
||||
if (!doc.isNull()) {
|
||||
Mqtt::publish(F("sm_data"), doc);
|
||||
}
|
||||
return output.size();
|
||||
}
|
||||
|
||||
// check to see if values have been updated
|
||||
@@ -184,7 +207,24 @@ bool Solar::updated_values() {
|
||||
}
|
||||
|
||||
// add console commands
|
||||
void Solar::console_commands() {
|
||||
void Solar::console_commands(Shell & shell, unsigned int context) {
|
||||
EMSESPShell::commands->add_command(ShellContext::SOLAR,
|
||||
CommandFlags::ADMIN,
|
||||
flash_string_vector{F_(read)},
|
||||
flash_string_vector{F_(typeid_mandatory)},
|
||||
[=](Shell & shell __attribute__((unused)), const std::vector<std::string> & arguments) {
|
||||
uint16_t type_id = Helpers::hextoint(arguments.front().c_str());
|
||||
EMSESP::set_read_id(type_id);
|
||||
EMSESP::send_read_request(type_id, device_id());
|
||||
});
|
||||
|
||||
EMSESPShell::commands->add_command(ShellContext::SOLAR,
|
||||
CommandFlags::USER,
|
||||
flash_string_vector{F_(show)},
|
||||
[&](Shell & shell, const std::vector<std::string> & arguments __attribute__((unused))) { show_values(shell); });
|
||||
|
||||
// enter the context
|
||||
Console::enter_custom_context(shell, context);
|
||||
}
|
||||
|
||||
// SM10Monitor - type 0x97
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <uuid/log.h>
|
||||
|
||||
#include "emsdevice.h"
|
||||
#include "emsesp.h"
|
||||
#include "telegram.h"
|
||||
#include "helpers.h"
|
||||
#include "mqtt.h"
|
||||
@@ -44,7 +45,9 @@ class Solar : public EMSdevice {
|
||||
private:
|
||||
static uuid::log::Logger logger_;
|
||||
|
||||
void console_commands();
|
||||
void console_commands(Shell & shell, unsigned int context);
|
||||
bool export_values(JsonObject & doc);
|
||||
bool command_info(const char * value, const int8_t id, JsonObject & output);
|
||||
|
||||
int16_t collectorTemp_ = EMS_VALUE_SHORT_NOTSET; // TS1: Temperature sensor for collector array 1
|
||||
int16_t tankBottomTemp_ = EMS_VALUE_SHORT_NOTSET; // TS2: Temperature sensor 1 cylinder, bottom (solar thermal system)
|
||||
@@ -65,7 +68,8 @@ class Solar : public EMSdevice {
|
||||
uint8_t availabilityFlag_ = EMS_VALUE_BOOL_NOTSET;
|
||||
uint8_t configFlag_ = EMS_VALUE_BOOL_NOTSET;
|
||||
uint8_t userFlag_ = EMS_VALUE_BOOL_NOTSET;
|
||||
bool changed_ = false;
|
||||
|
||||
bool changed_ = false;
|
||||
|
||||
void process_SM10Monitor(std::shared_ptr<const Telegram> telegram);
|
||||
void process_SM100Monitor(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
@@ -248,21 +248,34 @@ bool Thermostat::updated_values() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// info API command
|
||||
// returns the same MQTT publish payload in Nested format
|
||||
bool Thermostat::command_info(const char * value, const int8_t id, JsonObject & output) {
|
||||
return (export_values(MQTT_format::NESTED, output));
|
||||
}
|
||||
|
||||
// publish values via MQTT
|
||||
void Thermostat::publish_values() {
|
||||
// only publish on the master thermostat
|
||||
if (EMSESP::actual_master_thermostat() != this->device_id()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t flags = this->model();
|
||||
|
||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||
JsonObject rootThermostat = doc.to<JsonObject>();
|
||||
JsonObject dataThermostat;
|
||||
JsonObject output = doc.to<JsonObject>();
|
||||
export_values(mqtt_format_, output);
|
||||
|
||||
if (mqtt_format_ == MQTT_format::NESTED) {
|
||||
Mqtt::publish(F("thermostat_data"), output);
|
||||
}
|
||||
}
|
||||
|
||||
// creates JSON doc from values
|
||||
// returns false if empty
|
||||
bool Thermostat::export_values(uint8_t mqtt_format, JsonObject & rootThermostat) {
|
||||
uint8_t flags = this->model();
|
||||
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) && (mqtt_format_ == MQTT_format::SINGLE || mqtt_format_ == MQTT_format::CUSTOM)) {
|
||||
if (flags == EMS_DEVICE_FLAG_RC35 || flags == EMS_DEVICE_FLAG_RC30_1) {
|
||||
if (datetime_.size()) {
|
||||
rootThermostat["time"] = datetime_.c_str();
|
||||
@@ -302,9 +315,9 @@ void Thermostat::publish_values() {
|
||||
}
|
||||
|
||||
// send this specific data using the thermostat_data topic
|
||||
if (mqtt_format_ != MQTT_format::NESTED) {
|
||||
Mqtt::publish(F("thermostat_data"), doc);
|
||||
rootThermostat = doc.to<JsonObject>(); // clear object
|
||||
if (mqtt_format != MQTT_format::NESTED) {
|
||||
Mqtt::publish(F("thermostat_data"), rootThermostat);
|
||||
rootThermostat.clear(); // clear object
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,8 +328,7 @@ void Thermostat::publish_values() {
|
||||
has_data = true;
|
||||
|
||||
// if the MQTT format is 'nested' or 'ha' then create the parent object hc<n>
|
||||
// if (mqtt_format_ != MQTT_format::SINGLE) {
|
||||
if ((mqtt_format_ == MQTT_format::NESTED) || (mqtt_format_ == MQTT_format::HA)) {
|
||||
if ((mqtt_format == MQTT_format::NESTED) || (mqtt_format == MQTT_format::HA)) {
|
||||
char hc_name[10]; // hc{1-4}
|
||||
strlcpy(hc_name, "hc", 10);
|
||||
char s[3];
|
||||
@@ -397,11 +409,11 @@ void Thermostat::publish_values() {
|
||||
dataThermostat["summertemp"] = hc->summertemp;
|
||||
}
|
||||
|
||||
// when using HA always send the mode otherwise it'll may break the component/widget and report an error
|
||||
if ((Helpers::hasValue(hc->mode)) || (mqtt_format_ == MQTT_format::HA)) {
|
||||
// mode - always force showing this when in HA so not to break HA's climate component
|
||||
if ((Helpers::hasValue(hc->mode)) || (mqtt_format == MQTT_format::HA)) {
|
||||
uint8_t hc_mode = hc->get_mode(flags);
|
||||
// if we're sending to HA the only valid mode types are heat, auto and off
|
||||
if (mqtt_format_ == MQTT_format::HA) {
|
||||
if (mqtt_format == MQTT_format::HA) {
|
||||
if ((hc_mode == HeatingCircuit::Mode::MANUAL) || (hc_mode == HeatingCircuit::Mode::DAY)) {
|
||||
hc_mode = HeatingCircuit::Mode::HEAT;
|
||||
} else if ((hc_mode == HeatingCircuit::Mode::NIGHT) || (hc_mode == HeatingCircuit::Mode::OFF)) {
|
||||
@@ -425,15 +437,13 @@ void Thermostat::publish_values() {
|
||||
|
||||
// if format is single, send immediately and clear object for next hc
|
||||
// the topic will have the hc number appended
|
||||
// if (mqtt_format_ == MQTT_format::SINGLE) {
|
||||
if ((mqtt_format_ == MQTT_format::SINGLE) || (mqtt_format_ == MQTT_format::CUSTOM)) {
|
||||
if ((mqtt_format == MQTT_format::SINGLE) || (mqtt_format == MQTT_format::CUSTOM)) {
|
||||
char topic[30];
|
||||
char s[3];
|
||||
strlcpy(topic, "thermostat_data", 30);
|
||||
strlcat(topic, Helpers::itoa(s, hc->hc_num()), 30); // append hc to topic
|
||||
Mqtt::publish(topic, doc);
|
||||
rootThermostat = doc.to<JsonObject>(); // clear object
|
||||
} else if (mqtt_format_ == MQTT_format::HA) {
|
||||
rootThermostat.clear(); // clear object
|
||||
} else if (mqtt_format == MQTT_format::HA) {
|
||||
// see if we have already registered this with HA MQTT Discovery, if not send the config
|
||||
if (!hc->ha_registered()) {
|
||||
register_mqtt_ha_config(hc->hc_num());
|
||||
@@ -442,19 +452,12 @@ void Thermostat::publish_values() {
|
||||
// send the thermostat topic and payload data
|
||||
std::string topic(100, '\0');
|
||||
snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/climate/ems-esp/hc%d/state"), hc->hc_num());
|
||||
Mqtt::publish(topic, doc);
|
||||
Mqtt::publish(topic, rootThermostat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_data) {
|
||||
return; // nothing to send, quit
|
||||
}
|
||||
|
||||
// if we're using nested json, send all in one go under one topic called thermostat_data
|
||||
if (mqtt_format_ == MQTT_format::NESTED) {
|
||||
Mqtt::publish(F("thermostat_data"), doc);
|
||||
}
|
||||
return (has_data);
|
||||
}
|
||||
|
||||
// returns the heating circuit object based on the hc number
|
||||
@@ -599,7 +602,7 @@ void Thermostat::register_mqtt_ha_config(uint8_t hc_num) {
|
||||
std::string topic(100, '\0'); // e.g homeassistant/climate/hc1/thermostat/config
|
||||
snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/climate/ems-esp/hc%d/config"), hc_num);
|
||||
// Mqtt::publish(topic); // empty payload, this remove any previous config sent to HA
|
||||
Mqtt::publish_retain(topic, doc, true); // publish the config payload with retain flag
|
||||
Mqtt::publish_retain(topic, doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
||||
|
||||
// subscribe to the temp and mode commands
|
||||
snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/climate/ems-esp/hc%d/cmd_temp"), hc_num);
|
||||
@@ -1922,8 +1925,13 @@ bool Thermostat::set_manualtemp(const char * value, const int8_t id) {
|
||||
return set_temperature_value(value, id, HeatingCircuit::Mode::MANUAL);
|
||||
}
|
||||
|
||||
// commands for MQTT and Console
|
||||
// API commands for MQTT and Console
|
||||
void Thermostat::add_commands() {
|
||||
// API call
|
||||
Command::add_with_json(this->device_type(), F("info"), [&](const char * value, const int8_t id, JsonObject & object) {
|
||||
return command_info(value, id, object);
|
||||
});
|
||||
|
||||
// if this thermostat doesn't support write, don't add the commands
|
||||
if ((this->flags() & EMSdevice::EMS_DEVICE_FLAG_NO_WRITE) == EMSdevice::EMS_DEVICE_FLAG_NO_WRITE) {
|
||||
return;
|
||||
|
||||
@@ -108,6 +108,7 @@ class Thermostat : public EMSdevice {
|
||||
|
||||
void console_commands(Shell & shell, unsigned int context);
|
||||
void add_commands();
|
||||
bool export_values(uint8_t mqtt_format, JsonObject & doc);
|
||||
|
||||
// specific thermostat characteristics, stripping the option bits at pos 6 and 7
|
||||
inline uint8_t model() const {
|
||||
@@ -221,6 +222,7 @@ class Thermostat : public EMSdevice {
|
||||
std::shared_ptr<Thermostat::HeatingCircuit> heating_circuit(const uint8_t hc_num);
|
||||
|
||||
void register_mqtt_ha_config(uint8_t hc_num);
|
||||
bool command_info(const char * value, const int8_t id, JsonObject & output);
|
||||
|
||||
void process_RCOutdoorTemp(std::shared_ptr<const Telegram> telegram);
|
||||
void process_IBASettings(std::shared_ptr<const Telegram> telegram);
|
||||
|
||||
Reference in New Issue
Block a user