diff --git a/interface/src/project/ApplicationSettings.tsx b/interface/src/project/ApplicationSettings.tsx
index f833f1e96..f28dfd6d9 100644
--- a/interface/src/project/ApplicationSettings.tsx
+++ b/interface/src/project/ApplicationSettings.tsx
@@ -546,6 +546,26 @@ const ApplicationSettings: FC = () => {
justifyContent="flex-start"
alignItems="flex-start"
>
+ {data.shower_timer && (
+
+ {LL.SECONDS()}
+ )
+ }}
+ variant="outlined"
+ value={numberValue(data.shower_min_duration)}
+ fullWidth
+ type="number"
+ onChange={updateFormValue}
+ />
+
+ )}
{data.shower_alert && (
<>
diff --git a/interface/src/project/types.ts b/interface/src/project/types.ts
index c2a28423b..ed3519035 100644
--- a/interface/src/project/types.ts
+++ b/interface/src/project/types.ts
@@ -12,6 +12,7 @@ export interface Settings {
shower_alert: boolean;
shower_alert_coldshot: number;
shower_alert_trigger: number;
+ shower_min_duration: number;
rx_gpio: number;
tx_gpio: number;
telnet_enabled: boolean;
diff --git a/interface/src/project/validators.ts b/interface/src/project/validators.ts
index ab86314a0..c721dca84 100644
--- a/interface/src/project/validators.ts
+++ b/interface/src/project/validators.ts
@@ -234,6 +234,16 @@ export const createSettingsValidator = (settings: Settings) =>
{ type: 'number', min: 0, max: 10, message: 'Must be between 0 and 10' }
]
}),
+ ...(settings.shower_timer && {
+ shower_min_duration: [
+ {
+ type: 'number',
+ min: 1,
+ max: 3000,
+ message: 'Time must be between 1 and 3000 seconds'
+ }
+ ]
+ }),
...(settings.shower_alert && {
shower_alert_trigger: [
{
diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts
index e3c3ccb36..7fcfbcb1c 100644
--- a/mock-api/rest_server.ts
+++ b/mock-api/rest_server.ts
@@ -610,6 +610,7 @@ let settings = {
shower_alert: true,
shower_alert_trigger: 7,
shower_alert_coldshot: 10,
+ shower_min_duration: 1200,
rx_gpio: 23,
tx_gpio: 5,
phy_type: 0,
diff --git a/src/default_settings.h b/src/default_settings.h
index 81514e540..9d4a7455b 100644
--- a/src/default_settings.h
+++ b/src/default_settings.h
@@ -77,6 +77,10 @@
#define EMSESP_DEFAULT_SHOWER_ALERT_TRIGGER 7
#endif
+#ifndef EMSESP_DEFAULT_SHOWER_MIN_DURATION
+#define EMSESP_DEFAULT_SHOWER_MIN_DURATION 1200
+#endif
+
#ifndef EMSESP_DEFAULT_SHOWER_ALERT_COLDSHOT
#define EMSESP_DEFAULT_SHOWER_ALERT_COLDSHOT 10
#endif
diff --git a/src/shower.cpp b/src/shower.cpp
index 73ff9184e..5c90aa0c1 100644
--- a/src/shower.cpp
+++ b/src/shower.cpp
@@ -28,8 +28,9 @@ void Shower::start() {
EMSESP::webSettingsService.read([&](WebSettings & settings) {
shower_timer_ = settings.shower_timer;
shower_alert_ = settings.shower_alert;
- shower_alert_trigger_ = settings.shower_alert_trigger * 60000; // convert from minutes
- shower_alert_coldshot_ = settings.shower_alert_coldshot * 1000; // convert from seconds
+ shower_alert_trigger_ = settings.shower_alert_trigger * 60; // convert from minutes to seconds
+ shower_alert_coldshot_ = settings.shower_alert_coldshot; // in seconds
+ shower_min_duration_ = settings.shower_min_duration; // in seconds
});
Command::add(
@@ -60,7 +61,8 @@ void Shower::loop() {
return;
}
- uint32_t time_now = uuid::get_uptime();
+ // uint32_t time_now = uuid::get_uptime(); // in ms
+ auto time_now = uuid::get_uptime_sec(); // in sec
// if already in cold mode, ignore all this logic until we're out of the cold blast
if (!doing_cold_shot_) {
@@ -78,7 +80,7 @@ void Shower::loop() {
} 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_state_ && (time_now - timer_start_) > SHOWER_MIN_DURATION) {
+ if (!shower_state_ && (time_now - timer_start_) > shower_min_duration_) {
set_shower_state(true);
LOG_DEBUG("hot water still running, starting shower timer");
}
@@ -99,7 +101,7 @@ void Shower::loop() {
// because its unsigned long, can't have negative so check if length is less than OFFSET_TIME
if ((timer_pause_ - timer_start_) > SHOWER_OFFSET_TIME) {
duration_ = (timer_pause_ - timer_start_ - SHOWER_OFFSET_TIME);
- if (duration_ > SHOWER_MIN_DURATION) {
+ if (duration_ > shower_min_duration_) {
JsonDocument doc;
// duration in seconds
@@ -145,7 +147,7 @@ void Shower::shower_alert_start() {
(void)Command::call(EMSdevice::DeviceType::BOILER, "tapactivated", "false", 9);
doing_cold_shot_ = true;
force_coldshot = false;
- alert_timer_start_ = uuid::get_uptime(); // timer starts now
+ alert_timer_start_ = uuid::get_uptime_sec(); // timer starts now
}
// turn back on the hot water for the shower
diff --git a/src/shower.h b/src/shower.h
index e16fce391..256431371 100644
--- a/src/shower.h
+++ b/src/shower.h
@@ -36,11 +36,8 @@ class Shower {
private:
static uuid::log::Logger logger_;
- static constexpr uint32_t SHOWER_PAUSE_TIME = 15000; // in ms. 15 seconds, max time if water is switched off & on during a shower
- static constexpr uint32_t SHOWER_MIN_DURATION = 120000; // in ms. 2 minutes, before recognizing its a shower
- // static constexpr uint32_t SHOWER_MIN_DURATION = 5000; // for testing in ms. 5 seconds
-
- static constexpr uint32_t SHOWER_OFFSET_TIME = 5000; // in ms. 5 seconds grace time, to calibrate actual time under the shower
+ static constexpr uint32_t SHOWER_PAUSE_TIME = 15; // 15 seconds, max time if water is switched off & on during a shower
+ static constexpr uint32_t SHOWER_OFFSET_TIME = 5; // 5 seconds grace time, to calibrate actual time under the shower
void shower_alert_start();
void shower_alert_stop();
@@ -49,15 +46,17 @@ class Shower {
bool shower_alert_; // true if we want the alert of cold water
uint32_t shower_alert_trigger_; // default 7 minutes, before trigger a shot of cold water
uint32_t shower_alert_coldshot_; // default 10 seconds for cold water before turning back hot water
+ uint32_t shower_min_duration_; // default 2 minutes (1200 seconds), before recognizing its a shower
uint32_t next_alert_;
bool ha_configdone_ = false; // for HA MQTT Discovery
bool shower_state_;
- uint32_t timer_start_; // ms
- uint32_t timer_pause_; // ms
- uint32_t duration_; // ms
+
+ uint32_t timer_start_; // sec
+ uint32_t timer_pause_; // sec
+ uint32_t duration_; // sec
// cold shot
- uint32_t alert_timer_start_; // ms
+ uint32_t alert_timer_start_; // sec
bool doing_cold_shot_; // true if we've just sent a jolt of cold water
};
diff --git a/src/system.cpp b/src/system.cpp
index db07845bd..46bc76049 100644
--- a/src/system.cpp
+++ b/src/system.cpp
@@ -1448,12 +1448,13 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
// Settings
node = output["Settings"].to();
EMSESP::webSettingsService.read([&](WebSettings & settings) {
- node["board profile"] = settings.board_profile;
- node["locale"] = settings.locale;
- node["tx mode"] = settings.tx_mode;
- node["ems bus id"] = settings.ems_bus_id;
- node["shower timer"] = settings.shower_timer;
- node["shower alert"] = settings.shower_alert;
+ node["board profile"] = settings.board_profile;
+ node["locale"] = settings.locale;
+ node["tx mode"] = settings.tx_mode;
+ node["ems bus id"] = settings.ems_bus_id;
+ node["shower timer"] = settings.shower_timer;
+ node["shower alert"] = settings.shower_alert;
+ node["shpwe_min_duration"] = settings.shower_min_duration; // seconds
if (settings.shower_alert) {
node["shower alert coldshot"] = settings.shower_alert_coldshot; // seconds
node["shower alert trigger"] = settings.shower_alert_trigger; // minutes
diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp
index e3805d037..ee12c5f56 100644
--- a/src/web/WebSettingsService.cpp
+++ b/src/web/WebSettingsService.cpp
@@ -47,6 +47,7 @@ void WebSettings::read(WebSettings & settings, JsonObject root) {
root["shower_alert"] = settings.shower_alert;
root["shower_alert_coldshot"] = settings.shower_alert_coldshot;
root["shower_alert_trigger"] = settings.shower_alert_trigger;
+ root["shower_min_duration"] = settings.shower_min_duration;
root["rx_gpio"] = settings.rx_gpio;
root["tx_gpio"] = settings.tx_gpio;
root["dallas_gpio"] = settings.dallas_gpio;
@@ -237,6 +238,9 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
prev = settings.shower_alert_trigger;
settings.shower_alert_trigger = root["shower_alert_trigger"] | EMSESP_DEFAULT_SHOWER_ALERT_TRIGGER;
check_flag(prev, settings.shower_alert_trigger, ChangeFlags::SHOWER);
+ prev = settings.shower_min_duration;
+ settings.shower_min_duration = root["shower_min_duration"] | EMSESP_DEFAULT_SHOWER_MIN_DURATION;
+ check_flag(prev, settings.shower_min_duration, ChangeFlags::SHOWER);
prev = settings.shower_alert_coldshot;
settings.shower_alert_coldshot = root["shower_alert_coldshot"] | EMSESP_DEFAULT_SHOWER_ALERT_COLDSHOT;
check_flag(prev, settings.shower_alert_coldshot, ChangeFlags::SHOWER);
diff --git a/src/web/WebSettingsService.h b/src/web/WebSettingsService.h
index d820f1ce2..72e95c0ea 100644
--- a/src/web/WebSettingsService.h
+++ b/src/web/WebSettingsService.h
@@ -36,8 +36,9 @@ class WebSettings {
bool boiler_heatingoff;
bool shower_timer;
bool shower_alert;
- uint8_t shower_alert_trigger;
- uint8_t shower_alert_coldshot;
+ uint8_t shower_alert_trigger; // minutes
+ uint8_t shower_alert_coldshot; // seconds
+ uint32_t shower_min_duration; // seconds
bool syslog_enabled;
int8_t syslog_level; // uuid::log::Level
uint32_t syslog_mark_interval;