Emporia Vue Utility Connect

When I get a bit of time, my plan is to convert it into the newer esphome add-on format. Currently, they dont want to offer ANY support if it is a deprecated external component like it is in its current form.

@monkeyst Has been reverse engineering the v7+ protocol, I am just about to go down that rabbit hole myself as I think I am getting higher than actual watts reported but unsure.

Anyways, thank you for your work @jrouvier , it is greatly appreciated!

@monkeyst I got a new emporia vue connect and it has been upgraded to v 8 MGM firmware, so I am using your .h file. I am seeing a watts reading that seems to be higher than what the original emporia app did and I also see lots of extra data coming through the debug logs. I also see that some meter read messages arent caught because the first char isn’t a ‘$’ → [16:40:34][D][esp-idf:000]: E (22338618) Vue: 0x3ffb2bc4 34 0d 0a 24 01 72 2c |4..$.r,|

I havent had a chance to look at the .h file and go througyh it yet. I did have a different meter div value than the original repo code had and had to write some custom code to get the correct values. I am, assuming my meter div is throwing the reported watts off.

Ill try and take some time this week or this coming weekend to go over the v7 code and see if I can add anything. I appreciate your advice, work and input!

Thanks!

Some of the extra output I am seeing in debug logs (including missed meter reading msg)

16:40:08][D][Vue:319]: Parsing V7+ Payload
[16:40:08][I][Vue:079]: Watts = 1770.00
[16:40:08][D][sensor:094]: 'House Watts': Sending state 1770.00000 W with 2 decimals of accuracy
[16:40:08][D][sensor:094]: 'House Watts': Sending state 1770.00000 W with 2 decimals of accuracy
[16:40:08][D][sensor:094]: '': Sending state 123094352.00000  with 0 decimals of accuracy
[16:40:08][D][sensor:094]: '': Sending state 0.00000  with 0 decimals of accuracy
[16:40:08][I][Vue:119]: Consumed kWh = 123094.352
[16:40:08][D][sensor:094]: 'House Consumed kWh': Sending state 123094.35156 kWh with 3 decimals of accuracy
[16:40:08][D][sensor:094]: 'House Consumed kWh': Sending state 123094.35156 kWh with 3 decimals of accuracy
[16:40:08][D][sensor:094]: '': Sending state 0.00000  with 0 decimals of accuracy
[16:40:08][D][sensor:094]: '': Sending state 123094352.00000  with 0 decimals of accuracy
[16:40:08][I][Vue:101]: kWh = 123094.352
[16:40:08][D][sensor:094]: 'House Net kWh': Sending state 123094.35156 kWh with 3 decimals of accuracy
[16:40:08][D][sensor:094]: 'House Net kWh': Sending state 123094.35156 kWh with 3 decimals of accuracy
[16:40:08][W][component:232]: Component <unknown> took a long time for an operation (109 ms).
[16:40:08][W][component:233]: Components should block for at most 30 ms.
[16:40:10][D][sensor:094]: 'Wifi signal': Sending state -67.00000 dBm with 0 decimals of accuracy
[16:40:20][D][sensor:094]: 'Wifi signal': Sending state -68.00000 dBm with 0 decimals of accuracy
[16:40:30][D][sensor:094]: 'Wifi signal': Sending state -68.00000 dBm with 0 decimals of accuracy
[16:40:34][D][Vue:613]: Sending request for meter reading
[16:40:34][E][Vue:203]: Invalid input at position 1: 0x53
[16:40:34][E][Vue:182]: Skipped input:
[16:40:34][D][esp-idf:000]: E (22338190) Vue: 0x3ffb2bc4   53 65 49 68 64                                    |SeIhd|

[16:40:34][E][Vue:203]: Invalid input at position 1: 0xd
[16:40:34][E][Vue:182]: Skipped input:
[16:40:34][D][esp-idf:000]: E (22338261) Vue: 0x3ffb2bc4   0d 0a 54 30 30 30 30 30  30 30 30 3a 52 58 20 6c  |..T00000000:RX l|

[16:40:34][D][esp-idf:000]: E (22338274) Vue: 0x3ffb2bd4   65 6e 20 34 34 2c 20 65  70 20 30 31 2c 20 63 6c  |en 44, ep 01, cl|

