From 5135bcf81e401bc629b737eb74e8a44fd63528b3 Mon Sep 17 00:00:00 2001 From: KaufHA Date: Fri, 24 Jun 2022 15:52:30 -0700 Subject: move on_boot actions to entity automations --- .gitignore | 1 + kauf-plug-factory.yaml | 13 +-- kauf-plug-update.yaml | 12 +-- kauf-plug.yaml | 275 ++++++++++++++++++++++--------------------------- 4 files changed, 129 insertions(+), 172 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d218b6c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.esphome diff --git a/kauf-plug-factory.yaml b/kauf-plug-factory.yaml index b7cbee7..945a4af 100644 --- a/kauf-plug-factory.yaml +++ b/kauf-plug-factory.yaml @@ -1,17 +1,12 @@ substitutions: project_ver_let: "f" + packages: - kauf_plug_update: - url: https://github.com/KaufHA/PLF10 - files: kauf-plug-update.yaml - refresh: 0s + kauf_plug_update: !include kauf-plug-update.yaml esphome: - - - on_boot: then: @@ -78,9 +73,9 @@ esphome: - light.turn_on: blue_led - delay: 50ms - + globals: - - id: first_boot # used to run routine at factory to confirm + - id: first_boot # used to run routine at factory to confirm type: bool # correct firwmare is running. restore_value: yes initial_value: 'true' diff --git a/kauf-plug-update.yaml b/kauf-plug-update.yaml index 83977ee..30ed5a9 100644 --- a/kauf-plug-update.yaml +++ b/kauf-plug-update.yaml @@ -9,10 +9,7 @@ substitutions: packages: - kauf_plug_base: - url: https://github.com/KaufHA/PLF10 - files: kauf-plug.yaml - refresh: 0s + kauf_plug_base: !include kauf-plug.yaml dashboard_import: @@ -23,8 +20,8 @@ esphome: name_add_mac_suffix: true on_boot: then: - # implementing on_boot automation as a script makes it run in parallel with - # main on_boot script and any other on_boot scripts. + # implementing on_boot automation as a script makes it run in parallel + # with any other on_boot scripts. - script.execute: on_boot_wifi @@ -62,8 +59,6 @@ script: value: 'true' - script.execute: blink_led - delay: 10s - - # we have to restart because ESPHome's AP won't show the captive portal once wifi has been connected. - button.press: restart_button # blink LED forever. Used when button is held to re-enable AP. Stops blinking because plug restarts. @@ -73,7 +68,6 @@ script: - light.toggle: blue_led - delay: 333ms - script.execute: blink_led - # clear wifi credentials and reboot. causes AP to be enabled. - id: on_boot_wifi then: diff --git a/kauf-plug.yaml b/kauf-plug.yaml index bafd239..767056d 100644 --- a/kauf-plug.yaml +++ b/kauf-plug.yaml @@ -15,7 +15,7 @@ substitutions: # https://esphome.io/components/esphome.html#esphome-creators-project project_name: Kauf.PLF10 - project_ver_num: "1.964" + project_ver_num: "1.97" project_ver_let: y # https://esphome.io/components/switch/gpio.html?highlight=restore_mode @@ -90,6 +90,14 @@ globals: type: int restore_value: no initial_value: '0' + - id: global_has_debounce + type: boolean + restore_value: no + initial_value: "false" + - id: global_has_powermode + type: boolean + restore_value: no + initial_value: "false" # https://esphome.io/components/esphome.html#adjusting-flash-writes @@ -105,18 +113,13 @@ esphome: name: $project_name version: $project_ver_num($project_ver_let) - on_boot: - priority: 700 - then: - # implementing on_boot function as a script so that any other on_boot automations in other files - # will execute in parallel and not be blocked by this one. - - script.execute: on_boot_main # https://esphome.io/components/external_components.html external_components: - source: type: git url: https://github.com/KaufHA/common + ref: v2022.06.21 refresh: 0s @@ -146,8 +149,7 @@ api: # https://esphome.io/components/ota.html ota: on_error: - then: - - button.press: restart_button + - button.press: restart_button # https://esphome.io/components/web_server.html @@ -170,29 +172,27 @@ binary_sensor: pullup: true inverted: true on_press: - then: - - lambda: |- - // store time of press and clear duration sensor - id(global_press_time) = millis(); - id(sensor_press_duration).publish_state(0); - - // toggle if configured for toggle on press - if (id(select_button).state == "Toggle on Press") { - id(relay).toggle(); } - - script.execute: $sub_on_press - - script.execute: script_5s_timer + - lambda: |- + // store time of press and clear duration sensor + id(global_press_time) = millis(); + id(sensor_press_duration).publish_state(0); + + // toggle if configured for toggle on press + if (id(select_button).state == "Toggle on Press") { + id(relay).toggle(); } + - script.execute: $sub_on_press + - script.execute: script_5s_timer on_release: - then: - - lambda: |- - // set duration sensor - id(sensor_press_duration).publish_state(millis() - id(global_press_time) + id(number_debounce).state); - - // toggle if configured on release and toggle check script is not running. - if ( (id(select_button).state == "Toggle on Release") && !id($sub_toggle_check).is_running() ) { - id(relay).toggle(); - } - - script.execute: $sub_on_release - - script.stop: script_5s_timer + - lambda: |- + // set duration sensor + id(sensor_press_duration).publish_state(millis() - id(global_press_time) + id(number_debounce).state); + + // toggle if configured on release and toggle check script is not running. + if ( (id(select_button).state == "Toggle on Release") && !id($sub_toggle_check).is_running() ) { + id(relay).toggle(); + } + - script.execute: $sub_on_release + - script.stop: script_5s_timer # indicates whether plugged-in device is running based on configurable threshold. # https://esphome.io/components/binary_sensor/template.html @@ -288,10 +288,10 @@ script: else: - script.execute: script_set_power_leds # done with status LED, restore light power status - - id: script_new_debounce - mode: restart # only reboot plug once number is static for 10s. changing value again restarts timer. + - id: script_setting_reboot + mode: restart # only reboot plug settings are static for 10s. Another change restarts timer. then: - - lambda: ESP_LOGD("kauf-plug.yaml","New debounce value detected, rebooting in 10 seconds to effect change."); + - lambda: ESP_LOGD("kauf-plug.yaml","Setting change requiring reboot detected, rebooting in 10 seconds to effect change."); - delay: 10s - button.press: restart_button @@ -304,99 +304,6 @@ script: then: - lambda: return; - - id: on_boot_main - then: - - # this on_boot script has to execute after select and number entities are set up, so - # priority < 800. Adding a check here to make sure all needed entities are set up just - # in case another yaml file makes on_boot priority higher than 800 the following code - # will still work right. If on_boot priority becomes <= 600, the code for setting up - # power monitoring mode won't work because HLW will already be set up before values are - # changed in this script. - - wait_until: - lambda: return (id(select_monitor_mode).has_state() && - id(select_button_old).has_state() && - id(select_button).has_state() && - id(number_debounce).has_state() ); - - - lambda: |- - - ////////////////////////////////////////////////////////////////////// - // implement power monitoring mode per select entity - - if ( id(select_monitor_mode).state == "10s P / 40s V,I") { - id(hlw_main).set_update_interval(10000); - id(hlw_main).set_change_mode_every(1); } - - else if ( id(select_monitor_mode).state == "10s P,I Only" ) { - id(hlw_main).set_update_interval(10000); - id(hlw_main).set_change_mode_every(4294967295); - id(hlw_main).set_initial_mode(hlw8012::HLW8012_INITIAL_MODE_CURRENT); } - - else if ( id(select_monitor_mode).state == "10s P,V Only" ) { - id(hlw_main).set_update_interval(10000); - id(hlw_main).set_change_mode_every(4294967295); - id(hlw_main).set_initial_mode(hlw8012::HLW8012_INITIAL_MODE_VOLTAGE); } - - else if ( id(select_monitor_mode).state == " 2s P,I Only" ) { - id(hlw_main).set_update_interval(2000); - id(hlw_main).set_change_mode_every(4294967295); - id(hlw_main).set_initial_mode(hlw8012::HLW8012_INITIAL_MODE_CURRENT); } - - else if ( id(select_monitor_mode).state == " 2s P,V Only" ) { - id(hlw_main).set_update_interval(2000); - id(hlw_main).set_change_mode_every(4294967295); - id(hlw_main).set_initial_mode(hlw8012::HLW8012_INITIAL_MODE_VOLTAGE); } - - ////////////////////////////////////////////////////////////////////// - // Recover legacy button config if present, delete June 1, 2023. If - // you haven't updated in 1 year, you are going to lose your config, sorry. - - if ( id(select_button_old).state == "Didn't Restore" ) { - ESP_LOGD("Kauf Config Migration", "No legacy button configuration to migrate."); - } else { - ESP_LOGD("Kauf Config Migration", "Found legacy button configuration, migrating to new format."); - - // set button config select entity based on press/release/disabled - auto call_sel = id(select_button).make_call(); - if ( id(select_button_old).active_index() == 1 ) { call_sel.set_option("Don't Toggle"); } - else if ( id(select_button_old).active_index() >= 5 ) { call_sel.set_option("Toggle on Release"); } - else { call_sel.set_option("Toggle on Press"); } - call_sel.perform(); - - // set number_debounce if configured for longer than 100ms. - std::size_t found = id(select_button_old).state.find("250ms"); - if (found != std::string::npos) { - auto call_num = id(number_debounce).make_call(); - call_num.set_value(250); - call_num.perform(); } - found = id(select_button_old).state.find("1s"); - if (found != std::string::npos) { - auto call_num = id(number_debounce).make_call(); - call_num.set_value(1000); - call_num.perform(); } - - } - - // keep old format select entity from ever trying to save over the new one. - id(select_button_old).set_restore_value(false); - - // END SECTION TO DELETE JUNE 1, 2023 - ////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////// - // add a delayed_on filter to the button binary_sensor with time argument from number_debounce. - // this is placed after settings recovery so that it will take into account recovered setting - // on first boot. In any case, needs to be after priority 800 so that number_debounce is set up. - - binary_sensor::DelayedOnFilter *button_delayedonfilter; - button_delayedonfilter = new binary_sensor::DelayedOnFilter(id(number_debounce).state); - button_delayedonfilter->set_component_source("binary_sensor"); - App.register_component(button_delayedonfilter); - id(button_in).add_filters({button_delayedonfilter}); - - - # pwm outputs for LEDs so they can be dimmed # https://esphome.io/components/output/esp8266_pwm.html @@ -681,8 +588,19 @@ number: # used as a threshold for whether the plugged-in devices is running forced_hash: 2232959069 forced_addr: 40 global_addr: global_forced_addr - set_action: # currently, have to reboot plug to apply new delayed_on time - - script.execute: script_new_debounce + set_action: # currently rebooting plug to apply new delayed_on time + - script.execute: script_setting_reboot + on_value: + - lambda: |- + // add a delayed_on filter to the button binary_sensor with time argument from number_debounce. + if ( !id(global_has_debounce) ) { + binary_sensor::DelayedOnFilter *button_delayedonfilter; + button_delayedonfilter = new binary_sensor::DelayedOnFilter(id(number_debounce).state); + button_delayedonfilter->set_component_source("binary_sensor"); + App.register_component(button_delayedonfilter); + id(button_in).add_filters({button_delayedonfilter}); + id(global_has_debounce) = true; + } # https://esphome.io/components/select/index.html # https://esphome.io/components/select/template.html @@ -712,6 +630,39 @@ select: forced_hash: 3616613942 forced_addr: 34 global_addr: global_forced_addr + on_value: + - wait_until: # wait until new select entity is setup so set_option won't get overwritten with default value on setup + lambda: return ( id(select_button).has_state() ); + - lambda: |- + if ( x == "Didn't Restore" ) { + id(select_button_old).set_restore_value(false); // don't let old select save over new select + ESP_LOGD("Kauf Config Migration", "No legacy button configuration to migrate."); + } else { + ESP_LOGD("Kauf Config Migration", "Found legacy button configuration, migrating to new format."); + + // set button config select entity based on press/release/disabled + auto call_sel = id(select_button).make_call(); + if ( i == 1 ) { call_sel.set_option("Don't Toggle"); } + else if ( i >= 5 ) { call_sel.set_option("Toggle on Release"); } + else { call_sel.set_option("Toggle on Press"); } + call_sel.perform(); + + // set number_debounce if configured for longer than 100ms. + std::size_t found = x.find("250ms"); + if (found != std::string::npos) { + auto call_num = id(number_debounce).make_call(); + call_num.set_value(250); + call_num.perform(); } + found = x.find("1s"); + if (found != std::string::npos) { + auto call_num = id(number_debounce).make_call(); + call_num.set_value(1000); + call_num.perform(); } + + // go ahead and trigger a reboot on every config restoration + id(script_setting_reboot).execute(); + + } - platform: template name: $friendly_name Button Config @@ -748,13 +699,12 @@ select: forced_addr: 36 global_addr: global_forced_addr on_value: - then: - - if: - condition: - - lambda: return ( x == "Error Status" ); - then: - - light.turn_off: blue_led - - script.execute: script_set_power_leds + - if: + condition: + - lambda: return ( x == "Error Status" ); + then: + - light.turn_off: blue_led + - script.execute: script_set_power_leds - platform: template name: $friendly_name Red LED Config @@ -775,13 +725,12 @@ select: forced_addr: 38 global_addr: global_forced_addr on_value: - then: - - if: - condition: - - lambda: return ( x == "Error Status" ); - then: - - light.turn_off: red_led - - script.execute: script_set_power_leds + - if: + condition: + - lambda: return ( x == "Error Status" ); + then: + - light.turn_off: red_led + - script.execute: script_set_power_leds # change mode of power monitoring - platform: template @@ -808,7 +757,30 @@ select: - lambda: global_preferences->sync(); - delay: 2s - button.press: restart_button - + on_value: + - lambda: |- + if ( !id(global_has_powermode) ) { + if ( x == "10s P / 40s V,I") { + id(hlw_main).set_update_interval(10000); + id(hlw_main).set_change_mode_every(1); } + else if ( x == "10s P,I Only" ) { + id(hlw_main).set_update_interval(10000); + id(hlw_main).set_change_mode_every(4294967295); + id(hlw_main).set_initial_mode(hlw8012::HLW8012_INITIAL_MODE_CURRENT); } + else if ( x == "10s P,V Only" ) { + id(hlw_main).set_update_interval(10000); + id(hlw_main).set_change_mode_every(4294967295); + id(hlw_main).set_initial_mode(hlw8012::HLW8012_INITIAL_MODE_VOLTAGE); } + else if ( x == " 2s P,I Only" ) { + id(hlw_main).set_update_interval(2000); + id(hlw_main).set_change_mode_every(4294967295); + id(hlw_main).set_initial_mode(hlw8012::HLW8012_INITIAL_MODE_CURRENT); } + else if ( x == " 2s P,V Only" ) { + id(hlw_main).set_update_interval(2000); + id(hlw_main).set_change_mode_every(4294967295); + id(hlw_main).set_initial_mode(hlw8012::HLW8012_INITIAL_MODE_VOLTAGE); } + id(global_has_powermode) = true; + } # Send IP Address to HA # https://esphome.io/components/text_sensor/wifi_info.html @@ -824,16 +796,11 @@ text_sensor: interval: - interval: 5s then: - - if: - condition: - - lambda: return ( ( (App.get_app_state() & STATUS_LED_ERROR) != 0u) || ((App.get_app_state() & STATUS_LED_WARNING) != 0u) ); - then: - - if: - condition: - not: - - script.is_running: blink_status_led - then: - - script.execute: blink_status_led + - lambda: |- + if ( ( ((App.get_app_state() & STATUS_LED_ERROR ) != 0u) || + ((App.get_app_state() & STATUS_LED_WARNING) != 0u) ) + && !id(blink_status_led).is_running() ) + id(blink_status_led).execute(); # Current reserved flash memory: -- cgit v1.2.3