Last active
December 29, 2024 18:05
-
-
Save bradsjm/c2562df0e891f26e27191a31d617d471 to your computer and use it in GitHub Desktop.
Emporia VUE V3 ESPHome Configuration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
substitutions: | |
name: emporia-vue-v3 | |
friendly_name: Emporia Vue V3 | |
area: "Garage" | |
# Circuit Labels used for publishing to Home Assistant | |
circuit_1: "Dryer" #"Circuit 1" | |
circuit_2: "AC Blower/Heat" #"Circuit 2" | |
circuit_3: "AC Condenser" #"Circuit 3" | |
circuit_4: "Water Heater" #"Circuit 4" | |
circuit_5: "Master Bedroom Lights" #"Circuit 5" | |
circuit_6: "Master Bedroom Outlets" #"Circuit 6" | |
circuit_7: "Guest Room/Office" #"Circuit 7" | |
circuit_8: "Garage Rear" #"Circuit 8" | |
circuit_9: "Circuit 9" | |
circuit_10: "Circuit 10" | |
circuit_11: "Circuit 11" | |
circuit_12: "Circuit 12" | |
circuit_13: "Circuit 13" | |
circuit_14: "Circuit 14" | |
circuit_15: "Circuit 15" | |
circuit_16: "Circuit 16" | |
# Icons for Home Assistant | |
icon_circuit: "mdi:power-plug" | |
icon_current: "mdi:current-ac" | |
icon_meter: "mdi:meter-electric" | |
icon_phase: "mdi:angle-acute" | |
icon_power: "mdi:transmission-tower-import" | |
icon_voltage: "mdi:transmission-tower" | |
# Use Ethernet or WiFi on the Emporia Vue V3 (you can only include one) | |
wifi: | |
ap: # Enable access point mode for the captive portal | |
ssid: !secret wifi_ssid | |
password: !secret wifi_password | |
on_connect: | |
- light.turn_on: wifi_led | |
on_disconnect: | |
- light.turn_off: wifi_led | |
# ethernet: | |
# type: RTL8201 | |
# mdc_pin: GPIO32 | |
# mdio_pin: GPIO33 | |
# clk_mode: GPIO0_IN | |
# on_connect: | |
# - light.turn_on: ethernet_led | |
# on_disconnect: | |
# - light.turn_off: ethernet_led | |
# Define filters to be used in circuit sensors. | |
.defaultfilters: | |
- &throttle_avg # Average all raw readings together over a 5 second span before publishing | |
throttle_average: 5s | |
- &throttle_time # Only send the most recent measurement every 60 seconds | |
throttle: 60s | |
- &invert # Invert and filter out any values below 0. | |
lambda: "return max(-x, 0.0f);" | |
- &pos # Filter out any values below 0. | |
lambda: "return max(x, 0.0f);" | |
- &abs # Take the absolute value of the value | |
lambda: "return abs(x);" | |
- &zero # Use for disconnected circuits to return 0 | |
lambda: "return 0.0f;" | |
- &double # Use to double the measurement for 240V breakers | |
multiply: 2 | |
# Define the sensors to be exposed to Home Assistant. | |
sensor: | |
- platform: emporia_vue | |
i2c_id: i2c_a | |
# Configure the Emporia Vue wire harness phases. | |
phases: | |
# Verify that this specific phase/leg is connected to the matching input wire color on device listed below | |
- id: phase_a | |
# Vue device wire color (BLACK or RED for split phase) | |
input: BLACK | |
# To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage> | |
# 0.0194 is used as the default as starting point for Vue 3 but may need adjusted to ensure accuracy | |
calibration: 0.0194 | |
voltage: { id: phase_a_voltage, name: "Phase A Voltage", icon: $icon_voltage, accuracy_decimals: 0, filters: [ *throttle_avg, *pos ] } | |
frequency: { id: phase_a_freqency, name: "Phase A Frequency", accuracy_decimals: 0, filters: [ *throttle_avg, *pos ] } | |
# Verify that this specific phase/leg is connected to the matching input wire color on device listed below | |
- id: phase_b | |
# Vue device wire color (BLACK or RED for split phase) | |
input: RED | |
# To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage> | |
# 0.0194 is used as the default as starting point for Vue 3 but may need adjusted to ensure accuracy | |
calibration: 0.0194 | |
voltage: { id: phase_b_voltage, name: "Phase B Voltage", icon: $icon_voltage, accuracy_decimals: 0, filters: [ *throttle_avg, *pos ] } | |
phase_angle: { id: phase_b_angle, name: "Phase B Phase Angle", icon: $icon_phase, accuracy_decimals: 0, filters: [ *throttle_avg, *pos ] } | |
# Verify that this specific phase/leg is connected to the matching input wire color on device listed below | |
# - id: phase_c | |
# # Vue device wire color (BLUE for three phase) | |
# input: BLUE | |
# # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage> | |
# # 0.0194 is used as the default as starting point for Vue 3 but may need adjusted to ensure accuracy | |
# calibration: 0.0194 | |
# voltage: { id: phase_c_voltage, name: "Phase C Voltage", icon: $icon_voltage, accuracy_decimals: 0, filters: [ *throttle_avg, *pos ] } | |
# phase_angle: { id: phase_c_angle, name: "Phase C Phase Angle", icon: $icon_phase, accuracy_decimals: 0, filters: [ *throttle_avg, *pos ] } | |
# Configure the Emporia Vue CT clamps. | |
ct_clamps: | |
# Do not specify a name for any of the power sensors here, only an id. This leaves the power sensors internal to ESPHome. | |
# These non-throttled power sensors are used for accurately calculating energy. | |
# Copy sensors defined later will filter and then send power measurements to Home Assistant. | |
# Main Service CT Clamps (up to 3) | |
# Verify the correct input on the device is connected to the CT clamp phase defined (Vue 3 inputs are inverted) | |
- { input: "A", phase_id: phase_a, power: { id: phase_a_power, filters: *invert } } | |
- { input: "B", phase_id: phase_b, power: { id: phase_b_power, filters: *invert } } | |
# - { input: "C", phase_id: phase_c, power: { id: phase_c_power, filters: *invert } } | |
# Circuit CT Clamps (up to 16) | |
# Pay close attention to set the phase_id for each breaker by matching it to the phase/leg it connects to in the panel | |
# Use *abs filter to always take the positive absolute value | |
# Use *invert filter for inverted positive values (Vue 3 inputs are inverted) or *zero for un-used inputs | |
# Use *double filter for double (240v) breakers (this will assume power is evenly divided between the two legs) | |
- { input: "1", phase_id: phase_a, power: { id: c1_pwr, filters: [ *abs, *double ] }, current: { id: c1_cur, filters: [ *double ] } } | |
- { input: "2", phase_id: phase_a, power: { id: c2_pwr, filters: [ *abs, *double ] }, current: { id: c2_cur, filters: [ *double ] } } | |
- { input: "3", phase_id: phase_a, power: { id: c3_pwr, filters: [ *abs, *double ] }, current: { id: c3_cur, filters: [ *double ] } } | |
- { input: "4", phase_id: phase_a, power: { id: c4_pwr, filters: [ *abs, *double ] }, current: { id: c4_cur, filters: [ *double ] } } | |
- { input: "5", phase_id: phase_b, power: { id: c5_pwr, filters: [ *abs ] }, current: { id: c5_cur } } | |
- { input: "6", phase_id: phase_a, power: { id: c6_pwr, filters: [ *abs ] }, current: { id: c6_cur } } | |
- { input: "7", phase_id: phase_b, power: { id: c7_pwr, filters: [ *abs ] }, current: { id: c7_cur } } | |
- { input: "8", phase_id: phase_b, power: { id: c8_pwr, filters: [ *abs ] }, current: { id: c8_cur } } | |
# Unused CT clamp inputs are explicitly set to zero (*zero filter) to avoid phantom readings | |
- { input: "9", phase_id: phase_a, power: { id: c9_pwr, filters: [ *zero ] }, current: { id: c9_cur, filters: [ *zero ] } } | |
- { input: "10", phase_id: phase_a, power: { id: c10_pwr, filters: [ *zero ] }, current: { id: c10_cur, filters: [ *zero ] } } | |
- { input: "11", phase_id: phase_a, power: { id: c11_pwr, filters: [ *zero ] }, current: { id: c11_cur, filters: [ *zero ] } } | |
- { input: "12", phase_id: phase_a, power: { id: c12_pwr, filters: [ *zero ] }, current: { id: c12_cur, filters: [ *zero ] } } | |
- { input: "13", phase_id: phase_a, power: { id: c13_pwr, filters: [ *zero ] }, current: { id: c13_cur, filters: [ *zero ] } } | |
- { input: "14", phase_id: phase_a, power: { id: c14_pwr, filters: [ *zero ] }, current: { id: c14_cur, filters: [ *zero ] } } | |
- { input: "15", phase_id: phase_a, power: { id: c15_pwr, filters: [ *zero ] }, current: { id: c15_cur, filters: [ *zero ] } } | |
- { input: "16", phase_id: phase_a, power: { id: c16_pwr, filters: [ *zero ] }, current: { id: c16_cur, filters: [ *zero ] } } | |
# Update total power and balance power readings at the same time. | |
on_update: | |
then: | |
- component.update: total_power | |
- component.update: balance_power | |
# The total power sensor will be updated after all power sensors update via on_update trigger. | |
- platform: template | |
id: total_power | |
update_interval: never | |
device_class: power | |
state_class: measurement | |
unit_of_measurement: "W" | |
lambda: return id(phase_a_power).state + id(phase_b_power).state; | |
#lambda: return id(phase_a_power).state + id(phase_b_power).state + id(phase_c_power).state; | |
# The balance power sensor will be updated after all power sensors update via on_update trigger. | |
- platform: template | |
id: balance_power | |
update_interval: never | |
device_class: power | |
state_class: measurement | |
unit_of_measurement: "W" | |
lambda: !lambda |- | |
return max(0.0f, id(total_power).state | |
- id( c1_pwr).state | |
- id( c2_pwr).state | |
- id( c3_pwr).state | |
- id( c4_pwr).state | |
- id( c5_pwr).state | |
- id( c6_pwr).state | |
- id( c7_pwr).state | |
- id( c8_pwr).state | |
- id( c9_pwr).state | |
- id(c10_pwr).state | |
- id(c11_pwr).state | |
- id(c12_pwr).state | |
- id(c13_pwr).state | |
- id(c14_pwr).state | |
- id(c15_pwr).state | |
- id(c16_pwr).state | |
); | |
- platform: wifi_signal | |
name: "RSSI" | |
update_interval: 60s | |
disabled_by_default: true | |
# The copy sensors publish the each power state to Home Assistant. | |
- { platform: copy, name: "Phase A Power", source_id: phase_a_power, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_power } | |
- { platform: copy, name: "Phase B Power", source_id: phase_b_power, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_power } | |
- { platform: copy, name: "Total Power", source_id: total_power, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_power } | |
- { platform: copy, name: "Balance Power", source_id: balance_power, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_power } | |
- { platform: copy, name: "${circuit_1} Power", source_id: c1_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
- { platform: copy, name: "${circuit_2} Power", source_id: c2_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
- { platform: copy, name: "${circuit_3} Power", source_id: c3_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
- { platform: copy, name: "${circuit_4} Power", source_id: c4_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
- { platform: copy, name: "${circuit_5} Power", source_id: c5_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
- { platform: copy, name: "${circuit_6} Power", source_id: c6_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
- { platform: copy, name: "${circuit_7} Power", source_id: c7_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
- { platform: copy, name: "${circuit_8} Power", source_id: c8_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
# - { platform: copy, name: "${circuit_9} Power", source_id: cir9_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
# - { platform: copy, name: "${circuit_10} Power", source_id: cir10_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
# - { platform: copy, name: "${circuit_11} Power", source_id: cir11_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
# - { platform: copy, name: "${circuit_12} Power", source_id: cir12_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
# - { platform: copy, name: "${circuit_13} Power", source_id: cir13_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
# - { platform: copy, name: "${circuit_14} Power", source_id: cir14_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
# - { platform: copy, name: "${circuit_15} Power", source_id: cir15_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
# - { platform: copy, name: "${circuit_16} Power", source_id: cir16_pwr, filters: *throttle_avg, accuracy_decimals: 0, icon: $icon_circuit } | |
- { platform: copy, name: "${circuit_1} Current", source_id: c1_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
- { platform: copy, name: "${circuit_2} Current", source_id: c2_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
- { platform: copy, name: "${circuit_3} Current", source_id: c3_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
- { platform: copy, name: "${circuit_4} Current", source_id: c4_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
- { platform: copy, name: "${circuit_5} Current", source_id: c5_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
- { platform: copy, name: "${circuit_6} Current", source_id: c6_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
- { platform: copy, name: "${circuit_7} Current", source_id: c7_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
- { platform: copy, name: "${circuit_8} Current", source_id: c8_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
# - { platform: copy, name: "${circuit_9} Current", source_id: c9_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
# - { platform: copy, name: "${circuit_10} Current", source_id: c10_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
# - { platform: copy, name: "${circuit_11} Current", source_id: c11_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
# - { platform: copy, name: "${circuit_12} Current", source_id: c12_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
# - { platform: copy, name: "${circuit_13} Current", source_id: c13_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
# - { platform: copy, name: "${circuit_14} Current", source_id: c14_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
# - { platform: copy, name: "${circuit_15} Current", source_id: c15_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
# - { platform: copy, name: "${circuit_16} Current", source_id: c16_cur, filters: *throttle_avg, accuracy_decimals: 1, icon: $icon_current } | |
# The total daily energy sensors to be published to Home Assistant | |
- { platform: total_daily_energy, name: "Total Daily Energy", power_id: total_power, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
- { platform: total_daily_energy, name: "Balance Daily Energy", power_id: balance_power, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
- { platform: total_daily_energy, name: "${circuit_1} Daily Energy", power_id: c1_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
- { platform: total_daily_energy, name: "${circuit_2} Daily Energy", power_id: c2_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
- { platform: total_daily_energy, name: "${circuit_3} Daily Energy", power_id: c3_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
- { platform: total_daily_energy, name: "${circuit_4} Daily Energy", power_id: c4_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
- { platform: total_daily_energy, name: "${circuit_5} Daily Energy", power_id: c5_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
- { platform: total_daily_energy, name: "${circuit_6} Daily Energy", power_id: c6_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
- { platform: total_daily_energy, name: "${circuit_7} Daily Energy", power_id: c7_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
- { platform: total_daily_energy, name: "${circuit_8} Daily Energy", power_id: c8_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
# - { platform: total_daily_energy, name: "${circuit_9} Daily Energy", power_id: c9_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
# - { platform: total_daily_energy, name: "${circuit_10} Daily Energy", power_id: c10_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
# - { platform: total_daily_energy, name: "${circuit_11} Daily Energy", power_id: c11_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
# - { platform: total_daily_energy, name: "${circuit_12} Daily Energy", power_id: c12_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
# - { platform: total_daily_energy, name: "${circuit_13} Daily Energy", power_id: c13_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
# - { platform: total_daily_energy, name: "${circuit_14} Daily Energy", power_id: c14_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
# - { platform: total_daily_energy, name: "${circuit_15} Daily Energy", power_id: c15_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
# - { platform: total_daily_energy, name: "${circuit_16} Daily Energy", power_id: c16_pwr, filters: *throttle_time, accuracy_decimals: 0, restore: false, icon: $icon_meter } | |
# Core ESPHome Node Configuration. | |
esphome: | |
name: ${name} | |
area: ${area} | |
friendly_name: ${friendly_name} | |
name_add_mac_suffix: false | |
# Import the emporia-vue-local v3 community component. | |
external_components: | |
- source: github://emporia-vue-local/esphome@vue3 | |
components: | |
- emporia_vue | |
# Set ESPHome preferences. | |
preferences: | |
flash_write_interval: "48h" # The default of 1min is too short (flash chip is rated for approx 100k writes) | |
# The logger component automatically logs all log messages | |
logger: | |
baud_rate: 0 # Disable the hardware UART logging | |
level: INFO # Minimum log level | |
logs: | |
component: ERROR # Silence warnings about execution/blocking time | |
# Sets up the I²C bus used to communicate with the Emporia Vue hardware. | |
i2c: | |
id: i2c_a | |
sda: | |
number: 5 | |
ignore_strapping_warning: true | |
scl: 18 | |
frequency: 200kHz | |
scan: false | |
# The Emporia Vue V3 uses an ESP32 board. | |
esp32: | |
board: esp32dev | |
framework: | |
type: esp-idf | |
version: recommended | |
# Configure the two status LEDs on the Emporia Vue v3 case. | |
light: | |
- platform: status_led | |
id: wifi_led | |
pin: | |
number: 2 | |
ignore_strapping_warning: true | |
restore_mode: ALWAYS_OFF | |
- platform: status_led | |
id: ethernet_led | |
pin: 4 | |
restore_mode: ALWAYS_OFF | |
# The restart button platform allows you to restart your node remotely through Home Assistant. | |
button: | |
- platform: restart | |
name: Restart | |
id: restart_button | |
icon: mdi:restart | |
- platform: safe_mode | |
name: Restart (Safe Mode) | |
id: safe_mode_button | |
icon: mdi:restart-alert | |
# The preferred way to get time in ESPHome is using Home Assistant. This is used for the daily energy use calculation. | |
time: | |
- platform: homeassistant | |
# The ESPHome native API is used to communicate with Home Assistant directly. | |
api: | |
# The OTA (Over The Air) enables uploading firmware binaries to your node without having to use a USB cable for uploads. | |
ota: | |
platform: esphome | |
on_error: | |
then: | |
- button.press: safe_mode_button | |
# The web_server component creates a simple web server on the node that can be accessed through any browser and a simple REST API. | |
# This is not required for Home Assistant and can be commented out to reduce memory and processor utilization. | |
web_server: | |
# The captive portal component in ESPHome is a fallback mechanism used when connecting to WiFi fails. | |
captive_portal: | |
# Provide diagnostic information about the platform. | |
text_sensor: | |
- platform: wifi_info | |
ip_address: | |
name: "IP Address" | |
ssid: | |
name: "Connected SSID" | |
disabled_by_default: true | |
mac_address: | |
name: "MAC Address" | |
disabled_by_default: true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment