WeekendWarrior1 / emerald_electricity_advisor

Collection of code, tools and documentation for data retrieval from your Emerald Electricity Advisor (all reverse engineered)
GNU General Public License v3.0
37 stars 4 forks source link

Average power conversion #4

Open miragebird opened 1 year ago

miragebird commented 1 year ago

Firstly awesome work @WeekendWarrior1 to get this up and running! Reverse engineering the bluetooth comms protocol is next level.

In setting up my emerald ems, I did notice that the "power" output sensor seems to be off by a factor of 2-5 from the actual power output.

I believe I've tracked down the issue down to the average power equation, and specifically to the conversion between energy [wh] and power [w]

pulse_multiplier_ = (standard_update_interval / (pulses_per_kwh / kw_to_w_conversion));

float avg_watts_within_interval = pulses_within_interval * this->pulse_multiplier_;

In trying to balance the units in the equations I believe we're missing a conversion between "secounds" and "hours". I'll have a stab at an updated formula when I get a chance outside of work.

miragebird commented 1 year ago

Just created a pull request. (First pull request forgive me if I did anything wrong) WeekendWarrior1/esphome/pull/2

The suggested pulse multiplier equation is:

pulse_multiplier_ = ((hr_to_s_conversion * kw_to_w_conversion) / (standard_update_interval * pulses_per_kwh));

This can be tested using my (fork/branch) for the external components:

external_components:
  - source: github://miragebird/esphome@emerald_ble_powerfix

The updated formula results in a x4 increase in power output compared to the old formula, but will be colser to the actual power output with an accuracy +/- 120 W (assuming a 1000 pulses/kWh). Ideally if the timestamps were know for each pulse (or the delta) we could increase this accuracy further. Pretty basic code change so hopefully I didn't break anything. Tested locally, but please verify with the above code :)

bleckers commented 1 year ago

It seems you are right. Looking at it another way:

pulses_per_kwh = 1000

kwh_to_ws_conversion = 3600000; //Kilowatt hours to watt second (Joule)

pulsemultiplier = kwh_to_ws_conversion / (standard_update_interval pulses_per_kwh); //pulsemultiplier = 3600000 / (30 1000) = 120W

Then this is used here to calculate avg watts during interval:

float avg_watts_within_interval = pulses_within_interval * this->pulsemultiplier;

miragebird commented 1 year ago

Hi @bleckers

Really appreciate you verifying the formula, I probably could have done a better job describing the unit conversion process but glad we're on the same page. I've roughly validated the power output with a smart power plug and all seems in line -so somewhat confident in the data with the data at this stage.

Unfortunately due to the sample rate, a real time accuracy of +/- 120 W is somewhat poor (assuming the typical 1000 pulses per kWh) however for the use case of long term average graphs and identifying large loads it works quite well.

LeoRX commented 1 year ago

@WeekendWarrior1 @miragebird nice work guys.
Any idea if the changes is merged? I'm still seeing the power not matching up with EMS app itself.

miragebird commented 1 year ago

@WeekendWarrior1 @miragebird nice work guys.
Any idea if the changes is merged? I'm still seeing the power not matching up with EMS app itself.

Honestly I'm new to GitHub, I have a pull request, but I believe this requires approval by @WeekendWarrior1 to bring into the main branch.

In the mean time you can test/run my branch by changing the ESPHome config:

external_components:
  - source: github://miragebird/esphome@emerald_ble_powerfix
N3Cr0 commented 1 year ago

Hey all. Just stumbled on this bug and and I see it's still around; Really good job on the component by the way!

My two cents on the issue; The units are imp/Wh and thus multiplying by 30 won't work.

Instead of multiplying by 30 to get to current power you need to count how many pulses would happen in an hour at that current rate. So we take the 30 second count and multiply by 120, the number of 30s periods in an hour.

So say we have 1000KWh as the answer after projecting, that directly converts back to instantanious power of 1KW; 1 KW was being used for a whole hour to get 1KWh (projected from our 30s sample).

carryonrewardless commented 1 year ago

Replace line 78 in emerald_ble.h with

pulse_multiplier_ = ((hr_to_s_conversion * kw_to_w_conversion) / (standard_update_interval * pulses_per_kwh));

Fixes average power calculation.