[16:40:34][D][esp-idf:000]: E (22338287) Vue: 0x3ffb2be4   75 73 20 30 78 30 37 30  32 20 28 53 69 6d 70     |us 0x0702 (Simp|

[16:40:34][E][Vue:203]: Invalid input at position 1: 0x65
[16:40:34][E][Vue:182]: Skipped input:
[16:40:34][D][esp-idf:000]: E (22338323) Vue: 0x3ffb2bc4   65 20 4d 65 74 65 72 69  6e 67 29 20 46 43 20 31  |e Metering) FC 1|

[16:40:34][D][esp-idf:000]: E (22338336) Vue: 0x3ffb2bd4   38 20 73 65 71 20 33 36  20 63 6d 64 20 30 31 20  |8 seq 36 cmd 01 |

[16:40:34][D][esp-idf:000]: E (22338349) Vue: 0x3ffb2be4   70 61 79 6c 6f 61 64 5b  30 30 20 30 30 20 30     |payload[00 00 0|

[16:40:34][E][Vue:203]: Invalid input at position 1: 0x20
[16:40:34][E][Vue:182]: Skipped input:
[16:40:34][D][esp-idf:000]: E (22338386) Vue: 0x3ffb2bc4   20 32 35 20 36 30 20 34  35 20 35 36 20 30 37 20  | 25 60 45 56 07 |

[16:40:34][D][esp-idf:000]: E (22338399) Vue: 0x3ffb2bd4   30 30 20 30 30 20 30 31  20 30 30 20 30 30 20 32  |00 00 01 00 00 2|

[16:40:34][D][esp-idf:000]: E (22338412) Vue: 0x3ffb2be4   35 20 30 30 20 30 30 20  30 30 20 30 30 20 30     |5 00 00 00 00 0|

[16:40:34][E][Vue:203]: Invalid input at position 1: 0x20
[16:40:34][E][Vue:182]: Skipped input:
[16:40:34][D][esp-idf:000]: E (22338449) Vue: 0x3ffb2bc4   20 30 30 20 30 31 20 30  33 20 30 30 20 32 32 20  | 00 01 03 00 22 |

[16:40:34][D][esp-idf:000]: E (22338462) Vue: 0x3ffb2bd4   30 33 20 30 30 20 30 30  20 30 32 20 30 33 20 30  |03 00 00 02 03 0|

[16:40:34][D][esp-idf:000]: E (22338475) Vue: 0x3ffb2be4   30 20 32 32 20 38 38 20  31 33 20 30 30 20 30     |0 22 88 13 00 0|

[16:40:34][E][Vue:203]: Invalid input at position 1: 0x20
[16:40:34][E][Vue:182]: Skipped input:
[16:40:34][D][esp-idf:000]: E (22338511) Vue: 0x3ffb2bc4   20 30 34 20 30 30 20 32  41 20 43 44 20 30 36 20  | 04 00 2A CD 06 |

[16:40:34][D][esp-idf:000]: E (22338524) Vue: 0x3ffb2bd4   30 30 20 5d 0d 0a 2d 2d  20 47 6f 74 20 4d 65 74  |00 ]..-- Got Met|

[16:40:34][D][esp-idf:000]: E (22338536) Vue: 0x3ffb2be4   65 72 20 52 73 70 2c 20  6c 65 6e 3d 34 34 2c     |er Rsp, len=44,|

[16:40:34][E][Vue:203]: Invalid input at position 1: 0x35
[16:40:34][E][Vue:182]: Skipped input:
[16:40:34][D][esp-idf:000]: E (22338571) Vue: 0x3ffb2bc4   35 34 20 3d 20 35 34 3f  0d 0a 73 4d 52 42 20 6c  |54 = 54?..sMRB l|

[16:40:34][D][esp-idf:000]: E (22338584) Vue: 0x3ffb2bd4   65 6e 20                                          |en |

[16:40:34][E][Vue:203]: Invalid input at position 1: 0x34
[16:40:34][E][Vue:182]: Skipped input:
[16:40:34][D][esp-idf:000]: E (22338618) Vue: 0x3ffb2bc4   34 0d 0a 24 01 72 2c                              |4..$.r,|

