Reading onboard data from Grant Aerona HP290 HomeAssistant

The Grant Aerona HP290 heat pump uses a Plum ecoMAX360i touch screen controller. It’s a good controller and works well.

Grant use TP-Link hardware running custom firmware to post data to EcoNet. EcoNet service allows every setting to be adjusted remotely and lots metrics from onboard sensors to be monitored with basic graphing. The TP-link hardware has a local HTTP API which can be used to read data locally. Local control is also possible.

Currently, I’m aware of three Home Assistant integrations / methods which are able to do this, once the data is in Home Assistant it’s easy to use Emoncms History Integration to get the data into Emoncms for more advanced graphing:

1. EcoNET-300 HACS

Easy to setup, install via HACS. Supports many different Plum controllers. Only a limited number of metrics are supported on the Grant HP290

2. Econet MQTT Publisher

by @MrW

Run using a docker container, doesn’t require Home Assistant. Publishes data to MQTT. Supports most more metrics from Grant HP290

Forum thread:

3. Home Assistant REST

by @GSV3MiaC

REST API calls from HomeAssistant, requires manual setup. Most complete set of metrics, this is what I’m currently using. See forum post.

# For Econet Grant Heatpump

- authentication: basic
  username: "admin"
  password: "admin"
  scan_interval: 30
  resource: http://192.168.86.31/econet/editParams
  sensor:
    - name: "Heat pump SCOP"
      unique_id: 'f541d4d5-b12a-4c2b-9566-d284d75d5c7e'
      value_template: "{{ value_json['informationParams']['222'][1][0]
      [0] }}"
      state_class: measurement

    - name: "Circuit 1 thermostat day setting"
      unique_id: '38edd4cd-32d9-45c3-bc97-af814b29fbc5'
      value_template: "{{ value_json['data']['238']['value'] }}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

    - name: "Circuit 1 thermostat night setting"
      unique_id: 'da60f424-fc3c-49d4-9320-3eb5076c2b81'
      value_template: "{{ value_json['data']['239']['value'] }}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

    - name: "Circuit 1 hysteresis"
      unique_id: 'circuit1 hysteresis'
      value_template: "{{ value_json['data']['240']['value'] }}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

    - name: "Circuit 1 weather comp curve"
      unique_id: 'c1 weather curve'
      value_template: "{{ value_json['data']['273']['value'] }}"
      state_class: measurement

    - name: "Circuit 1 curve shift"
      unique_id: 'circuit1 curve shift'
      value_template: "{{ value_json['data']['275']['value'] }}"
      state_class: measurement

    - name: "DHW thermostat setting"
      unique_id: '458520e1-7dd6-42a6-83d0-40aa736ffc60'
      value_template: "{{ value_json['data']['103']['value'] }}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

    - name: "DHW thermostat hysteresis"
      unique_id: 'dhw hysteresis'
      value_template: "{{ value_json['data']['104']['value'] }}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

#- authentication: basic
#  username: "admin"
#  password: "admin"
#  scan_interval: 30
#  resource: http:/192.168.86.31/econet/editParams
#  sensor:
    - name: "Heat pump fan speed"
      unique_id: '1828f0ea-5f4e-4d3e-8d24-50a7670bda97'
      value_template: "{{ value_json['informationParams']['22'][1][0]
      [0] }}"
      unit_of_measurement: "rpm"
      state_class: measurement

    - name: "Heat pump electrical power"
      unique_id: '3f91960f-84bd-4c24-979e-baa3cb323e8a'
      value_template: "{{ value_json['informationParams']['211'][1][0]
      [0] }}"
      unit_of_measurement: "kW"
      device_class: power
      state_class: measurement

    - name: "Heat pump thermal power"
      unique_id: '1e66d359-d68f-4288-b461-5edaa227e682'
      value_template: "{{ value_json['informationParams']['212'][1][0]
      [0] }}"
      unit_of_measurement: "kW"
      device_class: power
      state_class: measurement

    - name: "Heat pump COP"
      unique_id: '98e05155-0dd7-476c-bd62-37370a429f37'
      value_template: "{{ value_json['informationParams']['221'][1][0]
      [0] }}"
      state_class: measurement

#    - name: "Heat pump flow rate"
#      unique_id: '43071e0d-09db-4e90-ae85-acf83c125b5a'
#      value_template: "{{ value_json['informationParams']['231'][1][0]
#      [0] }}"
#      unit_of_measurement: "l/s"
#      device_class: volume_flow_rate
#      state_class: measurement

# Water flow rate in cuM/hr * 10

    - name: "Heatpump Flow Rate"
      unique_id: 'flowrate'
      value_template: "{{ value_json['data']['1211']['value'] }}"
      state_class: measurement

    - name: "Register65"
      unique_id: 'register65'
      value_template: "{{ value_json['data']['1212']['value'] }}"
      state_class: measurement

#    - name: "Register68"
#      unique_id: 'register68'
#      value_template: "{{ value_json['data']['1215']['value'] }}"
#      state_class: measurement

 #   - name: "Fan Speed2"
 #     unique_id: 'Fanspeed2'
 #     value_template: "{{ value_json['data']['1219']['value'] }}"
 #     unit_of_measurement: "rpm"
 #     state_class: measurement

    - name: "Target Flow Temp"
      unique_id: 'targetflowtemp'
      value_template: "{{ value_json['informationParams']['12'][1][0][0]}}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

# Circuit 1 calculated flow temp

    - name: "C1 Desired Heating LWT"
      unique_id: 'c1flow'
      value_template: "{{ value_json['informationParams']['93'][1][0][0]}}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

# Water pump is info 11

    - name: "Water Pump running"
      unique_id: 'pump_running'
      value_template: "{% set s = value_json['informationParams']['11'][1][0][0] %} {% if s == '2' %} {{'No'}} {% elif s=='0' %} {{'Yes'}} {% else %} {{s}} {% endif %}"
 
# Heating demanded?

    - name: "Heat Demanded"
      unique_id: 'heatdemanded'
      value_template: "{%set s= value_json['informationParams']['26'][1][0][0] %} {% if s == '1' %} {{'No'}} {% elif s == '0' %} {{'Yes'}} {% else %} {{s}} {% endif %}"

    - name: "Information26"
      unique_id: 'information26'
      value_template: "{%set s= value_json['informationParams']['26'][1][0][0] %} {% if s == '1' %} {{'No'}} {% elif s == '0' %} {{'Yes'}} {% else %} {{s}} {% endif %}"
#      value_template: "{{ value_json['informationParams']['26'][1][0][0]}}"

# duplicate of 094 - CH valve state?

    - name: "CH or DHW"
      unique_id: 'chordhw'
      value_template: "{%set s= value_json['informationParams']['13'][1][0][0] %} {% if s == '1' %} {{'CH'}} {% elif s== '0' %} {{'HW'}} {% else %} {{s}} {% endif %}"

    - name: "Information13"
      unique_id: 'information13'
      value_template: "{%set s= value_json['informationParams']['13'][1][0][0] %} {% if s == '1' %} {{'CH'}} {% elif s== '0' %} {{'HW'}} {% else %} {{s}} {% endif %}"

# the following is also apparently under parameter 24,72 and 81 !!

    - name: "Actual Flow Temp"
      unique_id: 'actualflowtemp'
      value_template: "{{ value_json['informationParams']['14'][1][0][0]}}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

# the following is also apparently under parameter 25, and 91 !!

    - name: "Actual Return Temp"
      unique_id: 'actualreturntemp'
      value_template: "{{ value_json['informationParams']['15'][1][0][0]}}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

#      water pump runtime hrs, since last power cycle
#    - name: "Information201202"
#      unique_id: 'information201202'
#      value_template: "{{ value_json['informationParams']['201'][1][0][0]}}"

