eGauge Power Meter sensors over local REST API

eGauge is a building energy monitoring platform, not the cheapest, but high accuracy and very reliable (I’ve had one unit running for over 12 years continuously, and another at 8 years). They present data on the network over modbus, BACnet, and a local REST api, as well as an optional cloud platform.

For this simple integration I’m using the REST API, and the “rest” sensor platform in HA Core.

Initial Setup

Ensure that your eGauge is configured properly and visible on the network. Refer to their install manual to get everything up and running. Once things are working the way you want on the eGauge itself, you can proceed with the HA integration.

Visit the API URL in your browser to test the results:

Note: we are using the inst and tot parameters to get more detail in the query - see the documentation for examples.

Example XML output when viewing the REST API URL in the browser:

<data serial="0x5555555">
  <ts>1601133813</ts>
  <r t="P" n="Grid" did="0">
    <v>9941246985</v>
    <i>-789</i>
  </r>
  <r t="P" n="Solar" did="1">
    <v>10367491077</v>
    <i>1608</i>
  </r>
  <r t="P" n="Mini Split" did="2">
    <v>-457926256</v>
    <i>-240</i>
  </r>
  <r rt="total" t="P" n="Total Usage">
    <v>20308738062</v>
    <i>819.000</i>
  </r>
  <r rt="total" t="P" n="Total Generation">
    <v>10367491077</v>
    <i>1608.000</i>
  </r>
</data>

I have 5 registers setup in my eGauge, grid, solar and my mini split AC, as well as the default Total Generation and Total Usage registers. Your registers will be different but similar. The <i> readings are instantaneous power in watts. Negative means consuming energy, positive is generating.

Make a note of the order that your registers are in - this will be important when setting up the HA sensors to read each value in order.

We will use the HA rest sensor platform to query this url, convert XML to JSON and then extract the values we want using template sensors. We will also use the templates to reverse the sign of some readings and round the result for a nicer output.

Configure the rest and template sensors in Home Assistant

Below is the extract from my configuration.yaml:

# sensors from eGauge via API https://www.egauge.net/media/support/docs/egauge-xml-api.pdf
  - platform: rest
    name: egauge_meter
    resource: http://egaugeXYZ.local/cgi-bin/egauge?inst&tot
    json_attributes:
      - data
    value_template: 'OK'
# these sensors extract the individual attributes from the egauge_meter sensor, and format them using templates
  - platform: template
    sensors:
      grid_power:
        unique_id: grid_power
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][0]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      solar_power:
        unique_id: solar_power
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][1]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      minisplit_power:
        unique_id: minisplit_power
        value_template: '{{ (states.sensor.egauge_meter.attributes["data"]["r"][2]["i"]|float * -1)|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      total_usage:
        unique_id: total_usage
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][3]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      total_generation:
        unique_id: total_generation
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][4]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'

What is happening here?

  1. We use a single rest sensor to pull in the entire XML query, and format it as json data. This is better than using multiple rest sensors, because we only have to query the eGauge once. This sensor isn’t directly used in your automations and front end, since it just gives an “OK” or “unavailable” result, and stores the entire text of the json query. You will need to add your device url.

  2. Then we use template sensors to extract the individual readings from the json in the rest sensor. In each template you see the text {{ states.sensor.egauge_meter.attributes["data"]["r"][0]["i"]|round(0) }}. This means "from the attributes of the egauge_meter sensor, extract the data from i, inside the first (number 0) r, inside data. Then, round to the nearest integer.

  3. Edit the names, unique_ids and the [number] in the template to correspond to the order of sensors in your raw api output. The float * -1 you see in some changes the sign, if you want to invert any values.

Results:

Troubleshooting:

  1. First make sure your eGauge is setup properly, and that you can see the XML result when visiting the URL. If that isn’t working yet than the rest won’t do anything.

  2. Then, work on getting the rest sensor working. It will pull the XML data and reformat as json, and then store the entire json values as an attribute in the sensor, and it will have a main value of “OK” or “unavailable”. If it isn’t working, check the sensor formatting and the URL. You should get a sensor that looks like this in the configuration:

  1. Once that is working, get the template sensors going to extract each value. Experiment with the syntax in the template by trying out values in the Developer -> Template area of the HA configuration, that way you can see if you are getting the value you expect out of the egauge_sensor's json data without having to reload over and over.

Happy metering!

2 Likes

Wow, this is very extensive. Thank you so much for sharing. I have been curious if anyone else out there was using an eGauge. I had a command line basic readout using simple python code, but this is more elegant and functional. Will give it the world tomorrow and let you know how it works. I really like my eGauge and have deployed every available register.

Let me know how it works, this is the first time I’ve posted about a solution or integration. eGauges are a bit of an “old reliable” for me, they just don’t seem to ever die, and support a nice combination of local features.

Used your approach today and it works like a charm. A few new automations are now possible, such as turning kitchen HUE lights at 100% if the cooktop or oven are being used, while there is motion detected in the area.
Thanks again for sharing.

That was fast!

Here is another one you might like - I use a binary sensor to give me an “on/off” for my mini split AC (which is then used by Smart IR or other automations), and I use a template sensor to split the power up into ranges - Off, Fan Only, Low, Medium and High, based on the power output (I set the wattages for each power just by watching the unit for a few days and eyeballing the right values):

image

sensor:
  - platform: template
    sensors:
      minisplit_mode:
        unique_id: minisplit_mode
        friendly_name: "Minisplit Mode"
        value_template: >-
          {% if states('sensor.minisplit_power') | float > 700 %}
            High
          {% elif states('sensor.minisplit_power') | float > 350 %}
            Medium
          {% elif states('sensor.minisplit_power') | float > 150 %}
            Low
          {% elif states('sensor.minisplit_power') | float > 7 %}
            Fan Only
          {% else %}
            Off
          {% endif %}
binary_sensor:
  - platform: template
    sensors:
      minisplit_on:
        unique_id: minisplit_on
        device_class: power
        friendly_name: "Mini Split State"
        value_template: "{{ states('sensor.minisplit_power')|float > 7 }}"
        delay_off:
          seconds: 20
1 Like

Hope this thread still has eyes. I recently ran across it while reading up on HA and placed it on the
back burner while trying a few things to get started. I have a PV system with a egauge providing data on power generated and power consumed. I’d like to capture these in HA and so started working to do so.
I verified access to the device’s XML when accessing the url -

<data serial="0x709a27ea">
<ts>1605273951</ts>
<r t="P" n="Grid" did="0">
<v>135665034241</v>
<i>690</i>
</r>
<r t="P" n="Solar" did="1">
<v>167489209564</v>
<i>-7</i>
</r>
<r t="P" n="Solar+" did="2">
<v>167844148745</v>
<i>0</i>
</r>
<r t="#" n="Connection Quality" did="3">
<v>7074385411</v>
<i>100</i>
</r>
<r t="#" n="Temp" did="4">
<v>3732017487</v>
<i>31</i>
</r>
<r rt="total" t="P" n="Total Usage">
<v>136019973422</v>
<i>697.000</i>
</r>
<r rt="total" t="P" n="Total Generation">
<v>167489209564</v>
<i>-7.000</i>
</r>
</data>

I had added a couple of registers to the device some time back for temperature and connection quality so have the above.
I then took the example provided in this thread to make it specific to my system:

# sensors from eGauge via API https://www.egauge.net/media/support/docs/egauge-xml-api.pdf
  - platform: rest
    name: egauge_meter
    resource: http://egaugeofmine.local/cgi-bin/egauge?inst&tot
    json_attributes:
      - data
    value_template: 'OK'
# these sensors extract the individual attributes from the egauge_meter sensor, and format them using templates
  - platform: template
    sensors:
      grid_power:
        unique_id: Grid
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][0]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      solar_power:
        unique_id: Solar
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][1]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      Solar+:
        unique_id: Solar+
        value_template: '{{ (states.sensor.egauge_meter.attributes["data"]["r"][2]["i"]|float * -1)|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      connection_quality:
        unique_id: Connection_quality
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][3]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      temp:
        unique_id: temp
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][4]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'C'
      total_usage:
        unique_id: total_usage
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][3]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      total_generation:
        unique_id: total_generation
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][3]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'

With this in my configuration.yaml I receive the error on startup that states:

2020-11-13 07:15:16 ERROR (MainThread) [homeassistant.config] Invalid config for [sensor.template]: invalid slug Solar+ (try solar) for dictionary value @ data[‘sensors’]. Got OrderedDict([(‘grid_power’, OrderedDict([(‘unique_id’, ‘Grid’), (‘value_template’, ‘{{ states.sensor.egauge_meter.attributes[“data”][“r”][0][“i”]|round(0) }}’), (‘device_class’, ‘Power’), (‘unit_of_measurement’, ‘W’)])), (‘solar_power’, OrderedDict([(‘unique_id’, ‘Solar’), (‘value_template’, ‘{{ states.sensor.egauge_meter.attributes[“data”][“r”][1][“i”]|round(0) }}’), (‘device_class’, ‘Power’), (‘unit_of_measurement’, ‘W’)])), (‘Solar+’, OrderedDict([(‘unique_id’, ‘Solar+’), (‘value_template’… (See /config/configuration.yaml, line 34). Please check the docs at https://www.home-assistant.io/integrations/template

Maybe something has changed in HA that causes this error to surface. Not sure. I am hoping those in this thread that have this configured can tell me.
In HA in Developer Tools I have one (I assume it’s a truncated result because of the error) sensor for sensor.egauge_meter and data returned:

data:
@serial’: ‘0x709a27ea’
ts: ‘1605274466’
r:
- ‘@t’: P
@n’: Grid
@did’: ‘0’
v: ‘135665411581’
i: ‘754’
- ‘@t’: P
@n’: Solar
@did’: ‘1’
v: ‘167489206224’
i: ‘-6’
- ‘@t’: P
@n’: Solar+
@did’: ‘2’
v: ‘167844148745’
i: ‘0’
- ‘@t’: ‘#’
@n’: Connection Quality
@did’: ‘3’
v: ‘7074424911’
i: ‘100’
- ‘@t’: ‘#’
@n’: Temp
@did’: ‘4’
v: ‘3732033452’
i: ‘31’
- ‘@rt’: total
@t’: P
@n’: Total Usage
v: ‘136020354102’
i: ‘760.000’
- ‘@rt’: total
@t’: P
@n’: Total Generation
v: ‘167489206224’
i: ‘-6.000’
friendly_name: egauge_meter

So it seems it is partially working but am stumped on the error and how to fix. If anyone has any thoughts or suggestions I would appreciate them.
Thanks in advance.

Hi bill,

Glad to see another egauge user! I see two issues with your config that could be causing trouble:

      Solar+:
        unique_id: Solar+
        value_template: '{{ (states.sensor.egauge_meter.attributes["data"]["r"][2]["i"]|float * -1)|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'

In this section, I have a hunch that “+” is a special character that can’t be used in sensor names or IDs. Try changing to something like SolarPlus.

Lower down, in this section:

      total_usage:
        unique_id: total_usage
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][3]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      total_generation:
        unique_id: total_generation
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][3]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'

The [3] in the value_template indicates which register should be pulled, just in the order they are delivered, so your first sensor will be [0], the next [1], etc. By my count these last two should be [5] and [6].

A few other small tweaks that aren’t the cause of your error but might help:

  • Change the Device Class of the temp sensor to “Temperature”
  • Remove the device class and unit from Connection_quality, it isn’t needed there

Give those a try and see if the entities start populating.

-Sam

Sam

Thanks so much for the suggestions. I edited my entry in the configuration.yaml per your advice to -

# sensors from eGauge via API https://www.egauge.net/media/support/docs/egauge-xml-api.pdf
  - platform: rest
    name: egauge_meter
    resource: http://lg1789.d.lighthousesolar.com/cgi-bin/egauge?inst&tot
    json_attributes:
      - data
    value_template: 'OK'
# these sensors extract the individual attributes from the egauge_meter sensor, and format them using templates
  - platform: template
    sensors:
      grid_power:
        unique_id: Grid
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][0]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      solar_power:
        unique_id: Solar
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][1]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      Solar+:
        unique_id: SolarPlus
        value_template: '{{ (states.sensor.egauge_meter.attributes["data"]["r"][2]["i"]|float * -1)|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      connection_quality:
        unique_id: Connection_quality
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][3]["i"]|round(0) }}'
      temp:
        unique_id: temp
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][4]["i"]|round(0) }}'
        device_class: Temperature
        unit_of_measurement: 'C'
      total_usage:
        unique_id: total_usage
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][5]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'
      total_generation:
        unique_id: total_generation
        value_template: '{{ states.sensor.egauge_meter.attributes["data"]["r"][6]["i"]|round(0) }}'
        device_class: Power
        unit_of_measurement: 'W'

