Skip to content

Instantly share code, notes, and snippets.

@flaviut
Last active June 6, 2024 06:00
Show Gist options
  • Save flaviut/93a1212c7b165c7674693a45ad52c512 to your computer and use it in GitHub Desktop.
Save flaviut/93a1212c7b165c7674693a45ad52c512 to your computer and use it in GitHub Desktop.
Setting up Emporia Vue 2 with ESPHome
@browsean
Copy link

The external components shorthand link in the ESPHome code is broken. Does anyone have an idea on how to fix this? Was the link changed?

Here's what I'm using:
external_components:

  • source: github://flaviut/esphome@emporia-vue
    components: [ emporia_vue ]

@faelenor
Copy link

i'm not sure why these voltages are off I get 122v and 116v

@tylerwatt12 I had a look at the Vue circuit and made some tests with my multimeter and I think that the part of the circuit making the voltage readings is just badly designed. You should change the calibration values to get the voltage values closer to reality, but even when doing that, it won't be super accurate. I decided to live with it as a difference of 1 or 2 volts doesn't make a huge difference in the end.

Also noticed many of my CT's not showing any power reading, including my main A/B phase CT's.

Are you sure that the "audio" connectors are firmly connected to the Vue? Even when they look properly connected, they sometimes are not and you must push them hard. This is definitely what I hate the most about this device, these connectors are garbage!

@rananna
Copy link

rananna commented Apr 15, 2022

I'm having the exact same problem as @faelenor. I was previously using the Emporia app, and everything worked, so i'm not sure why these voltages are off I get 122v and 116v. I measure 120v on both phases using a multimeter going from the breaker connected to red (or black) and the neutral bus where the blue&white is connected. I've confirmed Red and Black are wired to different phases by metering both, and got 240v.

Also noticed many of my CT's not showing any power reading, including my main A/B phase CT's. Didn't make any changes to their configuration, I have all the CT wires wire-tied so they didn't move during the upgrade process.

Is it possible a firmware or hardware change could be the culprit?

[00:32:37][D][sensor:125]: 'Total Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:37][D][sensor:125]: 'Total Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:38][D][sensor:125]: 'Total Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:38][D][sensor:125]: 'Total Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:39][D][sensor:125]: 'Total Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:39][D][sensor:125]: 'Total Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Total Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Total Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Phase A Voltage': Sending state 117.10966 V with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Phase B Voltage': Sending state 123.97732 V with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Phase A Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Phase B Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 1 Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 1 Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 2 Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 2 Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 3 Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 3 Daily Energy': Sending state 0.10869 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 4 Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 4 Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 5 Power': Sending state 1.50708 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 5 Daily Energy': Sending state 1.12371 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 6 Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 6 Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 7 Power': Sending state 30.25700 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 7 Daily Energy': Sending state 16.23442 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 8 Power': Sending state 35.43851 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 8 Daily Energy': Sending state 22.35201 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 9 Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 9 Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 10 Power': Sending state 7.62167 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 10 Daily Energy': Sending state 4.54410 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 11 Power': Sending state 63.18918 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 11 Daily Energy': Sending state 34.56528 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 12 Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 12 Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 13 Power': Sending state 16.08334 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 13 Daily Energy': Sending state 9.04432 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 14 Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 14 Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 15 Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 15 Daily Energy': Sending state 0.00000 Wh with 0 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 16 Power': Sending state 0.00000 W with 1 decimals of accuracy
[00:32:40][D][sensor:125]: 'Circuit 16 Daily Energy': Sending state 0.00829 Wh with 0 decimals of accuracy

One thing to VERY carefully check is the phase id of the individual circuits. If this is wrong you will get a zero reading. Reverse the location of a/b main power cts(a to b and b to a) to see if that fixes the zero main power issue

@flaviut
Copy link
Author

flaviut commented Apr 18, 2022

The external components shorthand link in the ESPHome code is broken. Does anyone have an idea on how to fix this? Was the link changed?

@browsean probably a change in the upstream esphome code. I will try to find some time to integrate the update over the week.

@browsean
Copy link

My espHome was way outdated and still running through hacs on home assistant. I updated espHome and everything works now.

@EnDeRWiGiN
Copy link

Any chance you could do this for the Level 2 EV charger?

@flaviut
Copy link
Author

flaviut commented Apr 19, 2022

Any chance you could do this for the Level 2 EV charger?

I don't have one. But I would imagine that the two products have nothing in common, so this project wouldn't be a useful starting point.

Regardless, it would be cool if you could post photos of both sides of the circuit board. I'd be able to estimate the level of effort required for someone else (not me) to implement that.

@EnDeRWiGiN

@EnDeRWiGiN
Copy link

@flaviut From what I can tell it uses the same ESP32. Flashing a custom firmware on the ESP32 would probably work without affecting the rest of the functions of the charger. Here are some images from online. I can take better images later.

61g80CHOjnL
71UrscJc+qL
61L6d5JyIHL

@tylerwatt12
Copy link

One thing to VERY carefully check is the phase id of the individual circuits. If this is wrong you will get a zero reading. Reverse the location of a/b main power cts(a to b and b to a) to see if that fixes the zero main power issue

That was it. I had to reverse my mains CT clamps then the Phase A/B started reading, after that I didn't realize I had to specify which phase each circuit was on. Now it's all working smoothly. Thanks!

@crlogic
Copy link

crlogic commented Apr 21, 2022

IDF + MQTT is here!

esphome/esphome#2930

@flaviut
Copy link
Author

flaviut commented Apr 23, 2022

@crlogic Yes it is, very exciting! Feel free to test out, but note that I have not had a chance to test it myself.

Follow the instructions at https://esphome.io/guides/faq.html#how-do-i-update-to-the-latest-version to update esphome, and then update your config to this:

external_components:
  - source: github://flaviut/esphome@emporia-vue-2022.4.0
    components: [ emporia_vue ]

@EnDeRWiGiN thanks for the pictures! The main thing to note is that even though it also uses the esp32 (and it therefore compatible with esphome, given enough development), the other chips on the board are completely different from the Vue, and will have completely different software. This would have to be an independent reverse-engineering effort.

@browsean
Copy link

browsean commented Apr 24, 2022

I installed the 32 bit version of Home Assistant so I could compile the emporia espHome node. Now I'm getting these errors.

INFO Reading configuration /config/esphome/emporiavue2.yaml...
WARNING Found '${password}' (see api->password) which looks like a substitution, but 'password' was not declared
WARNING Found '${password}' (see ota->password) which looks like a substitution, but 'password' was not declared
WARNING Found '${ssid}' (see wifi->networks->0->ssid) which looks like a substitution, but 'ssid' was not declared
WARNING Found '${password}' (see wifi->networks->0->password) which looks like a substitution, but 'password' was not declared
INFO Detected timezone 'America/Denver'
INFO Generating C++ source...
INFO Compiling app...
Processing emporiavue2 (board: esp32dev; framework: espidf; platform: platformio/espressif32 @ 3.5.0)
--------------------------------------------------------------------------------
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
 - framework-espidf 3.40302.0 (4.3.2) 
 - tool-cmake 3.16.9 
 - tool-ninja 1.10.2 
 - toolchain-riscv32-esp 8.4.0+2021r2-patch2 
 - toolchain-xtensa-esp32 8.4.0+2021r2-patch2 
 - toolchain-xtensa-esp32s2 8.4.0+2021r2-patch2
Reading CMake configuration...
-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
-- The ASM compiler identification is unknown
-- Found assembler: /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc
-- Check for working C compiler: /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc
-- Check for working C compiler: /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc -- broken
-- Configuring incomplete, errors occurred!
See also "/data/emporiavue2/.pioenvs/emporiavue2/CMakeFiles/CMakeOutput.log".
See also "/data/emporiavue2/.pioenvs/emporiavue2/CMakeFiles/CMakeError.log".

fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
CMake Error at /data/cache/platformio/packages/tool-cmake/share/cmake-3.16/Modules/CMakeTestCCompiler.cmake:60 (message):
  The C compiler

    "/data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: /data/emporiavue2/.pioenvs/emporiavue2/CMakeFiles/CMakeTmp
    
    Run Build Command(s):/data/cache/platformio/packages/tool-ninja/ninja cmTC_46114 && [1/2] Building C object CMakeFiles/cmTC_46114.dir/testCCompiler.c.obj
    FAILED: CMakeFiles/cmTC_46114.dir/testCCompiler.c.obj 
    /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc   -mlongcalls -Wno-frame-address -o CMakeFiles/cmTC_46114.dir/testCCompiler.c.obj   -c testCCompiler.c
    /bin/sh: 1: /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc: not found
    ninja: build stopped: subcommand failed.
    
    

  

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  /data/cache/platformio/packages/framework-espidf/tools/cmake/project.cmake:311 (__project)
  CMakeLists.txt:3 (project)



========================= [FAILED] Took 10.42 seconds =========================

@flaviut
Copy link
Author

flaviut commented Apr 27, 2022 via email

@browsean
Copy link

We figured it out in the espHome forum. Thank you for the work you did btw. I had to have someone compile the code for me. I think I was running out of memory.

@Fran6u
Copy link

Fran6u commented May 5, 2022

I can't seem to get the code to compile, i keep getting the same error; (Tool Manager: Installing platformio/toolchain-esp32ulp @ ~1.22851.0
Error: Could not find the package with 'platformio/toolchain-esp32ulp @ ~1.22851.0' requirements for your system 'linux_aarch64') despite my esphome being the latest .
Any and all assistance is urgently needed. Thanks in advance.

@flaviut
Copy link
Author

flaviut commented May 5, 2022

@Fran6u
Copy link

Fran6u commented May 5, 2022

@flaviut Oh! missed that part of the documentation. Thanks. Although i have tried with 3 different computers but were all 64bit. I will look for and try it on a 32 bit and give a feedback. thanks again.

@Fran6u
Copy link

Fran6u commented May 5, 2022

@flaviut Sadly, tried with a 32bit computer but no luck.

@flaviut
Copy link
Author

flaviut commented May 5, 2022

Oh! missed that part of the documentation.

You didn't, I only wrote it just now :)

I'd need to see error logs to know what's wrong. If you're not able to compile anything ESPHome, I'd suggest reaching out on discord or their forums.

@Fran6u
Copy link

Fran6u commented May 5, 2022

@flaviut here's my log;

INFO Reading configuration /config/esphome/emporiavue2.yaml...
INFO Generating C++ source...
INFO Compiling app...
Processing emporiavue2 (board: esp32dev; framework: espidf; platform: platformio/espressif32 @ 3.5.0)
--------------------------------------------------------------------------------
Tool Manager: Installing platformio/toolchain-esp32ulp @ ~1.22851.0
Error: Could not find the package with 'platformio/toolchain-esp32ulp @ ~1.22851.0' requirements for your system 'linux_aarch64'

@Gagi2k
Copy link

Gagi2k commented May 5, 2022 via email

@Fran6u
Copy link

Fran6u commented May 5, 2022

@flaviut, @Gagi2k So I have installed a new HA + Esphome (32bit) on a RPI3 and tried compiling, but still having errors (different from the previous). Here is the new error, any ideas?

HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
 - framework-espidf 3.40302.0 (4.3.2) 
 - tool-cmake 3.16.9 
 - tool-ninja 1.10.2 
 - toolchain-riscv32-esp 8.4.0+2021r2-patch2 
 - toolchain-xtensa-esp32 8.4.0+2021r2-patch2 
 - toolchain-xtensa-esp32s2 8.4.0+2021r2-patch2
Reading CMake configuration...
-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
-- The ASM compiler identification is unknown
-- Found assembler: /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc
-- Check for working C compiler: /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc
-- Check for working C compiler: /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc -- broken
-- Configuring incomplete, errors occurred!
See also "/data/emporiavue2/.pioenvs/emporiavue2/CMakeFiles/CMakeOutput.log".
See also "/data/emporiavue2/.pioenvs/emporiavue2/CMakeFiles/CMakeError.log".

fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
CMake Error at /data/cache/platformio/packages/tool-cmake/share/cmake-3.16/Modules/CMakeTestCCompiler.cmake:60 (message):
  The C compiler

    "/data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: /data/emporiavue2/.pioenvs/emporiavue2/CMakeFiles/CMakeTmp
    
    Run Build Command(s):/data/cache/platformio/packages/tool-ninja/ninja cmTC_33678 && [1/2] Building C object CMakeFiles/cmTC_33678.dir/testCCompiler.c.obj
    FAILED: CMakeFiles/cmTC_33678.dir/testCCompiler.c.obj 
    /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc   -mlongcalls -Wno-frame-address -o CMakeFiles/cmTC_33678.dir/testCCompiler.c.obj   -c testCCompiler.c
    /bin/sh: 1: /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc: not found
    ninja: build stopped: subcommand failed.
    
    

  

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  /data/cache/platformio/packages/framework-espidf/tools/cmake/project.cmake:311 (__project)
  CMakeLists.txt:3 (project)  >

@flaviut
Copy link
Author

flaviut commented May 5, 2022

@Fran6u last person who ran into this said that they thought they ran out of memory: https://gist.github.com/flaviut/93a1212c7b165c7674693a45ad52c512?permalink_comment_id=4147507#gistcomment-4147507

I think the issue might be esphome/issues#3076, which apparently will be resolved "soon" :(

You could try building and installing from a desktop/laptop.

@Fran6u
Copy link

Fran6u commented May 6, 2022

@flaviut Just a feedback. I was eventually able to compile the code manually on a laptop running Ubuntu. Many thanks for your help

@cpyarger
Copy link

cpyarger commented May 8, 2022

What can we do to remove the platform restriction, I see that you have it set to only compile on the esp-idf platform. but most users won't have a development environment setup using their desktop, and will be running esphome on a pi,

I noticed that there are issues reading the sensors from the i2c bus when you remove the esp-idf restriction and compile with the arduino platform.

My thought is it's best to make things as accessible as possible for as many as possible.
otherwise great work! it seems to be running pretty solidly on my emporia vue 2

@flaviut
Copy link
Author

flaviut commented May 8, 2022

Great question @cpyarger. The reason things are running on esp-idf is because the esp32-arduino project did not support i2c messages longer than 256 bytes. This has been resolved in one of the patch releases of v2.0: espressif/arduino-esp32@7bb30b3

And very recently, it looks like platformio has been updated to also support esp32-arduino v2.0: platformio/platform-espressif32@581c7d0

However, I don't think that switching to esp32-ardunio will be helpful because v2 is based on esp-idf. I'm not sure what the problem here is exactly, but I think someone will need to fix it rather than try and work around it.

@kerhbal
Copy link

kerhbal commented May 11, 2022

@flaviut thanks a lot for this project! though my power for one 200A clamp is nonsense:(right part of graph is raw data without filter)
Safari-Overview – Home Assistant--2022-05-10 at 23 54 59
and power for the other 200A clamp is fine

will incorrect clamp direction cause this?(I'm pretty sure I followed the instruction and they look similar to the image posted in above discussions)
and also does phase A need BLACK as hardcoded or as long as everything is consistent then it's fine? since I find that my black is connected to right/B panel, and red is connected to left/A panel. I just changed them in yaml as well.

@flaviut
Copy link
Author

flaviut commented May 11, 2022

@kerhbal that's definitely not incorrect clamp direction. Is everything plugged completely? I found that the clamp connector likes getting lose.

If that's not the problem, are you on a 2 of 3 legs system? In North America, that's usually multi-family homes, commercial, and industrial situations. Do you have the colored wires lined up correctly with the phases in your config?

@kerhbal
Copy link

kerhbal commented May 11, 2022

@flaviut my bad... I accidentally plugged my phase A to C socket, after change it now the power is all good. this is wonderful, thanks!

@kerhbal
Copy link

kerhbal commented May 11, 2022

very happy to be off the hook from their cloud lol, who knows when they unplug the server...

@Fran6u
Copy link

Fran6u commented May 12, 2022

@flaviut Hi. So after installation I noticed my reading seems to be a decimal out of place (lower than expected) How do you recommend I fix this? Screenshot attached.
Screenshot_20220512-082438

@flaviut
Copy link
Author

flaviut commented May 13, 2022

@flaviut Hi. So after installation I noticed my reading seems to be a decimal out of place (lower than expected) How do you recommend I fix this?

Not sure I understand what's going on. If it's a 5% or so error, you can tune the calibration values.

If it's something else, same advice as before: make sure all connections are tight and maybe all clamps are fully closed

@Fran6u
Copy link

Fran6u commented May 13, 2022

@flaviut It seems to be measuring energy at 10% fraction. And the calibration only affects the voltage and not the energy use.
Also, I seem to be recording values on "circuits 1 & 16" which has no sensors plugged in. Thanks in advance.
Screenshot_20220513-113637

@flaviut
Copy link
Author

flaviut commented May 13, 2022

I'm really not sure what the problem might be. Sometimes the cables look plugged in, but they're just slightly unplugged. You can try using a multimeter to carefully debug things.

And you should remove the channels you don't use from the config. It's expected to see gibberish data on them.

@Fran6u
Copy link

Fran6u commented May 13, 2022

I'm really not sure what the problem might be. Sometimes the cables look plugged in, but they're just slightly unplugged. You can try using a multimeter to carefully debug things.

And you should remove the channels you don't use from the config. It's expected to see gibberish data on them.

I will just start afresh; take it all apart and re-install. Hopefully i would find the issue/issues.

@flaviut
Copy link
Author

flaviut commented May 13, 2022 via email

@ripvega
Copy link

ripvega commented May 15, 2022

This is an excellent piece of work. I have 4 Vue 2s and have ordered another to flash.

The hardware measures data every ¼ second, so you have quite a bit to work with. You do need to remove the sliding_window_moving_average since you do not want smoothed-out data.

Is there any way that the individual CTs can be calibrated/filtered individually? For some I need to catch the motor start spikes and for others the sliding_window_moving_average will be more appropriate.

Are any of the GPIOs still available to be used? I'm considering adding the Home Assistant Glow progect in to the Vue.

Keep up the excellent work!

@flaviut
Copy link
Author

flaviut commented May 15, 2022

Is there any way that the individual CTs can be calibrated/filtered individually?

Yes: the &foo and *foo is just a shorthand, as is the [a, b, c]. Each sensor has a set of filters, see https://esphome.io/components/sensor/index.html for details.

Are any of the GPIOs still available to be used?

I haven't checked, but I expect them to be available. Just I2C is used for communication. For me, the UL listing was a big part of why I went with this device over a DIY one, and making that kind of modification would make it no longer listed

@ripvega
Copy link

ripvega commented May 15, 2022

Where should I be seeing "&foo and *foo is just a shorthand, as is the [a, b, c]".

They're not in my yaml from the example.

@flaviut
Copy link
Author

flaviut commented May 15, 2022

foo is a placeholder. *moving_avg for example.

@jdavis7765
Copy link

This is probably a stupid question, but I see a few changes have been made to the configuration. Most notably, the calibration piece for phase a/b voltage. Anyway, I would need to change my current config and install like normal or does anything else need to be done? Assuming none of the sensor names change should everything continue to work as usual?

Thanks

@flaviut
Copy link
Author

flaviut commented May 17, 2022

If I remember correctly, there have been no backwards incompatible changes to the configuration. You are welcome to use your existing config. New options would just be filled in with reasonable defaults.

@ripvega
Copy link

ripvega commented May 18, 2022

@ccpk1 Ohhh, I like the balance/other power section. Someone I know is going to steal that. =)