#    - name: "Information2032042"
#      unique_id: 'information203204'
#      value_template: "{{ value_json['informationParams']['203'][1][0][0]}}"

#    - name: "Heating Energy"
#      unique_id: 'information203'
#      value_template: "{{ value_json['informationParams']['203'][1][0][0] | float / 1000}}"
#      unit_of_measurement: "kWh"
#      device_class: energy
#      state_class: measurement

#    - name: "DHW Heating Energy"
#      unique_id: 'information204'
#      value_template: "{{ value_json['informationParams']['204'][1][0][0] | float / 1000}}"
#      unit_of_measurement: "kWh"
#      device_class: energy
#      state_class: measurement

# compressor Hz?

    - name: "Compressor Freq"
      unique_id: 'compressor freq'
      value_template: "{{ value_json['informationParams']['21'][1][0][0]}}"
      unit_of_measurement: "Hz"
      device_class: frequency
      state_class: measurement

    - name: "Information21"
      unique_id: 'information21'
      value_template: "{{ value_json['informationParams']['21'][1][0][0]}}"
      unit_of_measurement: "Hz"
      device_class: frequency
      state_class: measurement

    - name: "Actual DHW Temp"
      unique_id: 'actualdhwtemp'
      value_template: "{{ value_json['informationParams']['61'][1][0][0]}}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

# CH Valve State?

    - name: "Information94"
      unique_id: 'information94'
      value_template: "{{ value_json['informationParams']['94'][1][0][0]}}"

    - name: "Information95"
      unique_id: 'information95'
      value_template: "{{ value_json['informationParams']['95'][1][0][0]}}"

    - name: "HP reported Ambient"
      unique_id: 'hpambienttemp'
      value_template: "{{ value_json['informationParams']['23'][1][0][0]}}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

    - name: "DHW Load time"
      unique_id: 'dhw load time'
      value_template: "{{ value_json['data']['113']['value'] }}"
      state_class: measurement

    - name: "DHW start 1 loading"
      unique_id: 'dhw start load'
      value_template: "{{ value_json['data']['115']['value'] }}"

    - name: "DHW work mode"
      unique_id: 'dhw work mode'
      value_template: "{% set s= value_json['data']['119']['value'] %} {% if s==2 %} {{'Scheduled'}} {% elif s==1 %}  {{'On'}} {% elif s==0 %} {{'Off'}} {% else %} {{s}} {% endif %}"

    - name: "Circuit1 work mode"
      unique_id: 'c1 work mode'
      value_template: "{% set s= value_json['data']['236']['value'] %}  {% if s==3 %} {{'Scheduled'}} {% elif s==1 %} {{'Day'}} {% elif s==2 %} {{'Night'}} {% elif s==0 %} {{'Off'}} {% else %} {{s}} {% endif %}" 

- authentication: basic
  username: "admin"
  password: "admin"
  scan_interval: 30
  resource: http://192.168.86.31/econet/regParams
  sensor:
 #   - name: "Hot water cylinder"
 #     unique_id: 'b9c0657f-e4cb-460d-b10f-f39092f5be62'
 #     value_template: "{{ value_json.curr.TempCWU }}"
 #     unit_of_measurement: "°C"
 #     device_class: temperature
 #     state_class: measurement

    - name: "Exterior weather sensor"
      unique_id: '230ae67e-169a-4a26-98b1-851d9f39492c'
      value_template: "{{ value_json.curr.TempWthr }}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

# 1 if (water circulation) pump is on
#    - name: "AxenUpperPump"
#      unique_id: 'axenupperpump'
#      value_template: "{{ value_json.curr.AxenUpperPump }}"
#      unit_of_measurement: "rpm"
#      state_class: measurement

#    - name: "Target flow temperature"
#      unique_id: 'a41f64ea-f29c-46b3-a29c-eb575f5b623f'
#      value_template: "{{ value_json.curr.HeatSourceCalcPresetTemp }}"
#      unit_of_measurement: "°C"
#      device_class: temperature
#      state_class: measurement

