diff options
-rw-r--r-- | kauf-plug.yaml | 367 |
1 files changed, 254 insertions, 113 deletions
diff --git a/kauf-plug.yaml b/kauf-plug.yaml index ee6e18f..c1daf04 100644 --- a/kauf-plug.yaml +++ b/kauf-plug.yaml @@ -2,8 +2,8 @@ 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 lines, and then overwrite these substitutions in your local - # yaml file by redefining them. + # 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://bkaufx/PLF10/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.90" + project_ver_num: "1.91" project_ver_let: y # https://esphome.io/components/switch/gpio.html?highlight=restore_mode @@ -31,7 +31,7 @@ substitutions: sub_on_release_quick: script_do_nothing # executes when button is released after being held under 750ms sub_on_release_short: script_do_nothing # executes when button is released after being held between 750ms and 5s # For a longer hold, see kauf-plug-update.yaml in the config-update directory. - # You have to start a time in the on_press script and cancel the timer in the on_release script. + # You have to start a timer in the on_press script and cancel the timer in the on_release script. # or if you wanted to require release, then start a counter on press and check the value on release. # If you want to have a hold action, you probably want to toggle on release_quick instead of on_press so that # you can perform the hold action without toggling the plug's relay. @@ -54,19 +54,21 @@ substitutions: voltage_cal_val2_in: "302.1" voltage_cal_val2_out: "117.1" - # set power monitoring mode in yaml, selecting the "yaml_configured" option in the select entity will cause these values - # to be used after next reboot. + # set power monitoring mode in yaml, selecting the "yaml_configured" option in the select entity will cause these + # values to be used after next reboot. # https://esphome.io/components/sensor/hlw8012.html#configuration-variables sub_change_mode_every: "1" sub_update_interval: 10s sub_initial_mode: CURRENT + # can be used to block status led from blinking + sub_blink_check: script_blink_check # https://esphome.io/components/esp8266.html esp8266: board: esp01_1m restore_from_flash: true - start_free: 62 + start_free: 74 global_addr: global_forced_addr @@ -94,9 +96,36 @@ esphome: on_boot: priority: 700 then: + # priority 700 ensures power monitoring mode variables are changed # in this script before HLW component is setup - - script.execute: script_set_monitor_mode + # hlw_main will already have the YAML configured values by default, so + # no need to handle that here. + - lambda: |- + + 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); } # https://esphome.io/components/external_components.html @@ -125,48 +154,30 @@ wifi: # https://esphome.io/components/logger.html -logger: # Enable logging - # baud_rate: 0 # Disable UART logging since TX pad not easily available +logger: # https://esphome.io/components/api.html -api: # Enable Home Assistant API +api: id: kauf_api - # password: !secret api_password # optional password field for Home Assistant API. # https://esphome.io/components/ota.html ota: - # password: !secret ota_password # optional password for OTA updates. on_error: then: - button.press: restart_button -# https://esphome.io/components/debug.html -debug: # outputs additional debug info when logs start - - # https://esphome.io/components/web_server.html -web_server: # web server allows access to device with a web browser +web_server: local: true - # auth: # optional login details for web interface - # username: admin - # password: !secret web_server_password - - -# red led, blink when not connected to WiFi or Home Assistant -# https://esphome.io/components/status_led.html -status_led: - pin: - number: GPIO0 - inverted: true # https://esphome.io/components/binary_sensor/index.html binary_sensor: - # button input toggles relay and thereby blue led + # button input toggles relay and thereby power led # https://esphome.io/components/binary_sensor/gpio.html - platform: gpio id: button_in @@ -177,7 +188,7 @@ binary_sensor: input: true pullup: true inverted: true - entity_category: '' + on_press: then: - script.execute: $sub_on_press @@ -203,6 +214,51 @@ binary_sensor: # 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(); + + // blue power status + if ( (id(select_bled).state == "Power Status") || (id(select_bled).state == "Error and Power") ) { + call.set_state(id(relay).state); + } + + // blue invert 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); + } + + call.perform(); + + + + call = id(red_led).make_call(); + + // red power status + if ( (id(select_rled).state == "Power Status") || (id(select_rled).state == "Error and Power") ) { + call.set_state(id(relay).state); + } + + // red invert power status + 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(); + + + + + ############################################################################ + # scripts for different things the button can do: # + # * toggle # + # * nothing # + ############################################################################ - id: script_toggle then: - if: @@ -210,51 +266,89 @@ script: lambda: return (id(select_button).state == "Enabled"); then: switch.toggle: relay + - id: script_do_nothing then: - lambda: return; - - id: script_no_hass + + + + ############################################################################ + # scripts for status led # + # * Blink LED - blinks led once. keeps calling itself as long as # + # warning/error exists # + # * Blink check - cancel blinking before it happens if desired # + # can be used to block blinking in specified conditions # + ############################################################################ + - id: blink_status_led + mode: queued then: - - delay: 1ms + + # allows the blinking to be blocked if desired by overwriting script substitution + # the script will need 'script.stop: blink_status_led' to stop status led + - script.execute: $sub_blink_check + - lambda: |- - if ( id(switch_no_hass).state ) { - id(kauf_api)->set_reboot_timeout(0); - id(kauf_api)->status_clear_warning(); + + // 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(); } - else { - id(kauf_api)->set_reboot_timeout(900000); + + // 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 - - id: script_set_monitor_mode - then: - lambda: |- - 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); + // 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(); + } - } 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); + // 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 - } 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); + - 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 - } 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); - } + - id: script_blink_check + then: + # - script.stop: blink_status_led # prevents status led from blinking. + - lambda: return; +# pwm outputs for LEDs so they can be dimmed # https://esphome.io/components/output/esp8266_pwm.html output: - platform: esp8266_pwm @@ -262,6 +356,11 @@ output: frequency: 1000 Hz pin: GPIO2 inverted: true + - platform: esp8266_pwm + id: red_led_pwm + frequency: 1000 Hz + pin: GPIO0 + inverted: true # https://esphome.io/components/light/index.html @@ -282,6 +381,21 @@ light: 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: @@ -298,32 +412,12 @@ switch: global_addr: global_forced_addr restore_mode: $sub_restore_mode - # automatically make blue led equal relay state - # don't turn LED on or off if disabled. on_turn_on: - - if: - condition: # only if blue LED enabled - lambda: return (id(select_led).state == "Enabled"); - then: - light.turn_on: blue_led - - if: - condition: # only if blue LED enabled - lambda: return (id(select_led).state == "Inverted"); - then: - light.turn_off: blue_led - + - script.execute: script_set_power_leds on_turn_off: - - if: - condition: # only if blue LED enabled - lambda: return (id(select_led).state == "Enabled"); - then: - light.turn_off: blue_led - - if: - condition: # only if blue LED enabled - lambda: return (id(select_led).state == "Inverted"); - then: - light.turn_on: blue_led - + - script.execute: script_set_power_leds + + # https://esphome.io/components/switch/template.html - platform: template id: switch_no_hass @@ -334,9 +428,11 @@ switch: disabled_by_default: $disable_entities icon: mdi:toggle-switch-off-outline on_turn_on: - - script.execute: script_no_hass + - 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 on_turn_off: - - script.execute: script_no_hass + - lambda: id(kauf_api)->set_reboot_timeout(900000); forced_hash: 657159011 forced_addr: 42 global_addr: global_forced_addr @@ -370,8 +466,8 @@ sensor: # Power monitoring sensors output to Home Assistant inverted: True cf_pin: GPIO5 cf1_pin: GPIO14 - current_resistor: $current_resistor_val # The value of the shunt resistor for current measurement. - voltage_divider: $voltage_divider_val # The value of the voltage divider on the board as (R_upstream + R_downstream) / R_downstream. + current_resistor: $current_resistor_val + voltage_divider: $voltage_divider_val change_mode_every: $sub_change_mode_every update_interval: $sub_update_interval @@ -386,8 +482,8 @@ sensor: # Power monitoring sensors output to Home Assistant - $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 - - if: + on_value: # set or clear in_use template binary sensor depending on + - if: # whether power usage is over threshold condition: lambda: return (x >= id(threshold).state); then: @@ -460,8 +556,8 @@ number: # used as a threshold for whether the plugged-in devices is running forced_hash: 3932521563 forced_addr: 4 global_addr: global_forced_addr - on_value: - - if: # set or clear in_use template binary sensor depending on whether power usage is above threshold + on_value: # set or clear in_use template binary sensor depending on + - if: # whether power usage is above threshold condition: lambda: return (id(wattage).state >= x); then: @@ -551,17 +647,19 @@ select: forced_addr: 34 global_addr: global_forced_addr - # option to disable blue LED - platform: template - name: $friendly_name LED - id: select_led + name: $friendly_name Blue LED + id: select_bled optimistic: true entity_category: config options: - - Enabled - - Disabled - - Inverted - initial_option: Enabled + - 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 @@ -569,19 +667,42 @@ select: global_addr: global_forced_addr on_value: - then: # changing to "disabled" will turn off LED, but then relay will not turn on or off LED. - - if: # when "Disabled", LED is initially turned off but then 100% controlled by light entity. - condition: - lambda: |- - if ( id(select_led).state == "Enabled" ) { return id(relay).state; } - else if ( id(select_led).state == "Inverted" ) { return !id(relay).state; } - else /* id(select_led).state == "Disabled" */ { return false; } - - then: - light.turn_on: blue_led - else: - light.turn_off: blue_led + then: + - 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 + 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 + + on_value: + then: + - 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 @@ -608,7 +729,7 @@ select: set_action: - delay: 1s - lambda: global_preferences->sync(); - - delay: 1s + - delay: 2s - button.press: restart_button @@ -621,6 +742,24 @@ text_sensor: disabled_by_default: $disable_entities +# emulate status_led +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 + + + # Current reserved flash memory: # 00-01: Power Monitoring Mode # 02-03: Relay output @@ -628,10 +767,12 @@ text_sensor: # 06-07: Total Daily Energy # 08-33: Wi-Fi Credentials # 34-35: Disable Button select entity -# 36-37: Disable LED select entity +# 36-37: Blue LED select entity +# 38-39: Red LED select 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 |