I also added this in my HA configuration.yaml:

template:
  - sensor:
      - name: "Home Total Power"
        unit_of_measurement: "W"
        device_class: power
        state: >
          {{ [ states('sensor.home1_total_power'), 
               states('sensor.home2_total_power') ]
               | map('float') | sum }}
        availability: >
          {{ not 'unavailable' in 
             [ states('sensor.home1_total_power'), 
               states('sensor.home1_total_power') ] }}

This was stolen/merged from a couple sources but gives a nice single total power for the house for graphing/metering. It would be easy to make home_total_energy, but the stock Energy dashboard is happy enough adding a couple things so... shrug

Forgive my templating ignorance. Is this adding sensor.home1_total_power and sensor.home2_total_power to give Home Total Power and the 'availabilty' checks that both sensors are available before doing the SUM?

@flaviut
Copy link
Author

flaviut commented May 18, 2022

Is this adding sensor.home1_total_power and sensor.home2_total_power to give Home Total Power and the 'availabilty' checks that both sensors are available before doing the SUM?

I believe that's right, and that it works using the availability key. I can't find the appropriate documentation however.

If you do find it, I'd appreciate it if you'd come back and share it here!

@ripvega
Copy link

ripvega commented May 18, 2022

I'm seeing some odd behaviour that I don't understand.
Screenshot 2022-05-18 at 10 50 49
In the screen shot above it shows voltage at 240, power at 0 and current at 0.63.
Where is the current coming from?

My config is as below:

esphome:
  name: emporia-main

external_components:
  - source: github://flaviut/esphome@emporia-vue-2022.4.0
    components: [ emporia_vue ]

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

# Enable Home Assistant API
api:

ota: 
  safe_mode: true
  password: !secret OTA_password

# Enable logging
logger:

wifi:
  ssid: !secret dryderdale_wifi_SSID
  password: !secret dryderdale_wifi_password

i2c:
  sda: 21
  scl: 22
  scan: false
  frequency: 200kHz  # recommended range is 50-200kHz
  id: i2c_a
time:
  - platform: sntp
    id: my_time

# these are called references in YAML. They allow you to reuse
# this configuration in each sensor, while only defining it once
.defaultfilters:
  - &moving_avg
    # we capture a new sample every 0.24 seconds, so the time can
    # be calculated from the number of samples as n * 0.24.
    sliding_window_moving_average:
      # we average over the past 2.88 seconds
      window_size: 12
      # we push a new value every 1.44 seconds
      send_every: 6
  - &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);'
  - &multiply # Current scaling factor
    lambda: 'return x * 0.01;'

sensor:
  - platform: emporia_vue
    i2c_id: i2c_a
    phases:
      - id: main_house_phase  # 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.022  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "Main House Voltage"
          filters: [*moving_avg, *pos]
      # - id: phase_b  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
      #   input: RED  # Vue device wire color
      #   calibration: 0.022  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
      #   # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
      #   voltage:
      #     name: "Phase B Voltage"
      #     filters: [*moving_avg, *pos]
    ct_clamps:
      - phase_id: main_house_phase
        input: "C"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Main House Power"
          id: main_house_power
          device_class: power
          filters: [*moving_avg, *pos]
        current:
          name: "Main house current"
          id: main_house_current
          device_class: current
          filters: [*moving_avg, *pos, *multiply]
      # - phase_id: phase_b
      #   input: "B"  # Verify the CT going to this device input also matches the phase/leg
      #   power:
      #     name: "Phase B Power"
      #     id: phase_b_power
      #     device_class: power
      #     filters: [*moving_avg, *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: main_house_phase, input:  "1", power: { name:  "Hob Power", id:  cir1, filters: [ *moving_avg, *pos ] } }
      - { phase_id: main_house_phase, input:  "2", power: { name:  "Oven/Microwave Power", id:  cir2, filters: [ *moving_avg, *pos ] } }
      - { phase_id: main_house_phase, input:  "3", power: { name:  "Kitchen sockets Power", id:  cir3, filters: [ *moving_avg, *pos ] } }
      # - { phase_id: main_house_phase, input:  "4", power: { name:  "Dining room & lounge sockets Power", id:  cir4, filters: [ *moving_avg, *pos ] } }
      # - { phase_id: main_house_phase, input:  "5", power: { name:  "First floor sockets Power", id:  cir5, filters: [ *moving_avg, *pos, multiply: 2 ] } }
      # - { phase_id: main_house_phase, input:  "6", power: { name:  "Main House Water Heater Power", id:  cir6, filters: [ *moving_avg, *pos, multiply: 2 ] } }
      # - { phase_id: main_house_phase, input:  "7", power: { name:  "Hall lights Power", id:  cir7, filters: [ *moving_avg, *pos, multiply: 2 ] } }
      # - { phase_id: main_house_phase, input:  "8", power: { name:  "Lounge/Dining/Cloaks lights Power", id:  cir8, filters: [ *moving_avg, *pos ] } }
      # - { phase_id: main_house_phase, input:  "9", power: { name:  "First floor lights Power", id:  cir9, filters: [ *moving_avg, *pos ] } }
      # - { phase_id: main_house_phase, input: "10", power: { name: "Mains cupboard light Power", id: cir10, filters: [ *moving_avg, *pos ] } }
      # - { phase_id: main_house_phase, input: "11", power: { name: "Attic WiFi Power", id: cir11, filters: [ *moving_avg, *pos, multiply: 2 ] } }
      # - { phase_id: main_house_phase, input: "12", power: { name: "Intruder alarm Power", id: cir12, filters: [ *moving_avg, *pos, multiply: 2 ] } }
      # - { phase_id: main_house_phase, input: "13", power: { name: "Basement lights Power", id: cir13, filters: [ *moving_avg, *pos ] } }
      - { phase_id: main_house_phase, input: "14", power: { name: "Hall socket Power", id: cir14, filters: [ *moving_avg, *pos ] } }
      - { phase_id: main_house_phase, input: "15", power: { name: "Security lights Power", id: cir15, filters: [ *moving_avg, *pos ] } }
      - { phase_id: main_house_phase, input: "16", power: { name: "Charging sockets Power", id: cir16, filters: [ *moving_avg, *pos ] } }
  - platform: template
    name: "Main House Total Power"
    lambda: return id(main_house_power).state; # + id(phase_b_power).state;
    update_interval: 1s
    id: main_house_total_power
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "Main House Total Daily Energy"
    power_id: main_house_total_power
    accuracy_decimals: 0
  - { power_id:  cir1, platform: total_daily_energy, accuracy_decimals: 0, name:  "Hob Daily Energy" }
  - { power_id:  cir2, platform: total_daily_energy, accuracy_decimals: 0, name:  "Oven/Microwave Daily Energy" }
  - { power_id:  cir3, platform: total_daily_energy, accuracy_decimals: 0, name:  "Kitchen sockets Daily Energy" }
  # - { power_id:  cir4, platform: total_daily_energy, accuracy_decimals: 0, name:  "Dining room & lounge sockets Daily Energy" }
  # - { power_id:  cir5, platform: total_daily_energy, accuracy_decimals: 0, name:  "First floor sockets Daily Energy" }
  # - { power_id:  cir6, platform: total_daily_energy, accuracy_decimals: 0, name:  "Main House Water Heater Daily Energy" }
  # - { power_id:  cir7, platform: total_daily_energy, accuracy_decimals: 0, name:  "Hall lights Daily Energy" }
  # - { power_id:  cir8, platform: total_daily_energy, accuracy_decimals: 0, name:  "Lounge/Dining/Cloaks lights Daily Energy" }
  # - { power_id:  cir9, platform: total_daily_energy, accuracy_decimals: 0, name:  "First floor lights Daily Energy" }
  # - { power_id: cir10, platform: total_daily_energy, accuracy_decimals: 0, name: "Mains cupboard light Daily Energy" }
  # - { power_id: cir11, platform: total_daily_energy, accuracy_decimals: 0, name: "Attic WiFi Daily Energy" }
  # - { power_id: cir12, platform: total_daily_energy, accuracy_decimals: 0, name: "Intruder alarm Daily Energy" }
  # - { power_id: cir13, platform: total_daily_energy, accuracy_decimals: 0, name: "Basement lights Daily Energy" }
  - { power_id: cir14, platform: total_daily_energy, accuracy_decimals: 0, name: "Hall socket Daily Energy" }
  - { power_id: cir15, platform: total_daily_energy, accuracy_decimals: 0, name: "Security lights Daily Energy" }
  - { power_id: cir16, platform: total_daily_energy, accuracy_decimals: 0, name: "Charging sockets Daily Energy" }

  - platform: template       # Sum of all cir wattages
    name: "Main house Calculated total watts"
    id: calculated_total_watts
    lambda: |-
      return (id(cir1).state + id(cir2).state + id(cir3).state + id(cir14).state + id(cir15).state + id(cir16).state);
    update_interval: 60s
    accuracy_decimals: 0
    # Take the total power and subtract all of the individually monitored circuits which will result in the remaining balance of power that is not individually monitored
  - platform: template
    name: "Main house Balance Power"
    lambda: return max((id(main_house_total_power).state - id(cir1).state - id(cir2).state - id(cir3).state - id(cir14).state - id(cir15).state - id(cir16).state), 0.0f);
    update_interval: 3s
    id: balance_power
    unit_of_measurement: "W"

I've had to add a multiply filter of 0.01 to get sensible current readings as it was showing 28,000 amps at one point!

@kingdogfish
Copy link

I've tried to search, has anyone successfully done this to a standard "Emporia Vue" ... the sticker says "Gen 2 Emporia Vue Smart....eter"

@flaviut
Copy link
Author

flaviut commented May 19, 2022

@ripvega I'm sorry, but I really don't know what's going on. You shouldn't have to do that multiplication. Maybe try re-flashing, increasing the logging level and posting logs, or double-checking that things are inserted tightly?

@kingdogfish if it looks like this, you should be fine:
60358c6f103e38508decf08d_Gen-2-Vue-Hero-Moble. The older model looks different and is neither compatible or possible to add support for here.

@crlogic
Copy link

crlogic commented May 19, 2022

Has anyone else noticed erroneous energy spikes and wifi drop-outs using ESPHome v2022.5.0? v2022.4.0 was solid for me.

@gbuntin
Copy link

gbuntin commented May 20, 2022

I've looked at this type of thing for a long time but finally decided to buy one after finding this hack. Being a complete newby when it comes to ESPHome, I'm wondering about what you have the Vue2 connected to... Ultimately I would want to use an RPi but do I need something between the Vue2 and the RPi?

Thanks for figuring out this hack... I'm anxious to try it

@ripvega
Copy link

ripvega commented May 20, 2022

I would bet that practically everyone who's done this is using it with Home Assistant and running HA on a Raspberry Pi is a good start.
ESPHome is very well integrated with HA these days.

@gbuntin
Copy link

gbuntin commented May 21, 2022

Thanks for the reply.

So assuming I have this right: Vue2 connected to -> USB to Serial Adapter connected to -> RPi (with Home Automation & ESPHome)

@ripvega
Copy link

ripvega commented May 21, 2022

You would need HA running on the Pi. Flash the Vue with ESPHome and then the Vue is integrated into HA over you network. There’s no USB involved.

I would begin by getting to grips with HA and integrations in the Pi and then flash and integrate the Vue.

I have 5 Vues and the they work great with HA.

@gbuntin
Copy link

gbuntin commented May 21, 2022

OH! I think I get it. The disconnect for me was that ESPHome runs on the Vue. I guess the USB to Serial is only required to flash and configure(?) the Vue to get it on the network. I was thinking that was a permanent connection to the PI.

I doubt getting HA running is going to be much trouble in and of itself. The community is pretty good and I already have several PIs running doing various things (Jukebox, Pi Hole, web dev, LED matricies)

Thank you again for the insights.

@Resterday
Copy link

I'm having an issue creating the esphome image. I have esphome as an addon on a rpi 4 and I am trying to do a manual download to my windows 11 laptop. The error I'm getting is pasted in this issue esphome/issues#3076 (comment)

Not sure if this is related to the "I'm using a raspi..." Note above but any help would be greatly appreciated!

@cpyarger
Copy link

There are currently issues with the esp-idf framework that break the emporia vue component.

easiest solution - build it on your computer locally.
next easiest, I threw together a quick esphome template, complete with ability to flash via web, or download the firmware, and you can use the prebuilt firmware if you want.
as long as you are ok with renaming your circuits inside home assistant for now

Work is being done to get the vue component able to be built on the pi

the templated firmware is here:
https://cpyarger.github.io/esphome-templates/

@cpyarger
Copy link

Just figured it might be useful to some to have a prebuilt firmware for the vue2.
it has both esp32-improv and improv_serial for doing the wifi connection
wifi AP password on all the devices is 12345678

@Resterday
Copy link

Thanks @cpyarger ! could you point me in the direction for how to build it on my computer? I want to make sure I've got the configuration set correctly for my wiring.

@flaviut
Copy link
Author

flaviut commented May 21, 2022

There's a guide at the top of this page on how to build this.

@Resterday
Copy link

@flaviut I see that it says to run esphome run vue2.yaml in console but where does vue2.yaml come from, and I get an error saying esphome is not a command.

@cpyarger
Copy link

Thanks @cpyarger ! could you point me in the direction for how to build it on my computer? I want to make sure I've got the configuration set correctly for my wiring.

The esphome website, Google, or Youtube are all good choices

@Jabroni
Copy link

Jabroni commented May 23, 2022

Does this currently support the 3 phases Emporia systems? I was able to flash, but I just see Phase A / B

@Sc00bs110
Copy link

@Jabroni You need to reconfigure the sample configuration file that was provided and get ESPhome to upload it for you. There is a pretty good video on it at https://www.youtube.com/watch?v=z0Jv4nO9OWg

@cpyarger
Copy link

Does this currently support the 3 phases Emporia systems? I was able to flash, but I just see Phase A / B

I am uploading a template for 3 phase, but I can't guarantee that the individual circuits will properly be set up as you need to set their phase in the config

@gregsheremeta
Copy link

Sharing in case this helps someone else out. For some reason I could not get the ESP32 into bootloader with my CH340G using 5V (my model supports both 3.3v and 5v). The Vue2 appeared to power on over 5v -- no long beep chime from the Vue2 -- but "no serial data" either. I had to use 3.3v to get it to work.

Powered the ESP32 via 5v, didn't ground IO1 - green LED, no chime.
Powered the ESP32 via 5v, grounded IO1 - green LED, no chime, but "no serial data" / could not connect.
Powered the ESP32 via 3.3v, didn't ground IO1 - green LED, long chime beep from Vue2. (Awfully obnoxious.)
Powered the ESP32 via 3.3v, grounded IO1 - green LED, no chime beep, and serial connection works as expected.

@tylerwatt12
Copy link

I recently had to hide the SSID to my IoT network and noticed my emporia wasn't connected. I had no other way to reconfigure without taking it apart and plugging it into serial. You may want to consider adding these lines in the wifi option, which will allow the ESPHome device go into a fallback AP mode in case your WiFi info gets changed.

wifi:
  ap:
      ssid: "emporiaVue2"
      password: "12345678"

Also to allow ESPHome to connect to a hidden SSID, simply add this line

fast_connect: true

right under wifi:, after the password.

@HunterWare
Copy link

HunterWare commented May 25, 2022 via email

@wollinger69
Copy link

Ultra noob here.

I finally got to flash ESPHome on my Vue2 ( i think so) and I can see it Discovered on the Integration list with the option to configure it but when i click to do so, it asks for a password I set in your configuration for vue2....

Where was that done? which pw would be a default pw?

the only thing i edited on the lines were my wifi info.

@flaviut
Copy link
Author

flaviut commented May 30, 2022

@wollinger69 I can see how this situation might be tricky for someone who's not familiar with ESPHome. Unfortunately I don't have time to break it down further right now :(

Anyway, to your question: take a look at your config around

api: {"password": "<ota password>"}
ota: {"password": "<ota password>"}

Your passwords are inside the quotes after the : . If you haven't changed them already, you should. It's a bit tricky to change the OTA password OTA, but it is doable.

@wollinger69
Copy link

@flaviut

thank you, i had tried some combinations but your tip helped, i used what's after : and it worked

@wollinger69
Copy link

wollinger69 commented May 30, 2022

i got it to work and connect to HA but the measurements are not goo at all, the only one that seems to be working is the breaker to my PC, i have the dryer on and besides the PC, everything else is 0W or single digits.
the Phase A power is between 0 and 90 W, B is always 0

I'll play around with *moving_avg, *pos, multiply: 2 on the double breakers config.

@flaviut
Copy link
Author

flaviut commented May 30, 2022

@wollinger69 Can you take a look at the FAQ and see if you can use that to try and resolve the problems? Particularly "I'm seeing zeros on certain current clamps".

@wollinger69
Copy link

yep.. sorry.. i jumped the gun, im recompiling it now with some changes.

@halomakes
Copy link

Hello, I got this flashed on my vue and it shows up correctly when I give it 3.3V from my flasher. however when I plug it in at the breaker box I see the indicator led come on but then it never connects to the network. I was wondering if anyone else has seen this behavior

@gregsheremeta
Copy link

I was wondering if anyone else has seen this behavior

Not when connected at the breaker box, but I couldn't get it to find the wifi while still connected to 3.3v. I had forgotten to attach the antenna 😄

@halomakes
Copy link

halomakes commented Jun 3, 2022

It has the same behavior when I power 5V directly, I wonder if maybe the 3.3V regulator is bad or something. I did get it used. Will try stock firmware for a sanity check
update: yeah it's like that on stock image as well. I'm going to remove the header pins and exchange the unit

@maegibbons
Copy link

Hi

Just got a vue 2 board to run this.

Did any of you find that your header holes were not through the board? Mine appear to be only half drilled!

Or are they pre-filled with solder?

Krs

Mark

@gregsheremeta
Copy link

Mine were filled with solder. It was easy to remove with desoldering wick.

@HunterWare
Copy link

HunterWare commented Jun 7, 2022 via email

@maegibbons
Copy link

Thanks guys!!

@fabiopbx
Copy link

fabiopbx commented Jun 8, 2022

Hi all,
I've been running this for a long time now, and recently noticed the watt readings are way off... I read and re-read this entire thread multiple times and I unable to figure out why, is there any configuration I missed?

Images shows ~1240 W but the math ( current * voltage = watts ) says this should be more like 800 W, as it stands I'm always somehow consuming huge amounts of wattage. I get a reading in HA of something 999.1 kWh a month... which doesn't feel right. Am I missing something?

Single phase setup, 1 CT clamp.

image

@flaviut
Copy link
Author

flaviut commented Jun 8, 2022

@fabiopbx the current reading doesn't work. I've never been able to figure it out, and there's been some past discussion where others couldn't figure it out either. I would recommend against using the current sensor.

I'd suggest you use a multimeter with a current clamp (don't touch any metal with your fingers! this stuff can easily kill you!) to see what's going on and if the kW reading is inaccurate. If you want current, you can always calculate it using power/voltage.