#    - name: "Heat pump inlet temperature"
#      unique_id: '5755ad9c-5707-4754-9920-74e6fc499616'
#      value_template: "{{ value_json.curr.AxenReturnTemp }}"
#      unit_of_measurement: "°C"
#      device_class: temperature
#      state_class: measurement

#    - name: "Heat pump outlet temperature"
#      unique_id: '2d68ee3a-6345-4d1e-949d-7952ad61f866'
#      value_template: "{{ value_json.curr.AxenOutgoingTemp }}"
#      unit_of_measurement: "°C"
#      device_class: temperature
#      state_class: measurement

#    - name: "Heat pump compressor frequency"
#      unique_id: '7786493f-70bd-4b87-9ad8-848a340aed23'
#      value_template: "{{ value_json.curr.AxenCompressorFreq }}"
#      unit_of_measurement: "Hz"
#      device_class: frequency
#      state_class: measurement

    - name: "Panel thermostat Temperature"
      unique_id: '4d98cf06-6b87-4193-9d0e-7ccf9c355386'
      value_template: "{{ value_json.curr.Circuit1thermostat }}"
      unit_of_measurement: "°C"
      device_class: temperature
      state_class: measurement

    - name: "Heat pump valve state"
      unique_id: 'c1659951-b9b7-4bad-bdf8-ea5bc9dc30f4'
      value_template: "{{ value_json.curr.flapValveStates}}"
      device_class: enum

    - name: "Heat pump work state"
      unique_id: '3d61585c-47f7-42c8-9ca1-81dab1103680'
      value_template: "{% set s= value_json.curr.AxenWorkState %} {% if s==2 %} {{'Scheduled'}} {% elif s==1 %}  {{'On'}} {% elif s==0 %} {{'Off'}} {% else %} {{s}} {% endif %}"

While onboard metrics are very intersting the sensors are not very accurate. COP figures should be ignored.

HA REST is working really well for me. Any speculation on Register65 and the information ones? some like 13 and 21 look like duplicates of CH or DHW and Compressor Freq.

Register 65 is always 0 for me.
Information 13 is either CH or DHW
Information 21 is duplicate of compressor freq
Information 26 is always Yes for me.
Information 94 is “On” during CH and “Off” during DHW
Information 95 is always 1 for me.

Thanks to all for sharing their work on this. Has anyone figured out which data in the REST output is the circulation pump PWM %?

P.S. Very quick and dirty emonhub interfacer for the Econet local http api at emonhub/src/interfacers/EmonHubEconet300Interfacer.py at local-production · dconlon/emonhub · GitHub. It seems like most folk are using HA these days but I’m happy to tune it up and submit a PR if it gets used.

Mmm I’m not sure, maybe @GSV3MiaC would know? I’m also interested to know if system water pressure metric is available.

That would be awesome! :folded_hands:

HA is great, but Emoncms is much better for data logging and detailed multigraphing with statistics etc. Although maybe I am biased :slight_smile:

System pressure would be very useful. There’s a bunch of pressures/temps in the engineer (1234) menu for the refrigerant side which I can’t think of a use case for now but I’d still graph them if I could! I expect they are all in the JSON but it’ll take a bit of time to figure out what is what.

Okay it’ll be a couple of weeks but I’ll find some time to make a decent job of it and send it through. I’m an emonhub fan, it’s a nice lightweight bridge between varied data sources and Emoncms/MQTT so thanks for your efforts :

1 Like

There are a whole bunch of sensors in the 1234 engineer menu but they are not exposed in any of the econet endpoints I know about. In particular I can’t find pressure or pump PWM data (both directions, the ‘pwm feedback %’ is documented elsewhere as advising the status of the pump).

In the meantime, to keep HA users amused, these are the RESTful commands I have found a use for (this needs inserting in config.yaml, and then the IP address needs changed to whatever your econet is at). Use at own risk! You call them from HA using the YAML syntax in a script:

