diff options
-rw-r--r-- | kauf-plug-lite.yaml | 418 |
1 files changed, 295 insertions, 123 deletions
diff --git a/kauf-plug-lite.yaml b/kauf-plug-lite.yaml index a0e7949..e616915 100644 --- a/kauf-plug-lite.yaml +++ b/kauf-plug-lite.yaml @@ -1,11 +1,26 @@ +# 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://bkaufx/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: "1.91" + project_ver_let: l + # https://esphome.io/components/switch/gpio.html?highlight=restore_mode sub_restore_mode: RESTORE_DEFAULT_OFF # overwrite to change boot up behavior of relay + disable_entities: "true" # set to "false" to have all entities show up in Home Assistant automatically @@ -16,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. @@ -39,52 +54,77 @@ substitutions: voltage_cal_val2_in: "302.1" voltage_cal_val2_out: "117.1" - # set power monitoring mode in yaml https://esphome.io/components/sensor/hlw8012.html#configuration-variables + # 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 -esp8266: # https://esphome.io/components/esp8266.html +# https://esphome.io/components/esp8266.html +esp8266: board: esp01_1m restore_from_flash: true +# https://esphome.io/components/esphome.html#adjusting-flash-writes preferences: flash_write_interval: 3s +# https://esphome.io/components/esphome.html esphome: name: $name + project: - name: "Kauf.PLF10" - version: "1.90(l)" + name: $project_name + version: $project_ver_num($project_ver_let) 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/wifi.html wifi: # **** ENTER WI-FI CREDENTIALS HERE, USING SECRETS.YAML RECOMMENDED **** ssid: initial_ap # !secret wifi_ssid password: asdfasdfasdfasdf # !secret wifi_password - # Uncomment below to set a static IP - # manual_ip: - # static_ip: !secret kauf_bulb_rgb_ip_address - # gateway: !secret wifi_gateway - # subnet: !secret wifi_subnet - # dns1: !secret wifi_dns1 - - # use_address allows wireless programming through dashboard. - # Set to the bulb's IP Address. Remove after programming. - # use_address: 192.168.86.244 - # default is 20, 17 is recommended. output_power: 17 @@ -92,42 +132,32 @@ wifi: fast_connect: true -logger: # Enable logging - # baud_rate: 0 # Disable UART logging since TX pad not easily available +# https://esphome.io/components/logger.html +logger: -api: # Enable Home Assistant API +# https://esphome.io/components/api.html +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 -debug: # outputs additional debug info when logs start - - -web_server: # web server allows access to device with a web browser +# https://esphome.io/components/web_server.html +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 -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 name: $friendly_name Button @@ -137,7 +167,7 @@ binary_sensor: input: true pullup: true inverted: true - entity_category: '' + on_press: then: - script.execute: $sub_on_press @@ -155,12 +185,59 @@ binary_sensor: - script.execute: $sub_on_release_short # 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(); + + // 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: @@ -168,59 +245,105 @@ 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 id: blue_led_pwm 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 +# https://esphome.io/components/light/monochromatic.html light: - platform: monochromatic name: $friendly_name Blue LED @@ -234,9 +357,24 @@ 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 + effects: + - flicker: + name: Flicker + alpha: 90% + intensity: 10% + + +# https://esphome.io/components/switch/index.html switch: -# relay output + # relay output + # https://esphome.io/components/switch/gpio.html - platform: gpio id: relay name: $friendly_name @@ -244,32 +382,13 @@ switch: entity_category: '' 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 name: $friendly_name No HASS @@ -279,11 +398,15 @@ 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); +# https://esphome.io/components/button/index.html +# https://esphome.io/components/button/restart.html button: - platform: restart id: restart_button @@ -293,12 +416,16 @@ button: # 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: hlw8012 id: hlw_main sel_pin: @@ -306,8 +433,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 @@ -322,8 +449,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: @@ -356,8 +483,8 @@ sensor: # Power monitoring sensors output to Home Assistant - lambda: return x * id(scale_voltage).state/100.0f; -# Reports the total Power so-far each day, resets at midnight -# See https://esphome.io/components/sensor/total_daily_energy.html + # 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 @@ -366,7 +493,7 @@ sensor: # Power monitoring sensors output to Home Assistant unit_of_measurement: kWh min_save_interval: 5min - + # https://esphome.io/components/sensor/uptime.html - platform: uptime name: $friendly_name Uptime update_interval: 60s @@ -374,6 +501,8 @@ sensor: # Power monitoring sensors output to Home Assistant disabled_by_default: $disable_entities +# 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 @@ -388,8 +517,8 @@ number: # used as a threshold for whether the plugged-in devices is running unit_of_measurement: Watt(s) mode: box disabled_by_default: $disable_entities - 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: @@ -450,6 +579,8 @@ number: # used as a threshold for whether the plugged-in devices is running - lambda: id(voltage)->publish_state(id(voltage)->get_raw_state()); +# https://esphome.io/components/select/index.html +# https://esphome.io/components/select/template.html select: # option to disable button @@ -465,33 +596,56 @@ select: icon: mdi:circle-double entity_category: config - # 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 + 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 + 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 @@ -514,13 +668,31 @@ select: set_action: - delay: 1s - lambda: global_preferences->sync(); - - delay: 1s + - delay: 2s - button.press: restart_button # 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 +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 |