@fabiopbx
Copy link

fabiopbx commented Jun 8, 2022

@flaviut yh I had a reading of 300amps and such before I saw there was an update to the gist with a filter to multiply it and make it much more probable, so your reckon the wattage reading should be accurate? wouldnt that be dependant on the current reading from the CT? I don’t mind it being a little off, but it feels very high..

@BlagovestKambarev
Copy link

@fabiopbx I am currently writing a driver for Tasmota. I also made a lot of measurements and came to the conclusion that the data from the CT are not accurate. The most accurate are the indications for consumption in the "Power data" section. Only from the readings of the CT I get whether there is a current transformer attached to the channel. If the CT readings are larger than 20400, there is no current transformer attached to the channel. This determines dynamically which channel is used and which is not. Even if the CT coefficient is used when there is a current transformer connected, but the one that does not measure has an indication such as 80-90-105 mA. Which is not OK. If I try to remove these readings and they are 0, then the measurements are not accurate. Therefore, in my writing so far I do not use the data for CT.

@hfuller
Copy link

hfuller commented Jun 11, 2022

Hey, I am here to say I followed this guide and it worked 100%.
I did comment out the total phase power measurements as I did not want to put clamps on my main service feeder. I replaced the summing logic for total power, with logic that sums all of my circuits. (My kit came with 16 clamps so I was able to clamp all 13 of my circuits.)
I had never used ESPHome in my life and this worked the first time. Thank you so much.

@cliffkujala
Copy link

@flaviut thank you very much for your work and clear write up on how to get these devices flashed over to esphome.

I was curious if you could give some insight into how best to configure multiple VUE2 devices inside one main panel, and then how to configure other VUE2 devices for monitoring subpanels that are below those main panels.

In my setup I have a main panel with more than 16 circuits, and then 1 subpanel that is fed by a breaker inside that main panel. So I only need "Total Power" from CT A and CT B on VUE2 #1, and then just the individual circuits from the rest of the CT's.

I guess the main question here is how to edit the config yaml so that it eliminates the Phase A Power, Phase B Power, Total Power, and Total Daily Energy sensors from being created by any of the VUE2's besides the "main" VUE2 which actually has CT's installed on the main power supply lines.

@VivantSenior
Copy link

Can anyone please share the esptool commands to flash the .bin file manually without ESPHome or esphome-flash? Have multiple reasons, but mostly also want to learn/document how to do this without other dependencies.

Step 1 esptool.py --chip esp32 erase_flash

Step 2 esptool.py --chip esp32 write_flash -z 0x1000 myvue.bin

However, it seems to be stuck in a boot loop, even after trying to flash it with ESPHome on another system. I'm guessing I missed something, maybe partitioning related?

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371
ets Jun  8 2016 00:22:57

I had similar issue. Reason for that was underpowered the ESP chip. By miastake I've mixed up 3.3 and 5V on the USB TTL. USB TTL jumer was set to 3.3V but I connected it to 5V on the ESP side. There were no issues with the firmware upload but when I tried to run Emporia by itself I received similar information. ESP was not able to connect to the wifi but I was able to get the (a lots of) logs in the HA addon using USB connection (it fell in the boot loop). Check your connections.

@flaviut thank you for sharing the code.

@mgulick
Copy link

mgulick commented Jun 13, 2022

Can anyone please share the esptool commands to flash the .bin file manually without ESPHome or esphome-flash? Have multiple reasons, but mostly also want to learn/document how to do this without other dependencies.
Step 1 esptool.py --chip esp32 erase_flash
Step 2 esptool.py --chip esp32 write_flash -z 0x1000 myvue.bin
However, it seems to be stuck in a boot loop, even after trying to flash it with ESPHome on another system. I'm guessing I missed something, maybe partitioning related?

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371
ets Jun  8 2016 00:22:57

I had similar issue. Reason for that was underpowered the ESP chip. By miastake I've mixed up 3.3 and 5V on the USB TTL. USB TTL jumer was set to 3.3V but I connected it to 5V on the ESP side. There were no issues with the firmware upload but when I tried to run Emporia by itself I received similar information. ESP was not able to connect to the wifi but I was able to get the (a lots of) logs in the HA addon using USB connection (it fell in the boot loop). Check your connections.

@flaviut thank you for sharing the code.

I was able to flash using esptool.py using the 3.3V from the FTDI adapter, but after flashing it was unable to boot up to the point where it would connect to wifi. The logs had a message about brownout detected. It worked fine after switching the FTDI to 5V and connecting to the 5V input instead of 3.3V.

@flaviut
Copy link
Author

flaviut commented Jun 13, 2022

@cliffkujala

Very simple! Just delete the entries for whatever you don't want. Don't want the phase a current? Delete this from the example:

      - phase_id: phase_b
        input: "B"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Phase B Power"
          id: phase_b_power
          device_class: power
          filters: [*moving_avg, *pos]

@cpyarger
Copy link

cpyarger commented Jun 13, 2022 via email

@cliffkujala
Copy link

cliffkujala commented Jun 14, 2022

@flaviut

Deleting the chunk of code you pasted means the build will fail because "phase_b_power" is no longer available to calculate the lambda for the Total Power template sensor.

  - platform: template
    name: "Total Power"
    lambda: return id(phase_a_power).state + id(phase_b_power).state;
    update_interval: 1s
    id: total_power
    unit_of_measurement: "W"

Deleting that template sensor then results in a fail because "total_power" is not available to calculate Total Daily Energy

  - platform: total_daily_energy
    name: "Total Daily Energy"
    power_id: total_power
    accuracy_decimals: 0

Deleting the Total Daily Energy Sensor results in what looks like a clean config with no warnings for non existent items being referenced, but then fails with the following result when trying to push the config to the device.

*** [/data/emporiavue2-02/.pioenvs/emporiavue2-02/src/esphome/components/template/sensor/template_sensor.o] Source `src/esphome/components/template/sensor/template_sensor.cpp' not found, needed by target `/data/emporiavue2-02/.pioenvs/emporiavue2-02/src/esphome/components/template/sensor/template_sensor.o'.
========================== [FAILED] Took 4.30 seconds ==========================

@flaviut
Copy link
Author

flaviut commented Jun 14, 2022

@cpyarger that's right, thanks for pointing that out!

@cliffkujala you've definitely gone down the right path. Interesting error—looks like some sort of bug where the cached files are out of date. Are you able to delete .pioenvs and try again? I'm not sure how you have ESPHome installed, so I can't give more detailed advice.

You might also want to reach out to the ESPHome community directly to ask about this, but if you do that, make sure to come back and let us know how you solved it!

@cliffkujala
Copy link

@flaviut I am using ESPHOME via Home Assistant Add-on. Your comment regarding cache reminded me I should try to "Clean Build Files" and then reinstall the config. That was the trick. I now have just the power sensors for my "nested" VUE2 devices like I want.

Thanks again for this awesome project.

@Sc00bs110
Copy link

Sc00bs110 commented Jun 15, 2022

Hi Everyone,

I have a single phase 230V configuration.

The config file below was working fine but I am now getting an error in the logs and no readings after upgrading using ESPHome.

[16:31:55][E][emporia_vue:048]: Failed to read from sensor due to I2C error 3

Any ideas as to what could be causing the problem? I have tried changing the Frequency but doesn't seem to make any difference.

Logs -

INFO Reading configuration /config/esphome/emporia.yaml...
INFO Detected timezone 'Africa/Johannesburg'
INFO Starting log output from emporiavue2.local using esphome API
INFO Successfully connected to emporiavue2.local
[16:31:54][I][app:102]: ESPHome version 2022.3.1 compiled on Apr 23 2022, 10:32:39
[16:31:54][C][wifi:491]: WiFi:
[16:31:54][C][wifi:353]:   Local MAC: AC:67:B2:63:53:54
[16:31:54][C][wifi:354]:   SSID: [redacted]
[16:31:54][C][wifi:355]:   IP Address: 192.168.1.193
[16:31:54][C][wifi:357]:   BSSID: [redacted]
[16:31:54][C][wifi:358]:   Hostname: 'emporiavue2'
[16:31:54][C][wifi:360]:   Signal strength: -16 dB ▂▄▆█
[16:31:54][C][wifi:364]:   Channel: 2
[16:31:54][C][wifi:365]:   Subnet: 255.255.255.0
[16:31:54][C][wifi:366]:   Gateway: 192.168.1.1
[16:31:54][C][wifi:367]:   DNS1: 8.8.8.8
[16:31:54][C][wifi:368]:   DNS2: 8.8.4.4
[16:31:55][E][emporia_vue:048]: Failed to read from sensor due to I2C error 3
[16:31:55][D][sensor:125]: 'Total Power': Sending state nan W with 1 decimals of accuracy
[16:31:55][C][logger:233]: Logger:
[16:31:55][C][logger:234]:   Level: DEBUG
[16:31:55][C][logger:235]:   Log Baud Rate: 115200
[16:31:55][C][logger:236]:   Hardware UART: UART0
[16:31:56][E][emporia_vue:048]: Failed to read from sensor due to I2C error 3
[16:31:56][D][sensor:125]: 'Total Power': Sending state nan W with 1 decimals of accuracy
[16:31:56][D][api.connection:159]: Home Assistant 2022.5.5 (::FFFF:192.168.1.80) requested disconnected
[16:31:56][C][i2c.idf:047]: I2C Bus:
[16:31:56][C][i2c.idf:048]:   SDA Pin: GPIO21
[16:31:56][C][i2c.idf:049]:   SCL Pin: GPIO22
[16:31:56][C][i2c.idf:050]:   Frequency: 200000 Hz
[16:31:56][C][i2c.idf:053]:   Recovery: bus successfully recovered
[16:31:57][E][emporia_vue:048]: Failed to read from sensor due to I2C error 3
[16:31:57][D][sensor:125]: 'Total Power': Sending state nan W with 1 decimals of accuracy
[16:31:57][D][api:102]: Accepted ::FFFF:192.168.1.80
[16:31:58][E][emporia_vue:048]: Failed to read from sensor due to I2C error 3
[16:31:58][D][sensor:125]: 'Total Power': Sending state nan W with 1 decimals of accuracy
[16:31:58][D][api.connection:827]: Home Assistant 2022.5.5 (::FFFF:192.168.1.80): Connected successfully
[16:31:58][C][emporia_vue:011]: Emporia Vue
[16:31:59][C][emporia_vue:012]:   Address: 0x64
[16:31:59][C][emporia_vue:027]:   Phase
[16:31:59][C][emporia_vue:028]:     Wire: BLACK
[16:31:59][C][emporia_vue:029]:     Calibration: 0.022720
[16:31:59][C][emporia_vue:030]:     Voltage 'Grid Voltage'
[16:31:59][C][emporia_vue:030]:       Device Class: 'voltage'
[16:31:59][C][emporia_vue:030]:       State Class: 'measurement'
[16:31:59][C][emporia_vue:030]:       Unit of Measurement: 'V'
[16:31:59][C][emporia_vue:030]:       Accuracy Decimals: 1
[16:31:59][C][emporia_vue:027]:   Phase
[16:31:59][C][emporia_vue:028]:     Wire: RED
[16:31:59][C][emporia_vue:029]:     Calibration: 0.022720
[16:31:59][C][emporia_vue:030]:     Voltage 'Phase B Voltage'
[16:31:59][C][emporia_vue:030]:       Device Class: 'voltage'
[16:31:59][C][emporia_vue:030]:       State Class: 'measurement'
[16:31:59][C][emporia_vue:030]:       Unit of Measurement: 'V'
[16:31:59][C][emporia_vue:030]:       Accuracy Decimals: 1

YAML file

esphome:
  name: emporiavue2

external_components:
  - source: github://flaviut/esphome@emporia-vue
    components: [ emporia_vue ]

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

# Enable Home Assistant API
api: 
ota: {"password": "9f5f34e8901ba8d73922ee1095e2204c"}

# Enable logging
logger:

wifi:
  ssid: "Darkness"
  password: "polaroid"

i2c:
  sda: 21
  scl: 22
  scan: false
  frequency: 200kHz  # recommended range is 50-200kHz
  id: i2c_a
time:
  - platform: sntp
    id: my_time

# these are called references in YAML. They allow you to reuse
# this configuration in each sensor, while only defining it once
.defaultfilters:
  - &moving_avg
    # we capture a new sample every 0.24 seconds, so the time can
    # be calculated from the number of samples as n * 0.24.
    sliding_window_moving_average:
      # we average over the past 2.88 seconds
      window_size: 12
      # we push a new value every 1.44 seconds
      send_every: 6
  - &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);'