[16:40:34][E][Vue:203]: Invalid input at position 1: 0x36
[16:40:34][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x1
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x25
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x60
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x45
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x56
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x7
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x1
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x25
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x1
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x3
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x22
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x3
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x2
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x3
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x22
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x88
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x13
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x4
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x2a
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0xcd
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x6
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0x0
[16:40:35][E][Vue:182]: Skipped input:
[16:40:35][E][Vue:203]: Invalid input at position 1: 0xd
[16:40:35][E][Vue:182]: Skipped input:

@visualage Did the “--before usb_reset” unblock you?

@jrouvier Thanks a lot for doing the initial heavy lifting! I can take ownership (for now at least) at GitHub - nekorevend/esphome-emporia-vue-utility: Alternative ESPHome firmware for the Emporia Vue Utility Connect

@baudneo Not sure about the your “Invalid input at position 1” issue, but regarding the watt reading looking too high, do you have any clue about how much higher it is than it should be? Something that comes to mind is that the V2 firmware had a MeterDiv field where the watt field (and watt-hour?) had to be divided by MeterDiv to get the correct wattage. Oops just read your message more carefully.

If MeterDiv is still a thing in V7+, then for me it is a 1. According to what I had documented, MeterDiv might be at byte 2, 13, 23, or 27 since those have a value of 1 for me. Are any of those bytes possibly not 1 for you?

Ive been kind of poking at it,

            Meter Response Bytes   0 to   3: 18 8a 01 00
            Meter Response Bytes   4 to   7: 00 00 25 7e
            Meter Response Bytes   8 to  11: 83 56 07 00
            Meter Response Bytes  12 to  15: 00 01 00 00
            Meter Response Bytes  16 to  19: 25 00 00 00
            Meter Response Bytes  20 to  23: 00 00 00 01
            Meter Response Bytes  24 to  27: 03 00 22 03
            Meter Response Bytes  28 to  31: 00 00 02 03
            Meter Response Bytes  32 to  35: 00 22 88 13
            Meter Response Bytes  36 to  39: 00 00 04 00
            Meter Response Bytes  40 to  43: 2a 23 05 00

Index 27 is 0x3, So I thought that may be it (my meter div was 3 in v2 struct as well), im going to flash back and forth to get some watt readings to compare. meter div 3 output seems to be lower than expected watts, so I am unsure.

The MGM chip is sending weird log messages, it seems they have some logging component spitting some logs out over that UART as well. Here is some of the message that keeps being repeated.

0x45 0x4d 0x42 0x45 0x52 0x5f 0x4e 0x45 0x54 0x57 0x4f 0x52 0x4b 0x5f 0x44 0x4f 0x57 0x4e 0x0d
E M B E R _ N E T W O R K _ D O W N

0x0a 0x53 0x65 0x74 0x74 0x69 0x6e 0x67 0x20 0x74 0x72 0x75 0x73 0x74 0x20 0x63 0x65 0x6e 0x74 0x65 0x72 0x20 0x6b 0x65 0x65 0x70 0x61 0x6c 0x69 0x76 0x65 0x20 0x69 0x6e 0x61 0x63 0x74 0x69 0x76 0x65 0x2e 0x0d
Setting trust center keepalive inactive.

0x0a 0x53 0x65 0x74 0x74 0x69 0x6e 0x67 0x20 0x74 0x72 0x75 0x73 0x74 0x20 0x63 0x65 0x6e 0x74 0x65 0x72 0x20 0x6b 0x65 0x65 0x70 0x61 0x6c 0x69 0x76 0x65 0x20 0x69 0x6e 0x61 0x63 0x74 0x69 0x76 0x65 0x2e 0x0d
Setting trust center keepalive inactive.

0x0a 0x3d 0x3d 0x20 0x53 0x54 0x41 0x43 0x4b 0x20 0x53 0x54 0x41 0x54 0x55 0x53 0x20 0x30 0x78 0x39 0x31 0x20 0x3d 0x3d 0x0d
== STACK STATUS 0x91 ==

0x0a 0x45 0x4d 0x42 0x45 0x52 0x5f 0x4e 0x45 0x54 0x57 0x4f 0x52 0x4b 0x5f 0x55 0x50 0x20 0x30 0x78 0x36 0x30 0x33 0x32 0x0d
EMBER_NETWORK_UP 0x6032

The logging is drowning the meter readings out as $ is not the first char. I am trying to implement something that will adjust for that.

It would be great if we could get this code switched over to the external component format, that way we can get support from the esphome team. ATM they refuse to help with any issues because this uses the deprecated includes component.

I had an issue upgrading to newer versions of esphome and needed to downgrade to get this code working again. I am stuck on esphome 2024.5.4, unsure if others are experiencing the same.

Yes. Adding --before usb_reset unblocked me.

At least for mine, the display on the actual utility meter periodically shows the current watt usage. Is that not the case for yours? I imagine you could have the ESPHome firmware installed and just stand at your meter and compare it on your phone.

Regarding the log outputs, have you identified a consistent header or byte that it always sends before a log? Could hopefully make the code ignore messages that start with that header. The first line of your example messages doesn’t have the 0x0a, but the rest do… Ideally the header also provides the expected length to read :crossed_fingers:

I did briefly look at converting to the external component format some months ago but dropped the idea at the time due to no familiarity with that format (and admittedly no familiarity with the deprecated format. I only added some C++ to jrouvier’s code.) Just curious, what problems were you hoping the ESPHome team would help with? Is it related to you saying you’re stuck on 2024.5.4?

It seems to me it’s roughly around half of the reported value - ish.

My reason for wanting to switch to the external component for esphome support is, I’ve had some minor problems when upgrading. The ::time issue I put a PR in for and then this newer issue of not being able to upgrade to x.5.

Every issue I’ve opened with esphome is closed immediately and I am told because this code is using deprecated custom_component, esphome devs won’t even look at the issue.

I am the main/only ML dev for ZoneMinder so I don’t have a lot of spare time, but I will try and get this code switched over to an external component format when I get some time.

I tried comparing your meter response values to mine and the differing bytes are at 27, 34, 35, but nothing obvious is jumping out at me about them to suggest “divide by 2”.

(Also noticed my documentation was missing two static bytes at 16 and 40 so I’ve pushed an update for that, not that they help here though)

As far as I can tell, 2024.5.4 is the latest version (which works for me). I guess you’re on some sort of beta release track?

If a breakage is impending then maybe I’ll revisit trying the external component conversion as well. :face_with_monocle:
EDIT: I’ve created a branch with stubbed external component stuff. Will look at it more later.

@baudneo Upon reading more of the V2 documentation, I realize that EnergyCostUnit probably also exists at bytes 34 and 35 in V7. For me the value equates to 1000 since I am billed per kWh. I see for your 0x8813 → 0x1388 → 5000, could you confirm if you are billed for every 5 kWh? Thanks!

I am billed per kWh on my energy bill. I don’t think it is exactly /2, but def in that area.

I misspoke, I’m stuck on 2024.3.2, so I think it was 2024.4.x maybe that has issues. When I upgraded, it was only the vue utility that didn’t work any longer. Downgrading back to 2024.3.2 gets the code working again. Esphome guys told me to kick rocks and get the maintainer to upgrade to an external component before they will even consider looking into the issue.

I’ve reached a minimally viable #WorksOnMyMachine conversion to external component at this branch the main branch, leaving the original implementation as unmodified as possible.

It is certainly not idiomatic to external components and I have no idea how update() is actually supposed to work. My understanding is the system should call update() at the stated update interval (30s in the sensor.py or 15s in my yaml override), but instead it calls incessantly The implementation skips using the update() function for now. (solved :slight_smile: needed to call the parent set_update_interval())

Anyway, these are the important parts of my yaml:

external_components:
  source:
    type: git
    url: https://github.com/nekorevend/esphome-emporia-vue-utility

substitutions:
  name: Meter

uart:
    id: emporia_uart
    rx_pin: GPIO21
    tx_pin: GPIO22
    baud_rate: 115200

sensor:
  - platform: emporia_vue_utility
    uart_id: emporia_uart
    update_interval: 15s
    power:
      name: "${name} Watts"
    power_export:
      name: "${name} Watts Returned"
    power_import:
      name: "${name} Watts Consumed"
    energy:
      name: "${name} Wh Net"
    energy_export:
      name: "${name} Wh Returned"
    energy_import:
      name: "${name} Wh Consumed"

I’ve listed out all 6 sensors you can choose from, but you probably don’t need all of them.

If you try it out, I would give the name some value like Test so potentially incorrect values don’t infect your sensor history.

1 Like

Awesome, great job! Going to try out the new code this evening.

Edit: It works for me!

The only thing is, I must have a newer v8 version of the firmware that also outputs some log messages on the UART between esp and MGM. I will try and modify the reading code to look for the meter responses amongst the other log output.

Thanks for your work @monkeyst

[19:27:23][D][emporia_vue_utility:342]: Parsing V7+ Payload
[19:27:23][D][sensor:094]: 'Meter Watts': Sending state 1736.00000 W with 0 decimals of accuracy
[19:27:23][D][sensor:094]: 'Meter Watts Consumed': Sending state 1736.00000 W with 0 decimals of accuracy
[19:27:23][D][sensor:094]: 'Meter Watts Returned': Sending state 0.00000 W with 0 decimals of accuracy
[19:27:23][D][sensor:094]: 'Meter Wh Consumed': Sending state 123506680.00000 Wh with 0 decimals of accuracy
[19:27:23][D][sensor:094]: 'Meter Wh Returned': Sending state 0.00000 Wh with 0 decimals of accuracy
[19:27:23][D][sensor:094]: 'Meter Wh Net': Sending state 123506680.00000 Wh with 0 decimals of accuracy
[19:27:23][W][component:232]: Component emporia_vue_utility.sensor took a long time for an operation (65 ms).
[19:27:23][W][component:233]: Components should block for at most 30 ms.
[19:27:36][D][emporia_vue_utility:699]: Sending request for meter reading
[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x53
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (491742) emporia_vue_utility: 0x3ffb2a68   53 65 49 68 64                                    |SeIhd|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0xd
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (491812) emporia_vue_utility: 0x3ffb2a68   0d 0a 54 30 30 30 30 30  30 30 30 3a 52 58 20 6c  |..T00000000:RX l|

[19:27:36][D][esp-idf:000]: E (491826) emporia_vue_utility: 0x3ffb2a78   65 6e 20 34 34 2c 20 65  70 20 30 31 2c 20 63 6c  |en 44, ep 01, cl|

[19:27:36][D][esp-idf:000]: E (491838) emporia_vue_utility: 0x3ffb2a88   75 73 20 30 78 30 37 30  32 20 28 53 69 6d 70     |us 0x0702 (Simp|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x65
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (491876) emporia_vue_utility: 0x3ffb2a68   65 20 4d 65 74 65 72 69  6e 67 29 20 46 43 20 31  |e Metering) FC 1|

[19:27:36][D][esp-idf:000]: E (491889) emporia_vue_utility: 0x3ffb2a78   38 20 73 65 71 20 46 41  20 63 6d 64 20 30 31 20  |8 seq FA cmd 01 |

[19:27:36][D][esp-idf:000]: E (491903) emporia_vue_utility: 0x3ffb2a88   70 61 79 6c 6f 61 64 5b  30 30 20 30 30 20 30     |payload[00 00 0|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x20
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (491941) emporia_vue_utility: 0x3ffb2a68   20 32 35 20 46 46 20 38  46 20 35 43 20 30 37 20  | 25 FF 8F 5C 07 |

[19:27:36][D][esp-idf:000]: E (491953) emporia_vue_utility: 0x3ffb2a78   30 30 20 30 30 20 30 31  20 30 30 20 30 30 20 32  |00 00 01 00 00 2|

[19:27:36][D][esp-idf:000]: E (491966) emporia_vue_utility: 0x3ffb2a88   35 20 30 30 20 30 30 20  30 30 20 30 30 20 30     |5 00 00 00 00 0|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x20
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492002) emporia_vue_utility: 0x3ffb2a68   20 30 30 20 30 31 20 30  33 20 30 30 20 32 32 20  | 00 01 03 00 22 |

[19:27:36][D][esp-idf:000]: E (492017) emporia_vue_utility: 0x3ffb2a78   30 33 20 30 30 20 30 30  20 30 32 20 30 33 20 30  |03 00 00 02 03 0|

[19:27:36][D][esp-idf:000]: E (492031) emporia_vue_utility: 0x3ffb2a88   30 20 32 32 20 38 38 20  31 33 20 30 30 20 30     |0 22 88 13 00 0|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x20
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492070) emporia_vue_utility: 0x3ffb2a68   20 30 34 20 30 30 20 32  41 20 42 45 20 30 36 20  | 04 00 2A BE 06 |

[19:27:36][D][esp-idf:000]: E (492083) emporia_vue_utility: 0x3ffb2a78   30 30 20 5d 0d 0a 2d 2d  20 47 6f 74 20 4d 65 74  |00 ]..-- Got Met|

[19:27:36][D][esp-idf:000]: E (492095) emporia_vue_utility: 0x3ffb2a88   65 72 20 52 73 70 2c 20  6c 65 6e 3d 34 34 2c     |er Rsp, len=44,|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x32
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492131) emporia_vue_utility: 0x3ffb2a68   32 35 30 20 3d 20 32 35  30 3f 0d 0a 73 4d 52 42  |250 = 250?..sMRB|

[19:27:36][D][esp-idf:000]: E (492144) emporia_vue_utility: 0x3ffb2a78   20 6c 65                                          | le|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x20
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492179) emporia_vue_utility: 0x3ffb2a68   20 34 34 0d 0a 24 01 72  2c                       | 44..$.r,|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0xfa
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492215) emporia_vue_utility: 0x3ffb2a68   fa 01                                             |..|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x0
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492249) emporia_vue_utility: 0x3ffb2a68   00 00                                             |..|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0xff
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492283) emporia_vue_utility: 0x3ffb2a68   ff 8f                                             |..|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x7
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492319) emporia_vue_utility: 0x3ffb2a68   07 00                                             |..|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x1
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492357) emporia_vue_utility: 0x3ffb2a68   01 00                                             |..|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x25
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492392) emporia_vue_utility: 0x3ffb2a68   25 00                                             |%.|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x0
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492427) emporia_vue_utility: 0x3ffb2a68   00 00                                             |..|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x0
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492462) emporia_vue_utility: 0x3ffb2a68   00 01                                             |..|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x0
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492497) emporia_vue_utility: 0x3ffb2a68   00 22                                             |."|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x0
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492533) emporia_vue_utility: 0x3ffb2a68   00 00                                             |..|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x3
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492572) emporia_vue_utility: 0x3ffb2a68   03 00                                             |..|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x88
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492609) emporia_vue_utility: 0x3ffb2a68   88 13                                             |..|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x0
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492647) emporia_vue_utility: 0x3ffb2a68   00 04                                             |..|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x2a
[19:27:36][E][emporia_vue_utility:203]: Skipped input:
[19:27:36][D][esp-idf:000]: E (492682) emporia_vue_utility: 0x3ffb2a68   2a be                                             |*.|

[19:27:36][E][emporia_vue_utility:224]: Invalid input at position 1: 0x0
[19:27:37][E][emporia_vue_utility:203]: Skipped input:
[19:27:37][D][esp-idf:000]: E (492719) emporia_vue_utility: 0x3ffb2a68   00                                                |.|

[19:27:51][D][emporia_vue_utility:699]: Sending request for meter reading

I managed to get something working for my setup. Just need to figure out how to get accurate watts reading.

[21:21:11][D][emporia_vue_utility:236]: Found start of meter response message (0x24 / '$') at pos: 6 in the raw_buffer, starting to fill input_buffer
[21:21:11][D][emporia_vue_utility:255]: Meter response data length: 1
[21:21:11][I][emporia_vue_utility:690]: Join response value: 1
[21:21:11][D][emporia_vue_utility:731]: Sending request for meter reading
[21:21:11][D][emporia_vue_utility:236]: Found start of meter response message (0x24 / '$') at pos: 277 in the raw_buffer, starting to fill input_buffer
[21:21:11][D][emporia_vue_utility:255]: Meter response data length: 44
[21:21:11][D][emporia_vue_utility:359]: Parsing V7+ Payload
[21:21:11][D][sensor:094]: 'Meter Watts': Sending state 1281.00000 W with 0 decimals of accuracy
[21:21:11][D][sensor:094]: 'Meter Watts Consumed': Sending state 1281.00000 W with 0 decimals of accuracy
[21:21:11][D][sensor:094]: 'Meter Watts Returned': Sending state 0.00000 W with 0 decimals of accuracy
[21:21:11][W][emporia_vue_utility:547]: Reported watt-hour change is too large vs previous reading. Skipping.
[21:21:11][D][emporia_vue_utility:390]: Meter Cost Unit: 5000
[21:21:11][D][emporia_vue_utility:391]: Meter Divisor: 3
[21:21:11][D][emporia_vue_utility:392]: Meter Energy Import Flags: 075c9c55
[21:21:11][D][emporia_vue_utility:393]: Meter Energy Export Flags: 00000000
[21:21:11][D][emporia_vue_utility:394]: Meter Power Flags: 0005012a
[21:21:11][D][emporia_vue_utility:395]: Meter Import Energy: 123509.845kWh
[21:21:11][D][emporia_vue_utility:396]: Meter Export Energy: 0.000kWh
[21:21:11][D][emporia_vue_utility:397]: Meter Net Energy: 0.000kWh
[21:21:11][D][emporia_vue_utility:398]: Meter Power:  1281W
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes   0 to   3: 18 af 01 00
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes   4 to   7: 00 00 25 55
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes   8 to  11: 9c 5c 07 00
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes  12 to  15: 00 01 00 00
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes  16 to  19: 25 00 00 00
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes  20 to  23: 00 00 00 01
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes  24 to  27: 03 00 22 03
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes  28 to  31: 00 00 02 03
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes  32 to  35: 00 22 88 13
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes  36 to  39: 00 00 04 00
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes  40 to  43: 2a 01 05 00
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes  44 to  47: 0d 00 00 00
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes 256 to 259: 53 65 49 68
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes 260 to 263: 64 3e 53 65
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes 264 to 267: 49 68 64 3e
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes 268 to 271: 0d 0a 54 30
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes 272 to 275: 30 30 30 30
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes 276 to 279: 30 30 30 3a
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes 280 to 283: 52 58 20 6c
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes 284 to 287: 65 6e 20 34
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes 288 to 291: 34 2c 20 65
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes 292 to 295: 70 20 30 31
[21:21:12][D][emporia_vue_utility:407]: Meter Response Bytes 296 to 299: 2c 20 63 6c
[21:21:12][D][emporia_vue_utility:407]: Meter Response Bytes 304 to 307: 78 30 37 30
[21:21:12][D][emporia_vue_utility:407]: Meter Response Bytes 308 to 311: 32 20 28 53
[21:21:12][D][emporia_vue_utility:407]: Meter Response Bytes 312 to 315: 69 6d 70 6c
[21:21:12][D][emporia_vue_utility:407]: Meter Response Bytes 316 to 319: 65 20 4d 65
[21:21:12][W][component:232]: Component emporia_vue_utility.sensor took a long time for an operation (334 ms).
[21:21:12][W][component:233]: Components should block for at most 30 ms.
[21:21:26][D][emporia_vue_utility:731]: Sending request for meter reading
[21:21:26][D][emporia_vue_utility:236]: Found start of meter response message (0x24 / '$') at pos: 271 in the raw_buffer, starting to fill input_buffer
[21:21:26][D][emporia_vue_utility:255]: Meter response data length: 44
[21:21:26][D][emporia_vue_utility:359]: Parsing V7+ Payload
[21:21:26][D][sensor:094]: 'Meter Watts': Sending state 1301.00000 W with 0 decimals of accuracy
[21:21:26][D][sensor:094]: 'Meter Watts Consumed': Sending state 1301.00000 W with 0 decimals of accuracy
[21:21:26][D][sensor:094]: 'Meter Watts Returned': Sending state 0.00000 W with 0 decimals of accuracy
[21:21:26][D][sensor:094]: 'Meter Wh Consumed': Sending state 123509848.00000 Wh with 0 decimals of accuracy
[21:21:26][D][sensor:094]: 'Meter Wh Returned': Sending state 0.00000 Wh with 0 decimals of accuracy
[21:21:26][D][sensor:094]: 'Meter Wh Net': Sending state 123509848.00000 Wh with 0 decimals of accuracy
[21:21:26][W][component:232]: Component emporia_vue_utility.sensor took a long time for an operation (91 ms).
[21:21:26][W][component:233]: Components should block for at most 30 ms.
[21:21:41][D][emporia_vue_utility:731]: Sending request for meter reading
[21:21:41][D][emporia_vue_utility:236]: Found start of meter response message (0x24 / '$') at pos: 271 in the raw_buffer, starting to fill input_buffer
[21:21:41][D][emporia_vue_utility:255]: Meter response data length: 44
[21:21:41][D][emporia_vue_utility:359]: Parsing V7+ Payload
[21:21:41][D][sensor:094]: 'Meter Watts': Sending state 1288.00000 W with 0 decimals of accuracy
[21:21:41][D][sensor:094]: 'Meter Watts Consumed': Sending state 1288.00000 W with 0 decimals of accuracy
[21:21:41][D][sensor:094]: 'Meter Watts Returned': Sending state 0.00000 W with 0 decimals of accuracy
[21:21:41][D][sensor:094]: 'Meter Wh Consumed': Sending state 123509856.00000 Wh with 0 decimals of accuracy
[21:21:41][D][sensor:094]: 'Meter Wh Returned': Sending state 0.00000 Wh with 0 decimals of accuracy
[21:21:41][D][sensor:094]: 'Meter Wh Net': Sending state 123509856.00000 Wh with 0 decimals of accuracy
[21:21:41][W][component:232]: Component emporia_vue_utility.sensor took a long time for an operation (91 ms).
[21:21:41][W][component:233]: Components should block for at most 30 ms.

