Sigh. Configuring a non-standard electrical setup.. solar and generator and multiple feeds

Hi Folks.. Well, I got my system working. I can do over the air updates and everything. Ended up hard-wiring to the Ethernet ports, because the shop and house are on two different wifi-networks.
Now if I can just figure out how to configure it so it makes sense for what I’m seeing in the energy pane… I don’t have any automation on the house (at this time). Just trying to find out where all my power is going…

This is what my system looks like. I have PGE coming in to a single point mix; Solar and PGE mix (can not seem to monitor PGE separately, , it’s only about 1/2" tabs into the backplane in the input panel). I can monitor the solar input, as those were added in. So I have two inputs, going into a merged point. From there, I have two outputs. One is the main to the house, covering all the power hungry things that don’t use the backup generator (oven, dryer, jacuzzi, etc). Then there is the other output that powers both the shop utility panel (which is not backed up), and feeds the transfer switch between the generator and the backed-up portion of the house.

I have a vue3 on the shop utility panel, with power being taken from the backed-up circuit side of the transfer switch. This ensures that it operates when on generator. Hmm.. Just realized that the power to the router in the shop may not be on the generator.. sigh. Oh well, next fix.

I have a vue3 on the non-backed-up panel at the house, with 15 circuits monitoring all those devices. I have a vue3 on the backed-up sub panel at the house, with 16 circuits monitoring all of those devices.

On the shop vue3, I’ve got PhaseA/B plugged in on the non-backed-up house feed output, after the merge point. I also have a couple of the smaller sensors watching the shop-utility feed. It’s 60amps, so it’s within range of the smaller units. I also have two smaller sensors on the solar inputs to the merge.

On the backed-up panel vue3 at the house, I have phaseA/B plugged in on the inputs from the transfer switch. On the non-backed-up panel at the house, I do not have PhaseA/B plugged in. I figured they were covered from the shop A/B sensors.

Any help getting this to be something readable would be great, and very appreciated!
The only thing I can think of (so far) is to subtract the power from solar from the other two circuits to get the PGE values… if that makes any sense. Haven’t tried it yet..

Here are the three YAML files: whoops, 2 of them. hit the character limits! Next post.

type or paste code here

esphome:
  name: house2
  friendly_name: House gen backed

esp32:
  board: esp32dev
  framework:
    type: esp-idf

# Enable Home Assistant API
api:
  encryption:
    key: !secret housegen__encryption_key
ota:
  - platform: esphome
    password: !secret housegen__ota_password

external_components:
  - source: github://emporia-vue-local/esphome@dev
    components:
      - emporia_vue


# …and use HA for setting our RTC time locally
time:
  - platform: homeassistant

# …and expose a (virtual) "switch" that HA can use to restart us
switch:
  - platform: restart
    name: Restart


# enable logging, with some customizations
logger:
  logs:
    # by default, every reading will be printed to the UART, which is very slow
    # This will disable printing the readings but keep other helpful messages
    sensor: INFO

preferences:
  # avoid wearing out the flash lifespan with rapidly-updating sensor data!
  # please also make sure `restore: false` is set on all `platform: total_daily_energy` sensors below.
  flash_write_interval: "48h"
#wifi:
#  ssid: !secret wifi_ssid
#  password: !secret wifi_password
#  on_connect:
#    - light.turn_on: wifi_led
#  on_disconnect:
#    - light.turn_off: wifi_led

light:
  - platform: status_led
    id: wifi_led
    pin:
      number: 2
      ignore_strapping_warning: true
    restore_mode: RESTORE_DEFAULT_ON

  - platform: status_led
    id: ethernet_led
    pin: 4
    restore_mode: ALWAYS_OFF

i2c:
  sda:
    number: 5
    ignore_strapping_warning: true
  scl: 18
  scan: false
  frequency: 400kHz
  timeout: 1ms
  id: i2c_a

# you can also use Ethernet for connectivity by uncommenting the following
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

  clk:
    pin:
      number: GPIO0
    mode: CLK_EXT_IN

substitutions:
  leg_1: PhaseA
  leg_2: PhaseB
  #leg_3 (`input: "C"` available but not used in this example)
  cir_1: "unused"  # unused
  cir_2: UPS 2
  cir_3: UPS 1
  cir_4: MasterBath
  cir_5: KitchenLights
  cir_6: Microwave
  cir_7: FreezerLaundry
  cir_8: TVWall
  cir_9: Refrigerator
  cir_10: CraftTrailerA
  cir_11: CraftTrailerB
  cir_12: RVgarage
  cir_13: Bedroom3
  cir_14: KitchenOutlets
  cir_15: KitchenIsland  # Solar A
  cir_16: AirHandler  # Solar B
  xtra: "Balance"  # displaying leftover/unmonitored energy (total minus circs 1–16)

.filters:
  # these are called references in YAML. They allow you to reuse
  # this configuration in each sensor, while only defining it once
  # you can adjust them here, split them up differently, even copy some inline…
  - &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 the value for solar
  - &neg
    # 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);'

sensor:
  - platform: emporia_vue
    variant: vue3
    i2c_id: i2c_a
    phases:
      - id: phase_a  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: BLACK # Vue device wire color
        calibration: 0.01925 # a starting point, may need adjusted to ensure accuracy!
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "${leg_1} Voltage"
          filters: [*throttle_avg, *pos]
        frequency:
          name: "${leg_1} Frequency"
          filters: [*throttle_avg, *pos]
      - id: phase_b  # see notes above
        input: RED
        calibration: 0.01925
        voltage:
          name: "${leg_2} Voltage"
          filters: [*throttle_avg, *pos]
        phase_angle:
          name: "${leg_2} Phase Angle"
          filters: [*throttle_avg, *pos]
    ct_clamps:
      # These non-throttled power sensors are used for accurately calculating energy.
      # Recommend not to specify a `name` for any of the power sensors here — only the `id`!
      # This leaves them internal to ESPHome locally; post-processed data is sent to HA below.
      - phase_id: phase_a
        input: "A"  # Verify the CT going to these devices input also matches the phase/leg
        power:
          id: phase_a_power
          device_class: power
          filters: [*pos]
      - phase_id: phase_b
        input: "B"
        power:
          id: phase_b_power
          device_class: power
          filters: [*pos]
      # Pay close attention to set the `phase_id` for each breaker by matching it to the phase/leg it connects to in the panel
      - { phase_id: phase_b, input:  "1", power: { id:  cir1, filters: [ *neg ] } }
      - { phase_id: phase_a, input:  "2", power: { id:  cir2, filters: [ ] } }
      - { phase_id: phase_b, input:  "3", power: { id:  cir3, filters: [ ] } }
      - { phase_id: phase_a, input:  "4", power: { id:  cir4, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "5", power: { id:  cir5, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "6", power: { id:  cir6, filters: [ *neg ] } }
      - { phase_id: phase_a, input:  "7", power: { id:  cir7, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "8", power: { id:  cir8, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "9", power: { id:  cir9, filters: [ *neg ] } }
      - { phase_id: phase_b, input: "10", power: { id: cir10, filters: [ *neg ] } }
      - { phase_id: phase_a, input: "11", power: { id: cir11, filters: [ *neg ] } }
      - { phase_id: phase_a, input: "12", power: { id: cir12, filters: [ *neg ] } }
      - { phase_id: phase_b, input: "13", power: { id: cir13, filters: [ *neg ] } }
      - { phase_id: phase_b, input: "14", power: { id: cir14, filters: [ *neg ] } }
      - { phase_id: phase_a, input: "15", power: { id: cir15, filters: [ *neg ] } }
      - { phase_id: phase_b, input: "16", power: { id: cir16, filters: [ *neg ] } }
    on_update:
      then:
        - component.update: total_power
        - component.update: balance_power

  # these `copy` sensors filter and send the power state to HA
  - { platform: copy, name: "${leg_1} Power", source_id: phase_a_power, filters: *throttle_avg }
  - { platform: copy, name: "${leg_2} Power", source_id: phase_b_power, filters: *throttle_avg }
  - { platform: copy, name: "Total Power", source_id: total_power, filters: *throttle_avg }
  - { platform: copy, name: "${xtra} Power", source_id: balance_power, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_1} Power", source_id:  cir1, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_2} Power", source_id:  cir2, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_3} Power", source_id:  cir3, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_4} Power", source_id:  cir4, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_5} Power", source_id:  cir5, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_6} Power", source_id:  cir6, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_7} Power", source_id:  cir7, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_8} Power", source_id:  cir8, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_9} Power", source_id:  cir9, filters: *throttle_avg }
  - { platform: copy, name: "${cir_10} Power", source_id: cir10, filters: *throttle_avg }
  - { platform: copy, name: "${cir_11} Power", source_id: cir11, filters: *throttle_avg }
  - { platform: copy, name: "${cir_12} Power", source_id: cir12, filters: *throttle_avg }
  - { platform: copy, name: "${cir_13} Power", source_id: cir13, filters: *throttle_avg }
  - { platform: copy, name: "${cir_14} Power", source_id: cir14, filters: *throttle_avg }
  - { platform: copy, name: "${cir_15} Power", source_id: cir15, filters: *throttle_avg }
  - { platform: copy, name: "${cir_16} Power", source_id: cir16, filters: *throttle_avg }

  - platform: template
    lambda: return id(phase_a_power).state + id(phase_b_power).state;
    update_interval: never   # will be updated after all power sensors update via on_update trigger
    id: total_power
    device_class: power
    state_class: measurement
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "Total Daily Energy"
    power_id: total_power
    accuracy_decimals: 0
    restore: false
    filters: *throttle_time
  
  - platform: template
    lambda: !lambda |-
      return max(0.0f, id(total_power).state -
        id( cir2).state -
        id( cir3).state -
        id( cir4).state -
        id( cir5).state -
        id( cir6).state -
        id( cir7).state -
        id( cir8).state -
        id( cir9).state -
        id(cir10).state -
        id(cir11).state -
        id(cir12).state -
        id(cir13).state -
        id(cir14).state -
        id(cir15).state -
        id(cir16).state);
    update_interval: never   # still happens, but via `on_update` trigger (*after* all power sensors update)
    id: balance_power
    device_class: power
    state_class: measurement
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "${xtra} Daily Energy"
    power_id: balance_power
    accuracy_decimals: 0
    restore: false
    filters: *throttle_time
  
  - { power_id:  cir1, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_1} Daily Energy", filters: *throttle_time }  
  - { power_id:  cir2, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_2} Daily Energy", filters: *throttle_time }
  - { power_id:  cir3, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_3} Daily Energy", filters: *throttle_time }
  - { power_id:  cir4, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_4} Daily Energy", filters: *throttle_time }
  - { power_id:  cir5, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_5} Daily Energy", filters: *throttle_time }
  - { power_id:  cir6, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_6} Daily Energy", filters: *throttle_time }
  - { power_id:  cir7, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_7} Daily Energy", filters: *throttle_time }
  - { power_id:  cir8, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_8} Daily Energy", filters: *throttle_time }
  - { power_id:  cir9, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_9} Daily Energy", filters: *throttle_time }
  - { power_id: cir10, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_10} Daily Energy", filters: *throttle_time }
  - { power_id: cir11, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_11} Daily Energy", filters: *throttle_time }
  - { power_id: cir12, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_12} Daily Energy", filters: *throttle_time }
  - { power_id: cir13, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_13} Daily Energy", filters: *throttle_time }
  - { power_id: cir14, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_14} Daily Energy", filters: *throttle_time }
  - { power_id: cir15, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_15} Daily Energy", filters: *throttle_time }
  - { power_id: cir16, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_16} Daily Energy", filters: *throttle_time }

Next:

esphome:
  name: houseutil3
  friendly_name: House Utility Panel

esp32:
  board: esp32dev
  framework:
    type: esp-idf

# Enable Home Assistant API
api:
  encryption:
    key: !secret housegen__encryption_key
ota:
  - platform: esphome
    password: !secret housegen__ota_password

external_components:
  - source: github://emporia-vue-local/esphome@dev
    components:
      - emporia_vue


# …and use HA for setting our RTC time locally
time:
  - platform: homeassistant

# …and expose a (virtual) "switch" that HA can use to restart us
switch:
  - platform: restart
    name: Restart


# enable logging, with some customizations
logger:
  logs:
    # by default, every reading will be printed to the UART, which is very slow
    # This will disable printing the readings but keep other helpful messages
    sensor: INFO

preferences:
  # avoid wearing out the flash lifespan with rapidly-updating sensor data!
  # please also make sure `restore: false` is set on all `platform: total_daily_energy` sensors below.
  flash_write_interval: "48h"
#wifi:
#  ssid: !secret wifi_ssid
#  password: !secret wifi_password
#  on_connect:
#    - light.turn_on: wifi_led
#  on_disconnect:
#    - light.turn_off: wifi_led

light:
  - platform: status_led
    id: wifi_led
    pin:
      number: 2
      ignore_strapping_warning: true
    restore_mode: RESTORE_DEFAULT_ON

  - platform: status_led
    id: ethernet_led
    pin: 4
    restore_mode: ALWAYS_OFF

i2c:
  sda:
    number: 5
    ignore_strapping_warning: true
  scl: 18
  scan: false
  frequency: 400kHz
  timeout: 1ms
  id: i2c_a

# you can also use Ethernet for connectivity by uncommenting the following
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
  clk:
    pin:
      number: GPIO0
    mode: CLK_EXT_IN

substitutions:
  leg_1: PhaseAutil
  leg_2: PhaseButil
  #leg_3 (`input: "C"` available but not used in this example)
  cir_1: oven
  cir_2: spaA
  cir_3: spaB
  cir_4: dryerA
  cir_5: pantry
  cir_6: dishwasher
  cir_7: disposal-compact
  cir_8: kitch-app
  cir_9: livingRmLights
  cir_10: laundryLight
  cir_11: garage
  cir_12: guestBath
  cir_13: laundryOutlet
  cir_14: masterBedroom
  cir_15: guestBath2
  cir_16: washer
  xtra: "Balance"  # displaying leftover/unmonitored energy (total minus circs 1–16)

.filters:
  # these are called references in YAML. They allow you to reuse
  # this configuration in each sensor, while only defining it once
  # you can adjust them here, split them up differently, even copy some inline…
  - &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 the value for solar
  - &neg
    # 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);'

sensor:
  - platform: emporia_vue
    variant: vue3
    i2c_id: i2c_a
    phases:
      - id: phase_a  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: BLACK # Vue device wire color
        calibration: 0.01925 # a starting point, may need adjusted to ensure accuracy!
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "${leg_1} Voltage"
          filters: [*throttle_avg, *pos]
        frequency:
          name: "${leg_1} Frequency"
          filters: [*throttle_avg, *pos]
      - id: phase_b  # see notes above
        input: RED
        calibration: 0.01925
        voltage:
          name: "${leg_2} Voltage"
          filters: [*throttle_avg, *pos]
        phase_angle:
          name: "${leg_2} Phase Angle"
          filters: [*throttle_avg, *pos]
    ct_clamps:
      # These non-throttled power sensors are used for accurately calculating energy.
      # Recommend not to specify a `name` for any of the power sensors here — only the `id`!
      # This leaves them internal to ESPHome locally; post-processed data is sent to HA below.
      - phase_id: phase_a
        input: "A"  # Verify the CT going to these devices input also matches the phase/leg
        power:
          id: phase_a_power
          device_class: power
          filters: [*pos]
      - phase_id: phase_b
        input: "B"
        power:
          id: phase_b_power
          device_class: power
          filters: [*pos]
      # Pay close attention to set the `phase_id` for each breaker by matching it to the phase/leg it connects to in the panel
      - { phase_id: phase_a, input:  "1", power: { id:  cir1, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "2", power: { id:  cir2, filters: [ *neg ] } }
      - { phase_id: phase_a, input:  "3", power: { id:  cir3, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "4", power: { id:  cir4, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "5", power: { id:  cir5, filters: [ *neg ] } }
      - { phase_id: phase_a, input:  "6", power: { id:  cir6, filters: [ *neg ] } }
      - { phase_id: phase_a, input:  "7", power: { id:  cir7, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "8", power: { id:  cir8, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "9", power: { id:  cir9, filters: [ *neg ] } }
      - { phase_id: phase_b, input: "10", power: { id: cir10, filters: [ *neg ] } }
      - { phase_id: phase_a, input: "11", power: { id: cir11, filters: [ *neg ] } }
      - { phase_id: phase_a, input: "12", power: { id: cir12, filters: [ *neg ] } }
      - { phase_id: phase_b, input: "13", power: { id: cir13, filters: [ *neg ] } }
      - { phase_id: phase_b, input: "14", power: { id: cir14, filters: [ *neg ] } }
      - { phase_id: phase_a, input: "15", power: { id: cir15, filters: [ *neg ] } }
      - { phase_id: phase_a, input: "16", power: { id: cir16, filters: [ *neg ] } }
    on_update:
      then:
        - component.update: total_power
        - component.update: balance_power

  # these `copy` sensors filter and send the power state to HA
  - { platform: copy, name: "${leg_1} Power", source_id: phase_a_power, filters: *throttle_avg }
  - { platform: copy, name: "${leg_2} Power", source_id: phase_b_power, filters: *throttle_avg }
  - { platform: copy, name: "Total Power", source_id: total_power, filters: *throttle_avg }
  - { platform: copy, name: "${xtra} Power", source_id: balance_power, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_1} Power", source_id:  cir1, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_2} Power", source_id:  cir2, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_3} Power", source_id:  cir3, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_4} Power", source_id:  cir4, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_5} Power", source_id:  cir5, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_6} Power", source_id:  cir6, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_7} Power", source_id:  cir7, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_8} Power", source_id:  cir8, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_9} Power", source_id:  cir9, filters: *throttle_avg }
  - { platform: copy, name: "${cir_10} Power", source_id: cir10, filters: *throttle_avg }
  - { platform: copy, name: "${cir_11} Power", source_id: cir11, filters: *throttle_avg }
  - { platform: copy, name: "${cir_12} Power", source_id: cir12, filters: *throttle_avg }
  - { platform: copy, name: "${cir_13} Power", source_id: cir13, filters: *throttle_avg }
  - { platform: copy, name: "${cir_14} Power", source_id: cir14, filters: *throttle_avg }
  - { platform: copy, name: "${cir_15} Power", source_id: cir15, filters: *throttle_avg }
  - { platform: copy, name: "${cir_16} Power", source_id: cir16, filters: *throttle_avg }

  - platform: template
    lambda: return id(phase_a_power).state + id(phase_b_power).state;
    update_interval: never   # will be updated after all power sensors update via on_update trigger
    id: total_power
    device_class: power
    state_class: measurement
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "Total Daily Energy"
    power_id: total_power
    accuracy_decimals: 0
    restore: false
    filters: *throttle_time
  
  - platform: template
    lambda: !lambda |-
      return max(0.0f, id(total_power).state -
        id( cir2).state -
        id( cir3).state -
        id( cir4).state -
        id( cir5).state -
        id( cir6).state -
        id( cir7).state -
        id( cir8).state -
        id( cir9).state -
        id(cir10).state -
        id(cir11).state -
        id(cir12).state -
        id(cir13).state -
        id(cir14).state -
        id(cir15).state -
        id(cir16).state);
    update_interval: never   # still happens, but via `on_update` trigger (*after* all power sensors update)
    id: balance_power
    device_class: power
    state_class: measurement
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "${xtra} Daily Energy"
    power_id: balance_power
    accuracy_decimals: 0
    restore: false
    filters: *throttle_time
  
  - { power_id:  cir1, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_1} Daily Energy", filters: *throttle_time }  
  - { power_id:  cir2, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_2} Daily Energy", filters: *throttle_time }
  - { power_id:  cir3, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_3} Daily Energy", filters: *throttle_time }
  - { power_id:  cir4, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_4} Daily Energy", filters: *throttle_time }
  - { power_id:  cir5, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_5} Daily Energy", filters: *throttle_time }
  - { power_id:  cir6, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_6} Daily Energy", filters: *throttle_time }
  - { power_id:  cir7, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_7} Daily Energy", filters: *throttle_time }
  - { power_id:  cir8, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_8} Daily Energy", filters: *throttle_time }
  - { power_id:  cir9, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_9} Daily Energy", filters: *throttle_time }
  - { power_id: cir10, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_10} Daily Energy", filters: *throttle_time }
  - { power_id: cir11, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_11} Daily Energy", filters: *throttle_time }
  - { power_id: cir12, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_12} Daily Energy", filters: *throttle_time }
  - { power_id: cir13, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_13} Daily Energy", filters: *throttle_time }
  - { power_id: cir14, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_14} Daily Energy", filters: *throttle_time }
  - { power_id: cir15, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_15} Daily Energy", filters: *throttle_time }
  - { power_id: cir16, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_16} Daily Energy", filters: *throttle_time }

Oh, and I’m running home assistant green for the base. Just in case that matters… Shouldn’t?
Oh, and just to make it more fun, next month I’m adding another line for solar. So there will be two solar feeds into the merge point. Yay me.

3rd YAML file:

esphome:
  name: shopsub1
  friendly_name: Shop Sub1

esp32:
  board: esp32dev
  framework:
    type: esp-idf

# Enable Home Assistant API
api:
  encryption:
    key: !secret housegen__encryption_key
ota:
  - platform: esphome
    password: !secret housegen__ota_password

external_components:
  - source: github://emporia-vue-local/esphome@dev
    components:
      - emporia_vue


# and use HA for setting our RTC time locally
time:
  - platform: homeassistant

# and expose a (virtual) "switch" that HA can use to restart us
switch:
  - platform: restart
    name: Restart


# enable logging, with some customizations
logger:
  logs:
    # by default, every reading will be printed to the UART, which is very slow
    # This will disable printing the readings but keep other helpful messages
    sensor: INFO

preferences:
  # avoid wearing out the flash lifespan with rapidly-updating sensor data!
  # please also make sure `restore: false` is set on all `platform: total_daily_energy` sensors below.
  flash_write_interval: "48h"
#wifi:
#  ssid: !secret wifi_ssid
#  password: !secret wifi_password
#  on_connect:
#    - light.turn_on: wifi_led
#  on_disconnect:
#    - light.turn_off: wifi_led

light:
  - platform: status_led
    id: wifi_led
    pin:
      number: 2
      ignore_strapping_warning: true
    restore_mode: RESTORE_DEFAULT_ON

  - platform: status_led
    id: ethernet_led
    pin: 4
    restore_mode: ALWAYS_OFF

i2c:
  sda:
    number: 5
    ignore_strapping_warning: true
  scl: 18
  scan: false
  frequency: 400kHz
  timeout: 1ms
  id: i2c_a

# you can also use Ethernet for connectivity by uncommenting the following
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
  clk:
    pin:
      number: GPIO0
    mode: CLK_EXT_IN

substitutions:
  leg_1: "Phase A" # Master input (pge+solar)
  leg_2: "Phase B" # Master input (pge+solar)
  #leg_3 (`input: "C"` available but not used in this example)
  cir_1: Ozone  # Ozone power
  cir_2: WaterPump  # Water pumps
  cir_3: SubAhouseOut # sub feed to the house
  cir_4: SubBhouseOut # sub feed to the house
  cir_5: "Circuit 5"
  cir_6: "Circuit 6"
  cir_7: "Circuit 7"
  cir_8: "Circuit 8"
  cir_9: "Circuit 9"
  cir_10: "Circuit 10"
  cir_11: "Circuit 11"
  cir_12: "Circuit 12"
  cir_13: "Circuit 13"
  cir_14: "Circuit 14"
  cir_15: SolarA  # Solar A
  cir_16: SolarB  # Solar B
  xtra: "Balance"  # displaying leftover/unmonitored energy (total minus circs 1–16)

.filters:
  # these are called references in YAML. They allow you to reuse
  # this configuration in each sensor, while only defining it once
  # you can adjust them here, split them up differently, even copy some inline…
  - &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 the value for solar
  - &neg
    # 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);'

sensor:
  - platform: emporia_vue
    variant: vue3
    i2c_id: i2c_a
    phases:
      - id: phase_a  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: BLACK # Vue device wire color
        calibration: 0.01925 # a starting point, may need adjusted to ensure accuracy!
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "${leg_1} Voltage"
          filters: [*throttle_avg, *pos]
        frequency:
          name: "${leg_1} Frequency"
          filters: [*throttle_avg, *pos]
      - id: phase_b  # see notes above
        input: RED
        calibration: 0.01925
        voltage:
          name: "${leg_2} Voltage"
          filters: [*throttle_avg, *pos]
        phase_angle:
          name: "${leg_2} Phase Angle"
          filters: [*throttle_avg, *pos]
    ct_clamps:
      # These non-throttled power sensors are used for accurately calculating energy.
      # Recommend not to specify a `name` for any of the power sensors here — only the `id`!
      # This leaves them internal to ESPHome locally; post-processed data is sent to HA below.
      - phase_id: phase_a
        input: "A"  # Verify the CT going to these devices input also matches the phase/leg
        power:
          id: phase_a_power
          device_class: power
          filters: [*pos]
      - phase_id: phase_b
        input: "B"
        power:
          id: phase_b_power
          device_class: power
          filters: [*pos]
      # Pay close attention to set the `phase_id` for each breaker by matching it to the phase/leg it connects to in the panel
      - { phase_id: phase_a, input:  "1", power: { id:  cir1, filters: [ *neg ] } }
      - { phase_id: phase_a, input:  "2", power: { id:  cir2, filters: [ *neg ] } }
      - { phase_id: phase_a, input:  "3", power: { id:  cir3, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "4", power: { id:  cir4, filters: [ *neg ] } }
      - { phase_id: phase_a, input:  "5", power: { id:  cir5, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "6", power: { id:  cir6, filters: [ *neg ] } }
      - { phase_id: phase_a, input:  "7", power: { id:  cir7, filters: [ *neg ] } }
      - { phase_id: phase_b, input:  "8", power: { id:  cir8, filters: [ *neg ] } }
      - { phase_id: phase_a, input:  "9", power: { id:  cir9, filters: [ *neg ] } }
      - { phase_id: phase_b, input: "10", power: { id: cir10, filters: [ *neg ] } }
      - { phase_id: phase_a, input: "11", power: { id: cir11, filters: [ *neg ] } }
      - { phase_id: phase_b, input: "12", power: { id: cir12, filters: [ *neg ] } }
      - { phase_id: phase_a, input: "13", power: { id: cir13, filters: [ *neg ] } }
      - { phase_id: phase_b, input: "14", power: { id: cir14, filters: [ *neg ] } }
      - { phase_id: phase_a, input: "15", power: { id: cir15, filters: [ *neg ] } }
      - { phase_id: phase_b, input: "16", power: { id: cir16, filters: [ *neg ] } }
    on_update:
      then:
        - component.update: total_power
        - component.update: balance_power

  # these `copy` sensors filter and send the power state to HA
  - { platform: copy, name: "${leg_1} Power", source_id: phase_a_power, filters: *throttle_avg }
  - { platform: copy, name: "${leg_2} Power", source_id: phase_b_power, filters: *throttle_avg }
  - { platform: copy, name: "Total Power", source_id: total_power, filters: *throttle_avg }
  - { platform: copy, name: "${xtra} Power", source_id: balance_power, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_1} Power", source_id:  cir1, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_2} Power", source_id:  cir2, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_3} Power", source_id:  cir3, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_4} Power", source_id:  cir4, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_5} Power", source_id:  cir5, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_6} Power", source_id:  cir6, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_7} Power", source_id:  cir7, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_8} Power", source_id:  cir8, filters: *throttle_avg }
  - { platform: copy, name:  "${cir_9} Power", source_id:  cir9, filters: *throttle_avg }
  - { platform: copy, name: "${cir_10} Power", source_id: cir10, filters: *throttle_avg }
  - { platform: copy, name: "${cir_11} Power", source_id: cir11, filters: *throttle_avg }
  - { platform: copy, name: "${cir_12} Power", source_id: cir12, filters: *throttle_avg }
  - { platform: copy, name: "${cir_13} Power", source_id: cir13, filters: *throttle_avg }
  - { platform: copy, name: "${cir_14} Power", source_id: cir14, filters: *throttle_avg }
  - { platform: copy, name: "${cir_15} Power", source_id: cir15, filters: *throttle_avg }
  - { platform: copy, name: "${cir_16} Power", source_id: cir16, filters: *throttle_avg }

  - platform: template
    lambda: return id(phase_a_power).state + id(phase_b_power).state;
    update_interval: never   # will be updated after all power sensors update via on_update trigger
    id: total_power
    device_class: power
    state_class: measurement
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "Total Daily Energy"
    power_id: total_power
    accuracy_decimals: 0
    restore: false
    filters: *throttle_time
  
  - platform: template
    lambda: !lambda |-
      return max(0.0f, id(total_power).state -
        id( cir1).state -
        id( cir2).state -
        id( cir3).state -
        id( cir4).state -
        id( cir5).state -
        id( cir6).state -
        id( cir7).state -
        id( cir8).state -
        id( cir9).state -
        id(cir10).state -
        id(cir11).state -
        id(cir12).state -
        id(cir13).state -
        id(cir14).state -
        id(cir15).state -
        id(cir16).state);
    update_interval: never   # still happens, but via `on_update` trigger (*after* all power sensors update)
    id: balance_power
    device_class: power
    state_class: measurement
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "${xtra} Daily Energy"
    power_id: balance_power
    accuracy_decimals: 0
    restore: false
    filters: *throttle_time
  
  - { power_id:  cir1, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_1} Daily Energy", filters: *throttle_time }  # ozone
  - { power_id:  cir2, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_2} Daily Energy", filters: *throttle_time }  # water pumps
  - { power_id:  cir3, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_3} Daily Energy", filters: *throttle_time }  # RV power
  - { power_id:  cir4, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_4} Daily Energy", filters: *throttle_time }
  - { power_id:  cir5, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_5} Daily Energy", filters: *throttle_time }
  - { power_id:  cir6, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_6} Daily Energy", filters: *throttle_time }
  - { power_id:  cir7, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_7} Daily Energy", filters: *throttle_time }
  - { power_id:  cir8, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_8} Daily Energy", filters: *throttle_time }
  - { power_id:  cir9, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name:  "${cir_9} Daily Energy", filters: *throttle_time }
  - { power_id: cir10, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_10} Daily Energy", filters: *throttle_time }
  - { power_id: cir11, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_11} Daily Energy", filters: *throttle_time }
  - { power_id: cir12, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_12} Daily Energy", filters: *throttle_time }
  - { power_id: cir13, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_13} Daily Energy", filters: *throttle_time }
  - { power_id: cir14, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_14} Daily Energy", filters: *throttle_time }
  - { power_id: cir15, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_15} Daily Energy", filters: *throttle_time }  # Solar A
  - { power_id: cir16, platform: total_daily_energy, accuracy_decimals: 0, restore: false, name: "${cir_16} Daily Energy", filters: *throttle_time }  # Solar B