jrouvier / esphome-emporia-vue-utility

Alternative ESPHome firmware for the Emporia Vue Utility Connect
GNU General Public License v2.0
75 stars 17 forks source link

Reported Power Usage is extremely high #8

Open SinclairKS opened 1 year ago

SinclairKS commented 1 year ago

On the current firmware (1.2.2), the reported usage is extremely high compared to the actual usage (I have a Vue 2 also available at the panel for more detailed readings). The official Emporia firmware reads correctly from the meter:

Debug Output:

[I][Vue:067]: kWh = 331838.156 [I][Vue:085]: Watts = 9078.000 [D][Vue:264]: Meter Divisor: 3 [D][Vue:265]: Meter Cost Unit: 5000 [D][Vue:266]: Meter Flags: 2c 2b [D][Vue:267]: Meter Energy Flags: 06 [D][Vue:268]: Meter Power Flags: 00 [D][Vue:270]: Meter Timestamp: 529 [D][Vue:271]: Meter Energy: 331838.144kWh [D][Vue:272]: Meter Power: 9078W [D][Vue:282]: Meter Response Bytes 4 to 7: 06 97 d0 f4 [D][Vue:282]: Meter Response Bytes 44 to 47: 00 00 00 03 [D][Vue:282]: Meter Response Bytes 48 to 51: 00 00 13 88 [D][Vue:282]: Meter Response Bytes 52 to 55: 2c 2b 00 00 [D][Vue:282]: Meter Response Bytes 56 to 59: 00 00 0b d2 [D][Vue:282]: Meter Response Bytes 148 to 151: a6 10 08 00

Actual usage during this time was roughly 1750W at the panel input. Obviously this is probably something specific to how this is reading from my specific meter.

SinclairKS commented 1 year ago

Debug data from Emporia firmware if it's of any help:

I (450695) Readings: ===readings_calc==== D (450705) Readings: Curr time: 1674269930 D (450705) Readings: uS since boot: 450067081 D (450715) Readings: Instant Amps: 15.180001 D (450715) Readings: Sample Delta, period: 7, clock delta: 6499368, AmpInt: 106.260005 D (450725) Readings: - Calculated summation = 66368.914062 kWh D (450735) Readings: Meter sum A: 1991067374.933333 D (450735) Readings: Local sum A: 1991067302.660068 D (450745) Readings: Solar sum A: 0.000000 D (450745) Readings: Delta sum-prevMeter A: 1365.333333 D (450755) Readings: Delta sum A: 72.273265

Uart Response [MeterR]: Uart Response: 24 01 72 98 00 00 00 00 06 97 d7 fb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 00 13 88 2c 2b 00 00 00 00 0b 77 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 af 7c 00 00 0d Uart Response [MeterR]: Uart Response: 24 01 72 98 00 00 00 00 06 97 d7 fb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 00 13 88 2c 2b 00 00 00 00 0b 77 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 77 8f 00 00 0d Uart Response [MeterR]: Uart Response: 24 01 72 98 00 00 00 00 06 97 d7 fb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 00 13 88 2c 2b 00 00 00 00 0b 77 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cf a3 00 00 0d

jrouvier commented 1 year ago

Interesting. Short answer, try with this emporia_vue_utility.h.

Long answer, you have a Meter Cost Unit: 5000, which I've only seen as 1000 before. You also have a Meter Divisor: 3. Today, the code is taking the raw values from the meter and multiplying by Meter Divisor, so when the meter reports at raw watts value of 3026 x 3 = 9078W. However, 3026 x ( 3 / (5000 / 1000)) = 1816W. Therefore, the updated emporia_vue_utility.h includes this change

SinclairKS commented 1 year ago

We've gone to the other side of the spectrum now. While I wish I was actually only using that much, we're very low now. Actual draw was around 1580W.

[I][Vue:067]: kWh = 9541.379 [I][Vue:085]: Watts = 229.941 [D][Vue:264]: Meter Divisor: 3 [D][Vue:265]: Meter Cost Unit: 5000 [D][Vue:266]: Meter Flags: 2c 2b [D][Vue:267]: Meter Energy Flags: 06 [D][Vue:268]: Meter Power Flags: 00 [D][Vue:270]: Meter Timestamp: 140 [D][Vue:271]: Meter Energy: 9541.379kWh [D][Vue:272]: Meter Power: 230W [D][Vue:282]: Meter Response Bytes 4 to 7: 06 9a 8a 8f [D][Vue:282]: Meter Response Bytes 44 to 47: 00 00 00 03 [D][Vue:282]: Meter Response Bytes 48 to 51: 00 00 13 88 [D][Vue:282]: Meter Response Bytes 52 to 55: 2c 2b 00 00 [D][Vue:282]: Meter Response Bytes 56 to 59: 00 00 0a 6e [D][Vue:282]: Meter Response Bytes 148 to 151: d8 22 02 00