It’s interesting that the log message seems to be inserted into the meter response “packet” (though with a huge gap) according to

[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes  44 to  47: 0d 00 00 00
[21:21:11][D][emporia_vue_utility:407]: Meter Response Bytes 256 to 259: 53 65 49 68

If it’s always trailing a response packet like that, perhaps the answer is in here:

        default:
          if (pos < data_len + 5) {
            ;
          } else if (c == 0x0d) {  // 0x0d == "/r", which should end a message
            return pos;
          } else {
            ESP_LOGE(TAG, "Invalid terminator at pos %d 0x%x", pos, c);
            ESP_LOGE(TAG, "Following char is 0x%x", read());
            dump_serial_input(true);
            return 0;
          }

Specifically, maybe this change would do the job of wiping out the log message part of the “packet”:

          } else if (c == 0x0d) {  // 0x0d == "/r", which should end a message
            dump_serial_input(true);
            return pos;
          }

BTW, I see you added Meter Divisor: 3 to the debug print that prints once at startup, and it might interest you to add debug: true to the YAML so it prints on every message :slight_smile:

  - platform: emporia_vue_utility
    uart_id: emporia_uart
    debug: true
    update_interval: 15s

I am noticing that the e type message seems to be an out of range/no connection to meter. My test bench is on the other side of the basement and the connection is spotty.

