These instructions have moved to https://github.com/emporia-vue-local/esphome
-
-
Save flaviut/93a1212c7b165c7674693a45ad52c512 to your computer and use it in GitHub Desktop.
@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)
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.
@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?
@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!
very happy to be off the hook from their cloud lol, who knows when they unplug the server...
@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.
@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
@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.
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'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.
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!
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
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.
foo
is a placeholder. *moving_avg
for example.
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
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.
@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?
Is this adding
sensor.home1_total_power
andsensor.home2_total_power
to giveHome 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!
I'm seeing some odd behaviour that I don't understand.
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!
I've tried to search, has anyone successfully done this to a standard "Emporia Vue" ... the sticker says "Gen 2 Emporia Vue Smart....eter"
@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:
. The older model looks different and is neither compatible or possible to add support for here.
Has anyone else noticed erroneous energy spikes and wifi drop-outs using ESPHome v2022.5.0? v2022.4.0 was solid for me.
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
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.
Thanks for the reply.
So assuming I have this right: Vue2 connected to -> USB to Serial Adapter connected to -> RPi (with Home Automation & ESPHome)
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.
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.
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!
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/
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
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.
There's a guide at the top of this page on how to build this.
@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.
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
Does this currently support the 3 phases Emporia systems? I was able to flash, but I just see Phase A / B
@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
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
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.
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.
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.
@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.
thank you, i had tried some combinations but your tip helped, i used what's after : and it worked
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.
@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".
yep.. sorry.. i jumped the gun, im recompiling it now with some changes.
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
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 😄
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
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
Mine were filled with solder. It was easy to remove with desoldering wick.
Thanks guys!!
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.
@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.
@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..
@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.
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.
@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.
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.
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.
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]
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 ==========================
@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!
@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.
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" }
@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
Thanks Flaviut, will try that
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)
@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 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....
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.
Thanks, maybe something like this would be a solution:
https://www.amazon.com/Inovat-Headphone-Converter-Adapter-Right/dp/B01KOJAJKW
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.
@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();
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.
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
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 ==========================
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.
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?
I didn't play with the timezone as ESPHome automatically picks it from the device running ESPHome. At least, it has for me.
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:
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?
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:
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?
@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 @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!
@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:
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 re. the time, I don't know.
I live in
America/New_York
too, my config istime: - platform: sntp id: my_time
and everything works perfectly:
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
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.
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 😄
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
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:
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.
@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.
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.
@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.
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" }
@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!
@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
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.
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?
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?
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.
@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
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 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.
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?
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.
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:
But the data just keeps going up:
Thanks for any help!
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
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)
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.
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 ...
You could try syncing with homeassistant:
time:
- platform: homeassistant
id: homeassistant_time
timezone: America/New_York
for name_timezone I have name_timezone: 'CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00'
I'm out of ideas :)
I'd suggest asking the ESPHome community directly. Please let us know what you find out!
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.
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.
- 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.
- 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.
- 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.
- 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!
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. :)
@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
@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.
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?
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
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.
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?
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.
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?
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.
Still no log output though. the esphome integration is showing active details, but no logs are viewable from esphome, just keeps timing out!!! wth?
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.
@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?
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.
nevermind..... it was a stupid typo
well thanks guys, even if it was my stupid mistake. Now onto cracking open and hacking esphome onto all my emporia plugs.....
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?
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.
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
thanks @cdavis289 and @flaviut I appreciate what you both do to help this project!
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?
@hiveai delete their lines in the config and remove the places they're referenced from
@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.
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.
@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.
@dcorwin8222 a couple options, take a look at https://newscrewdriver.com/2022/03/26/recording-esphome-sensor-values-min-max-and-average/, or alternatively, you can try using template sensors with filters
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 :(
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!
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.
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 toesphome::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()'
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 .....
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.
How does HA know when to reset daily energy numbers? My new install doesn't seem to reset at midnight.
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!
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.
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..
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.
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?
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).
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'.
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.
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.
@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).
Ha!!!! That did the trick, it compiled! Now to see if it fixes things at midnight ....
Thanks!
@clowrey sure, my point is that these issues are not related to the Emporia Vue.
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.
@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.
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 =========================`
@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
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.