I don't classify myself as a programmer but I do have some experience writing tools in Perl and it's been years since I last saw C, but I did a bit of troubleshooting since the formula you had looked solid based on my numbers. It looks like you are querying a meter read directly for the cost_unit in these two changes ("(float)mr->cost_unit") but aren't re-doing the initial adjustment to that value again that happens further up. I'm guessing this is just a typo since both the "meter_div" and "cost_unit" variables are already set at this point and work fine once the meter read is removed from the cost_unit part of the formula:

watt_hours = (float)watt_hours_raw ((float)meter_div / ((float)cost_unit / 1000)); watts = (float)watts_raw ((float)meter_div / ((float)cost_unit / 1000));

works great and yields these values:

[I][Vue:067]: kWh = 66477.016 [I][Vue:085]: Watts = 1674.000 [D][Vue:264]: Meter Divisor: 3 [D][Vue:265]: Meter Cost Unit: 5000 [D][Vue:266]: Meter Flags: 2c 2b [D][Vue:267]: Meter Energy Flags: 06 [D][Vue:268]: Meter Power Flags: 00 [D][Vue:270]: Meter Timestamp: 663 [D][Vue:271]: Meter Energy: 66477.016kWh [D][Vue:272]: Meter Power: 1674W [D][Vue:282]: Meter Response Bytes 4 to 7: 06 9a 99 11 [D][Vue:282]: Meter Response Bytes 44 to 47: 00 00 00 03 [D][Vue:282]: Meter Response Bytes 48 to 51: 00 00 13 88 [D][Vue:282]: Meter Response Bytes 52 to 55: 2c 2b 00 00 [D][Vue:282]: Meter Response Bytes 56 to 59: 00 00 0a e6 [D][Vue:282]: Meter Response Bytes 148 to 151: ea 1d 0a 00

The watts value is in the ballpark now based on my Vue 2 that is in the panel (within 10-30 watts, given the delay in reporting on the Vue 2 (haven't reflashed that one yet)). No idea on the kWh yet since as you noted there's no way to tell when that resets, so I'll have to add an entity to calculate that over time and see if it's near what the Vue 2 reports.

Looks good now tho, appreciate the help!

baudneo commented 1 year ago

I have the same issue. Meter div = 3 and cost = 5000. My mains power is 220V so IDK why it would be 3? What does the value of meter_div mean?

The proposed fix doesnt work for me so, I played around a bit and this works for me. It will also work for div = 1 and cost = 1000. Not sure how it would handle other combos.

current code:

watt_hours = (float)watt_hours_raw * (float)meter_div;
watts = (float)watts_raw * (float)meter_div;

ESP_LOGD(TAG, "Meter Energy: %.3fkWh", watt_hours / 1000 );
ESP_LOGD(TAG, "Meter Power:  %3.0fW", watts);

// results in output being 5 times to high

proposed fix:

watt_hours = (float)watt_hours_raw * ((float)meter_div / (cost_unit / 1000));
watts = (float)watts_raw * ((float)meter_div / (cost_unit / 1000));

ESP_LOGD(TAG, "Meter Energy: %.3fkWh", watt_hours / 1000 );
ESP_LOGD(TAG, "Meter Power:  %3.0fW", watts);

// results in incorrect data

This works for me:

   // kWh
   watt_hours = (float)watt_hours_raw * (float)meter_div;
   ESP_LOGD(TAG, "Wh after meter divisor (%f): %.3f", (float)meter_div, watt_hours);
   watt_hours = watt_hours / (cost_unit / 1000);
   ESP_LOGD(TAG, "Wh after cost unit (%d): %.3f", cost_unit / 1000, watt_hours);
   // whenever publishing data to kWh: / 1000.0

   // Watts
   watts = (float)watts_raw * (float)meter_div;
   ESP_LOGD(TAG, "Watts after * meter divisor (%f): %.2f", (float)meter_div, watts);
   watts = watts / (cost_unit / 1000);
   ESP_LOGD(TAG, "Watts after cost unit (%d): %.2f", cost_unit / 1000, watts);

   ESP_LOGD(TAG, "Meter Energy: %.3fkWh", watt_hours / 1000.0);
   ESP_LOGD(TAG, "Meter Power:  %3.0fW", watts);