diff options
-rw-r--r-- | test-yamls/.gitignore | 5 | ||||
-rw-r--r-- | test-yamls/kauf-plug-no-webserver.yaml | 972 |
2 files changed, 977 insertions, 0 deletions
diff --git a/test-yamls/.gitignore b/test-yamls/.gitignore new file mode 100644 index 0000000..d8b4157 --- /dev/null +++ b/test-yamls/.gitignore @@ -0,0 +1,5 @@ +# Gitignore settings for ESPHome +# This is an example and may include too much for your use-case. +# You can modify this file to suit your needs. +/.esphome/ +/secrets.yaml diff --git a/test-yamls/kauf-plug-no-webserver.yaml b/test-yamls/kauf-plug-no-webserver.yaml new file mode 100644 index 0000000..2795f17 --- /dev/null +++ b/test-yamls/kauf-plug-no-webserver.yaml @@ -0,0 +1,972 @@ +# https://esphome.io/guides/configuration-types.html#substitutions +substitutions: + + # substitutions can be changed here if you are using this file directly in the ESPHome dashboard. The better approach is + # to incorporate this file as a package using the following packages: configuration, and then overwrite these substitutions + # in your local yaml file by redefining them. + # + # packages: + # kauf.plf10: github://KaufHA/PLF10/kauf-plug.yaml + # + + name: kauf-plug # **** CHANGE DEVICE NAME TO SOMETHING UNIQUE PER DEVICE. RENAME YAML FILE TO SAME NAME. **** + # **** USE DASHES (-) INSTEAD OF SPACES OR UNDERSCORE (_). USE ONLY LOWER CASE LETTERS. **** + friendly_name: Kauf Plug # **** CHANGE FRIENDLY NAME TO SOMETHING UNIQUE PER DEVICE **** + + # https://esphome.io/components/esphome.html#esphome-creators-project + project_name: Kauf.PLF10 + project_ver_num: "2.02" + project_ver_let: y + + # https://esphome.io/components/switch/gpio.html?highlight=restore_mode + sub_restore_mode: RESTORE_DEFAULT_ON # overwrite to change boot up behavior of relay + + disable_entities: "true" # set to "false" to have all entities show up in Home Assistant automatically + disable_webserver: "false" # set to "true" to disable the webserver listening on port 80. + + # substitutions for button actions. on_press and on_release implement a timer scheme with configurable delay. + # on_hold_30s re-enables the AP and captive portal for the precompiled update binary. + # any length of hold can be implemented with just on_press and on_release using the following directions. This + # is basically how this yaml file works. + # * have a delay for the desired hold in the on_press script + # * stop the on_press script in the on_release script + # * place actions in the on_press script after the delay to perform them while still holding the button + # * place actions in the on_release script, with the condition that the on_press script is not running, to + # perform them on release of the button. + sub_on_press: script_do_nothing # executes right when button is initially pressed + sub_on_release: script_do_nothing # executes right when button is released + sub_on_hold_30s: script_force_ap # executes right when button has been held for 5s, while button is still being held + + sub_on_turn_on: script_do_nothing + sub_on_turn_off: script_do_nothing + + # an extra script that, if running, will stop the relay from toggling on button release. + # used to not toggle when WiFi AP is re-enabled on update bin file. + sub_toggle_check: script_force_ap + + # made this a substitution so that the update bin file and yaml compiled versions can have different defaults + default_button_config: "Toggle on Press" + + # substitutions for power monitoring calibration. Allows end users to change calibration in their yaml and still + # incorporate this file as a package to get all the updates we release. + current_resistor_val: "0.001" + voltage_divider_val: "2401" + sub_hlw_model: HLW8012 + power_cal_val1_in: "0.0" + power_cal_val1_out: "0.0" + power_cal_val2_in: "333.8" + power_cal_val2_out: "60" + current_cal_val1_in: "0.0" + current_cal_val1_out: "0.0" + current_cal_val2_in: "0.6" + current_cal_val2_out: "0.515" + voltage_cal_val1_in: "0.0" + voltage_cal_val1_out: "0.0" + voltage_cal_val2_in: "302.1" + voltage_cal_val2_out: "117.1" + + # set default power monitoring update interval in yaml. + # this will only be effective as long as the select entity is set to "YAML Configured" + sub_update_interval: 10s + sub_pm_initial_option: YAML Configured ($sub_update_interval) + + # GPIO definitions + sub_pm_sel_pin: GPIO12 + sub_pm_cf_pin: GPIO5 + sub_pm_cf1_pin: GPIO14 + sub_button_pin: GPIO13 + sub_blue_led_pin: GPIO2 + sub_red_led_pin: GPIO0 + sub_relay_pin: GPIO4 + + # debounce specifications + sub_default_debounce: "100" + sub_min_debounce: "50" + + +# https://esphome.io/components/esp8266.html +esp8266: + board: esp01_1m + restore_from_flash: true + early_pin_init: false + start_free: 76 + global_addr: global_forced_addr + + +# https://esphome.io/guides/automations.html#global-variables +globals: + - id: global_forced_addr + type: int + restore_value: no + initial_value: '12345' + - id: global_press_time + type: int + restore_value: no + initial_value: '0' + - id: global_has_debounce + type: boolean + restore_value: no + initial_value: "false" + + +# https://esphome.io/components/esphome.html#adjusting-flash-writes +preferences: + # setting interval to 5 minutes since this defines writing total daily energy to flash, which will occur + # every interval length 24/7/365. Created a specific save script that is executed for things that need + # to save more quickly. + flash_write_interval: 5min + + +# https://esphome.io/components/esphome.html +esphome: + name: $name + + project: + name: $project_name + version: $project_ver_num($project_ver_let) + + on_boot: + then: + # implementing on_boot automation as a script makes it run in parallel + # with any other on_boot scripts. + - script.execute: script_set_power_leds + - script.execute: on_wifi_connect + + +# https://esphome.io/components/external_components.html +external_components: + - source: + type: git + url: https://github.com/KaufHA/common + ref: v2022.12.07.2 + refresh: 365250d + components: [esp8266, gpio, kauf_hlw8012, light, monochromatic, ota, switch, template, total_daily_energy, wifi] + +# https://esphome.io/components/wifi.html +wifi: + + # **** ENTER WI-FI CREDENTIALS HERE, USING SECRETS.YAML RECOMMENDED **** + ssid: initial_ap # !secret wifi_ssid + password: asdfasdfasdfasdf # !secret wifi_password + + # using fast_connect as default since it is required for hidden networks. + fast_connect: true + + # enable wifi ap with ridiculous timeout so it does not normally turn on. + ap: + ap_timeout: 2147483647ms # maximum 32 bit value. About 3.5 weeks in milliseconds. + + forced_addr: 8 + global_addr: global_forced_addr + + +# https://esphome.io/components/captive_portal.html +# captive_portal: + + +# https://esphome.io/components/logger.html +logger: + + +# https://esphome.io/components/api.html +api: + id: kauf_api + + +# https://esphome.io/components/ota.html +ota: + on_error: + - button.press: restart_button + + +# https://esphome.io/components/web_server.html +# web_server: +# local: true +# disable: $disable_webserver + + +# https://esphome.io/components/binary_sensor/index.html +binary_sensor: + + # button input toggles relay and thereby power led + # https://esphome.io/components/binary_sensor/gpio.html + - platform: gpio + id: button_in + name: $friendly_name Button + pin: + number: $sub_button_pin + mode: + input: true + pullup: true + inverted: true + on_press: + - 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_30s_timer + on_release: + - 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_30s_timer + + # indicates whether plugged-in device is running based on configurable threshold. + # https://esphome.io/components/binary_sensor/template.html + - platform: template + id: in_use + name: ${friendly_name} Device In Use + + +# https://esphome.io/guides/automations.html#script-component +script: + + # sets LEDs to proper state based on LED configuration and relay state + - id: script_set_power_leds + then: + - lambda: |- + auto call = id(blue_led).make_call(); + + // if blue led follows power status + if ( (id(select_bled).state == "Power Status") || (id(select_bled).state == "Error and Power") ) { + call.set_state(id(relay).state); + } + + // if blue led follows inverse of power status + else if ( (id(select_bled).state == "Invert Power Status") || (id(select_bled).state == "Error and Invert Power") ) { + call.set_state(!id(relay).state); + } + + // if blue led is set to not change on power status (error only or disabled), performing an empty call does nothing. + call.perform(); + + // same as blue but for red led + call = id(red_led).make_call(); + if ( (id(select_rled).state == "Power Status") || (id(select_rled).state == "Error and Power") ) { + call.set_state(id(relay).state); } + else if ( (id(select_rled).state == "Invert Power Status") || (id(select_rled).state == "Error and Invert Power") ) { + call.set_state(!id(relay).state); } + call.perform(); + + - script.execute: script_save_changes + + - id: blink_status_led + mode: queued + then: + + - lambda: |- + // turn on blue LED if configured for error status + if ( (id(select_bled).state == "Error Status") || + (id(select_bled).state == "Error and Power") || + (id(select_bled).state == "Error and Invert Power") ) { + auto call = id(blue_led).turn_on(); + call.set_save(false); + call.perform(); + } + + // turn on red LED if configured for error status + if ( (id(select_rled).state == "Error Status") || + (id(select_rled).state == "Error and Power") || + (id(select_rled).state == "Error and Invert Power") ) { + auto call = id(red_led).turn_on(); + call.set_save(false); + call.perform(); + } + + - delay: 350ms + + - lambda: |- + // turn off blue LED if configured for error status + if ( (id(select_bled).state == "Error Status") || + (id(select_bled).state == "Error and Power") || + (id(select_bled).state == "Error and Invert Power") ) { + auto call = id(blue_led).turn_off(); + call.set_save(false); + call.perform(); + } + + // turn off red LED if configured for error status + if ( (id(select_rled).state == "Error Status") || + (id(select_rled).state == "Error and Power") || + (id(select_rled).state == "Error and Invert Power") ) { + auto call = id(red_led).turn_off(); + call.set_save(false); + call.perform(); + } + + - delay: 1150ms + + - if: + condition: + - lambda: return ( ( (App.get_app_state() & STATUS_LED_ERROR) != 0u) || ((App.get_app_state() & STATUS_LED_WARNING) != 0u) ); + then: + - script.execute: blink_status_led # repeat as long as error/warning exists + else: + - script.execute: script_set_power_leds # done with status LED, restore light power status + + - id: script_setting_reboot + mode: restart # only reboot plug settings are static for 10s. Another change restarts timer. + then: + - lambda: ESP_LOGCONFIG("kauf-plug.yaml","Setting change requiring reboot detected, rebooting in 10 seconds to effect change."); + - delay: 10s + - button.press: restart_button + + - id: script_30s_timer + then: + - delay: !lambda return (30000-id(number_debounce).state); + - script.execute: $sub_on_hold_30s + + - id: on_wifi_connect + then: + + # wait until wifi connects + - wait_until: wifi.connected + + - lambda: |- + ESP_LOGD("KAUF on_boot","------------------->>>>>>>>>>>>>>>>> wifi connected, cranking ap timeout back up"); + wifi_wificomponent->set_ap_timeout(2147483647); + + - id: script_force_ap + then: + - logger.log: "------------------->>>>>>>>>>>>>>>>> HELD BUTTON 30 SECONDS, FORCING AP" + + # overwrite software defined credentials to force ap to turn on. + - lambda: wifi::global_wifi_component->save_wifi_sta("initial_ap","asdfasdfasdfasdf"); + + # blink LED for 10s then restart to get captive portal to turn on. + - script.execute: blink_led + - delay: 10s + - button.press: restart_button + + # blink LED forever. Used when button is held to re-enable AP. Stops blinking because plug restarts. + - id: blink_led + mode: queued + then: + - light.toggle: blue_led + - delay: 333ms + - script.execute: blink_led + + - id: script_do_nothing + then: + - lambda: return; + + - id: script_save_changes + mode: restart + then: + - delay: 3s + - lambda: global_preferences->sync(); + + +# pwm outputs for LEDs so they can be dimmed +# https://esphome.io/components/output/esp8266_pwm.html +output: + - platform: esp8266_pwm + id: blue_led_pwm + frequency: 200 Hz + pin: $sub_blue_led_pin + inverted: true + - platform: esp8266_pwm + id: red_led_pwm + frequency: 200 Hz + pin: $sub_red_led_pin + inverted: true + + +# light entities for blue and red LEDs +# https://esphome.io/components/light/index.html +# https://esphome.io/components/light/monochromatic.html +light: + - platform: monochromatic + name: $friendly_name Blue LED + id: blue_led + output: blue_led_pwm + entity_category: config + default_transition_length: 0s + forced_hash: 3831461887 + forced_addr: 44 + global_addr: global_forced_addr + effects: + - flicker: + name: Flicker + alpha: 90% + intensity: 10% + + - platform: monochromatic + name: $friendly_name Red LED + id: red_led + output: red_led_pwm + entity_category: config + default_transition_length: 0s + forced_hash: 261191305 + forced_addr: 62 + global_addr: global_forced_addr + effects: + - flicker: + name: Flicker + alpha: 90% + intensity: 10% + + +# https://esphome.io/components/switch/index.html +switch: + + # relay output + # https://esphome.io/components/switch/gpio.html + - platform: gpio + id: relay + name: $friendly_name + pin: $sub_relay_pin + entity_category: '' + forced_hash: 41191675 + forced_addr: 2 + global_addr: global_forced_addr + restore_mode: $sub_restore_mode + on_turn_on: + - script.execute: script_save_changes + - script.execute: script_set_power_leds + - script.execute: $sub_on_turn_on + on_turn_off: + - script.execute: script_save_changes + - script.execute: script_set_power_leds + - script.execute: $sub_on_turn_off + + # https://esphome.io/components/switch/template.html + - platform: template + id: switch_no_hass + name: $friendly_name No HASS + optimistic: true + restore_state: true + entity_category: config + disabled_by_default: $disable_entities + icon: mdi:toggle-switch-off-outline + on_turn_on: + - lambda: |- + id(kauf_api).set_reboot_timeout(0); // 0 disables auto rebooting and also new status led blinking. doesn't stop current status led blinking + id(kauf_api).status_clear_warning(); // stops current status led blinking, timeout 0 keeps it from restarting + - script.execute: script_save_changes + on_turn_off: + - lambda: id(kauf_api).set_reboot_timeout(900000); + - script.execute: script_save_changes + forced_hash: 657159011 + forced_addr: 42 + global_addr: global_forced_addr + + +# https://esphome.io/components/button/index.html +# https://esphome.io/components/button/restart.html +button: + - platform: restart + id: restart_button + name: $friendly_name Restart Firmware + entity_category: diagnostic + disabled_by_default: $disable_entities + + +# clock input from Home Assistant used to calculate total daily energy +# https://esphome.io/components/time.html#home-assistant-time-source +time: + - platform: homeassistant + id: homeassistant_time + + +# https://esphome.io/components/sensor/index.html +sensor: # Power monitoring sensors output to Home Assistant + + # https://esphome.io/components/sensor/hlw8012.html + - platform: kauf_hlw8012 + id: hlw_main + sel_pin: + number: $sub_pm_sel_pin + inverted: True + cf_pin: $sub_pm_cf_pin + cf1_pin: $sub_pm_cf1_pin + current_resistor: $current_resistor_val + voltage_divider: $voltage_divider_val + + update_interval: $sub_update_interval + + model: $sub_hlw_model + + power: + name: ${friendly_name} Power + unit_of_measurement: W + id: wattage + filters: + - calibrate_linear: + - $power_cal_val1_in -> $power_cal_val1_out + - $power_cal_val2_in -> $power_cal_val2_out + - lambda: return x * id(scale_power).state/100.0f; + on_value: # set or clear in_use template binary sensor depending on whether power usage is over threshold + - lambda: id(in_use).publish_state(x >= id(threshold).state); + + current: + name: ${friendly_name} Current + unit_of_measurement: A + id: current + filters: + - calibrate_linear: + - $current_cal_val1_in -> $current_cal_val1_out + - $current_cal_val2_in -> $current_cal_val2_out + - lambda: return x * id(scale_current).state/100.0f; + + voltage: + name: ${friendly_name} Voltage + unit_of_measurement: V + id: voltage + filters: + - calibrate_linear: + - $voltage_cal_val1_in -> $voltage_cal_val1_out + - $voltage_cal_val2_in -> $voltage_cal_val2_out + - lambda: return x * id(scale_voltage).state/100.0f; + + # Reports the total Power so-far each day, resets at midnight + # https://esphome.io/components/sensor/total_daily_energy.html + - platform: total_daily_energy + name: ${friendly_name} Total Daily Energy + power_id: wattage + filters: + - multiply: 0.001 ## convert Wh to kWh + unit_of_measurement: kWh + forced_hash: 1903527169 + forced_addr: 6 + global_addr: global_forced_addr + + # https://esphome.io/components/sensor/uptime.html + - platform: uptime + name: $friendly_name Uptime + update_interval: 60s + entity_category: diagnostic + disabled_by_default: $disable_entities + + # https://esphome.io/components/sensor/template.html + - platform: template + name: $friendly_name Button Press Duration + id: sensor_press_duration + entity_category: diagnostic + disabled_by_default: $disable_entities + unit_of_measurement: ms + icon: mdi:timer-outline + + +# https://esphome.io/components/number/index.html +# https://esphome.io/components/number/template.html +number: # used as a threshold for whether the plugged-in devices is running. + - platform: template + name: ${friendly_name} Use Threshold + min_value: 1 + max_value: 100 + step: 1 + initial_value: 3 + id: threshold + entity_category: config + optimistic: true + restore_value: true + unit_of_measurement: Watt(s) + mode: box + disabled_by_default: $disable_entities + forced_hash: 3932521563 + forced_addr: 4 + global_addr: global_forced_addr + set_action: + - script.execute: script_save_changes + on_value: # set or clear in_use template binary sensor depending on whether power usage is above threshold + - lambda: id(in_use).publish_state(id(wattage).state >= x); + + - platform: template + name: ${friendly_name} Scale Power + min_value: 50 + max_value: 200 + step: .1 + initial_value: 100 + id: scale_power + entity_category: config + optimistic: true + restore_value: true + unit_of_measurement: "%" + mode: box + disabled_by_default: $disable_entities + forced_hash: 3565176138 + forced_addr: 56 + global_addr: global_forced_addr + set_action: + - script.execute: script_save_changes + on_value: # republish value. Sensor automation applies new scaling factor. + - lambda: id(wattage).publish_state(id(wattage).get_raw_state()); + + - platform: template + name: ${friendly_name} Scale Current + min_value: 50 + max_value: 200 + step: .1 + initial_value: 100 + id: scale_current + entity_category: config + optimistic: true + restore_value: true + unit_of_measurement: "%" + mode: box + disabled_by_default: $disable_entities + forced_hash: 2293595686 + forced_addr: 58 + global_addr: global_forced_addr + set_action: + - script.execute: script_save_changes + on_value: # republish value. Sensor automation applies new scaling factor. + - lambda: id(current).publish_state(id(current).get_raw_state()); + + - platform: template + name: ${friendly_name} Scale Voltage + min_value: 50 + max_value: 200 + step: .1 + initial_value: 100 + id: scale_voltage + entity_category: config + optimistic: true + restore_value: true + unit_of_measurement: "%" + mode: box + disabled_by_default: $disable_entities + forced_hash: 254525215 + forced_addr: 60 + global_addr: global_forced_addr + set_action: + - script.execute: script_save_changes + on_value: # republish value. Sensor automation applies new scaling factor. + - lambda: id(voltage).publish_state(id(voltage).get_raw_state()); + + - platform: template + name: ${friendly_name} Debounce Time + min_value: $sub_min_debounce + max_value: 2000 + step: 1 + initial_value: $sub_default_debounce + id: number_debounce + entity_category: config + optimistic: true + restore_value: true + unit_of_measurement: "ms" + mode: box + disabled_by_default: $disable_entities + forced_hash: 2232959069 + forced_addr: 40 + global_addr: global_forced_addr + set_action: # currently rebooting plug to apply new delayed_on time + - script.execute: script_save_changes + - 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 +select: + + # legacy select button configuration; remove June 1, 2023 + # removed name, so won't show up in UI. This is kept so that previous + # setting can be migrated to new select entities. + # new entity is saved at same address with incremented hash so once the new + # one is saved, this one won't be loaded next time. + - platform: template + id: select_button_old + optimistic: true + options: + - Toggle if Pressed For 20ms + - Disable Button + - Toggle if Pressed For 100ms + - Toggle if Pressed For 250ms + - Toggle if Pressed For 1s + - Toggle if Released After 20ms + - Toggle if Released After 100ms + - Toggle if Released After 250ms + - Toggle if Released After 1s + - Didn't Restore + initial_option: Didn't Restore + restore_value: true + 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_save_changes).execute(); + id(script_setting_reboot).execute(); + + } + + - platform: template + name: $friendly_name Button Config + id: select_button + optimistic: true + options: + - Toggle on Press + - Toggle on Release + - Don't Toggle + initial_option: $default_button_config + restore_value: true + icon: mdi:circle-double + entity_category: config + forced_hash: 3616613943 + forced_addr: 34 + global_addr: global_forced_addr + set_action: + - script.execute: script_save_changes + + - platform: template + name: $friendly_name Blue LED Config + id: select_bled + optimistic: true + entity_category: config + options: + - Power Status + - No Automation + - Invert Power Status + - Error Status + - Error and Power + - Error and Invert Power + initial_option: Power Status + restore_value: true + icon: mdi:led-on + forced_hash: 3104663617 + forced_addr: 36 + global_addr: global_forced_addr + set_action: + - script.execute: script_save_changes + on_value: + - 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 + id: select_rled + optimistic: true + entity_category: config + options: + - Power Status + - No Automation + - Invert Power Status + - Error Status + - Error and Power + - Error and Invert Power + initial_option: Error Status + restore_value: true + icon: mdi:led-on + forced_hash: 261191305 + forced_addr: 38 + global_addr: global_forced_addr + set_action: + - script.execute: script_save_changes + on_value: + - if: + condition: + - lambda: return ( x == "Error Status" ); + then: + - light.turn_off: red_led + - script.execute: script_set_power_leds + + # legacy select monitor mode configuration; remove December 1, 2023 + # removed name, so won't show up in UI. This is kept so that previous + # setting can be migrated to new select entities. + # new entity is saved at same address with incremented hash so once the new + # one is saved, this one won't be loaded next time. + - platform: template + id: select_monitor_mode_old + optimistic: true + options: + - "10s P / 20s V,I" + - "10s P,I Only" + - "10s P,V Only" + - " 2s P,I Only" + - " 2s P,V Only" + - "YAML Configured" + - " 2s P / 4s V,I" + - "Didn't Restore" + initial_option: "Didn't Restore" + restore_value: true + icon: mdi:wrench-clock + entity_category: config + disabled_by_default: $disable_entities + forced_hash: 1025003090 + forced_addr: 0 + global_addr: global_forced_addr + set_action: + - script.execute: script_save_changes + - script.execute: script_setting_reboot + on_value: + - wait_until: # wait until new select entity is setup so it won't get overwritten with default value on setup + lambda: return ( id(select_monitor_interval).has_state() ); + - lambda: |- + if ( x == "Didn't Restore" ) { + id(select_monitor_mode_old).set_restore_value(false); // don't let old select save over new select + ESP_LOGD("Kauf Config Migration", "No legacy monitor mode configuration to migrate."); + } else { + ESP_LOGD("Kauf Config Migration", "Found legacy monitor mode configuration, migrating to new format."); + + // set monitor mode config select entity. 10s is default so just need to + auto call_sel = id(select_monitor_interval).make_call(); + if ( str_startswith(x,"10s") ) { call_sel.set_option("10s"); } + else if ( str_startswith(x," 2s") ) { call_sel.set_option("2s"); } + else { call_sel.set_option("YAML Configured"); } + call_sel.perform(); + + // go ahead and trigger a reboot on every config restoration + id(script_save_changes).execute(); + id(script_setting_reboot).execute(); + } + + # change update interval for power monitoring sensors + - platform: template + name: $friendly_name Monitoring Update Interval + id: select_monitor_interval + optimistic: true + options: + - 60s + - 30s + - 10s + - 5s + - 2s + - YAML Configured ($sub_update_interval) + initial_option: $sub_pm_initial_option + restore_value: true + icon: mdi:wrench-clock + entity_category: config + disabled_by_default: $disable_entities + forced_hash: 1025003091 + forced_addr: 0 + global_addr: global_forced_addr + set_action: + - script.execute: script_save_changes + - script.execute: script_setting_reboot + on_value: + - lambda: |- + if ( x == "60s" ) { id(hlw_main).set_update_interval(60000); } + else if ( x == "30s" ) { id(hlw_main).set_update_interval(30000); } + else if ( x == "10s" ) { id(hlw_main).set_update_interval(10000); } + else if ( x == "5s" ) { id(hlw_main).set_update_interval(5000); } + else if ( x == "2s" ) { id(hlw_main).set_update_interval(2000); } + + - platform: template + name: $friendly_name Boot State + id: select_boot_state + optimistic: true + options: + - "Restore Power Off State" + - "Invert Power Off State" + - "Always On" + - "Always Off" + - "YAML Configured ($sub_restore_mode)" + initial_option: "Restore Power Off State" + restore_value: true + icon: mdi:restart-alert + entity_category: config + forced_hash: 2390278151 + forced_addr: 74 + global_addr: global_forced_addr + on_value: + - lambda: |- + if ( x == "Restore Power Off State") + relay->set_restore_mode(SWITCH_RESTORE_DEFAULT_OFF); + else if ( x == "Invert Power Off State") + relay->set_restore_mode(SWITCH_RESTORE_INVERTED_DEFAULT_OFF); + else if ( x == "Always On") + relay->set_restore_mode(SWITCH_ALWAYS_ON); + else if ( x == "Always Off") + relay->set_restore_mode(SWITCH_ALWAYS_OFF); + else + relay->set_restore_mode(SWITCH_$sub_restore_mode); + + // republish state so it gets saved if necessary + // but make sure relay already set up, don't want to publish here on boot + if ( id(relay).is_setup() ) id(relay).publish_state(id(relay).state, true); + + - script.execute: script_save_changes + + +# Send IP Address to HA +# https://esphome.io/components/text_sensor/wifi_info.html +text_sensor: + - platform: wifi_info + ip_address: + name: $friendly_name IP Address + disabled_by_default: $disable_entities + + +# emulate status_led +# https://esphome.io/guides/automations.html#interval-component +interval: + - interval: 5s + then: + - 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: +# 00-01: Power Monitoring Mode +# 02-03: Relay output +# 04-05: Use Threshold +# 06-07: Total Daily Energy +# 08-33: Wi-Fi Credentials +# 34-35: Button Config select entity +# 36-37: Blue LED select entity +# 38-39: Red LED select entity +# 40-41: Debounce number entity +# 42-43: No HASS switch +# 44-55: Blue LED light entity +# 56-57: Scale Power +# 58-59: Scale Current +# 60-61: Scale Voltage +# 62-73: Red LED light entity +# 74-75: Boot State select entity |