home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
71.63k stars 29.93k forks source link

Adax - get kWh Energy reading (updated from #20030) #93793

Open thegreenmilecornant opened 1 year ago

thegreenmilecornant commented 1 year ago

The problem

Was searching for kWh in the Adax HA integration and read issue #20030 .

I took a look at the Adax API documentation and saw that it has been updated. I don't know when though. And the text is wrong as it says it only has three endpoints (when they've updated it to four..). See below.

Using Adax API

The API provides 3 end points:

    /auth/ for authentication to the REST service.
    /rest/v1/control/ for controlling your rooms
    /rest/v1/content/ for getting rooms statuses. (add ?withEnergy=1 to get heaters power consumption for past hour)
    /rest/v1/energy_log/{roomId} – returns hourly energy log from current time back to 1 week for the specified room in 1h intervals.

Would love to see this added into the Adax integration! Then I have full insight into my heating power.

What version of Home Assistant Core has the issue?

core-2023.5.4

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant Container

Integration causing the issue

Adax

Link to integration documentation on our website

https://www.home-assistant.io/integrations/adax/

Diagnostics information

No response

Example YAML snippet

No response

Anything in the logs that might be useful for us?

No response

Additional information

No response

home-assistant[bot] commented 1 year ago

Hey there @danielhiversen, mind taking a look at this issue as it has been labeled with an integration (adax) you are listed as a code owner for? Thanks!

Code owner commands Code owners of `adax` can trigger bot actions by commenting: - `@home-assistant close` Closes the issue. - `@home-assistant rename Awesome new title` Renames the issue. - `@home-assistant reopen` Reopen the issue. - `@home-assistant unassign adax` Removes the current integration label and assignees on the issue, add the integration domain after the command.

(message by CodeOwnersMention)


adax documentation adax source (message by IssueLinks)

thegreenmilecornant commented 1 year ago

Have you had the chance to look at this @Danielhiversen ? I can't help with the coding - but I would be happy to testflight a release and report any bugs.

thegreenmilecornant commented 1 year ago

I see that @emontnemery is active on the repo as well. What do you think of the API changes and the possibility to integrate energy readings into the Adax-integration?

WaterInTheLake commented 1 year ago

I am also looking forward to this! I saw that there was some acitivity in https://github.com/Danielhiversen/pyAdax, so I think it is on it's way! 👍

holmbom commented 1 year ago

Any plan on releasing Adax integration with energy reading? :)

badguy99 commented 1 year ago

I had a look at the Adax API, but it didn't work properly for me. The energy_log one always reported zero usage, even when I'd heated the room. Also the content with_energy=1 didn't reset to zero an hour after I stopped using power. So there may be issues with them, or maybe it is fine for others? I messaged Adax using their web form, but haven't had any response.

thegreenmilecornant commented 12 months ago

I had a look at the Adax API, but it didn't work properly for me. The energy_log one always reported zero usage, even when I'd heated the room. Also the content with_energy=1 didn't reset to zero an hour after I stopped using power. So there may be issues with them, or maybe it is fine for others? I messaged Adax using their web form, but haven't had any response.

Have you tried using pyAdax?

badguy99 commented 12 months ago

It's the same with pyAdax, all zeros for energy. The data goes back a week and what is interesting with that is the energy consumption graph on the iOS Adax app is showing usage on 21st, 22nd, 23rd, 24th and 26th for me. So I don't know if the app uses some private API, or another way of getting the data, but code calling the official /rest/v1/energy_log/{room_id} API only seems to get zeros - or at least that is all I get

badguy99 commented 11 months ago

I got an email back from Adax, and they've fixed the API - The energy information is coming back from their server correctly now

runemoennike commented 10 months ago

I would also be interested in this, and I can possibly help with some code if needed.

Brumhilde commented 10 months ago

I got an email back from Adax, and they've fixed the API - The energy information is coming back from their server correctly now

Is it possible to use RESTful integration to fetch energy? Until Adax integration gets updated.

le-clu commented 10 months ago

It is. But data looks like below, so there's some logic needed to make it usable (which I haven't found the motivation to create).

endpoint https://api-1.adax.no/client-api/rest/v1/content

"devices": [ { "id": xxx, "homeId": xxx, "roomId": xxx, "name": "Office ", "type": "Heater", "energyTime": 1700947123320, "energyWh": 3 } ]

endpoint https://api-1.adax.no/client-api/rest/v1/energy_log/xxxxx

{ "fromTime": 1700337600000, "toTime": 1700946000000, "points": [ { "fromTime": 1700337600000, "toTime": 1700341200000, "energyWh": 56 }, { "fromTime": 1700341200000, "toTime": 1700344800000, "energyWh": 56 }, { "fromTime": 1700344800000, "toTime": 1700348400000, "energyWh": 50 },

holmbom commented 9 months ago

I can see the problem with energy reading from the API, because HA uses energy usage "right now" and the reading from the API is like a history. But wouldnt one half good thing just to put the latest energy reading into the attributes? And then we can use it to plot graphs? And when time comes and the developer finds a way to do it "the right way" fix it? Would love just to be able to see what room takes more energy and so on, getting it into the energy page is not that necesary. (Im swedish, so my english isnt that good)

le-clu commented 9 months ago

Your English is good, don't worry about it :)

This is what the data looks like. I use a Restful sensor with the energy values in the attributes. Like you said, it is not ideal, but I have not had time nor motivation to dive into it.

image
holmbom commented 9 months ago

custom_components should override core integrations i read. So I created an custom_component named adax, copied the files from core adax integration and added code for a attribute and update the energy reading. But dont know how to get HA to use it yet. I guess I have to use configuration.yaml to load it, platform: adax. But the rest of the settings. I have no idea. :P will find a way...

holmbom commented 9 months ago
image

I succeded in adding the attribute :) Will see how this turns out.

Brumhilde commented 9 months ago

Your English is good, don't worry about it :)

This is what the data looks like. I use a Restful sensor with the energy values in the attributes. Like you said, it is not ideal, but I have not had time nor motivation to dive into it.

image

Hello! Can you share the restful sensor? I can have a look at it as well.

runemoennike commented 9 months ago

@le-clu did you try changing the sensor's state class to total_increasing? That should get rid of the resets to 0 and give a constantly increasing plot.

le-clu commented 9 months ago

@le-clu did you try changing the sensor's state class to total_increasing? That should get rid of the resets to 0 and give a constantly increasing plot.

Good point, worth a try :) Thanks

le-clu commented 9 months ago

Your English is good, don't worry about it :) This is what the data looks like. I use a Restful sensor with the energy values in the attributes. Like you said, it is not ideal, but I have not had time nor motivation to dive into it.

image

Hello! Can you share the restful sensor? I can have a look at it as well.

Sure, @Brumhilde

Here is for the authentication. It will create a sensor which holds the access and refresh tokens as attributes.

resource: https://api-1.adax.no/client-api/auth/token
method: POST 
scan_interval: 42200
headers:
  Content-Type: application/x-www-form-urlencoded
payload: grant_type=password&username=yourUserID&password=yourPassword
sensor:
  - name: adax_access_token
    value_template: "OK"
    unique_id: adax_access_token
    json_attributes:
      - access_token
      - refresh_token
      - token_type #optional
      - expires_in #optional

This token is then used in the REST sensor as follows:

resource: https://api-1.adax.no/client-api/rest/v1/content
method: GET
headers:
  Authorization: >
    Bearer {{ states.sensor.adax_access_token.attributes["access_token"] }}
params: 
  withEnergy: 1
scan_interval: 600
sensor:
  - name: adax_heater_office
    unique_id: sensor.adax_heater_office
    json_attributes_path: "$.devices[?(@.id==1789269)]"
    value_template: "OK
    json_attributes:
      - id
      - name
      - energyTime
      - energyWh

You will need to parse your devices based on ID or name, I recommend to test first in an API explorer (I use HTTPie) so that you can test authentication and retrieve your devices. Whether you define your JSON filter criteria using ID or name is not important, but testing the API outside of Home Assistant will save you frustration.

Again, data is stored in the attributes of this sensor.

A third template sensor is used to collect energy readings (the one from the screenshot I attached in a previous post)

