mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
added shower trigger and coldshot times - #436
This commit is contained in:
@@ -35,6 +35,8 @@
|
||||
- Read time from IVT-controller [#439](https://github.com/emsesp/EMS-ESP32/issues/439)
|
||||
- Hybrid Heatpump product-id 168 [#459](https://github.com/emsesp/EMS-ESP32/issues/459), thermostat settings
|
||||
- Junkers ISM2 and IPM in warm water mode [#437](https://github.com/emsesp/EMS-ESP32/issues/437)
|
||||
- Added Shower Alert trigger time and cold shot time [#436](https://github.com/emsesp/EMS-ESP32/issues/436)
|
||||
- Improved Table layout in Web UI (searching, filtering, sorting, exporting to CSV)
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -53,6 +55,7 @@
|
||||
- Burner selected max power can have a value higher than 100% [#314](https://github.com/emsesp/EMS-ESP32/issues/314)
|
||||
- some missing fahrenheit calculations
|
||||
- limited number of exclusions [#339](https://github.com/emsesp/EMS-ESP32/issues/339)
|
||||
- MQTT sometimes would not reconnect after a WiFi outage
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -63,7 +66,7 @@
|
||||
- Show Sensors quality in WebUI
|
||||
- Controller not shown in WebUI dashboard
|
||||
- renamed "Home Assistant Integration" to "MQTT Discovery" in MQTT Settings [#290](https://github.com/emsesp/EMS-ESP32/issues/290)
|
||||
- Show ems tx reads and writes separatly
|
||||
- Show ems tx reads and writes separately
|
||||
- Show ems device handlers separated for received, fetched and pending handlers.
|
||||
- Wired renamed to Ethernet
|
||||
- removed system/pin command, new commands in analogsensors
|
||||
|
||||
@@ -343,11 +343,6 @@ const SettingsApplication: FC = () => {
|
||||
label="Convert temperature values to Fahrenheit"
|
||||
disabled={saving}
|
||||
/>
|
||||
<BlockFormControlLabel
|
||||
control={<Checkbox checked={data.low_clock} onChange={updateFormValue} name="low_clock" />}
|
||||
label="Underclock CPU speed"
|
||||
disabled={saving}
|
||||
/>
|
||||
<BlockFormControlLabel
|
||||
control={<Checkbox checked={data.notoken_api} onChange={updateFormValue} name="notoken_api" />}
|
||||
label="Bypass Access Token authorization on API calls"
|
||||
@@ -358,6 +353,11 @@ const SettingsApplication: FC = () => {
|
||||
label="Enable Read only mode (blocks all outgoing EMS Tx write commands)"
|
||||
disabled={saving}
|
||||
/>
|
||||
<BlockFormControlLabel
|
||||
control={<Checkbox checked={data.low_clock} onChange={updateFormValue} name="low_clock" />}
|
||||
label="Underclock CPU speed"
|
||||
disabled={saving}
|
||||
/>
|
||||
<Grid container spacing={0} direction="row" justifyContent="flex-start" alignItems="flex-start">
|
||||
<BlockFormControlLabel
|
||||
control={<Checkbox checked={data.shower_timer} onChange={updateFormValue} name="shower_timer" />}
|
||||
@@ -367,8 +367,36 @@ const SettingsApplication: FC = () => {
|
||||
<BlockFormControlLabel
|
||||
control={<Checkbox checked={data.shower_alert} onChange={updateFormValue} name="shower_alert" />}
|
||||
label="Enable Shower Alert"
|
||||
disabled={saving}
|
||||
disabled={!data.shower_timer}
|
||||
/>
|
||||
{data.shower_alert && (
|
||||
<>
|
||||
<Grid item xs={2}>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
name="shower_alert_trigger"
|
||||
label="Trigger Time (minutes)"
|
||||
variant="outlined"
|
||||
value={data.shower_alert_trigger}
|
||||
type="number"
|
||||
onChange={updateFormValue}
|
||||
disabled={!data.shower_timer}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={2}>
|
||||
<ValidatedTextField
|
||||
fieldErrors={fieldErrors}
|
||||
name="shower_alert_coldshot"
|
||||
label="Cold Shot Time (seconds)"
|
||||
variant="outlined"
|
||||
value={data.shower_alert_coldshot}
|
||||
type="number"
|
||||
onChange={updateFormValue}
|
||||
disabled={!data.shower_timer}
|
||||
/>
|
||||
</Grid>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
<Typography sx={{ pt: 2 }} variant="h6" color="primary">
|
||||
Formatting Options
|
||||
|
||||
@@ -9,6 +9,8 @@ export interface Settings {
|
||||
master_thermostat: number;
|
||||
shower_timer: boolean;
|
||||
shower_alert: boolean;
|
||||
shower_alert_coldshot: number;
|
||||
shower_alert_trigger: number;
|
||||
rx_gpio: number;
|
||||
tx_gpio: number;
|
||||
telnet_enabled: boolean;
|
||||
|
||||
@@ -40,5 +40,9 @@ export const createSettingsValidator = (settings: Settings) =>
|
||||
{ required: true, message: 'Mark interval is required' },
|
||||
{ type: 'number', min: 0, max: 10, message: 'Port must be between 0 and 10' }
|
||||
]
|
||||
}),
|
||||
...(settings.shower_alert && {
|
||||
shower_alert_trigger: [{ type: 'number', min: 1, max: 20, message: 'Time must be between 1 and 20 minutes' }],
|
||||
shower_alert_coldshot: [{ type: 'number', min: 1, max: 10, message: 'Time must be between 1 and 10 seconds' }]
|
||||
})
|
||||
});
|
||||
|
||||
@@ -29,6 +29,8 @@ class DummySettings {
|
||||
uint8_t master_thermostat = 0;
|
||||
bool shower_timer = true;
|
||||
bool shower_alert = false;
|
||||
uint8_t shower_alert_coldshot = 10;
|
||||
uint8_t shower_alert_trigger = 7;
|
||||
bool hide_led = false;
|
||||
bool notoken_api = false;
|
||||
bool readonly_mode = false;
|
||||
|
||||
@@ -316,7 +316,9 @@ settings = {
|
||||
syslog_port: 514,
|
||||
master_thermostat: 0,
|
||||
shower_timer: true,
|
||||
shower_alert: false,
|
||||
shower_alert: true,
|
||||
shower_alert_trigger: 7,
|
||||
shower_alert_coldshot: 10,
|
||||
rx_gpio: 23,
|
||||
tx_gpio: 5,
|
||||
phy_type: 0,
|
||||
|
||||
@@ -64,6 +64,14 @@
|
||||
#define EMSESP_DEFAULT_SHOWER_ALERT false
|
||||
#endif
|
||||
|
||||
#ifndef EMSESP_DEFAULT_SHOWER_ALERT_TRIGGER
|
||||
#define EMSESP_DEFAULT_SHOWER_ALERT_TRIGGER 7
|
||||
#endif
|
||||
|
||||
#ifndef EMSESP_DEFAULT_SHOWER_ALERT_COLDSHOT
|
||||
#define EMSESP_DEFAULT_SHOWER_ALERT_COLDSHOT 10
|
||||
#endif
|
||||
|
||||
#ifndef EMSESP_DEFAULT_HIDE_LED
|
||||
#define EMSESP_DEFAULT_HIDE_LED false
|
||||
#endif
|
||||
|
||||
@@ -26,6 +26,8 @@ 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
|
||||
});
|
||||
|
||||
set_shower_state(false, true); // turns shower to off and creates HA topic if not already done
|
||||
@@ -59,7 +61,7 @@ void Shower::loop() {
|
||||
LOG_DEBUG(F("[Shower] hot water still running, starting shower timer"));
|
||||
}
|
||||
// check if the shower has been on too long
|
||||
else if ((time_now - timer_start_) > SHOWER_MAX_DURATION) {
|
||||
else if ((time_now - timer_start_) > shower_alert_trigger_) {
|
||||
shower_alert_start();
|
||||
}
|
||||
}
|
||||
@@ -95,7 +97,7 @@ void Shower::loop() {
|
||||
|
||||
// at this point we're in the shower cold shot (doing_cold_shot_ == true)
|
||||
// keep repeating until the time is up
|
||||
if ((time_now - alert_timer_start_) > SHOWER_COLDSHOT_DURATION) {
|
||||
if ((time_now - alert_timer_start_) > shower_alert_coldshot_) {
|
||||
shower_alert_stop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +52,6 @@ class Shower {
|
||||
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_OFFSET_TIME = 5000; // in ms. 5 seconds grace time, to calibrate actual time under the 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_shower_data() const;
|
||||
void shower_alert_start();
|
||||
@@ -61,6 +59,8 @@ class Shower {
|
||||
|
||||
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
|
||||
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
|
||||
bool ha_configdone_ = false; // for HA MQTT Discovery
|
||||
bool shower_state_;
|
||||
uint32_t timer_start_; // ms
|
||||
|
||||
@@ -998,6 +998,10 @@ bool System::command_settings(const char * value, const int8_t id, JsonObject &
|
||||
|
||||
node["shower_timer"] = settings.shower_timer;
|
||||
node["shower_alert"] = settings.shower_alert;
|
||||
if (settings.shower_alert) {
|
||||
node["shower_alert_coldshot"] = settings.shower_alert_coldshot / 1000; // seconds
|
||||
node["shower_alert_trigger"] = settings.shower_alert_trigger / 60000; // minutes
|
||||
}
|
||||
|
||||
node["rx_gpio"] = settings.rx_gpio;
|
||||
node["tx_gpio"] = settings.tx_gpio;
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.4.0b14"
|
||||
#define EMSESP_APP_VERSION "3.4.0b15"
|
||||
|
||||
@@ -137,8 +137,9 @@ void WebDataService::sensor_data(AsyncWebServerRequest * request) {
|
||||
for (const auto & sensor : EMSESP::analogsensor_.sensors()) {
|
||||
// don't send if it's marked for removal
|
||||
if (sensor.type() != AnalogSensor::AnalogType::MARK_DELETED) {
|
||||
count++;
|
||||
JsonObject obj = analogs.createNestedObject();
|
||||
obj["id"] = Helpers::smallitoa(buffer, ++count); // needed for sorting table
|
||||
obj["id"] = Helpers::smallitoa(buffer, count); // needed for sorting table
|
||||
obj["g"] = sensor.gpio();
|
||||
obj["n"] = sensor.name();
|
||||
obj["u"] = sensor.uom();
|
||||
|
||||
@@ -48,6 +48,8 @@ void WebSettings::read(WebSettings & settings, JsonObject & root) {
|
||||
root["master_thermostat"] = settings.master_thermostat;
|
||||
root["shower_timer"] = settings.shower_timer;
|
||||
root["shower_alert"] = settings.shower_alert;
|
||||
root["shower_alert_coldshot"] = settings.shower_alert_coldshot;
|
||||
root["shower_alert_trigger"] = settings.shower_alert_trigger;
|
||||
root["rx_gpio"] = settings.rx_gpio;
|
||||
root["tx_gpio"] = settings.tx_gpio;
|
||||
root["dallas_gpio"] = settings.dallas_gpio;
|
||||
@@ -152,6 +154,12 @@ StateUpdateResult WebSettings::update(JsonObject & root, WebSettings & settings)
|
||||
prev = settings.shower_alert;
|
||||
settings.shower_alert = root["shower_alert"] | EMSESP_DEFAULT_SHOWER_ALERT;
|
||||
check_flag(prev, settings.shower_alert, ChangeFlags::SHOWER);
|
||||
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_alert_coldshot;
|
||||
settings.shower_alert_coldshot = root["shower_alert_coldshot"] | EMSESP_DEFAULT_SHOWER_ALERT_COLDSHOT;
|
||||
check_flag(prev, settings.shower_alert_coldshot, ChangeFlags::SHOWER);
|
||||
|
||||
// led
|
||||
prev = settings.led_gpio;
|
||||
|
||||
@@ -34,6 +34,8 @@ class WebSettings {
|
||||
uint8_t master_thermostat;
|
||||
bool shower_timer;
|
||||
bool shower_alert;
|
||||
uint8_t shower_alert_trigger;
|
||||
uint8_t shower_alert_coldshot;
|
||||
bool syslog_enabled;
|
||||
int8_t syslog_level; // uuid::log::Level
|
||||
uint32_t syslog_mark_interval;
|
||||
|
||||
Reference in New Issue
Block a user