mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 16:29:51 +03:00
fixed edge case in shower logic when state didn't change
This commit is contained in:
@@ -437,7 +437,6 @@ void EMSESP::publish_all_loop() {
|
||||
Mqtt::ha_status();
|
||||
}
|
||||
system_.send_heartbeat();
|
||||
shower_.send_mqtt_stat(false, true);
|
||||
break;
|
||||
default:
|
||||
// all finished
|
||||
|
||||
107
src/shower.cpp
107
src/shower.cpp
@@ -28,7 +28,7 @@ void Shower::start() {
|
||||
shower_alert_ = settings.shower_alert;
|
||||
});
|
||||
|
||||
send_mqtt_stat(false);
|
||||
set_shower_state(false, true); // turns shower to off and creates HA topic if not already done
|
||||
}
|
||||
|
||||
void Shower::loop() {
|
||||
@@ -49,14 +49,13 @@ void Shower::loop() {
|
||||
timer_pause_ = 0; // remove any last pauses
|
||||
doing_cold_shot_ = false;
|
||||
duration_ = 0;
|
||||
shower_on_ = false;
|
||||
shower_state_ = false;
|
||||
} else {
|
||||
// hot water has been on for a while
|
||||
// first check to see if hot water has been on long enough to be recognized as a Shower/Bath
|
||||
if (!shower_on_ && (time_now - timer_start_) > SHOWER_MIN_DURATION) {
|
||||
shower_on_ = true;
|
||||
send_mqtt_stat(true);
|
||||
publish_values();
|
||||
if (!shower_state_ && (time_now - timer_start_) > SHOWER_MIN_DURATION) {
|
||||
set_shower_state(true);
|
||||
publish_shower_data();
|
||||
LOG_DEBUG(F("[Shower] hot water still running, starting shower timer"));
|
||||
}
|
||||
// check if the shower has been on too long
|
||||
@@ -77,18 +76,27 @@ void Shower::loop() {
|
||||
if ((timer_pause_ - timer_start_) > SHOWER_OFFSET_TIME) {
|
||||
duration_ = (timer_pause_ - timer_start_ - SHOWER_OFFSET_TIME);
|
||||
if (duration_ > SHOWER_MIN_DURATION) {
|
||||
send_mqtt_stat(false);
|
||||
publish_shower_data();
|
||||
LOG_DEBUG(F("[Shower] finished with duration %d"), duration_);
|
||||
publish_values();
|
||||
}
|
||||
}
|
||||
#if defined(EMSESP_DEBUG)
|
||||
else {
|
||||
if (shower_state_) {
|
||||
Mqtt::publish("message", "shower state is ON");
|
||||
} else {
|
||||
Mqtt::publish("message", "shower state is OFF");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// reset everything
|
||||
timer_start_ = 0;
|
||||
timer_pause_ = 0;
|
||||
shower_on_ = false;
|
||||
doing_cold_shot_ = false;
|
||||
alert_timer_start_ = 0;
|
||||
|
||||
set_shower_state(false);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -101,37 +109,6 @@ void Shower::loop() {
|
||||
}
|
||||
}
|
||||
|
||||
// send status of shower to MQTT
|
||||
void Shower::send_mqtt_stat(bool state, bool force) {
|
||||
if (!shower_timer_ && !shower_alert_) {
|
||||
return;
|
||||
}
|
||||
|
||||
char s[7];
|
||||
Mqtt::publish(F("shower_active"), Helpers::render_boolean(s, state)); // https://github.com/emsesp/EMS-ESP/issues/369
|
||||
|
||||
// if we're in HA mode make sure we've first sent out the HA MQTT Discovery config topic
|
||||
if ((Mqtt::ha_enabled()) && (!ha_configdone_ || force)) {
|
||||
ha_configdone_ = true;
|
||||
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_HA_CONFIG> doc;
|
||||
doc["name"] = FJSON("Shower Active");
|
||||
doc["uniq_id"] = FJSON("shower_active");
|
||||
doc["~"] = Mqtt::base(); // default ems-esp
|
||||
doc["stat_t"] = FJSON("~/shower_active");
|
||||
char result[10];
|
||||
doc[F("payload_on")] = Helpers::render_boolean(result, true);
|
||||
doc[F("payload_off")] = Helpers::render_boolean(result, false);
|
||||
JsonObject dev = doc.createNestedObject("dev");
|
||||
JsonArray ids = dev.createNestedArray("ids");
|
||||
ids.add("ems-esp");
|
||||
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(topic, sizeof(topic), "binary_sensor/%s/shower_active/config", Mqtt::base().c_str());
|
||||
Mqtt::publish_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
|
||||
}
|
||||
}
|
||||
|
||||
// turn back on the hot water for the shower
|
||||
void Shower::shower_alert_stop() {
|
||||
if (doing_cold_shot_) {
|
||||
@@ -150,9 +127,10 @@ void Shower::shower_alert_start() {
|
||||
}
|
||||
}
|
||||
|
||||
// Publish shower data
|
||||
// returns true if added to MQTT queue went ok
|
||||
void Shower::publish_values() {
|
||||
// Publish to the shower_data topic
|
||||
// showing whether the shower timer and alert are enabled or disabled
|
||||
// and the duration of the last shower
|
||||
void Shower::publish_shower_data() {
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_SMALL> doc;
|
||||
|
||||
char result[10];
|
||||
@@ -169,4 +147,47 @@ void Shower::publish_values() {
|
||||
Mqtt::publish(F("shower_data"), doc.as<JsonObject>());
|
||||
}
|
||||
|
||||
// send status of shower to MQTT topic called shower_active - which is determined by the state parameter
|
||||
// and creates the HA config topic if HA enabled
|
||||
// force is used by EMSESP::publish_all_loop()
|
||||
void Shower::set_shower_state(bool state, bool force) {
|
||||
if (!shower_timer_ && !shower_alert_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// sets the state
|
||||
shower_state_ = state;
|
||||
|
||||
// only publish if that state has changed
|
||||
static bool old_shower_state_;
|
||||
if ((shower_state_ == old_shower_state_) && !force) {
|
||||
return;
|
||||
}
|
||||
old_shower_state_ = shower_state_; // copy current state
|
||||
|
||||
char s[7];
|
||||
Mqtt::publish(F("shower_active"), Helpers::render_boolean(s, shower_state_)); // https://github.com/emsesp/EMS-ESP/issues/369
|
||||
|
||||
// send out HA MQTT Discovery config topic
|
||||
if ((Mqtt::ha_enabled()) && (!ha_configdone_ || force)) {
|
||||
ha_configdone_ = true;
|
||||
|
||||
StaticJsonDocument<EMSESP_JSON_SIZE_HA_CONFIG> doc;
|
||||
doc["name"] = FJSON("Shower Active");
|
||||
doc["uniq_id"] = FJSON("shower_active");
|
||||
doc["~"] = Mqtt::base(); // default ems-esp
|
||||
doc["stat_t"] = FJSON("~/shower_active");
|
||||
char result[10];
|
||||
doc[F("payload_on")] = Helpers::render_boolean(result, true);
|
||||
doc[F("payload_off")] = Helpers::render_boolean(result, false);
|
||||
JsonObject dev = doc.createNestedObject("dev");
|
||||
JsonArray ids = dev.createNestedArray("ids");
|
||||
ids.add("ems-esp");
|
||||
|
||||
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
|
||||
snprintf(topic, sizeof(topic), "binary_sensor/%s/shower_active/config", Mqtt::base().c_str());
|
||||
Mqtt::publish_ha(topic, doc.as<JsonObject>()); // publish the config payload with retain flag
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace emsesp
|
||||
|
||||
@@ -28,7 +28,7 @@ class Shower {
|
||||
void start();
|
||||
void loop();
|
||||
|
||||
void send_mqtt_stat(bool state, bool force = false);
|
||||
void set_shower_state(bool state, bool force = false);
|
||||
|
||||
bool shower_alert() const {
|
||||
return shower_alert_;
|
||||
@@ -55,14 +55,14 @@ class Shower {
|
||||
static constexpr uint32_t SHOWER_COLDSHOT_DURATION = 10000; // 10 seconds for cold water before turning back hot water
|
||||
static constexpr uint32_t SHOWER_MAX_DURATION = 420000; // in ms. 7 minutes, before trigger a shot of cold water
|
||||
|
||||
void publish_values();
|
||||
void publish_shower_data();
|
||||
void shower_alert_start();
|
||||
void shower_alert_stop();
|
||||
|
||||
bool shower_timer_; // true if we want to report back on shower times
|
||||
bool shower_alert_; // true if we want the alert of cold water
|
||||
bool ha_configdone_ = false; // for HA MQTT Discovery
|
||||
bool shower_on_;
|
||||
bool shower_state_;
|
||||
uint32_t timer_start_; // ms
|
||||
uint32_t timer_pause_; // ms
|
||||
uint32_t duration_; // ms
|
||||
|
||||
Reference in New Issue
Block a user