sensor:
  - platform: emporia_vue
    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.02272  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "Grid Voltage"
          filters: [*moving_avg, *pos]
      - id: phase_b  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: RED  # Vue device wire color
        calibration: 0.02272  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "Phase B Voltage"
          filters: [*moving_avg, *pos]
    ct_clamps:
      - phase_id: phase_a
        input: "A"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Phase A Power"
          id: phase_a_power
          device_class: power
          filters: [*moving_avg, *pos]
      - phase_id: phase_b
        input: "B"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Phase B Power"
          id: phase_b_power
          device_class: power
          filters: [*moving_avg, *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: { name:  "Circuit 1 Power", id:  cir1, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "2", power: { name:  "Circuit 2 Power", id:  cir2, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "3", power: { name:  "Circuit 3 Power", id:  cir3, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "4", power: { name:  "Circuit 4 Power", id:  cir4, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "5", power: { name:  "Circuit 5 Power", id:  cir5, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "6", power: { name:  "Circuit 6 Power", id:  cir6, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "7", power: { name:  "Circuit 7 Power", id:  cir7, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "8", power: { name:  "Circuit 8 Power", id:  cir8, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "9", power: { name:  "Circuit 9 Power", id:  cir9, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "10", power: { name: "Circuit 10 Power", id: cir10, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "11", power: { name: "Circuit 11 Power", id: cir11, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "12", power: { name: "Circuit 12 Power", id: cir12, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "13", power: { name: "Circuit 13 Power", id: cir13, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "14", power: { name: "Circuit 14 Power", id: cir14, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "15", power: { name: "Circuit 15 Power", id: cir15, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "16", power: { name: "Circuit 16 Power", id: cir16, filters: [ *moving_avg, *pos ] } }
  - platform: template
    name: "Total Power"
    lambda: return id(phase_a_power).state + id(phase_b_power).state;
    update_interval: 1s
    id: total_power
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "Total Daily Energy"
    power_id: total_power
    accuracy_decimals: 0
  - { power_id:  cir1, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 1 Daily Energy" }
  - { power_id:  cir2, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 2 Daily Energy" }
  - { power_id:  cir3, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 3 Daily Energy" }
  - { power_id:  cir4, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 4 Daily Energy" }
  - { power_id:  cir5, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 5 Daily Energy" }
  - { power_id:  cir6, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 6 Daily Energy" }
  - { power_id:  cir7, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 7 Daily Energy" }
  - { power_id:  cir8, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 8 Daily Energy" }
  - { power_id:  cir9, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 9 Daily Energy" }
  - { power_id: cir10, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 10 Daily Energy" }
  - { power_id: cir11, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 11 Daily Energy" }
  - { power_id: cir12, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 12 Daily Energy" }
  - { power_id: cir13, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 13 Daily Energy" }
  - { power_id: cir14, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 14 Daily Energy" }
  - { power_id: cir15, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 15 Daily Energy" }
  - { power_id: cir16, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 16 Daily Energy" }

@flaviut
Copy link
Author

flaviut commented Jun 15, 2022

@Sc00bs110 Looks like error 3 is "timeout". I'm not sure what the problem is, but I'd suggest the following steps to debug:

  • Clear the esphome caches; reinstall the firmware on the vue
  • downgrade esphome to the last working version; clear esphome caches; reinstall the firmware on the vue
  • Install the original stock firmware on the vue, and see if it still works

@Sc00bs110
Copy link

Thanks Flaviut, will try that

@rjchu
Copy link

rjchu commented Jun 15, 2022

Has anyone tried this with MQTT yet? I upgraded ESPHome to the latest version and added the relavent items to my config, compiled, and uploaded but it cannot connect to my MQTT broker. I'm using plain-text (no SSL/TLS) on my broker over port 1883 and despite me specifying port 1883 in my yaml, ESPHome is still trying to use encryption/certs to connect to the MQTT broker. Does anyone know how I can force it to connect over tcp vs ssl/tls/etc?

Thanks in advance!

[18:21:17][E][mqtt.idf:119]: MQTT_EVENT_ERROR
[18:21:17][E][mqtt.idf:121]: Last error code reported from esp-tls: 0x0
[18:21:17][E][mqtt.idf:122]: Last tls stack error number: 0x0
[18:21:17][E][mqtt.idf:124]: Last captured errno : 104 (Connection reset by peer)

@flaviut
Copy link
Author

flaviut commented Jun 15, 2022

@rjchu Do you know if this is still an issue without the emporia vue component?

You can replace the Vue component with something like

sensor:
  - platform: template
    name: "Random Numbers"
    id: random_sensor
    unit_of_measurement: "%"
    lambda: |-
      return rand() % 100;
    update_interval: 60s

for testing. If this is an issue with the Vue component, I can dig deeper, but otherwise, I'd suggest asking the ESPHome community directly. Please do let us know what the issue was once you resolve it!

@rjchu
Copy link

rjchu commented Jun 15, 2022

@rjchu Do you know if this is still an issue without the emporia vue component?

I don't think this is related to the vue component. Based on the error message I included in my original post it looks like it can't even connect to the broker. The reference of tls in the errors is what makes me think it's trying that by default and not 'tcp' which according to the spec is supported....

@jwelter1971
Copy link

Hi - sorry for this as a bit off topic but was about to order the CircuitSetup kit that supports ESPhome by default. But the Vue-2 is certainly a much more economical solution.

Anyone with regrets going the Vue-2 path? Was against it with the cloud services they use by default but if the lobotomy to ESPHome works this would be fantastic.

@jdwhite
Copy link

jdwhite commented Jun 16, 2022 via email

@jwelter1971
Copy link

jwelter1971 commented Jun 16, 2022

Thanks, maybe something like this would be a solution:

https://www.amazon.com/Inovat-Headphone-Converter-Adapter-Right/dp/B01KOJAJKW

@flaviut
Copy link
Author

flaviut commented Jun 16, 2022

I would imagine the cables are quite stiff for some sort of compliance/safety reasons. If they gave me more trouble than they actually did, I might duct tape them tightly in place.

The other mildly annoying thing is having to remove the solder from the header holes for the initial programming.

But once installed, it just sits there and requires no further attention.

You might want to calibrate things manually, or you might be off by up to 5%. I've been unable to reverse engineer their code for these calibration constants. They're the same for all Vues, but which set of constants is used depends on the order the phases are connected in or something like that.

@plopes9000
Copy link

plopes9000 commented Jun 18, 2022

@rjchu, Yes mqtt is working quite well - I use FHEM (https://fhem.de/) hence mqtt is my choice of integration in this case.

Btw, unlike the emporia app which only calculates apparent power on the 16 CTs, this implementation is correctly measuring real power - thank you @flaviut !

sudo docker run --rm -v "${PWD}":/config -it esphome/esphome version
Version: 2022.6.0

here is my draft config - still making design decisions but working quite well already.
the send times are temporarily set too low, I plan on every 10 secs for instant and every 5 mins for totals, etc

esphome:
  name: emporiavue2

external_components:
  - source: github://flaviut/esphome@emporia-vue-2022.4.0
    components: [ emporia_vue ]

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

# Enable Home Assistant API
#api: {"password": "<ota password>"}
ota: {"password": "<xyz>"}

# Enable logging
logger:
  level: WARN

wifi:
  ssid: "myssid"
  password: "mypassword"

mqtt:
  broker: 1.2.3.4
  client_id: vue2
  username: myuser
  password: mypassword
  port: 1883
  topic_prefix: vue2
  discovery: false
  log_topic: null


i2c:
  sda: 21
  scl: 22
  scan: false
  frequency: 200kHz  # recommended range is 50-200kHz
  id: i2c_a

# these are called references in YAML. They allow you to reuse
# this configuration in each sensor, while only defining it once
.defaultfilters:
  - &moving_avg
    # we capture a new sample every 0.24 seconds, so the time can
    # be calculated from the number of samples as n * 0.24.
    sliding_window_moving_average:
      # we average over the past 2.88 seconds
      window_size: 12
      # we push a new value every 1.44 seconds
      send_every: 6
  - &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);'

sensor:
  - platform: emporia_vue
    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.0229  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "Phase A Voltage"
          internal: true
          id: phase_a_voltage
          filters: [*moving_avg, *pos]
      - id: phase_b  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: RED  # Vue device wire color
        calibration: 0.022  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "Phase B Voltage"
          internal: true
          id: phase_b_voltage
          filters: [*moving_avg, *pos]
      - id: phase_c  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: BLUE  # Vue device wire color
        calibration: 0.022193  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          internal: true
          name: "Phase C Voltage"
          id: phase_c_voltage
          filters: [*moving_avg, *pos]
    ct_clamps:
      - phase_id: phase_a
        input: "A"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Phase A Power"
          internal: true
          id: phase_a_power
          device_class: power
          filters: [*moving_avg, *pos]
      - phase_id: phase_b
        input: "B"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Phase B Power"
          internal: true
          id: phase_b_power
          device_class: power
          filters: [*moving_avg, *pos]
      - phase_id: phase_c
        input: "C"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Phase C Power"
          internal: true
          id: phase_c_power
          device_class: power
          filters: [*moving_avg, *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: { name: "Front Steps (Camera, Lights)",                            internal: true, id:  cir1, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_b, input:  "2", power: { name: "Kitchen Left (Fridge, Oven, Microwave)",                  internal: true, id:  cir2, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_b, input:  "3", power: { name: "Kitchen Right (Dishwasher, Coffee Machine)",              internal: true, id:  cir3, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_b, input:  "4", power: { name: "4 ??",                                                       internal: true, id:  cir4, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_c, input:  "5", power: { name: "Kitchen Stove",                                           internal: true, id:  cir5, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_b, input:  "6", power: { name: "Downstairs Right (Study, Hall, Bathroom, Guest, Server)", internal: true, id:  cir6, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_c, input:  "7", power: { name: "Downstairs Left (Living, Dining Room)",                   internal: true, id:  cir7, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_b, input:  "8", power: { name: "Upstairs (Master Bedroom)",                               internal: true, id:  cir8, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "9", power: { name: "Upstairs (incl. Attic lights, except Master Bedroom)",    internal: true, id:  cir9, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_c, input: "10", power: { name: "Cellar, Washing Room, Power Room (incl. Freezer)",        internal: true, id: cir10, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "11", power: { name: "Doorbell",                                                internal: true, id: cir11, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "12", power: { name: "Shutters",                                                internal: true, id: cir12, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "13", power: { name: "Cellar (Dryer, Washer)",                                  internal: true, id: cir13, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "14", power: { name: "Cellar Right, Workshop Play Room, Heating Room",          internal: true, id: cir14, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "15", power: { name: "Outdoors Lights",                                         internal: true, id: cir15, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "16", power: { name: "Cellar Left, Washing Room (Plants Lights, Garage)",       internal: true, id: cir16, filters: [ *moving_avg, *pos ] } }





  - platform: template
    internal: true
    name: "Total Circuits Power"
    lambda: return 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: 1s
    id: total_power_circuits
    unit_of_measurement: "W"
  - platform: template
    internal: true
    name: "Total Power"
    lambda: return id(phase_a_power).state + id(phase_b_power).state + id(phase_c_power).state;
    update_interval: 1s
    id: total_power
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "Total Daily Energy"
    internal: true
    power_id: total_power
    id: total_daily_power
    accuracy_decimals: 0
    min_save_interval: 10s
    unit_of_measurement: "W"
  - { power_id:  cir1, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir1 }
  - { power_id:  cir2, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir2 }
  - { power_id:  cir3, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir3 }
  - { power_id:  cir4, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir4 }
  - { power_id:  cir5, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir5 }
  - { power_id:  cir6, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir6 }
  - { power_id:  cir7, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir7 }
  - { power_id:  cir8, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir8 }
  - { power_id:  cir9, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir9 }
  - { power_id: cir10, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir10 }
  - { power_id: cir11, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir11 }
  - { power_id: cir12, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir12 }
  - { power_id: cir13, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir13 }
  - { power_id: cir14, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir14 }
  - { power_id: cir15, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir15 }
  - { power_id: cir16, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir16 }

time:
  - platform: sntp
    id: my_time
    timezone: Europe/Berlin
    servers: 
      - 192.168.178.99
      - 0.pool.ntp.org
      - 1.pool.ntp.org
    on_time_sync:
      then:
        - logger.log: "Synchronized system clock"
    on_time:
      - seconds: /10
        then:
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir01_power");
              payload: !lambda |-
                return to_string(id(cir1).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir02_power");
              payload: !lambda |-
                return to_string(id(cir2).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir03_power");
              payload: !lambda |-
                return to_string(id(cir3).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir04_power");
              payload: !lambda |-
                return to_string(id(cir4).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir05_power");
              payload: !lambda |-
                return to_string(id(cir5).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir06_power");
              payload: !lambda |-
                return to_string(id(cir6).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir07_power");
              payload: !lambda |-
                return to_string(id(cir7).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir08_power");
              payload: !lambda |-
                return to_string(id(cir8).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir09_power");
              payload: !lambda |-
                return to_string(id(cir9).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir10_power");
              payload: !lambda |-
                return to_string(id(cir10).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir11_power");
              payload: !lambda |-
                return to_string(id(cir11).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir12_power");
              payload: !lambda |-
                return to_string(id(cir12).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir13_power");
              payload: !lambda |-
                return to_string(id(cir13).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir14_power");
              payload: !lambda |-
                return to_string(id(cir14).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir15_power");
              payload: !lambda |-
                return to_string(id(cir15).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir16_power");
              payload: !lambda |-
                return to_string(id(cir16).state);
          - mqtt.publish:
              topic: "vue2/circuits/total_power_circuits"
              payload: !lambda |-
                return to_string(id(total_power_circuits).state);
          - mqtt.publish:
              topic: "vue2/mains/total/total_power"
              payload: !lambda |-
                return to_string(id(total_power).state);

      - seconds: /10
        then:
          - mqtt.publish:
              topic: "vue2/mains/phase_a_voltage"
              payload: !lambda |-
                return to_string(id(phase_a_voltage).state);
          - mqtt.publish:
              topic: "vue2/mains/phase_b_voltage"
              payload: !lambda |-
                return to_string(id(phase_b_voltage).state);
          - mqtt.publish:
              topic: "vue2/mains/phase_c_voltage"
              payload: !lambda |-
                return to_string(id(phase_c_voltage).state);
          - mqtt.publish:
              topic: "vue2/mains/phase_a_power"
              payload: !lambda |-
                return to_string(id(phase_a_power).state);
          - mqtt.publish:
              topic: "vue2/mains/phase_b_power"
              payload: !lambda |-
                return to_string(id(phase_b_power).state);
          - mqtt.publish:
              topic: "vue2/mains/phase_c_power"
              payload: !lambda |-
                return to_string(id(phase_c_power).state);

      - seconds: 0
        minutes: /5
        then:
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir01_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir1).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir02_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir2).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir03_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir3).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir04_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir4).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir05_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir5).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir06_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir6).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir07_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir7).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir08_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir8).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir09_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir9).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir10_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir10).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir11_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir11).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir12_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir12).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir13_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir13).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir14_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir14).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir15_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir15).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir16_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir16).state);


      - seconds: 0
        minutes: /5
        then:
          - mqtt.publish:
              topic: "vue2/mains/total/total_daily_power"
              payload: !lambda |-
                return to_string(id(total_daily_power).state);

      - seconds: 0
        minutes: /10
        then:
          - mqtt.publish:
              topic: "vue2/circuits/cir01_name"
              payload: !lambda |-
                return id(cir1).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir02_name"
              payload: !lambda |-
                return id(cir2).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir03_name"
              payload: !lambda |-
                return id(cir3).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir04_name"
              payload: !lambda |-
                return id(cir4).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir05_name"
              payload: !lambda |-
                return id(cir5).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir06_name"
              payload: !lambda |-
                return id(cir6).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir07_name"
              payload: !lambda |-
                return id(cir7).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir08_name"
              payload: !lambda |-
                return id(cir8).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir09_name"
              payload: !lambda |-
                return id(cir9).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir10_name"
              payload: !lambda |-
                return id(cir10).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir11_name"
              payload: !lambda |-
                return id(cir11).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir12_name"
              payload: !lambda |-
                return id(cir12).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir13_name"
              payload: !lambda |-
                return id(cir13).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir14_name"
              payload: !lambda |-
                return id(cir14).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir15_name"
              payload: !lambda |-
                return id(cir15).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir16_name"
              payload: !lambda |-
                return id(cir16).get_name();

@poblabs
Copy link

poblabs commented Jun 18, 2022

How do I set the timezone correctly? When choosing the homeassistant time platform, I get errors that sntp is required. When I add an addition time reference for homeassistant platform, I get undefined reference errors, and when I try this config below, It doesn't appear to be applying.

time:
  - platform: sntp
    timezone: UTC-5
    id: my_time

Also trying America/New_York doesn't appear to be working either. The logs still show UTC.

@jwelter1971
Copy link

How do I set the timezone correctly? When choosing the homeassistant time platform, I get errors that sntp is required. When I add an addition time reference for homeassistant platform, I get undefined reference errors, and when I try this config below, It doesn't appear to be applying.

time:
  - platform: sntp
    timezone: UTC-5
    id: my_time

Also trying America/New_York doesn't appear to be working either. The logs still show UTC.

I use the following with HomeAssistant

time:
  - platform: homeassistant
    id: homeassistant_time

@poblabs
Copy link

poblabs commented Jun 18, 2022

How do I set the timezone correctly? When choosing the homeassistant time platform, I get errors that sntp is required. When I add an addition time reference for homeassistant platform, I get undefined reference errors, and when I try this config below, It doesn't appear to be applying.

time:
  - platform: sntp
    timezone: UTC-5
    id: my_time

Also trying America/New_York doesn't appear to be working either. The logs still show UTC.

I use the following with HomeAssistant

time:
  - platform: homeassistant
    id: homeassistant_time

When I try that, I get this error below:

Compiling .pioenvs/emporiavue2/src/esphome/components/sensor/sensor.o
*** [.pioenvs/emporiavue2/src/esphome/components/sntp/sntp_component.o] Source `src/esphome/components/sntp/sntp_component.cpp' not found, needed by target `.pioenvs/emporiavue2/src/esphome/components/sntp/sntp_component.o'.
========================== [FAILED] Took 8.69 seconds ==========================

@ripvega
Copy link

ripvega commented Jun 19, 2022

I had this issue too, and seem to remember that the compilation framework used doesn't support homeassistant time, only SNTP, whereas the arduino framework does. I think we're stuck with SNTP.

@poblabs
Copy link

poblabs commented Jun 19, 2022

I had this issue too, and seem to remember that the compilation framework used doesn't support homeassistant time, only SNTP, whereas the arduino framework does. I think we're stuck with SNTP.

Were you able to get timezone working?

@ripvega
Copy link

ripvega commented Jun 19, 2022

I didn't play with the timezone as ESPHome automatically picks it from the device running ESPHome. At least, it has for me.

@VivantSenior
Copy link

How do I set the timezone correctly? When choosing the homeassistant time platform, I get errors that sntp is required. When I add an addition time reference for homeassistant platform, I get undefined reference errors, and when I try this config below, It doesn't appear to be applying.

time:
  - platform: sntp
    timezone: UTC-5
    id: my_time

Also trying America/New_York doesn't appear to be working either. The logs still show UTC.

Have you tried to do:

esphome clean emporia.yaml

I found cleaning helpful when was unable to add wifi sensor to the configuration.

BTW I have noticed that sensors are super noisy:
image

Close look:
image

This one is not event connencted to the Emporia yet. I'm thinking about moving to the median to smooth out the output - maybe it will be less sensitive to the measurement outliers.

Do you have the same issue guys?

@poblabs
Copy link

poblabs commented Jun 20, 2022

How do I set the timezone correctly? When choosing the homeassistant time platform, I get errors that sntp is required. When I add an addition time reference for homeassistant platform, I get undefined reference errors, and when I try this config below, It doesn't appear to be applying.

time:
  - platform: sntp
    timezone: UTC-5
    id: my_time

Also trying America/New_York doesn't appear to be working either. The logs still show UTC.

Have you tried to do:

esphome clean emporia.yaml

I found cleaning helpful when was unable to add wifi sensor to the configuration.

BTW I have noticed that sensors are super noisy: image

Close look: image

This one is not event connencted to the Emporia yet. I'm thinking about moving to the median to smooth out the output - maybe it will be less sensitive to the measurement outliers.

Do you have the same issue guys?

I do have 1 sensor that keeps flapping like this. I've moved it to another position but same results so I think that must be a noisy area in the panel? How would you implement the median?

@flaviut
Copy link
Author

flaviut commented Jun 20, 2022

@poblabs @VivantSenior that behavior isn't normal at all--none of my sensors do that.

How about the following? And let me know if it worked and which step solved things.

  • move the problematic sensor to a different port (@poblabs sounds like you've already tried this!)
  • unclamp the problematic clamp, maybe shake it around a bit and use gentle percussive maintenance, and re-clamp it
  • use a different clamp for that sensor

@poblabs
Copy link

poblabs commented Jun 20, 2022

@poblabs @VivantSenior that behavior isn't normal at all--none of my sensors do that.

How about the following? And let me know if it worked and which step solved things.

  • move the problematic sensor to a different port (@poblabs sounds like you've already tried this!)
  • unclamp the problematic clamp, maybe shake it around a bit and use gentle percussive maintenance, and re-clamp it
  • use a different clamp for that sensor

I'll try another clamp to see if that helps.

Any thoughts on the time? I'm trying something like the below, but I'm not seeing anything in the log with my "POB" lines, and the logs time is still in UTC.

I'd like to have the right timezone that way the "Total Daily Energy" is right in my timezone and doesn't reset at UTC

time:
  - platform: homeassistant
    timezone: America/New_York
    id: ha_time
    on_time_sync:
      if:
        condition:
          time.has_time:
        then:
          - logger.log: POB POB POB POB Time has been set and is valid!

@flaviut
Copy link
Author

flaviut commented Jun 20, 2022

@poblabs re. the time, I don't know.

I live in America/New_York too, my config is

time:
  - platform: sntp
    id: my_time

and everything works perfectly:

2022-06-20-102634_375x299_scrot

Only idea I have here is that maybe you have a router firewall blocking outbound UDP connections on port 123. I don't know anything about the homeassistant time platform. You can try asking the esphome community.

@poblabs
Copy link

poblabs commented Jun 20, 2022

@poblabs re. the time, I don't know.

I live in America/New_York too, my config is

time:
  - platform: sntp
    id: my_time

and everything works perfectly:

2022-06-20-102634_375x299_scrot

Only idea I have here is that maybe you have a router firewall blocking outbound UDP connections on port 123. I don't know anything about the homeassistant time platform. You can try asking the esphome community.

Just curious then - are your esphome logs in UTC with sntp set? Also does your daily power reset at 8pm or midnight? Looks like midnight on that chart

@flaviut
Copy link
Author

flaviut commented Jun 20, 2022

@poblabs

Logs are in local time:

[10:50:35][D][sensor:125]: 'Circuit 8 Daily Energy': Sending state 180.83740 Wh with 0 decimals of accuracy
[10:50:35][D][sensor:125]: 'Circuit 9 Power': Sending state 0.25883 W with 0 decimals of accuracy
[10:50:35][D][sensor:125]: 'Circuit 9 Daily Energy': Sending state 4.03635 Wh with 0 decimals of accuracy
[10:50:35][D][sensor:125]: 'Circuit 10 Power': Sending state 12.47641 W with 0 decimals of accuracy

And the daily reset happens at midnight.

@poblabs
Copy link

poblabs commented Jun 20, 2022

@poblabs

Logs are in local time:

[10:50:35][D][sensor:125]: 'Circuit 8 Daily Energy': Sending state 180.83740 Wh with 0 decimals of accuracy
[10:50:35][D][sensor:125]: 'Circuit 9 Power': Sending state 0.25883 W with 0 decimals of accuracy
[10:50:35][D][sensor:125]: 'Circuit 9 Daily Energy': Sending state 4.03635 Wh with 0 decimals of accuracy
[10:50:35][D][sensor:125]: 'Circuit 10 Power': Sending state 12.47641 W with 0 decimals of accuracy

And the daily reset happens at midnight.

Thanks for confirming, and thanks for all your work with this! I'll have to dig in deeper outside of the emporia firmware 😄

@poblabs
Copy link

poblabs commented Jun 20, 2022

EDIT I've figured it out. I'm running esphome in Docker, and I need to pass the timezone through to the container using environment variables.

Thanks to this link for the insight

example:

    volumes:
      - "./data:/config"
      - /etc/localtime:/etc/localtime
      - /etc/timezone:/etc/timezone

@VivantSenior
Copy link

I think I've figured it out also ;-) My issue what that even when sensor wasn't connected to the port the output was like random noise. When I connected the clamp it looks good:
image

Missing data at 16:06 and later it's my Emporia dropping from the wifi.

@flaviut, is there a smart way to do in ESPHome a sensor that will calculate power from the other circuts not measured by Emporia (by phase)? Something like this:

phase_a_other_circuts_power = id(phase_a_power).state - sum(all measured circurs on phase a)

and the same for daily energy.

@flaviut
Copy link
Author

flaviut commented Jun 21, 2022

@VivantSenior glad to hear you figured it out!

Re. doing math on results, copy "Total Power" in the config and try and modify it for your situation.

@cshields
Copy link

First, thanks for this! Truly epic.

Have you heard of an issue where half of the CTs/ports go dead at the same time after working fine for days? I'm pretty sure something went belly up in the hardware but figure I'd ask. At first I thought it must be a fried multiplexer, but the bad ports span both of them.

@flaviut
Copy link
Author

flaviut commented Jun 22, 2022

@cshields all on the same phase? Check the wiring on the 2x2 connector: that all the wire nuts are tight, screws tight, and connector completely inserted.

@Ofloo
Copy link

Ofloo commented Jun 25, 2022

energy monitor keeps disconnecting, ..

INFO energy-monitor.local: Error while reading incoming messages: Error while reading data: 0 bytes read on a total of 1 expected bytes
INFO Disconnected from ESPHome API for energy-monitor.local
WARNING Disconnected from API
INFO energy-monitor.local: Ping Failed: Error while reading data: 0 bytes read on a total of 1 expected bytes
INFO Successfully connected to energy-monitor.local

Configuration:

Config
substitutions:
  devicename: "energy-monitor"
  upper_devicename: "emporiavue2"

  wifi_ssid: !secret iot_wifi_ssid
  wifi_pass: !secret iot_wifi_password
  fallback_pass: !secret fallback_wifi_password
  api_pass: !secret esp_api_password
  ota_pass: !secret esp_ota_password
  webserver_username: !secret webserver_username
  webserver_password: !secret webserver_password

esphome:
  name: $devicename

external_components:
  - source: github://flaviut/esphome@emporia-vue-2022.4.0
    components: [ emporia_vue ]

esp32:
  board: esp32dev
  framework:
    type: esp-idf
    version: recommended
    
# Enable Home Assistant API
api:
  password: "${api_pass}"

# Enable over the air updates
ota:
  password: "${ota_pass}"

# Enable logging
logger:

wifi:
  ssid: "${wifi_ssid}"
  password: "${wifi_pass}"

i2c:
  sda: 21
  scl: 22
  scan: false
  frequency: 200kHz  # recommended range is 50-200kHz
  id: i2c_a
  
time:
  - platform: sntp
    timezone: 'CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00'
    id: my_time
    servers: 
      - 162.159.200.123
      - 195.13.23.5
      - 195.13.1.153
    on_time_sync:
      then:
        - logger.log: "Synchronized system clock"

# these are called references in YAML. They allow you to reuse
# this configuration in each sensor, while only defining it once
.defaultfilters:
  - &moving_avg
    # we capture a new sample every 0.24 seconds, so the time can
    # be calculated from the number of samples as n * 0.24.
    sliding_window_moving_average:
      # we average over the past 2.88 seconds
      window_size: 12
      # we push a new value every 1.44 seconds
      send_every: 6
  - &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);'

sensor:
  - platform: emporia_vue
    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.02260  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "Grid Voltage"
          filters: [*moving_avg, *pos]
      - id: phase_b  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: RED  # Vue device wire color
        calibration: 0.02260  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "Neutral Voltage"
          filters: [*moving_avg, *pos]
      - id: phase_c  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: BLUE  # Vue device wire color
        calibration: 0.02260  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "PE Voltage"
          filters: [*moving_avg, *pos]
    ct_clamps:
      - phase_id: phase_a
        input: "A"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Grid Power"
          id: phase_a_power
          device_class: power
          filters: [*moving_avg, *pos]
      - phase_id: phase_b
        input: "B"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Neutral Power"
          id: phase_b_power
          device_class: power
          filters: [*moving_avg, *pos]
      - phase_id: phase_c
        input: "C"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "PE Power"
          id: phase_c_power
          device_class: power
          filters: [*moving_avg, *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: { name:  "Circuit 1 Power", id:  cir1, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "2", power: { name:  "Circuit 2 Power", id:  cir2, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "3", power: { name:  "Circuit 3 Power", id:  cir3, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "4", power: { name:  "Circuit 4 Power", id:  cir4, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "5", power: { name:  "Circuit 5 Power", id:  cir5, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "6", power: { name:  "Circuit 6 Power", id:  cir6, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "7", power: { name:  "Circuit 7 Power", id:  cir7, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "8", power: { name:  "Circuit 8 Power", id:  cir8, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "9", power: { name:  "Circuit 9 Power", id:  cir9, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "10", power: { name: "Circuit 10 Power", id: cir10, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "11", power: { name: "Circuit 11 Power", id: cir11, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "12", power: { name: "Circuit 12 Power", id: cir12, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "13", power: { name: "Circuit 13 Power", id: cir13, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "14", power: { name: "Circuit 14 Power", id: cir14, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "15", power: { name: "Circuit 15 Power", id: cir15, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "16", power: { name: "Circuit 16 Power", id: cir16, filters: [ *moving_avg, *pos ] } }
  # phase A L1
  - platform: template
    name: "Total Power Grid"
    lambda: return id(phase_a_power).state;
    update_interval: 1s
    id: total_power_a
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "Total Daily Energy Grid"
    power_id: total_power_a
    accuracy_decimals: 0
  # phase B Neutral
  - platform: template
    name: "Total Power Neutral"
    lambda: return id(phase_b_power).state;
    update_interval: 5s
    id: total_power_b
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "Total Daily Energy Neutral"
    power_id: total_power_b
    accuracy_decimals: 0
  # phase C to Earth
  - platform: template
    name: "Total Power PE"
    lambda: return id(phase_c_power).state;
    update_interval: 5s
    id: total_power_c
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "Total Daily Energy PE"
    power_id: total_power_c
    accuracy_decimals: 0

  - { power_id:  cir1, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 1 Daily Energy" }
  - { power_id:  cir2, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 2 Daily Energy" }
  - { power_id:  cir3, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 3 Daily Energy" }
  - { power_id:  cir4, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 4 Daily Energy" }
  - { power_id:  cir5, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 5 Daily Energy" }
  - { power_id:  cir6, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 6 Daily Energy" }
  - { power_id:  cir7, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 7 Daily Energy" }
  - { power_id:  cir8, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 8 Daily Energy" }
  - { power_id:  cir9, platform: total_daily_energy, accuracy_decimals: 0, name:  "Circuit 9 Daily Energy" }
  - { power_id: cir10, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 10 Daily Energy" }
  - { power_id: cir11, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 11 Daily Energy" }
  - { power_id: cir12, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 12 Daily Energy" }
  - { power_id: cir13, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 13 Daily Energy" }
  - { power_id: cir14, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 14 Daily Energy" }
  - { power_id: cir15, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 15 Daily Energy" }
  - { power_id: cir16, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 16 Daily Energy" }

@flaviut
Copy link
Author

flaviut commented Jun 26, 2022

@Ofloo I'm not sure; are you able to get any logs over the serial adapter, ideally while not connected to mains?

If not, I'd suggest reaching out to general ESPHome community and asking them. Please remember to let us know how you solved this!

@Ofloo
Copy link

Ofloo commented Jun 26, 2022 via email

@devWaves
Copy link

devWaves commented Jun 27, 2022

@flaviut just wanted to say thanks for this (also thanks to ESPhome devs). Works awesome. I am now using the MQTT integration at it is exactly what I wanted. So you can update your documentation to say MQTT is working

The main reason I wanted it was to monitor things like the electric stove/oven if it was accidentaly left on while we are away or when everyone is asleep etc. I could only trust a local solution for that

@tappyson
Copy link

Hi. Thank you so much for the brilliant work on this. I managed to flash my Emporia Vue and it seems to be working perfectly. I ran it with the Emporia software and the cloud prior to make sure it all worked fine before I went ahead an flashed it. My issue (Due to lack of templating knowledge) now is that I have a solar system and in order to pull in the right data to home assistant I need to be able to create Current/Total energy exported to the grid (All negative values of the Total Power) and All the Energy imported from the Grid (Positive numbers on total power) I removed the filter so my total power or phase power shows negative and positive depending on if my house is producing more than it uses or not. I've found ways to do this in HA but I'd prefer that it was done locally on the device before being pushed to HA.

@maegibbons
Copy link

Hi. Thank you so much for the brilliant work on this. I managed to flash my Emporia Vue and it seems to be working perfectly. I ran it with the Emporia software and the cloud prior to make sure it all worked fine before I went ahead an flashed it. My issue (Due to lack of templating knowledge) now is that I have a solar system and in order to pull in the right data to home assistant I need to be able to create Current/Total energy exported to the grid (All negative values of the Total Power) and All the Energy imported from the Grid (Positive numbers on total power) I removed the filter so my total power or phase power shows negative and positive depending on if my house is producing more than it uses or not. I've found ways to do this in HA but I'd prefer that it was done locally on the device before being pushed to HA.

Can you share what you have done so far so we can see where you are at?

@tappyson
Copy link

tappyson commented Jun 29, 2022

i2c:
  sda: 21
  scl: 22
  scan: false
  frequency: 200kHz  # recommended range is 50-200kHz
  id: i2c_a
time:
  - platform: sntp
    id: my_time

# these are called references in YAML. They allow you to reuse
# this configuration in each sensor, while only defining it once
.defaultfilters:
  - &moving_avg
    # we capture a new sample every 0.24 seconds, so the time can
    # be calculated from the number of samples as n * 0.24.
    sliding_window_moving_average:
      # we average over the past 2.88 seconds
      window_size: 12
      # we push a new value every 1.44 seconds
      send_every: 6
  - &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);'

sensor:
  - platform: emporia_vue
    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.022  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "Phase A Voltage"
          filters: [*moving_avg, *pos]

    ct_clamps:
      - phase_id: phase_a
        input: "C"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Phase A Power"
          id: phase_a_power
          device_class: power
          filters: [*moving_avg]

      # 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: { name:  "Lights N9 Power", id:  cir1, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "2", power: { name:  "Lights N8 Power", id:  cir2, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "3", power: { name:  "Plugs N7 Power", id:  cir3, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "4", power: { name:  "Plugs N6 Power", id:  cir4, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "5", power: { name:  "Plugs N5 Power", id:  cir5, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "6", power: { name:  "Solar Power", id:  cir6, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "7", power: { name:  "Aircon N3 Power", id:  cir7, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "8", power: { name:  "Stove N2 Power", id:  cir8, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "9", power: { name:  "Hot Water N1", id:  cir9, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "10", power: { name: "Plugs N4 Power", id: cir10, filters: [ *moving_avg, *pos ] } }


  - platform: template
    name: "Total Power"
    lambda: return id(phase_a_power).state ;
    update_interval: 1s
    id: total_power
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "Total Daily Energy"
    power_id: total_power
    accuracy_decimals: 0
  - { power_id:  cir1, platform: total_daily_energy, accuracy_decimals: 0, name:  "Lights N9 Daily Energy", id: total_daily_cir1 }
  - { power_id:  cir2, platform: total_daily_energy, accuracy_decimals: 0, name:  "Lights N8 Daily Energy", id: total_daily_cir2 }
  - { power_id:  cir3, platform: total_daily_energy, accuracy_decimals: 0, name:  "Plugs N7 Daily Energy", id: total_daily_cir3 }
  - { power_id:  cir4, platform: total_daily_energy, accuracy_decimals: 0, name:  "Plugs N6 Daily Energy", id: total_daily_cir4 }
  - { power_id:  cir5, platform: total_daily_energy, accuracy_decimals: 0, name:  "Plugs N5 Daily Energy", id: total_daily_cir5 }
  - { power_id:  cir6, platform: total_daily_energy, accuracy_decimals: 0, name:  "Solar Power Daily Energy", id: total_daily_cir6 }
  - { power_id:  cir7, platform: total_daily_energy, accuracy_decimals: 0, name:  "Aircon N3 Daily Energy", id: total_daily_cir7 }
  - { power_id:  cir8, platform: total_daily_energy, accuracy_decimals: 0, name:  "Stove N2 Daily Energy", id: total_daily_cir8 }
  - { power_id:  cir9, platform: total_daily_energy, accuracy_decimals: 0, name:  "Hot Water N1 Daily Energy", id: total_daily_cir9 }
  - { power_id: cir10, platform: total_daily_energy, accuracy_decimals: 0, name: "Plugs N4 Daily Energy", id: total_daily_cir10 }
  
  
  - platform: template
    name: "Total Usage Power"
    lambda: return id(total_daily_cir1).state + id(total_daily_cir2).state + id(total_daily_cir3).state + id(total_daily_cir4).state + id(total_daily_cir5).state
      + id(total_daily_cir7).state + id(total_daily_cir8).state + id(total_daily_cir9).state + id(total_daily_cir10).state ; 
    update_interval: 1s
    id: total_power_usage
    unit_of_measurement: "W"
    internal: true 

 #Total House Watts Positive
  - platform: template
    name: Total Import
    id: totalconsumed
    lambda: |-
      if (id(total_power).state < 0) {
        return 0;
      } else {
        return id(total_power).state ;
      }
    accuracy_decimals: 1
    unit_of_measurement: "W"
    icon: "mdi:flash-circle"
    update_interval: 1s
    filters: [*moving_avg]
    
#Total House Watts Negative
  - platform: template
    name: Total Export
    id: totalexported
    lambda: |-
      if (id(total_power).state > 0) {
        return 0;
      } else {
        return abs(id(total_power).state) ;
      }
    accuracy_decimals: 1
    unit_of_measurement: "W"
    icon: "mdi:flash-circle"
    update_interval: 1s
    filters: [*moving_avg]

Kinda works but doesn't work in the HA dashboard and the data doesn't look like it's a running total but more like some sort of average?

@tappyson
Copy link

Basically I want two Total Daily's. One that is for all the Grid Import (When the total is positive) and one for Grid Export (When the total is positive) Also please excuse the horrendous editing on the code above. No idea why Github kept editing it that way. I used the insert code tool.

@flaviut
Copy link
Author

flaviut commented Jun 29, 2022

@tappyson you're on the right track. You have the instantaneous power imported and exported. But you need to add that up over time.

Try adding two more sensors like the existing total daily energy:

  - platform: total_daily_energy
    name: "Total Daily Energy"
    power_id: total_power
    accuracy_decimals: 0

Details on how it works: https://esphome.io/components/sensor/total_daily_energy.html

You'll want to replace the thing it's summing over with your totalexported, etc.

PS: I fixed the formatting, here's an explanation of how it works

@Ofloo
Copy link

Ofloo commented Jun 30, 2022

I didn't fix the problem, however I've established how to circumvent it. Seems like the culprit is ESPHome, not sure as to why this specific firmware is having issues with it. Since none of my other clients do but it does.

I've changed my config to mqtt and set all internal to true and now I have no packets going to ESPHome and so no more disconnects and no more packet loss.

Downside I have to configure all my sensors in mqtt: - sensors ..

substitutions:
  devicename: "energy-monitor"
  upper_devicename: "emporiavue2"

  wifi_ssid: !secret iot_wifi_ssid
  wifi_pass: !secret iot_wifi_password
  fallback_pass: !secret fallback_wifi_password
  api_pass: !secret esp_api_password
  ota_pass: !secret esp_ota_password

  # phase a connected to main leat L1 load closet
  name_a_power: "Grid Power"
  name_a_voltage: "Grid Voltage"
  name_total_a_power: "Total Power Grid"
  name_total_a_energy: "Total Daily Energy Grid"
  # phase b connected to main lead N direction load N
  name_b_power: "Neutral Power"
  name_b_voltage: "Neutral Voltage"
  name_total_b_power: "Total Power Neutral"
  name_total_b_energy: "Total Daily Energy Neutral"
  # phase c connected main lead to earth direction load earth
  name_c_power: "PE Power"
  name_c_voltage: "PE Voltage"
  name_total_c_power: "Total Power PE"
  name_total_c_energy: "Total Daily Energy PE"
  # individual circuits
  # individual circuits
  name_circuit01: "Circuit 1"
  name_circuit02: "Circuit 2"
  name_circuit03: "Circuit 3"
  name_circuit04: "Circuit 4"
  name_circuit05: "Circuit 5"
  name_circuit06: "Circuit 6"
  name_circuit07: "Circuit 7"
  name_circuit08: "Circuit 8"
  name_circuit09: "Circuit 9"
  name_circuit10: "Circuit 10"
  name_circuit11: "Circuit 11"
  name_circuit12: "Circuit 12"
  name_circuit13: "Circuit 13"
  name_circuit14: "Circuit 14"
  name_circuit15: "Circuit 15"
  name_circuit16: "Circuit 16"
  name_timezone: 'CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00'


esphome:
  name: $devicename

external_components:
  - source: github://flaviut/esphome@emporia-vue-2022.4.0
    components: [ emporia_vue ]

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

# Enable Home Assistant API
api:
  password: "${api_pass}"

# Enable over the air updates
ota:
  password: "${ota_pass}"

# Enable logging
logger:
  level: error

wifi:
  ssid: "${wifi_ssid}"
  password: "${wifi_pass}"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${devicename} Fallback Hotspot"
    password: "${fallback_pass}"

i2c:
  sda: 21
  scl: 22
  scan: false
  frequency: 200kHz  # recommended range is 50-200kHz
  id: i2c_a

# these are called references in YAML. They allow you to reuse
# this configuration in each sensor, while only defining it once
.defaultfilters:
  - &moving_avg
    # we capture a new sample every 0.24 seconds, so the time can
    # be calculated from the number of samples as n * 0.24.
    sliding_window_moving_average:
      # we average over the past 2.88 seconds
      window_size: 12
      # we push a new value every 1.44 seconds
      send_every: 6
  - &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);'

mqtt:
  broker: !secret mqtt_hostname
  username: !secret mqtt_username
  password: !secret mqtt_password
  client_id: vue2
  port: 1883
  topic_prefix: vue2
  discovery: false
  log_topic: null

sensor:
  - platform: emporia_vue
    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.02260  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: $name_a_voltage
          internal: true
          id: phase_a_voltage
          filters: [*moving_avg, *pos]
      - id: phase_b  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: RED  # Vue device wire color
        calibration: 0.02260  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: $name_b_voltage
          internal: true
          id: phase_b_voltage
          filters: [*moving_avg, *pos]
      - id: phase_c  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: BLUE  # Vue device wire color
        calibration: 0.02260  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: $name_c_voltage
          internal: true
          id: phase_c_voltage
          filters: [*moving_avg, *pos]
    ct_clamps:
      - phase_id: phase_a
        input: "A"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: $name_a_power
          internal: true
          id: phase_a_power
          device_class: power
          filters: [*moving_avg, *pos]
      - phase_id: phase_b
        input: "B"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: $name_b_power
          internal: true
          id: phase_b_power
          device_class: power
          filters: [*moving_avg, *pos]
      - phase_id: phase_c
        input: "C"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: $name_c_power
          internal: true
          id: phase_c_power
          device_class: power
          filters: [*moving_avg, *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: { name: $name_circuit01, internal: true, id: power_cir01, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "2", power: { name: $name_circuit02, internal: true, id: power_cir02, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "3", power: { name: $name_circuit03, internal: true, id: power_cir03, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "4", power: { name: $name_circuit04, internal: true, id: power_cir04, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "5", power: { name: $name_circuit05, internal: true, id: power_cir05, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "6", power: { name: $name_circuit06, internal: true, id: power_cir06, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "7", power: { name: $name_circuit07, internal: true, id: power_cir07, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "8", power: { name: $name_circuit08, internal: true, id: power_cir08, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "9", power: { name: $name_circuit09, internal: true, id: power_cir09, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "10", power: { name: $name_circuit10, internal: true, id: power_cir10, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "11", power: { name: $name_circuit11, internal: true, id: power_cir11, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "12", power: { name: $name_circuit12, internal: true, id: power_cir12, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "13", power: { name: $name_circuit13, internal: true, id: power_cir13, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "14", power: { name: $name_circuit14, internal: true, id: power_cir14, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "15", power: { name: $name_circuit15, internal: true, id: power_cir15, device_class: power, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "16", power: { name: $name_circuit16, internal: true, id: power_cir16, device_class: power, filters: [ *moving_avg, *pos ] } }

  - platform: template
    name: "${name_circuit01} in W"
    lambda: return id(power_cir01).state;
    id: total_cir01
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit02} in W"
    lambda: return id(power_cir02).state;
    id: total_cir02
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit03} in W"
    lambda: return id(power_cir03).state;
    id: total_cir03
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit04} in W"
    lambda: return id(power_cir04).state;
    id: total_cir04
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit05} in W"
    lambda: return id(power_cir05).state;
    id: total_cir05
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit06} in W"
    lambda: return id(power_cir06).state;
    id: total_cir06
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit07} in W"
    lambda: return id(power_cir07).state;
    id: total_cir07
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit08} in W"
    lambda: return id(power_cir08).state;
    id: total_cir08
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit09} in W"
    lambda: return id(power_cir09).state;
    id: total_cir09
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit10} in W"
    lambda: return id(power_cir10).state;
    id: total_cir10
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit11} in W"
    lambda: return id(power_cir11).state;
    id: total_cir11
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit12} in W"
    lambda: return id(power_cir12).state;
    id: total_cir12
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit13} in W"
    lambda: return id(power_cir13).state;
    id: total_cir13
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit14} in W"
    lambda: return id(power_cir14).state;
    id: total_cir14
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit15} in W"
    lambda: return id(power_cir15).state;
    id: total_cir15
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge
  - platform: template
    name: "${name_circuit16} in W"
    lambda: return id(power_cir16).state;
    id: total_cir16
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    update_interval: 1s
    icon: mdi:gauge

    # phase A
  - platform: template
    name: $name_total_a_power
    lambda: return id(phase_a_power).state;
    update_interval: 1s
    id: total_power_a
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    icon: mdi:gauge
  - platform: total_daily_energy
    name: $name_total_a_energy
    power_id: total_power_a
    id: total_power_a_wh
    accuracy_decimals: 0
    unit_of_measurement: "Wh"
    internal: true
    icon: mdi:gauge
  - platform: total_daily_energy
    name: $name_total_a_energy
    power_id: total_power_a
    id: total_power_a_kwh
    accuracy_decimals: 3
    filters: [multiply: 0.001]
    unit_of_measurement: "kWh"
    internal: true
    icon: mdi:gauge
    # phase B
  - platform: template
    name: $name_total_b_power
    lambda: return id(phase_b_power).state;
    update_interval: 1s
    id: total_power_b
    accuracy_decimals: 0
    unit_of_measurement: "W"
    internal: true
    icon: mdi:gauge
  - platform: total_daily_energy
    name: $name_total_b_energy
    power_id: total_power_b
    id: total_power_b_wh
    accuracy_decimals: 0
    internal: true
    icon: mdi:gauge
  - platform: total_daily_energy
    name: $name_total_b_energy
    power_id: total_power_b
    id: total_power_b_kwh
    accuracy_decimals: 3
    filters: [multiply: 0.001]
    unit_of_measurement: "kWh"
    internal: true
    icon: mdi:gauge
    # phase C
  - platform: template
    name: $name_total_c_power
    lambda: return id(phase_c_power).state;
    update_interval: 1s
    id: total_power_c
    unit_of_measurement: "W"
    internal: true
    icon: mdi:gauge
  - platform: total_daily_energy
    name: $name_total_c_energy
    power_id: total_power_c
    id: total_power_c_wh
    accuracy_decimals: 0
    unit_of_measurement: "Wh"
    internal: true
    icon: mdi:gauge
  - platform: total_daily_energy
    name: $name_total_c_energy
    power_id: total_power_c
    id: total_power_c_kwh
    accuracy_decimals: 3
    filters: [multiply: 0.001]
    unit_of_measurement: "kWh"
    internal: true
    icon: mdi:gauge


  - { power_id: total_cir01, id: total_cir01_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit01} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir02, id: total_cir02_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit02} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir03, id: total_cir03_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit03} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir04, id: total_cir04_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit04} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir05, id: total_cir05_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit05} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir06, id: total_cir06_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit06} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir07, id: total_cir07_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit07} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir08, id: total_cir08_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit08} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir09, id: total_cir09_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit09} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir10, id: total_cir10_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit10} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir11, id: total_cir11_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit11} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir12, id: total_cir12_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit12} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir13, id: total_cir13_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit13} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir14, id: total_cir14_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit14} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir15, id: total_cir15_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit15} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }
  - { power_id: total_cir16, id: total_cir16_wh, platform: total_daily_energy, accuracy_decimals: 1, name: "${name_circuit16} in Wh", unit_of_measurement: "Wh", internal: true, icon: mdi:calendar-clock }

  - { power_id: total_cir01, id: total_cir01_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit01} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir02, id: total_cir02_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit02} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir03, id: total_cir03_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit03} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir04, id: total_cir04_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit04} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir05, id: total_cir05_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit05} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir06, id: total_cir06_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit06} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir07, id: total_cir07_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit07} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir08, id: total_cir08_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit08} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir09, id: total_cir09_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit09} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir10, id: total_cir10_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit10} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir11, id: total_cir11_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit11} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir12, id: total_cir12_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit12} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir13, id: total_cir13_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit13} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir14, id: total_cir14_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit14} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir15, id: total_cir15_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit15} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }
  - { power_id: total_cir16, id: total_cir16_kwh, platform: total_daily_energy, accuracy_decimals: 3, name: "${name_circuit16} in kWh", unit_of_measurement: "kWh", internal: true, filters: [multiply: 0.001], icon: mdi:calendar-clock }



time:
  - platform: sntp
    id: my_time
    timezone: $name_timezone
    servers:
      - 10.13.35.1
    on_time_sync:
      then:
        - logger.log: "Synchronized system clock"

    on_time:
      - seconds: /3
        then:
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/1/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir01).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/2/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir02).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/3/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir03).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/4/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir04).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/5/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir05).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/6/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir06).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/7/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir07).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/8/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir08).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/9/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir09).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/10/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir10).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/11/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir11).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/12/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir12).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/13/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir13).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/14/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir14).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/15/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir15).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/16/watt/state");
              payload: !lambda |-
                return to_string(id(total_cir16).state);
      - seconds: /3
        then:
          - mqtt.publish:
              topic: "vue2/mains/A/watt/state"
              payload: !lambda |-
                return to_string(id(phase_a_power).state);
          - mqtt.publish:
              topic: "vue2/mains/B/watt/state"
              payload: !lambda |-
                return to_string(id(phase_b_power).state);
          - mqtt.publish:
              topic: "vue2/mains/C/watt/state"
              payload: !lambda |-
                return to_string(id(phase_c_power).state);
          - mqtt.publish:
              topic: "vue2/mains/A/voltage/state"
              payload: !lambda |-
                return to_string(id(phase_a_voltage).state);
          - mqtt.publish:
              topic: "vue2/mains/B/voltage/state"
              payload: !lambda |-
                return to_string(id(phase_b_voltage).state);
          - mqtt.publish:
              topic: "vue2/mains/C/voltage/state"
              payload: !lambda |-
                return to_string(id(phase_c_voltage).state);
      - seconds: /5
        then:
          - mqtt.publish:
              topic: "vue2/mains/A/wh/state"
              payload: !lambda |-
                return to_string(id(total_power_a_wh).state);
          - mqtt.publish:
              topic: "vue2/mains/B/wh/state"
              payload: !lambda |-
                return to_string(id(total_power_b_wh).state);
          - mqtt.publish:
              topic: "vue2/mains/C/wh/state"
              payload: !lambda |-
                return to_string(id(total_power_c_wh).state);

          - mqtt.publish:
              topic: "vue2/mains/A/kwh/state"
              payload: !lambda |-
                return to_string(id(total_power_a_kwh).state);
          - mqtt.publish:
              topic: "vue2/mains/B/kwh/state"
              payload: !lambda |-
                return to_string(id(total_power_b_kwh).state);
          - mqtt.publish:
              topic: "vue2/mains/C/kwh/state"
              payload: !lambda |-
                return to_string(id(total_power_c_kwh).state);
      - seconds: /10
        then:
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/1/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir01_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/2/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir02_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/3/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir03_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/4/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir04_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/5/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir05_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/6/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir06_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/7/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir07_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/8/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir08_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/9/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir09_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/10/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir10_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/11/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir11_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/12/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir12_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/13/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir13_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/14/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir14_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/15/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir15_wh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/16/wh/state");
              payload: !lambda |-
                return to_string(id(total_cir16_wh).state);
      - seconds: /20
        then:
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/1/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir01_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/2/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir02_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/3/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir03_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/4/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir04_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/5/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir05_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/6/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir06_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/7/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir07_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/8/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir08_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/9/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir09_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/10/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir10_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/11/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir11_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/12/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir12_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/13/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir13_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/14/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir14_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/15/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir15_kwh).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/16/kwh/state");
              payload: !lambda |-
                return to_string(id(total_cir16_kwh).state);
      - seconds: 0
        minutes: /5
        then:
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/mains/A/name/state");
              payload: !lambda |-
                return id(phase_a_power).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/mains/B/name/state");
              payload: !lambda |-
                return id(phase_b_power).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/mains/C/name/state");
              payload: !lambda |-
                return id(phase_c_power).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/1/name/state");
              payload: !lambda |-
                return id(power_cir01).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/2/name/state");
              payload: !lambda |-
                return id(power_cir02).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/3/name/state");
              payload: !lambda |-
                return id(power_cir03).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/4/name/state");
              payload: !lambda |-
                return id(power_cir04).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/5/name/state");
              payload: !lambda |-
                return id(power_cir05).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/6/name/state");
              payload: !lambda |-
                return id(power_cir06).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/7/name/state");
              payload: !lambda |-
                return id(power_cir07).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/8/name/state");
              payload: !lambda |-
                return id(power_cir08).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/9/name/state");
              payload: !lambda |-
                return id(power_cir09).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/10/name/state");
              payload: !lambda |-
                return id(power_cir10).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/11/name/state");
              payload: !lambda |-
                return id(power_cir11).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/12/name/state");
              payload: !lambda |-
                return id(power_cir12).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/13/name/state");
              payload: !lambda |-
                return id(power_cir13).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/14/name/state");
              payload: !lambda |-
                return id(power_cir14).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/15/name/state");
              payload: !lambda |-
                return id(power_cir15).get_name();
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/16/name/state");
              payload: !lambda |-
                return id(power_cir16).get_name();

@tappyson
Copy link

tappyson commented Jul 1, 2022

@tappyson you're on the right track. You have the instantaneous power imported and exported. But you need to add that up over time.

Try adding two more sensors like the existing total daily energy:

  - platform: total_daily_energy
    name: "Total Daily Energy"
    power_id: total_power
    accuracy_decimals: 0

Details on how it works: https://esphome.io/components/sensor/total_daily_energy.html

You'll want to replace the thing it's summing over with your totalexported, etc.

PS: I fixed the formatting, here's an explanation of how it works

Thanks so much. Got to working a treat.

@tappyson
Copy link

tappyson commented Jul 1, 2022

What would good practice be for creating a 1 or 5 min sensor. Create a new sensor with more datapoints using the rolling moving average?

Also does anyone know of a good way to send only say 5min data but then activate a 1s sensor for live viewing with some form of button click?

@flaviut
Copy link
Author

flaviut commented Jul 2, 2022

@tappyson

What would good practice be for creating a 1 or 5 min sensor. Create a new sensor with more datapoints using the rolling moving average?

Yup, exactly. Moving averages are way more complicated than you'd expect, but the sliding_window_moving_average is likely what you're looking for.

Also does anyone know of a good way to send only say 5min data but then activate a 1s sensor for live viewing with some form of button click?

Sorry, I can't help here.


@devWaves Thanks for the reminder! I've updated the guide.

@cosmicosmo4
Copy link

cosmicosmo4 commented Jul 4, 2022

I am having an issue, my total_daily_energy sensors are not resetting at all. I am running esphome and homeassistant in docker containers, with configs nearly identical to the example. I do see the accurate local time in my esphome logs.

In the device's config I have:

time:
  - platform: sntp
    id: my_time

In docker-compose.yaml I have:

    environment:
      ESPHOME_DASHBOARD_USE_PING: 'true'
      TZ: 'America/Chicago'
    volumes:
      - './esphomeconfig/:/config:rw'
      - /etc/localtime:/etc/localtime
      - /etc/timezone:/etc/timezone

(possibly redundant?)

And in the logs I see:

[10:14:17][C][sntp:050]: SNTP Time:
[10:14:17][C][sntp:051]:   Server 1: '0.pool.ntp.org'
[10:14:17][C][sntp:052]:   Server 2: '1.pool.ntp.org'
[10:14:17][C][sntp:053]:   Server 3: '2.pool.ntp.org'
[10:14:17][C][sntp:054]:   Timezone: 'CST6CDT,M3.2.0,M11.1.0'
[10:14:19][D][sensor:125]: 'Total Power': Sending state 236.83893 W with 1 decimals of accuracy
[10:14:19][D][sensor:125]: 'Total Daily Energy': Sending state 283491.21875 Wh with 0 decimals of accuracy

which is the correct local time.

The device is in a VLAN that's firewalled off from the internet, but I opened a rule to allow it to send packets to port 123:

image

But the data just keeps going up:

image

Thanks for any help!

@Ofloo
Copy link

Ofloo commented Jul 4, 2022

you need cycle: daily inside your energy total`

  - platform: total_daily_energy
    name: "Total Daily Energy"
    power_id: total_power
    accuracy_decimals: 0
    cycle: daily

@cosmicosmo4
Copy link

That gives me:
image

@flaviut
Copy link
Author

flaviut commented Jul 4, 2022

I don't see a cycle parameter documented: https://esphome.io/components/sensor/total_daily_energy.html

Anyway @cosmicosmo4, are you sure the time is getting synchronized? You should see a log message: esphome/issues#449 (comment)

@cosmicosmo4
Copy link

I haven't noticed the "Synchronizing..." message. How often is it supposed to synchronize? Also, I do have the correct time in the logs, so it must have synchronized at some point.

@Ofloo
Copy link

Ofloo commented Jul 4, 2022

oh that's inside the emporia config

I have

time:
  - platform: sntp
    id: my_time
    timezone: $name_timezone
    servers:
      - 10.13.35.1
    on_time_sync:
      then:
        - logger.log: "Synchronized system clock"

However keep in mind that I have setup ntp on my gateway don't like my iot clients going to the internet so ...

@stephenjamieson
Copy link

You could try syncing with homeassistant:

time:
  - platform: homeassistant
    id: homeassistant_time
    timezone: America/New_York

@Ofloo
Copy link

Ofloo commented Jul 4, 2022

for name_timezone I have name_timezone: 'CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00'

@flaviut
Copy link
Author

flaviut commented Jul 4, 2022

I'm out of ideas :)

I'd suggest asking the ESPHome community directly. Please let us know what you find out!

@cosmicosmo4
Copy link

cosmicosmo4 commented Jul 11, 2022

Well I solved the problem by specifying the IP addresses of some NTP servers. I have no idea why the emporia was either not finding my pihole or failing DNS lookup for some reason. Everything else on this VLAN works fine.

time:
  - platform: sntp
    id: my_time
    servers:
      - 69.130.244.141
      - 69.164.198.192
      - 185.216.231.116

Unfortunately I imagine this is more likely to break in the future if IP addresses change.

@cdavis289
Copy link

Just wanted to say thanks for all of your work! I set this up yesterday and everything went very smoothly. I wanted to add some additional info for others that install this. I was quite nervous when I did this and this info may help others.

  1. Instead of holding the wire from the IO0 pin to the shield I used a piece of masking tape. I'm not sure if that is risky, but it worked for me.
  2. On os x, if this command failed "esptool.py -b 921600 read_flash 0 0x800000" I had to unplug my USB to serial converter module before trying the other baud rate otherwise I would get "in use" errors.
  3. When I ran the command "esphome run vue2.yaml" I didn't receive any errors.

To do a quick test after the software is flashed, I disconnected the power (VCC) and the IO0 ground, then plugged the VCC pin back in. You can then see if the unit successfully connects to your wifi without having to assemble the entire unit.

@flaviut
Copy link
Author

flaviut commented Jul 13, 2022

  1. Instead of holding the wire from the IO0 pin to the shield I used a piece of masking tape. I'm not sure if that is risky, but it worked for me.

Good idea! I've made a note of that in the instructions

You're right, I've taken so much stuff apart that I don't feel this is at all risky. But people unfamiliar with electronics very likely feel differently.

For future calibration, the only risk here is connecting the positive power and ground backwards, and I think that might be OK too as long as you notice within a few seconds.

To do a quick test after the software is flashed, I disconnected the power (VCC) and the IO0 ground, then plugged the VCC pin back in

Yes, this works, but some adapters don't have enough power to do this, since WiFi draws a lot of power. There's no risk of harm, but it will just keep turning on and off. So rather than answer questions about that, I've omitted it. I've never heard of any trouble connecting to WiFi, so it seems to have worked out!

@PanicRide
Copy link

Instead of holding the wire from the IO0 pin to the shield I used a piece of masking tape.

If your TTL adapter happens to have both the DTR and RTS pins exposed, you can let it automatically reboot the board and put the chip into flash mode when necessary. IO0 connects to DTR, and EN connects to RTS.

Here's an example of an adapter where you can easily solder a PIN to RTS on the side of it. :)

@rjchu
Copy link

rjchu commented Jul 13, 2022

@plopes9000
Thank you for your reply and MQTT code/config example, I appreciate it! I finally had a chance to give this a try and while things compile just fine, when I try and upload I get the output below and all that the Emporia publishes to MQTT is the status as being online or offline - no actual telemetry is published. Any ideas?

I'm on ESPHome 2022.6.22

INFO Uploading /config/.esphome/build/vue-casita-mains/.pioenvs/vue-casita-mains/firmware.bin (881440 bytes)
Uploading: [============================================================] 100% Done...

INFO Waiting for result...
INFO OTA successful
INFO Successfully uploaded program.
Traceback (most recent call last):
File "/usr/local/bin/esphome", line 33, in
sys.exit(load_entry_point('esphome', 'console_scripts', 'esphome')())
File "/esphome/esphome/main.py", line 931, in main
return run_esphome(sys.argv)
File "/esphome/esphome/main.py", line 918, in run_esphome
rc = POST_CONFIG_ACTIONS[args.command](args, config)
File "/esphome/esphome/main.py", line 397, in command_run
return show_logs(config, args, port)
File "/esphome/esphome/main.py", line 292, in show_logs
return mqtt.show_logs(
File "/esphome/esphome/mqtt.py", line 105, in show_logs
topic = config[CONF_MQTT][CONF_LOG_TOPIC][CONF_TOPIC]
TypeError: 'NoneType' object is not subscriptable

@flaviut
Copy link
Author

flaviut commented Jul 16, 2022

@rjchu If you're not using their manual timing of MQTT messages, you'll want to remove the internal: true fields from the config.

As far as the other issue, try clearing the ESPHome caches. I'm not sure how to do that on your particular setup, but it might help out.

@wbarber69
Copy link

not sure what to do. Ive followed the directions. Ive got esphome to install through the terminal on my pc. Ive double checked and my vue just inst coming online on my wifi. my credentials are correct. when i get to the logger portion of installing, nothing shows in the terminal, it just sits as if its waiting for data but nothing comes through. I cannot understand why the device wont join my network. am i supposed to hook it up to mains for wifi to start working? shouldnt the esp module work independantly of the rest of the board? Has something changed that isnt being reflected in the instructions?

@wbarber69
Copy link

okay so I guess its a combination of not having the antenna connected and the usb to serial not delivering enough power for wifi. its on wifi now, but in the logs i get nothing:

INFO Reading configuration /config/esphome/vue2.yaml... INFO Detected timezone 'America/Chicago' INFO Starting log output from 192.168.1.178 using esphome API

@wbarber69
Copy link

And to make matters worse i cannot do ota updates to try to fix anything because i keep getting the error:
Error: Could not find the package with 'platformio/toolchain-esp32ulp @ ~1.22851.0' requirements for your system 'linux_aarch64'

but I have no other way to use esphome. its either pi4 and HAOS or win10 over usb-serial.

@cdavis289
Copy link

And to make matters worse i cannot do ota updates to try to fix anything because i keep getting the error: Error: Could not find the package with 'platformio/toolchain-esp32ulp @ ~1.22851.0' requirements for your system 'linux_aarch64'

but I have no other way to use esphome. its either pi4 and HAOS or win10 over usb-serial.

The error you are getting sounds similar to the error when you try to compile the yaml on the rpi. I had to setup esphome on my Mac to compile and OTA the updated bin files.

Do you have the unit installed with the clamps in your panel and you are not seeing any output?

@wbarber69
Copy link

I know that. I got the device online, and figured id try to install from esphome off HAOS as ive been having so many problems doing it from cmd terminal. Its not that i get no output with or without clamps, the logs timeout over and over again when trying to read logs. they arent empty there is nothing being reported.

@wbarber69
Copy link

okay Im not sure whats going on. Now HAOS is reporting 37 devices and i can see the power consumption. I guess i just had to wait 3 hours... Only issue now is that i left the configuration as is from the instructions intending to go in and change the clamp IDs etc. so now its working, but now am going to have to pull it all the way apart to be able to change settings?

@cdavis289
Copy link

okay Im not sure whats going on. Now HAOS is reporting 37 devices and i can see the power consumption. I guess i just had to wait 3 hours... Only issue now is that i left the configuration as is from the instructions intending to go in and change the clamp IDs etc. so now its working, but now am going to have to pull it all the way apart to be able to change settings?

You don’t need to remove it from the panel or take it apart. You can setup esphome on windows and update the config OTA.

@wbarber69
Copy link

Still no log output though. the esphome integration is showing active details, but no logs are viewable from esphome, just keeps timing out!!! wth?

@wbarber69
Copy link

okay Im not sure whats going on. Now HAOS is reporting 37 devices and i can see the power consumption. I guess i just had to wait 3 hours... Only issue now is that i left the configuration as is from the instructions intending to go in and change the clamp IDs etc. so now its working, but now am going to have to pull it all the way apart to be able to change settings?

You don’t need to remove it from the panel or take it apart. You can setup esphome on windows and update the config OTA.

yeah i wouldnt be complaining if that was an option. it also times out trying to connect.

@flaviut
Copy link
Author

flaviut commented Jul 17, 2022

@wbarber69 is the antenna fully screwed on? Is it fully inserted into the pcb? Is the antenna sticking out a side of the panel box that has the fewest wires (nearby wires interfere)? What happens if you move an access point closer to your panel?

@wbarber69
Copy link

the antenna is fine. the device is relaying information to HAOS but i cannot initiate a log output from ephome. I cannot do an ota update either through haos or esphome on windows, as it simply times out.

@wbarber69
Copy link

nevermind..... it was a stupid typo

@wbarber69
Copy link

well thanks guys, even if it was my stupid mistake. Now onto cracking open and hacking esphome onto all my emporia plugs.....

@stratus-ss
Copy link

Does anyone know how to get Home Assistant's Grid Consumption to recognize total power coming in off the grid. I assume there is something I have to do with the Vue template. Currently total power is set like this (I believe this is from the example)

 - platform: template
    name: "Total Power"
    lambda: return id(phase_a_power).state + id(phase_b_power).state;
    update_interval: 1s
    id: total_power
    unit_of_measurement: "W"

Does this have to be Wh?

@flaviut
Copy link
Author

flaviut commented Jul 26, 2022

Power is in watts, energy is in watt-hours or joules. Take a look at and use total_daily_energy, the next entry down.

I can't remember how I configured homeassistant, but everything you need should be in there--I have the exact same config, with a few numbers and names switched around.

@cdavis289
Copy link

cdavis289 commented Jul 26, 2022

Here is my code. You need to first get total power and then you use the total daily energy platform.

- platform: template
    name: "${friendly_devicename}: Total Power"
    lambda: return id(${devicename_no_dashes}_phase_a_power).state + id(${devicename_no_dashes}_phase_b_power).state;
    update_interval: 1s
    id: "${devicename_no_dashes}_total_power"
    unit_of_measurement: "W"
  
  - platform: total_daily_energy
    name: "${friendly_devicename}: Total Daily Energy"
    power_id: "${devicename_no_dashes}_total_power"
    accuracy_decimals: 0

@stratus-ss
Copy link

thanks @cdavis289 and @flaviut I appreciate what you both do to help this project!

@hiveai
Copy link

hiveai commented Jul 28, 2022

What is the recommended config for an unused input on the emporia vue2? I have some unused inputs that are showing values that are jumping all around (e.g. 0W->8W->24W->0W). How can I configure these Emporia inputs as unused and zero them out?

@flaviut
Copy link
Author

flaviut commented Jul 28, 2022

@hiveai delete their lines in the config and remove the places they're referenced from

@hiveai
Copy link

hiveai commented Jul 29, 2022

@flaviut and other contributors: Thanks for this great project and documentation! I have the vue2 flashed with custom ESPHome code and it working.
Is there a pointer to the recommended way to integrate the data into the energy dashboard in home assistant? I can bring up the device under ESPHome and see the power usage, but I'm not clear on how to configure Home Assistant to use this as a data source for energy monitoring.

@cdavis289
Copy link

Settings -> Dashboards -> Energy -> Electricity Grid (left side) -> Add Consumption or Add device

Select Emporia Vue Circuit Daily Energy Entities or Total Daily Energy.

I like to add each circuit to the consumption. Home assistant will stack the entities in the bar chart so you can get a visual of which circuit uses the most energy. You can also add them to the devices to see a comparison. Just depends on your preference.

@hiveai
Copy link

hiveai commented Jul 29, 2022

@cdavis289 Thanks! That's the info I needed. Looking up in the other comments I see that some folks are using MQTT for integration. Is that in addition to adding devices to the energy dashboard, or instead of the energy dashboard integration. What does MQTT integration of the ESPHome Vue2 get you? I apologize for these basic questions, but looking at the documentation and previous Comments/Q&A it's not clear to me.

@flaviut
Copy link
Author

flaviut commented Jul 29, 2022 via email

@dcorwin8222
Copy link

dcorwin8222 commented Jul 31, 2022 via email

@flaviut
Copy link
Author

flaviut commented Jul 31, 2022

@Jens5395
Copy link

Jens5395 commented Aug 5, 2022

If I upload the bare stub that is generated when a new device is added to ESPHome, should the Emporia connect to wifi? I can't upload the full configuration because it won't compile on the pi4 so I was hoping to maybe do the full configuration over the air once the Emporia is connected to the network. Right now I am dead in the water :(

@flaviut
Copy link
Author

flaviut commented Aug 5, 2022 via email

@Jens5395
Copy link

Jens5395 commented Aug 6, 2022

What's a 'regular computer'? LOL
Anyway, things have progressed substantially from my earlier post. The stub uploads and programs just fine and if you supply enough juice, the emporia does connect to the wifi network. I had to hook up line power to the emporia to make it run.
I tried everything I could think of to upload the required configuration but of course because of the lack of the required tool chain, that got me nowhere :(.
I have now set up an ubuntu laptop with ESPHome and ESPHome dashboard (no Home Assistant) and I got the configuration to compile! now my problem is 'how do I get the magic file that compiled onto the emporia which is wifi connected to the emporia'.. Unfortunately the upload via wifi fails and the ESPHome program will not recognize my serial port to do a wired transfer.
I am also working on some network issues because even though Ubiquity reports the empora to be on line, I can not ping it (although pings might not be allowed in ESPHome.
More research is required!

@flaviut
Copy link
Author

flaviut commented Aug 6, 2022

I'm pretty sure something weird is going on with your wifi, ping works fine for me:

$ ping emporiavue2.lan
PING emporiavue2.lan (192.168.86.144) 56(84) bytes of data.
64 bytes from emporiavue2.lan (192.168.86.144): icmp_seq=1 ttl=255 time=114 ms
64 bytes from emporiavue2.lan (192.168.86.144): icmp_seq=2 ttl=255 time=17.5 ms
64 bytes from emporiavue2.lan (192.168.86.144): icmp_seq=3 ttl=255 time=55.1 ms

anyway, now that you've compiled the file, you can transfer the .bin file over to the Pi, where presumably you had a working serial connection. Something like esptool.py --port /dev/ttyUSB0 write_flash 0x0 emporiavue2.bin should work.

@Jens5395
Copy link

Jens5395 commented Aug 6, 2022

Unfortunately, I am giving up for now.
I am now able to send a configuration from my secondary (non pi4) computer to the emporia but I am now getting a butt load of linking errors during the compile which I do not know how to deal with.
Note that I DO NOT HAVE the full Home Assistant installed on this computer. I only installed ESPHome and ESPHome dashboard. I suspect that some of te stuff that is being complained about relates to the HA not being installed.
Here is a shortened version that shows the beginning of the compile followed by a tiny portion of the linking errors (everything after the line that starts with "linking...." is an error message:

INFO Reading configuration config/emporia-01.yaml...
INFO Detected timezone 'America/Vancouver'
INFO Generating C++ source...
INFO Compiling app...
Processing emporia-01 (board: esp32dev; framework: espidf; platform: platformio/espressif32 @ 3.5.0)

HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash

  • framework-espidf @ 3.40302.0 (4.3.2)
  • tool-cmake @ 3.16.4
  • tool-ninja @ 1.7.1
  • toolchain-riscv32-esp @ 8.4.0+2021r2-patch2
  • toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch2
  • toolchain-xtensa-esp32s2 @ 8.4.0+2021r2-patch2
    Reading CMake configuration...
    LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
    No dependencies
    Linking .pioenvs/emporia-01/firmware.elf
    /home/jens/.platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/emporia-01/src/esphome/components/api/api_connection.o:(.literal._ZN7esphome3api13APIConnection17send_sensor_stateEPNS_6sensor6SensorEf+0xc): undefined reference to esphome::sensor::Sensor::has_state() const' /home/jens/.platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/emporia-01/src/esphome/components/api/api_connection.o:(.literal._ZN7esphome3api13APIConnection16send_sensor_infoEPNS_6sensor6SensorE+0x10): undefined reference to esphome::sensor::Sensor::get_unit_of_measurementabi:cxx11'
    /home/jens/.platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/emporia-01/src/esphome/components/api/api_connection.o:(.literal._ZN7esphome3api13APIConnection16send_sensor_infoEPNS_6sensor6SensorE+0x14): undefined reference to `esphome::sensor::Sensor::get_accuracy_decimals()'

@Jens5395
Copy link

Jens5395 commented Aug 7, 2022

Final entry:

For reasons unknown to me, the Emporia configuration compiled, was installed wireless and seems to function. There was a computer reboot involved so that might have fixed whatever was causing the compile errors.
To sum it up, a pi4 64 bit HA server configuration can not compile the Emporia Vue 2 configuration via ESPHome. It can however generate a configuration stub that, once uploaded to the emporia with a wired connection, will allow the emporia to connect to the network via wifi.
Now that the Emporia is on line, the Emporia configuration can be built. This is done, in my case, on a Ubuntu machine that runs an Intel processor and has the required tool chains available.
I installed ESPHome and ESPHome dashboard on my computer (the one wit the Intel processor). Note that there was only ESPHome installed and no Home Assistant files/system. I started up ESPHome, went to the dashboard (btw, you can also do this without the dashboard and I think I read that the dashboard only works on Linux) and generated a new stub for the Emporia. I then copied the configuration as shown in the article here into the stub, over-writing the temporary stub (it was just a place holder). I adjusted the wifi parameters for my setup. There are a couple of gotcha's here. My normal esphome configuration files use !secrets for the ssid and password. This will not work because we are compiling on a computer that does not have these HA options available. The ssid and password must be hard coded into the configuration. I also had to set up static IP parameters in the configuration in order to make this work .... although I can't recall the exact reason. All my esphome devices have static IP's set up in the router so hardcoding a static IP in the configuration might not be required. YMMV.
So, we have an Emporia device that is on the network and we have a configuration file set up on the Intel computer. All that is required now is to install the new configuration to the Emporia.
If all goes as planned (and not like in my case), the configuration will be compiled, uploaded to the Emporia that is on line already and when finished, the Emporia will reboot and spew out all kinds of data which will be captured in the Home Assistant system running on the Pi4.
When you set up the hard coded credentials, please note that the SSIDS field is case sensitive. I new this was so for the password but did not realize that this was the case for the SSID. That error took me WAY too long to find!
I hope that this might help future HA builders to set up an Emporia device without all the crap I went through .....

@Jens5395
Copy link

Jens5395 commented Aug 7, 2022

The instructions for the Emporia indicate that it doesn't matter which of the three 200A circuits you plug into. I am in North America so there are two 200A clamps and it does indeed matter how they are connected to the Emporia. With the configuration script shown in this article, one needs to use inputs A and B.
Yes I know they are called A and B in the configuration but I didn't make the connection ....
While the instructions allude to the fact that you need to keep the legs sorted, I would like to stress that it is important not only for the current clamps but also how you hook up power to the Emporia. If the power leads to the emporia do not not match which 200A clamp is on what leg, readings might be wrong or you might have no readings at all. The black Emporia power wire needs to be on the same power distribution leg that has current clamp A on it. The red power wire needs to be on the same power leg as the clamp that feeds input B.

@Jens5395
Copy link

Jens5395 commented Aug 7, 2022

How does HA know when to reset daily energy numbers? My new install doesn't seem to reset at midnight.

@flaviut
Copy link
Author

flaviut commented Aug 7, 2022 via email

@flaviut
Copy link
Author

flaviut commented Aug 7, 2022 via email

@clowrey
Copy link

clowrey commented Aug 8, 2022

Thanks for all the work getting this working!! I spent about 5 hours thinking there was some way I could get it to compile on a raspberry pi 4 with 4gb ram- including switching to the 32bit version, but it still wont work.. So in the end I relented and am now running home assistant on a 7 year old i3 intel NUC and it works great!! I definitely recommend anyone wanting to use this currently in a standalone installation to just buy a used intel NUC for < $100 on ebay and be done with it... Going to try get it working with three phase inputs some time soon, not sure how hard/easy that will be.

EDIT > looks like it works with three phase just by adding in phase C in the config file! awesome!

@Jens5395
Copy link

Jens5395 commented Aug 8, 2022

I spent way too many hours on this ... but in the end, my method works great and I still have my original Pi4 running HA.

@clowrey
Copy link

clowrey commented Aug 8, 2022

I spent way too many hours on this ... but in the end, my method works great and I still have my original Pi4 running HA.

But can you change the ESPhome settings from the RPI4? that is my main reason, I anticipate needing to re-compile and update, and will have remote systems running this etc..

Edit > I'm not saying one method is better than the other, just saying for me this is overall easier and more maintainable, at least until we can compile it on ARM..

@Jens5395
Copy link

Jens5395 commented Aug 8, 2022

No, I would not be able to change the configuration from the Pi4 .... that would require a recompile which can't be done from the Pi4.
I installed ESPHome and the dashboard on one of my laptops. It just sits there ready for use. If I need to recompile, I just start up ESPHome, go to the dashboard, load te configuration file, tweak it and send it back to the Emporia - no muss, no fuss, I just have to remember to do it via Chrome instead of my normal browser (Thunderbird).
I recompiled a whole bunch of times as I was setting everything up so yes, you absolutely need to be able to recompile and send te result to the Emporia. I am still working out a couple of issues and expect that I am not finished configuring things.
BTW, I did not try generating the .bin file on my laptop, transfer it to the pi and then send it to the Emporia. That should (in theory) work but it's an extra step that is not really required.

@Jens5395
Copy link

Jens5395 commented Aug 9, 2022

Does anybody else have issues with 'daily energy' never resetting at the end of the day?
I did need to set my own sntp server (network doesn't allow traffic to the outside) but that didn't help. Looking at the logs from the Emporia, every message has the correct time in front of it.
Let me clarify this a bit - if I look at the 'energy' dashboard, the daily energy is correct. I have an 'entities' card set up in one of my dashboard views and it shows individual circuits and individual daily power usage (and total daily power usage). It is those totals sensors that do not reset.
Platfom 'Total Daily Energy Sensor' states:

# Enable time component to reset energy at midnight
time:
  - platform: sntp
    id: my_time

From what I can tell, the time platform is working as every single status message from the Emporia has the correct time stamp .... but maybe that time component is different from the time that shows up in the logs - how do I check if id: my_time is correct? my_time is not an entity or a helper so how can I verify it?

@mgulick
Copy link

mgulick commented Aug 9, 2022

Does anybody else have issues with 'daily energy' never resetting at the end of the day?

My daily energy value also did not reset at first. I don't know exactly what I did to fix it. It may have started working on its own at some point after a few days or maybe a week. I do remember that I changed the time platform from sntp to:

time:
  - platform: homeassistant
    id: homeassistant_time

This is working fine for me and is syncing time via home assistant. I have my emporia vue 2 on an isolated VLAN which doesn't have internet access, so sntp probably wasn't working (my DHCP server hands out local ntp server info, but I think most devices ignore that).

@Jens5395
Copy link

Jens5395 commented Aug 9, 2022

Thanks for that mgulick. I tried that this morning but this gives me a compile error which is likely due to me having to compile the Emporia configuration on a computer other than the computer running HA.
It is good to know I am not the only person that has/had daily reset issues.

*** [.pioenvs/emporia-01/src/esphome/components/sntp/sntp_component.o] Source `src/esphome/components/sntp/sntp_component.cpp' not found, needed by target `.pioenvs/emporia-01/src/esphome/components/sntp/sntp_component.o'.

@stephenjamieson
Copy link

Is there another location, discord or an issue somewhere, that these things can be discussed. I'm honestly watching this gist in case there are changes or issues with the integration itself.

@clowrey
Copy link

clowrey commented Aug 9, 2022

You could just watch the Integration source repository that is linked to in the example configuration. Not sure where else to discuss issues as there is no issue tracker?

changes or issues with the integration itself.

@mgulick
Copy link

mgulick commented Aug 9, 2022

@Jens5395, I would frequently have compile errors when rebuilding after making changes to the configuration. Cleaning the build artifacts usually resolved the issue. It looks like this option is called "Clean Build Files" from the ESPHome dashboard (https://esphome.io/guides/getting_started_hassio.html) and esphome clean <config> from the ESPHome CLI (https://esphome.io/guides/cli.html#clean-command).

@Jens5395
Copy link

Jens5395 commented Aug 9, 2022

Ha!!!! That did the trick, it compiled! Now to see if it fixes things at midnight ....
Thanks!

@stephenjamieson
Copy link

@clowrey sure, my point is that these issues are not related to the Emporia Vue.

@flaviut
Copy link
Author

flaviut commented Aug 9, 2022

Please keep all discussion here

Hey y'all, I've had my own gripes with Gist as a discussion platform as well.

Any further comments here will be deleted and recreated in https://github.com/emporia-vue-local/esphome/discussions. This will be the last comment on this gist.

@doronazl
Copy link

@rjchu, Yes mqtt is working quite well - I use FHEM (https://fhem.de/) hence mqtt is my choice of integration in this case.

Btw, unlike the emporia app which only calculates apparent power on the 16 CTs, this implementation is correctly measuring real power - thank you @flaviut !

sudo docker run --rm -v "${PWD}":/config -it esphome/esphome version
Version: 2022.6.0

here is my draft config - still making design decisions but working quite well already. the send times are temporarily set too low, I plan on every 10 secs for instant and every 5 mins for totals, etc

esphome:
  name: emporiavue2

external_components:
  - source: github://flaviut/esphome@emporia-vue-2022.4.0
    components: [ emporia_vue ]

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

# Enable Home Assistant API
#api: {"password": "<ota password>"}
ota: {"password": "<xyz>"}

# Enable logging
logger:
  level: WARN

wifi:
  ssid: "myssid"
  password: "mypassword"

mqtt:
  broker: 1.2.3.4
  client_id: vue2
  username: myuser
  password: mypassword
  port: 1883
  topic_prefix: vue2
  discovery: false
  log_topic: null


i2c:
  sda: 21
  scl: 22
  scan: false
  frequency: 200kHz  # recommended range is 50-200kHz
  id: i2c_a

# these are called references in YAML. They allow you to reuse
# this configuration in each sensor, while only defining it once
.defaultfilters:
  - &moving_avg
    # we capture a new sample every 0.24 seconds, so the time can
    # be calculated from the number of samples as n * 0.24.
    sliding_window_moving_average:
      # we average over the past 2.88 seconds
      window_size: 12
      # we push a new value every 1.44 seconds
      send_every: 6
  - &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);'

sensor:
  - platform: emporia_vue
    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.0229  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "Phase A Voltage"
          internal: true
          id: phase_a_voltage
          filters: [*moving_avg, *pos]
      - id: phase_b  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: RED  # Vue device wire color
        calibration: 0.022  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          name: "Phase B Voltage"
          internal: true
          id: phase_b_voltage
          filters: [*moving_avg, *pos]
      - id: phase_c  # Verify that this specific phase/leg is connected to correct input wire color on device listed below
        input: BLUE  # Vue device wire color
        calibration: 0.022193  # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
        # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
        voltage:
          internal: true
          name: "Phase C Voltage"
          id: phase_c_voltage
          filters: [*moving_avg, *pos]
    ct_clamps:
      - phase_id: phase_a
        input: "A"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Phase A Power"
          internal: true
          id: phase_a_power
          device_class: power
          filters: [*moving_avg, *pos]
      - phase_id: phase_b
        input: "B"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Phase B Power"
          internal: true
          id: phase_b_power
          device_class: power
          filters: [*moving_avg, *pos]
      - phase_id: phase_c
        input: "C"  # Verify the CT going to this device input also matches the phase/leg
        power:
          name: "Phase C Power"
          internal: true
          id: phase_c_power
          device_class: power
          filters: [*moving_avg, *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: { name: "Front Steps (Camera, Lights)",                            internal: true, id:  cir1, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_b, input:  "2", power: { name: "Kitchen Left (Fridge, Oven, Microwave)",                  internal: true, id:  cir2, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_b, input:  "3", power: { name: "Kitchen Right (Dishwasher, Coffee Machine)",              internal: true, id:  cir3, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_b, input:  "4", power: { name: "4 ??",                                                       internal: true, id:  cir4, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_c, input:  "5", power: { name: "Kitchen Stove",                                           internal: true, id:  cir5, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_b, input:  "6", power: { name: "Downstairs Right (Study, Hall, Bathroom, Guest, Server)", internal: true, id:  cir6, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_c, input:  "7", power: { name: "Downstairs Left (Living, Dining Room)",                   internal: true, id:  cir7, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_b, input:  "8", power: { name: "Upstairs (Master Bedroom)",                               internal: true, id:  cir8, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input:  "9", power: { name: "Upstairs (incl. Attic lights, except Master Bedroom)",    internal: true, id:  cir9, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_c, input: "10", power: { name: "Cellar, Washing Room, Power Room (incl. Freezer)",        internal: true, id: cir10, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "11", power: { name: "Doorbell",                                                internal: true, id: cir11, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "12", power: { name: "Shutters",                                                internal: true, id: cir12, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "13", power: { name: "Cellar (Dryer, Washer)",                                  internal: true, id: cir13, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "14", power: { name: "Cellar Right, Workshop Play Room, Heating Room",          internal: true, id: cir14, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "15", power: { name: "Outdoors Lights",                                         internal: true, id: cir15, filters: [ *moving_avg, *pos ] } }
      - { phase_id: phase_a, input: "16", power: { name: "Cellar Left, Washing Room (Plants Lights, Garage)",       internal: true, id: cir16, filters: [ *moving_avg, *pos ] } }





  - platform: template
    internal: true
    name: "Total Circuits Power"
    lambda: return 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: 1s
    id: total_power_circuits
    unit_of_measurement: "W"
  - platform: template
    internal: true
    name: "Total Power"
    lambda: return id(phase_a_power).state + id(phase_b_power).state + id(phase_c_power).state;
    update_interval: 1s
    id: total_power
    unit_of_measurement: "W"
  - platform: total_daily_energy
    name: "Total Daily Energy"
    internal: true
    power_id: total_power
    id: total_daily_power
    accuracy_decimals: 0
    min_save_interval: 10s
    unit_of_measurement: "W"
  - { power_id:  cir1, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir1 }
  - { power_id:  cir2, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir2 }
  - { power_id:  cir3, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir3 }
  - { power_id:  cir4, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir4 }
  - { power_id:  cir5, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir5 }
  - { power_id:  cir6, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir6 }
  - { power_id:  cir7, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir7 }
  - { power_id:  cir8, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir8 }
  - { power_id:  cir9, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir9 }
  - { power_id: cir10, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir10 }
  - { power_id: cir11, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir11 }
  - { power_id: cir12, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir12 }
  - { power_id: cir13, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir13 }
  - { power_id: cir14, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir14 }
  - { power_id: cir15, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir15 }
  - { power_id: cir16, platform: total_daily_energy, accuracy_decimals: 0, internal: true, id: total_daily_power_cir16 }

time:
  - platform: sntp
    id: my_time
    timezone: Europe/Berlin
    servers: 
      - 192.168.178.99
      - 0.pool.ntp.org
      - 1.pool.ntp.org
    on_time_sync:
      then:
        - logger.log: "Synchronized system clock"
    on_time:
      - seconds: /10
        then:
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir01_power");
              payload: !lambda |-
                return to_string(id(cir1).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir02_power");
              payload: !lambda |-
                return to_string(id(cir2).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir03_power");
              payload: !lambda |-
                return to_string(id(cir3).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir04_power");
              payload: !lambda |-
                return to_string(id(cir4).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir05_power");
              payload: !lambda |-
                return to_string(id(cir5).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir06_power");
              payload: !lambda |-
                return to_string(id(cir6).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir07_power");
              payload: !lambda |-
                return to_string(id(cir7).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir08_power");
              payload: !lambda |-
                return to_string(id(cir8).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir09_power");
              payload: !lambda |-
                return to_string(id(cir9).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir10_power");
              payload: !lambda |-
                return to_string(id(cir10).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir11_power");
              payload: !lambda |-
                return to_string(id(cir11).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir12_power");
              payload: !lambda |-
                return to_string(id(cir12).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir13_power");
              payload: !lambda |-
                return to_string(id(cir13).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir14_power");
              payload: !lambda |-
                return to_string(id(cir14).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir15_power");
              payload: !lambda |-
                return to_string(id(cir15).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir16_power");
              payload: !lambda |-
                return to_string(id(cir16).state);
          - mqtt.publish:
              topic: "vue2/circuits/total_power_circuits"
              payload: !lambda |-
                return to_string(id(total_power_circuits).state);
          - mqtt.publish:
              topic: "vue2/mains/total/total_power"
              payload: !lambda |-
                return to_string(id(total_power).state);

      - seconds: /10
        then:
          - mqtt.publish:
              topic: "vue2/mains/phase_a_voltage"
              payload: !lambda |-
                return to_string(id(phase_a_voltage).state);
          - mqtt.publish:
              topic: "vue2/mains/phase_b_voltage"
              payload: !lambda |-
                return to_string(id(phase_b_voltage).state);
          - mqtt.publish:
              topic: "vue2/mains/phase_c_voltage"
              payload: !lambda |-
                return to_string(id(phase_c_voltage).state);
          - mqtt.publish:
              topic: "vue2/mains/phase_a_power"
              payload: !lambda |-
                return to_string(id(phase_a_power).state);
          - mqtt.publish:
              topic: "vue2/mains/phase_b_power"
              payload: !lambda |-
                return to_string(id(phase_b_power).state);
          - mqtt.publish:
              topic: "vue2/mains/phase_c_power"
              payload: !lambda |-
                return to_string(id(phase_c_power).state);

      - seconds: 0
        minutes: /5
        then:
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir01_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir1).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir02_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir2).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir03_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir3).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir04_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir4).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir05_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir5).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir06_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir6).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir07_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir7).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir08_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir8).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir09_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir9).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir10_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir10).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir11_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir11).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir12_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir12).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir13_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir13).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir14_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir14).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir15_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir15).state);
          - mqtt.publish:
              topic: !lambda |-
                return std::string("vue2/circuits/cir16_total_daily_power");
              payload: !lambda |-
                return to_string(id(total_daily_power_cir16).state);


      - seconds: 0
        minutes: /5
        then:
          - mqtt.publish:
              topic: "vue2/mains/total/total_daily_power"
              payload: !lambda |-
                return to_string(id(total_daily_power).state);

      - seconds: 0
        minutes: /10
        then:
          - mqtt.publish:
              topic: "vue2/circuits/cir01_name"
              payload: !lambda |-
                return id(cir1).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir02_name"
              payload: !lambda |-
                return id(cir2).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir03_name"
              payload: !lambda |-
                return id(cir3).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir04_name"
              payload: !lambda |-
                return id(cir4).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir05_name"
              payload: !lambda |-
                return id(cir5).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir06_name"
              payload: !lambda |-
                return id(cir6).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir07_name"
              payload: !lambda |-
                return id(cir7).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir08_name"
              payload: !lambda |-
                return id(cir8).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir09_name"
              payload: !lambda |-
                return id(cir9).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir10_name"
              payload: !lambda |-
                return id(cir10).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir11_name"
              payload: !lambda |-
                return id(cir11).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir12_name"
              payload: !lambda |-
                return id(cir12).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir13_name"
              payload: !lambda |-
                return id(cir13).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir14_name"
              payload: !lambda |-
                return id(cir14).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir15_name"
              payload: !lambda |-
                return id(cir15).get_name();
          - mqtt.publish:
              topic: "vue2/circuits/cir16_name"
              payload: !lambda |-
                return id(cir16).get_name();

Hi. How is your setup working with 3 phase?
Just bought a couple of emporia and noticed the yaml is setup for 2 phase, not 3.

@cangaroo82
Copy link

Good morning
VUE 2 modified with ESPHOME.
same as VUE2.yaml. on home assistant virtual machine works well.
on ihost modified Home assistant returns:

`- Configuring incomplete, errors occurred!
See also "/data/build/vue2-1/.pioenvs/vue2-1/CMakeFiles/CMakeOutput.log".
See also "/data/build/vue2-1/.pioenvs/vue2-1/CMakeFiles/CMakeError.log".

fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
CMake Error at /data/cache/platformio/packages/tool-cmake/share/cmake-3.16/Modules/CMakeTestCCompiler.cmake:60 (message):
The C compiler

"/data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc"

is not able to compile a simple test program.

It fails with the following output:

Change Dir: /data/build/vue2-1/.pioenvs/vue2-1/CMakeFiles/CMakeTmp

Run Build Command(s):/data/cache/platformio/packages/tool-ninja/ninja cmTC_22cff && [1/2] Building C object CMakeFiles/cmTC_22cff.dir/testCCompiler.c.obj
[2/2] Linking C executable cmTC_22cff
FAILED: cmTC_22cff 
: && /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcc -mlongcalls -Wno-frame-address   CMakeFiles/cmTC_22cff.dir/testCCompiler.c.obj  -o cmTC_22cff   && :
/data/cache/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/../libexec/gcc/xtensa-esp32-elf/8.4.0/liblto_plugin.so: error loading plugin: /data/cache/platformio/packages/toolchain-xtensa-esp32/bin/../libexec/gcc/xtensa-esp32-elf/8.4.0/liblto_plugin.so: cannot open shared object file: No such file or directory
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
/data/cache/platformio/packages/framework-espidf/tools/cmake/project.cmake:298 (__project)
CMakeLists.txt:3 (project)

========================= [FAILED] Took 26.35 seconds =========================`

@SamSavageSpeed
Copy link

SamSavageSpeed commented Jun 6, 2024

@fabiopbx the current reading doesn't work. I've never been able to figure it out, and there's been some past
discussion where others couldn't figure it out either. I would recommend against using the current sensor.

I'd suggest you use a multimeter with a current clamp (don't touch any metal with your fingers! this stuff can easily kill you!)
to see what's going on and if the kW reading is inaccurate. If you want current, you can always calculate it using power/voltage.

Hello @flaviut,

Are current readings ok now ? What should I add in the yaml in order to expose
them in HA for the small 16 clamps ? Because I'd like to give a try to the following :

emporia-vue-local/esphome#287 (comment)
Thanks in advance for your input. Best regards.

S@M

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment