Powerpal smart energy monitor

Hi @drew-t I got mine working 7 days back with @muneeb1990 code from above here, I copied his “powerpal_ble” & “http_request” to my pi4 microSD and pointed the .yaml at it to use as a local source to compile but only for components: [powerpal_ble, http_request] not the ble_client, and that worked well, the only thing is I don’t think its pushing to the Powerpal cloud, even after adding my device_id and apikey, but I might have done something wrong my end, hope this helps.

In saying that, I was looking at @muneeb1990 's powerpal_ble.h and I noticed it is referencing an internal ip address as possibly part of the cloud uploading, but I’m only a shade tree coder, so I might be of the mark totally. The powerpal_ble.h code below lines 145 - 150:-

uint8_t stored_measurements_count_{0};
std::vector stored_measurements_;
std::string powerpal_api_root_ = “http://192.168.1.44:3000/”;
std::string powerpal_device_id_; // = “00002bc3”;
std::string powerpal_apikey_; // = “4a89e298-b17b-43e7-a0c1-fcd1412e98ef”;
double energy_cost_;

Where @WeekendWarrior1 's original code refereed to:-

std::string powerpal_api_root_ = “https://readings.powerpal.net/api/v1/meter_reading/”;

1 Like

Thanks @compacthack! I’ve managed to get it to compile by excluding ble_client in the YAML code.

external_components:
  - source:
      type: local
      path: my_components
    components: [powerpal_ble, http_request]

@drew-t excellent work :+1: are you trying to do the Powerpal cloud upload ? I think the data representation in the Powerpal app is pretty good, just a design downfall that the unit relies on a flaky intermittent Bluetooth connection, I get missing chunks of data doing it the official way. I’ve just tried substituting in the “https://readings.powerpal.net/api/v1/meter_reading/”; into the powerpal_ble.h and cleaning / re-compile, will see if that helps.

@compacthack I’ve managed to get Powerpal integrated with Home Assistant via ESP 32 :slight_smile: I used NRF Connect to find the BLE MAC address. Had to use my Android tablet for that as the NRF Connect iOS version was obfuscating the MAC address for some reason. How did you go with the cloud integration?

Hey guys, as I mentioned on Github, I’m not using @WeekendWarrior1’s code for cloud upload as I couldn’t get it to work. What I’m doing instead is uploading the values using a POST request through HA native REST command platform.

EDIT: Use the code from this post instead

Let’s try this again. Here’s what I’ve got in my configuration.yaml. You’ll need to replace device-id and api-key for your own device:

rest_command:
  my_request:
    url: https://readings.powerpal.net/api/v1/meter_reading/<device-id>
    method: POST
    headers:
      authorization: "<you-powerpal-api-key>"
      accept: ""
    payload: >-
       [ {"cost":{{ states.sensor.powerpal_cost_json.state }},"is_peak": false, "pulses":{{ states.sensor.powerpal_pulses_json.state }}, "timestamp": {{ (int(states.sensor.powerpal_timestamp_json.state)//60) * 60 }}, "watt_hours": {{ states.sensor.powerpal_watt_hours_json.state}} } ]
    content_type: 'application/json'
    verify_ssl: true

Next, I’m using an automation to trigger upload everytime the value of timestamp sensor changes which is every 60s.
From automations.yaml:

- alias: Powerpal Cloud Upload
  description: ''
  trigger:
  - platform: state
    entity_id:
    - sensor.powerpal_timestamp_json
  condition: []
  action:
  - service: rest_command.my_request
    data: {}
  mode: single

It’s been working flawlessly for me for the past month or so. Here’s a screenshot of my Powerpal app where you can see the data being uploaded while Bluetooth is disabled:

Happy to help with further questions!

1 Like

Thanks @muneeb1990 ! I added your configuration.yaml and and created an automation to upload to the cloud and it is working perfectly!

Hey @muneeb1990 , what do they say RTFM, I got it working a treat. Thanks again for your efforts :+1:

Thanks @muneeb1990 got your code up and running today on an M5 Atom Lite.
From what I can see in HA everything looks good, however the data being pushed to Powerpal by the automation\Rest is way off! See screenshot attached showing 15.4kW!! It should be like 700watts.
Is it possible it’s not reflecting the pulse_per_kwh ? Mine is set to 3200 as per my meter and configured in the yaml file of the ESP device.

Any help would be greatly appreciated!!!

I’m having this experience too with a 3200/pulse per kw meter too.
The watt hours seem to be super far off compared to everyone else.

I’m testing this code now, so far it seems to work but I haven’t got much data to compare yet.

int mywatt_hrs = (uint32_t)roundf((pulses_within_interval / this->pulses_per_kwh_) * kw_to_w_conversion);

Have you set 3200 in Powerpal app as well? I don’t see anywhere in the code where this value is hard-coded to 1000 so not sure what’s going on.

Yeah, 3200 in the Powerpal app as well. I couldn’t see anywhere in the code where it was hard set. I’m getting some discrepancy between HA and Powerpal, so will compare with what the United energy platform says my meter is doing.

Powerpal cloud is now significantly lower than United energy and HA. Will hopefully get a bit of time this week to dig into it a bit more and roll my testing change back.



image

I think there might be an issue with update frequency associated with using timestamp as the trigger. Can you try changing the configuration.yaml to the following:

rest_command:
  my_request:
    url: https://readings.powerpal.net/api/v1/meter_reading/<device-id>
    method: POST
    headers:
      authorization: "authorization key"
      accept: ""
    payload: >-
       [ {"cost":{{ states.sensor.powerpal_cost_json.state }},"is_peak": false, "pulses":{{ states.sensor.powerpal_pulses_json.state }}, "timestamp": {{ as_timestamp(now(),0) | int(0) }} , "watt_hours": {{ states.sensor.powerpal_watt_hours_json.state}} } ]
    content_type: 'application/json'
    verify_ssl: true

And automation.yaml:

alias: Powerpal Cloud Upload
description: ""
trigger:
  - platform: time_pattern
    minutes: /1
condition: []
action:
  - service: rest_command.my_request
    data: {}
mode: single
1 Like

Went to try this today and discovered my Powerpal stopped sending data some time yesterday. Will do some digging into why and hopefully I can get it running again.

Just tried but unfortunately results appear to be the same in Powerpal app.
The timestamp is different between the two but the rest remains the same.

Example output pasting the payload line into templates:
Old:
[ {“cost”:0.00549223134,“is_peak”: false, “pulses”:93, “timestamp”: 1674627660, “watt_hours”: 298 } ]

New:
[ {“cost”:0.00549223134,“is_peak”: false, “pulses”:93, “timestamp”: 1674627840 , “watt_hours”: 298 } ]

Yeah that fix was for reduced usage being reflected in the app. Have you set your app to 3200 as well?

Confirming I do have it set to 3200 in the PowerPal app and readings had been accurate with direct Bluetooth connection. That said I think I’ve got it pretty close now!

With the readings being far to high I first tried dividing the watt hours being sent to PowerPal by 3.2 thinking that would account for the flashes per second and that possibly by disconnecting the PowerPal from the app that it may default back to 1000 even though it was set to 3200.
That theory went out the window as results were still to high but I’ve got it pretty close by dividing by 5. I can’t say I understand why it’s by 5 but it does seem to get me within +/-0.1 kWh from what I see in HA (which is 100% accurate confirmed with power distributors web portal) so I’m happy enough with that.

Final config below for anyone else who may have similar issues.

configuration.yaml

rest_command:
  my_request:
    url: https://readings.powerpal.net/api/v1/meter_reading/<device-id>
    method: POST
    headers:
      authorization: "authorization key"
      accept: ""
    payload: >-
       [ {"cost":{{ states.sensor.powerpal_cost_json.state }},"is_peak": false, "pulses":{{ states.sensor.powerpal_pulses_json.state }}, "timestamp": {{ (int(states.sensor.powerpal_timestamp_json.state)//60) * 60 }}, "watt_hours": {{ int(states.sensor.powerpal_watt_hours_json.state)/5}} } ]
    content_type: 'application/json'
    verify_ssl: true

Automation you suggested:

alias: Powerpal Cloud Upload
description: ""
trigger:
  - platform: time_pattern
    minutes: /1
condition: []
action:
  - service: rest_command.my_request
    data: {}
mode: single
1 Like

That seems to have done the trick, it’s tracking much more accurately now with the time change and the change to how the watt hours are calculated.

I’ve been tracking for about 8 hours now and it’s spot on! Thank you!