mindmelting / hass-powerpal

Home Assistant custom integration to fetch data from Powerpal
MIT License
44 stars 11 forks source link

HOw to get Authorization Key and Device ID Explanation #25

Open mrkatz opened 1 year ago

mrkatz commented 1 year ago

Is your feature request related to a problem? Please describe. Unable to setup as I don't know how to get Authorization Key and Device ID

Describe the solution you'd like A clear and concise tutorial of how to do this

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Additional context Add any other context or screenshots about the feature request here.

pencilhead1 commented 1 year ago

Check: https://github.com/WeekendWarrior1/powerpal_ble Details there. You may need to check / disable all bluetooth on all devices, apart from the one you are using to get codes.

mindmelting commented 1 year ago

Thanks @pencilhead1 - I can add reference to this in the README. Alternatively, owning a Powerpal Pro makes this painless (been a while since I looked up the status of those devices though)

matthewbayard commented 2 months ago

Thanks @pencilhead1 - I can add reference to this in the README. Alternatively, owning a Powerpal Pro makes this painless (been a while since I looked up the status of those devices though)

Are you still using the Pro?

mindmelting commented 2 months ago

@matthewbayard yes I am - although I got the email about them decommissioning it. This technically does not affect this integration as it pulls from the API directly - but would mean needing to replace the Pro with an ESPHome solution which is available...(I haven't tried this yet!)

matthewbayard commented 2 months ago

@matthewbayard yes I am - although I got the email about them decommissioning it. This technically does not affect this integration as it pulls from the API directly - but would mean needing to replace the Pro with an ESPHome solution which is available...(I haven't tried this yet!)

Its a shame they won't just keep the Pro working as its been very solid.

Any tips on getting the Powerpal API Authorization Key in 2024?

mindmelting commented 2 months ago

I believe that the authorisation key you are using today will stay the same... you will just need a device (an ESPHome or an always powered tablet) to send the data continuously instead of the Pro...

mindmelting commented 2 months ago

Also if you are using the ESPHome solution here https://github.com/WeekendWarrior1/powerpal_ble you may not actually need to use this integration anymore...

lukechadwick commented 4 weeks ago

Just got a Powerpal and I had a lot of issues trying to extract the key info using the script here due to timeouts and failing to get read access on some of the UUIDs even after pairing and auth https://github.com/WeekendWarrior1/powerpal_ble/blob/main/auth_extraction/retrieve_api_key.py

I ended up using this Bluetooth LE Explorer app on my windows laptop. There should be similar apps on other OSes.

You can connect to the device manually and write your pairing code to 59DA0011-12F4-25A6-7D4F-55961DCE4205

You should then be able to read your api key from 59DA0009-12F4-25A6-7D4F-55961DCE4205 and serial from 59DA0010-12F4-25A6-7D4F-55961DCE4205

I simplified the script to just do the web request, you just need to add your serial and api key

from encodings import utf_8
import sys
import asyncio
import requests

serial = b"\x00\x00\x00\x00"
apikey = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

async def main():
  formatted_serial = ''.join('{:02x}'.format(x) for x in reversed(serial)).lower()
  print(f"Retrieved Device Serial:   {formatted_serial}")
  print(f"Meaning your meter reading endpoint is:  https://readings.powerpal.net/api/v1/meter_reading/{formatted_serial}\n")

  print(f"Attempting to retrieve apikey (Powerpal UUID)...")
  joined_apikey = ''.join('{:02x}'.format(x) for x in apikey)
  formatted_apikey = f"{joined_apikey[:8]}-{joined_apikey[8:12]}-{joined_apikey[12:16]}-{joined_apikey[16:20]}-{joined_apikey[20:]}".lower()
  print(f"Retrieved apikey: {formatted_apikey}\n")

  test_endpoint = input(f"Would you like this script to validate your apikey by using it to make a request for your device information from https://readings.powerpal.net/api/v1/device/{formatted_serial}? (y/n): ")
  if test_endpoint.lower().startswith('y'):
      url = f"https://readings.powerpal.net/api/v1/device/{formatted_serial}"
      headers = { 'Authorization': formatted_apikey }

      response = requests.request("GET", url, headers=headers)
      if (response.status_code < 300):
          print("Success! Looks like your Device Serial and apikey were succesfully retrieved! Here is the device information returned from https://readings.powerpal.net/api/ :")
          print(response.text)
      else: 
          print("Failure!")
          print(f"{response.status_code} - {response.reason} - {response.text}")
  else:
      print(f'You may also confirm your apikey by using curl:\ncurl -H "Authorization: {formatted_apikey}" https://readings.powerpal.net/api/v1/device/{formatted_serial}')

asyncio.run(main())

Note that the format you get the API/Serial back in might be something like AA-BB-CC-DD, which you'll need to format so change it to the format in the script above like b"\xAA\xBB\xCC\xDD".

Sage222 commented 3 weeks ago

Just got a Powerpal and I had a lot of issues trying to extract the key info using the script here due to timeouts and failing to get read access on some of the UUIDs even after pairing and auth https://github.com/WeekendWarrior1/powerpal_ble/blob/main/auth_extraction/retrieve_api_key.py

I ended up using this Bluetooth LE Explorer app on my windows laptop. There should be similar apps on other OSes.

You can connect to the device manually and write your pairing code to 59DA0011-12F4-25A6-7D4F-55961DCE4205

You should then be able to read your api key from 59DA0009-12F4-25A6-7D4F-55961DCE4205 and serial from 59DA0010-12F4-25A6-7D4F-55961DCE4205

I simplified the script to just do the web request, you just need to add your serial and api key

from encodings import utf_8
import sys
import asyncio
import requests

serial = b"\x00\x00\x00\x00"
apikey = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

async def main():
  formatted_serial = ''.join('{:02x}'.format(x) for x in reversed(serial)).lower()
  print(f"Retrieved Device Serial:   {formatted_serial}")
  print(f"Meaning your meter reading endpoint is:  https://readings.powerpal.net/api/v1/meter_reading/{formatted_serial}\n")

  print(f"Attempting to retrieve apikey (Powerpal UUID)...")
  joined_apikey = ''.join('{:02x}'.format(x) for x in apikey)
  formatted_apikey = f"{joined_apikey[:8]}-{joined_apikey[8:12]}-{joined_apikey[12:16]}-{joined_apikey[16:20]}-{joined_apikey[20:]}".lower()
  print(f"Retrieved apikey: {formatted_apikey}\n")

  test_endpoint = input(f"Would you like this script to validate your apikey by using it to make a request for your device information from https://readings.powerpal.net/api/v1/device/{formatted_serial}? (y/n): ")
  if test_endpoint.lower().startswith('y'):
      url = f"https://readings.powerpal.net/api/v1/device/{formatted_serial}"
      headers = { 'Authorization': formatted_apikey }

      response = requests.request("GET", url, headers=headers)
      if (response.status_code < 300):
          print("Success! Looks like your Device Serial and apikey were succesfully retrieved! Here is the device information returned from https://readings.powerpal.net/api/ :")
          print(response.text)
      else: 
          print("Failure!")
          print(f"{response.status_code} - {response.reason} - {response.text}")
  else:
      print(f'You may also confirm your apikey by using curl:\ncurl -H "Authorization: {formatted_apikey}" https://readings.powerpal.net/api/v1/device/{formatted_serial}')

asyncio.run(main())

Note that the format you get the API/Serial back in might be something like AA-BB-CC-DD, which you'll need to format so change it to the format in the script above like b"\xAA\xBB\xCC\xDD".

thanks for the write up can you expand a bit on using BT LE Explorer on Windows?

I have installed it, confirmed the MAC address of the powerpal, Connected to it via LE Explorer.

I can see the ServiceName 59DA0011-12F4-25A6-7D4F-55961DCE4205 (same as yours above).

It states "READ NOT PERMITTED" which is expected as i am yet to AUTH.

Though if i click on that Service or one of it's Child Characteristics and try to Write my pairing code i get an error:

"Error writing to characteristic. This usually happens when a device reports that is supports writing, but it actually doesn't".

I have tried both HEX and UTF8 same result.

Little help would be appreciated!

Sage222 commented 3 weeks ago

ahh getting closer realised my decimal code needs to be turned into a Hex array and then reversed as per details here from the code.

[code extract] uint32_t powerpal_pass_key = 123123; // in hex 01E0F3, so uint32_t powerpal_pass_key_hex = 0x01E0F3; // esp32 arduino BLE library needs to write data as an array of uint8_t's, so uint8_t powerpal_pass_key_array[] = {0x00, 0x01, 0xE0, 0xF3}; // Powerpal wants this array in reversed byte order (little endian), so: uint8_t powerpal_pass_key_array_reversed[] = {0xF3, 0xE0, 0x01, 0x00}; [/code]

mine is 411758 so hex is 0x6486e

Which i work converted and reversed to be - {0x0e,0x86,0x64,0x00} Though you cant send these characters as HEX.. so not sure what do next.

lukechadwick commented 3 weeks ago

Hey @Sage222

Sure thing, my process was

  1. Ensure any device that has previously connected/paired to the device is unpaired, or the bluetooth is switched off.
  2. Unpair from the windows device if previously done.
  3. Open Bluetooth LE explorer and hit start on the discover/pair sidebar tab.
  4. Wait for the Powerpal to show up, click pair, accept any windows dialog things that popup. Then once paired click into device and wait for the connecting... prompt.
  5. Under the Battery Service there should be a list of services, go to the 59DA011 one image
  6. Write you pairing code as decimal. I didn't get any feedback or response from this. image
  7. Go back to the main window and hit refresh, the services should all be readable now
  8. The 59DA011 serial is just your powerpal serial number backwards/little endian as btyes, so the API key should be all you need at 59DA010 image

You can take that output and and reformat into xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format for the API key.

Sage222 commented 3 weeks ago

thank you very much @lukechadwick! getting closer now! got AUTH to the device. Can now see the data within the services. Not sure what the code above as saying about converting and using an array for the auth.. :)

The API key from Service 10 seems to be AB-CD-EF-10-D4-70-40-F2-8C-B0-07-84-1D-6C-10-16 (Changed the first 3 for privacy)

And reading the data as Decimal from Service 09 (the Device ID) is a 6 digit code 33XXXX.

And you say i need to get the API Key output then reverse it and remove the characters separating the bytes.

So my API key would be 6101c6d148700bc82f04074d01fedcba ? and my device ID is unchanged at 33XXXX.

Though when i put this into the HACS Powerpal integration i get "Credentials are incorrect".

What am i missing? (Hope this thread helps others as much as me!)

lukechadwick commented 3 weeks ago

Hey @Sage222 sorry you only need to reverse the bytes of the serial. The API key is in the correct order but needs formatting to xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

In your case that would be abcdef10-d470-40f2-8cb0-07841d6c1016

For the serial you don't need to convert it to decimal, just flip the bytes. If the BT app outputs 33-40-05-00, your endpoint would be https://readings.powerpal.net/api/v1/meter_reading/00054033. (should just be the same as the piece of paper that has the serial and pairing code.

Sage222 commented 3 weeks ago

giddyup! you sir are a gentlemen and a scholar! im in!

Just for anyone else reading up you don't need the 09 Service Reading Serial number from the Device. You should can just get the DeviceID from the Bluetooth scan should look like Powerpal_00051d4g. The DeviceID is the last section. In that example Powerpal_00051d4g. You put it in directly with no change.

Thanks again @lukechadwick!