- sensor:
  - name: Office Heater consumption last reading
    unique_id: sensor.office_heater_consumption_last_reading
    unit_of_measurement: kWh
    state: >-
      {% if has_value('sensor.adax_heater_office') %}
        {{ states.sensor.adax_heater_office.attributes.energyWh / 1000 }}
      {% endif %}

I'm pretty sure there are better ways to do it - I kind of lost motivation after this first test though :D

Hope it helps

thegreenmilecornant commented 6 months ago

Any progress on this? Would be amazing to see individual energy usage in the new upcoming energy dashboard layout.

bild Screenshot taken from the beta channel in Discord. Not mine.

Brumhilde commented 6 months ago

Fetching the data didn't work for me (in HA, works in reqbin.com testing tool) so I dropped it for now. I can fetch the access token in HA only data isn't working.

Brumhilde commented 6 months ago

This works for me but the rest sensor is very unreliable. The initial GET after restart or rest entities reload always fails. I have to wait 10 min for first update and that is about 50/50, if it passes it will work until next restart/reload though.

Maybe someone better than me in Python can implement it in the integration instead. The logic is quite simple. @holmbom since you already have the attribute added it should just be a matter of adding the logic at the very bottom in the automation :)

Below can be copied to a yaml-file and added to config/packages. Just add your ID, token and room ID.

rest:
  - resource: https://api-1.adax.no/client-api/auth/token
    method: POST
    scan_interval: 42200
    headers:
      Content-Type: application/x-www-form-urlencoded
    payload: grant_type=password&username=<insert_ID>&password=<insert_password>
    sensor:
      - name: adax_access_token
        value_template: "OK"
        unique_id: adax_access_token
        json_attributes:
          - access_token
          - refresh_token

  - resource: https://api-1.adax.no/client-api/rest/v1/content?withEnergy=1
    method: GET
    headers:
      User-Agent: Home Assistant
      Content-Type: application/json
      Authorization: >
        Bearer {{ state_attr('sensor.adax_access_token', 'access_token') }}
    scan_interval: 600
    sensor:
      - name: adax_guestroom_energy
        unique_id: adax_guestroom_energy
        json_attributes_path: "$.devices[?(@.id==<insert_room_id>)]"
        value_template: "OK"
        json_attributes:
          - id
          - name
          - energyWh

template:
  - sensor:
    - name: adax_guestroom_energy_counter
      unit_of_measurement: "Wh"
      state: >
        {% if state_attr('sensor.adax_guestroom_energy', 'energyWh') | is_number %}
          {{ state_attr('sensor.adax_guestroom_energy', 'energyWh') }}
        {% else %}
          {{ states('sensor.adax_guestroom_energy_counter') }}
        {% endif %}
    - name: adax_guestroom_energy_total
      unit_of_measurement: "kWh"
      device_class: energy
      state_class: total_increasing
      state: >
        {{ states('input_number.adax_guestroom_energy_total') }}

input_number:
  adax_guestroom_energy_total:
    min: 0
    max: 900000
    unit_of_measurement: "kWh"

automation:
  - alias: adax_guestroom_energy_total
    initial_state: true
    trigger:
      - platform: state
        entity_id: sensor.adax_guestroom_energy_counter
    action:
      - service: input_number.set_value
        target:
          entity_id: input_number.adax_guestroom_energy_total
        data:
          value: >
            {% if trigger.to_state.state|int < trigger.from_state.state|int %}
              {{ states('input_number.adax_guestroom_energy_total')|float + (trigger.from_state.state|float / 1000) }}
            {% else %}
              {{ states('input_number.adax_guestroom_energy_total')|float }}
            {% endif %}
Brumhilde commented 6 months ago

The rest sensor above stopped working after some hours and it also messes with my other rest sensor that have been stable for 6 months. I believe it has to be implemented in the integration, preferably as a kWh sensor but attribute is also ok.

caribo commented 6 months ago

Id love to see this in the HA adax component too, but in the meantime I'm in the process of migrating my adax energy scripts to appdaemon to simplify my setup considerably. I don't know if this approach would work with other people's setup but it's here if anyone want's to try something similar.

badguy99 commented 5 months ago

Is there any progress on this @Danielhiversen

danielbergholm commented 2 months ago

Anything new here? 👀 Would love to get the energy data in HA!