action: rest_command.set_ch1_night_temp
data:
value: “{{new_target}}”
response_variable: rest_response

What you do with the response variable is up to you (you may not even want one).

hopefully the rather critical indentation survives the pasting ..

rest_command:
  set_dhw_temp:
    username: "admin"
    password: "admin"
    method: put
    url: "http://192.168.1.25/econet/newParam?newParamName=103&newParamValue={{value}}&_=UID"

  set_dhw_hysteresis:
    username: "admin"
    password: "admin"
    method: put
    url: "http://192.168.1.25/econet/newParam?newParamName=104&newParamValue={{value}}&_=UID"

# 0 =off, 1=day, 2=night, 3=scheduled
  set_ch1_work_state:
    username: "admin"
    password: "admin"
    method: put
    url: "http://192.168.1.25/econet/newParam?newParamName=236&newParamValue={{value}}&_=UID"

# 0 =off, 1=on, 2=scheduled
  set_dhw_work_state:
    username: "admin"
    password: "admin"
    method: put
    url: "http://192.168.1.25/econet/newParam?newParamName=119&newParamValue={{value}}&_=UID"

  set_ch1_day_temp:
    username: "admin"
    password: "admin"
    method: put
    url: "http://192.168.1.25/econet/newParam?newParamName=238&newParamValue={{value}}&_=UID"

  set_ch1_night_temp:
    username: "admin"
    password: "admin"
    method: put
    url: "http://192.168.1.25/econet/newParam?newParamName=239&newParamValue={{value}}&_=UID"

  set_ch1_hysteresis:
    username: "admin"
    password: "admin"
    method: put
    url: "http://192.168.1.25/econet/newParam?newParamName=240&newParamValue={{value}}&_=UID"

  set_ch1_curve:
    username: "admin"
    password: "admin"
    method: put
    url: "http://192.168.1.25/econet/newParam?newParamName=273&newParamValue={{value}}&_=UID"

  set_ch1_curve_shift:
    username: "admin"
    password: "admin"
    method: put
    url: "http://192.168.1.25/econet/newParam?newParamName=275&newParamValue={{value}}&_=UID"

  boost_dhw:
    username: "admin"
    password: "admin"
    method: put
    url: "http://192.168.1.25/econet/newParam?newParamName=115&newParamValue=1&_=UID"

This lets me turn on/off CH (off before switch to DHW avoids some valve noise), and potentially vary the WC curve and offset based on a LOT of parameters, other than just what the thermostat thinks is happening in one room. OK, I admit this is buying a dog and barking yourself. :grinning_face:

1 Like

I’ve been working on integrating some sensors, numbers and selects for ecomax360i controller to the econet300 hacs integration: https://github.com/LeeNuss/ecoNET-300-Home-Assistant-Integration/tree/feature/sensors-inputs-ecomax360i
Controls are still bit clunky and needs thorougher testing, but the basics work. Happy to extend the available entities if anyone wants to use the integration

Ah cool, nice work. What’s the easiest way to test this via HACS?

you should be able to install it via hacs by adding https://github.com/LeeNuss/ecoNET-300-Home-Assistant-Integration as custom repo, make sure to remove jontofront’s original integration. Then download tag 1.2.0-a-ecomax360-1 (click “Need a different version”), restart & add device as usual with econet300 integration. hope that works, I currently can’t verify installing it via the hacs

Ok great, are you going to try and get jontofront’ to merge these changes into his main repo?

yeah that’s definitely the plan, but it might take a while to get that merged. The different api endpoint and his recent changes means there’s a decent amount of refactoring to do. I’ll keep working on supporting more functionality of the controller so it’s at least usable from my fork until merged.

1 Like

Firstly, my HP was installed just over a week ago and this integration has helped me loads!
I tried to install via HACS and it wouldn’t work. I don’t know if it’s because I previously had the jontofront original installed.

I manually installed from your dev branch and it’s working well. Now I’ll need to have a dig around to see if I can contribute in any way.

Thanks!