[22:30:55][D][emporia_vue_utility:736]: Sending request for meter reading
[22:31:00][I][emporia_vue_utility:106]: Got 'e'-type message with value: 0
[22:31:03][I][emporia_vue_utility:106]: Got 'e'-type message with value: 2
[22:31:10][D][emporia_vue_utility:736]: Sending request for meter reading
[22:31:11][I][emporia_vue_utility:106]: Got 'e'-type message with value: 2
[22:31:15][I][emporia_vue_utility:106]: Got 'e'-type message with value: 0

Got it, can confirm I also tried moving mine farther from the meter and started seeing ‘e’-type messages again.

I’ve updated the doc and log output to suggest moving closer to the meter.

Have you figured out the wattage divisor?

Yes, I forgot I found this issue in V2 and fixed it:

   watts >>= 8;
   watts = ((float) watts * (float) meter_div) / ((float) cost_unit / 1000.0);
1 Like

Neat! Pretty strange and I hope it applies to everyone. Seems fine for me so I’ve updated the code here: Support MeterDiv involvement in Watt calculation. · nekorevend/esphome-emporia-vue-utility@b47be07 · GitHub

Looks like V2 uses meter div for watt-hour calculation as well. Did that need adjustment for your setup too?

I’m not sure about watt hours, haven’t checked the data to compare yet. I will take a look this evening.

Edit: It seems to also need the meter div and cost unit calculations.

1 Like

Good to know, I’ve now applied the calculation to watt and watt-hour parsing for both V2 and V7:

Thanks for the info!

1 Like