However upon restart the error remains:

2020-11-13 11:19:37 ERROR (MainThread) [homeassistant.config] Invalid config for [sensor.template]: invalid slug Solar+ (try solar) for dictionary value @ data['sensors']. Got OrderedDict([('grid_power', OrderedDict([('unique_id', 'Grid'), ('value_template', '{{ states.sensor.egauge_meter.attributes["data"]["r"][0]["i"]|round(0) }}'), ('device_class', 'Power'), ('unit_of_measurement', 'W')])), ('solar_power', OrderedDict([('unique_id', 'Solar'), ('value_template', '{{ states.sensor.egauge_meter.attributes["data"]["r"][1]["i"]|round(0) }}'), ('device_class', 'Power'), ('unit_of_measurement', 'W')])), ('Solar+', OrderedDict([('unique_id', 'SolarPlus'), ('value_templa.... (See /config/configuration.yaml, line 34). Please check the docs at https://www.home-assistant.io/integrations/template

Notice that Solar+ is returned in the XML from the device. Looking at the egauge docs is seems it’s something that was configured there.

When I look at my registers on the device I don’t actually see it.

Hope my images make it. If not, let me know and I’ll place them somewhere else.

Try changing the top level Solar+ to SolarPlus as well, I think that one is triggering the error. It does not have to match the name in your XML result - the template pulls the values by number, not name.

1 Like

Worked like a charm! Thanks so much. Wife and I headed out for a meal for our 42nd anniversary soon. She’ll see my smile but never guess what I’m grinning about! Thanks so much.

1 Like

Happy anniversary, glad I could help!

Another eGauge user here. Thanks for this, @phidauex. This is just excellent! I’ve had an eGauge 3000 since late 2015 when we got our solar panels installed.

One thing I’ve noticed in your graphs, and mine as well, is that the Total Generated goes negative. For me it’s currently night and my total generated is floating between -8 and -6W. Curious why this is given the system is supposedly shut down, but perhaps the optimizers (I have 31 of them, one for each panel) are drawing power? No idea. This isn’t an issue with Home Assistant, this is what the eGauge is reporting.

Glad it was helpful!

As for the negative generation, this is normal - basically the inverter has to stay partially on in order to detect when irradiance comes up in the morning and start switching the main systems on. The few watts you are seeing is just the internal draw of the start-up microcontroller. If you shut off the PV breaker you’d see that go down to zero (but then you’d need to manually start the inverter each morning, not recommended).

On utility scale PV systems the nighttime consumption is higher because the transformers in the system consume energy to stay magnetized, so for instance my 20 MW systems (the ones without grid batteries, at least) consume about 20 kW at night!

1 Like

Really nice work here. I had an eGauge installed with my solar system, and I started with something very similar. I just finished putting together a custom component that should make setting this up a little easier. It also supports historical data.

Please give it a shot. Dedicated thread over here

Has anyone tried the new ENERGY Dashboard launched with version 2021.8.1 ?

Seems promising but none of my egauge sensors are showing: