Custom Component: IoTaWatt Energy Monitor integration

This makes no sense whatsoever, I have created sensors using all integration methods. The results are wildly different.

The iotawatt Graph+ interface gives me for the daily export: 3.9kWh and 19.3kWh for import.

I think the calculation using the right method got wildly wrong because I rebooted the HA twice today (was adding new sensors) and due to the bug above, it count things multiple times.

If a sensor is unavailable the template doesn’t set it to 0

So it would appear that left is the way to go then?

This is what the powercalc sensor ( GitHub - bramstroker/homeassistant-powercalc: Custom component to calculate estimated power consumption of lights and other appliances ) does. It updates every 10mins (default can change with an option). Might need to open an issue on this integeration in github? Edit: I see you have done that. Ill add to the conversation.

That may be true for some cases, but it’s definitely not what I’m seeing for the template I’m using in combination sur the utility_meter and the integration integration.
It reads a value, followed by 0, then another value

I took a screenshot earlier which I unfortunately can’t find now where you can clearly see the original IotaWatt output sensor going steadily up, with a few gaps in the middle following a restart of HA.
And the template sensor that takes the absolute value of it, see its value go back to 0 wherever there was a gap in the original value.

That totally screws up the utility_meter integration.

For export, it seems so.
Yesterday, I restarted the HA during the day, and on restart the “integration” integration doing W → Wh added another extra 1kWh ; I ended up with the right method being 3kWh more than reality.

This is now, 3 hours after my solar panels started producing energy:

the real value is 1.64kWh
The right method isn’t just inaccurate, it’s totally nonsensical
In fact, I have no explanation on what it is doing, other than there’s a bug somewhere. How could it be so wrong?

The first recorded value is totally wrong to start with:

the reason for that is that the last value the original templates recorded was 0 at midnight, and then 1.67kWh at 9AM ; nothing in between. It took the first reading and assumed that was the average of the last 9 hours.
And it did so again 15 minutes later doubling the value instantly.
This is based on this sensor:
sensor.ower_grid_export which is defined as:

    power_grid_export:
      friendly_name: "Grid Power Export"
      unit_of_measurement: W
      device_class: power
      value_template: "{{ states('sensor.iotawatt_output_export')|float|abs }}"
      availability_template: "{{ states('sensor.iotawatt_output_export') not in ['unavailable', 'unknown', 'none' ] }}"
      attribute_templates:
        last_reset: "{{ state_attr('sensor.iotawatt_output_export', 'last_reset') }}"
        state_class: "{{ state_attr('sensor.iotawatt_output_export', 'state_class') }}"

the plot shows:

So I can’t explain what the right method does; but it’s very broken.

Here is the code:

try:
                # integration as the Riemann integral of previous measures.
                area = 0
                elapsed_time = (
                    new_state.last_updated - old_state.last_updated
                ).total_seconds()

                if self._method == TRAPEZOIDAL_METHOD:
                    area = (
                        (Decimal(new_state.state) + Decimal(old_state.state))
                        * Decimal(elapsed_time)
                        / 2
                    )
                elif self._method == LEFT_METHOD:
                    area = Decimal(old_state.state) * Decimal(elapsed_time)
                elif self._method == RIGHT_METHOD:
                    area = Decimal(new_state.state) * Decimal(elapsed_time)

                integral = area / (self._unit_prefix * self._unit_time)
                assert isinstance(integral, Decimal)
            except ValueError as err:
                _LOGGER.warning("While calculating integration: %s", err)
            except DecimalException as err:
                _LOGGER.warning(
                    "Invalid state (%s > %s): %s", old_state.state, new_state.state, err
                )
            except AssertionError as err:
                _LOGGER.error("Could not calculate integral: %s", err)
            else:
                self._state += integral
                self.async_write_ha_state()

So to me it looks like the right method just takes the new state and yes assumes that has been the value since the last update. Left appears to take the state immediately prior to the update and assume that has been the value since the last update. Trapezoidal takes the average of the two states and assumes that has been the value for the whole time.
So it is explainable why the huge jump for you when a reading comes in after nine hours (And I would have expected Trapezoidal to do a similar thing (halved)?). Note sure what happened after that because it should have settled down. Regardless if the IotaWatt integration can keep updating the state regularly then this should be fixed.

I lodged Riemann Sum right integration providing unexpected result · Issue #55130 · home-assistant/core · GitHub
Edit: closed that bug, the issue is with the iotawatt integration

Turned out, the bug is in this IotaWatt integration.
It doesn’t update the sensor if its value didn’t change; which makes it rather incompatible with the integration system
I opened Sensor state isn't updated unless the value change. · Issue #16 · gtdiehl/iotawatt_ha · GitHub

@jyavenard I merged the code changes and released a new IoTaWatt release through HACS. Does it fix the issue?

On a side note and exciting news. The IoTaWatt integration will be added to Home Assistant in the next release or two. I’m not sure if it’ll make it in 2021.9 or 2021.10.

The PR has had some comments and suggestions from the devs. I have made some good progress in resolving them and trying to fix some smaller issues that are in the current integration.

If any fixes are made they will appear in both the custom integration and the official one until the integration is released in Home Assistant. At that time I’ll deprecate the custom integration.

5 Likes

Happy to help if needed. I made some rather major changes in both the integration and iotawattpy

I’ve pushed the modifications to GitHub - jyavenard/iotawatt_ha at IntegrateLocally and GitHub - jyavenard/iotawattpy at AddEnergyReadout respectively.

This creates a 3rd entity for power entities that will construct a high resolution readout of the output and don’t face the issues mentioned in the thread when reading all from January 1st of the year.

I’ve handled cases where if the iota watt will become unresponsive or unreachable for a while, it will retrieve the missing data since the last update.

I’m considering if it’s required to handle the case where the HA instance is down for a while (like what could happen during an update), which is on restart, the HA will rebuild the missing data.

I’m waiting for a few days to see how that work locally. I’m pretty pleased already in that I get much better data for the import/export calculations.

@jyavenard Great I will take a look this week. Need to catch up on some school work, been a bit behind spending too much time with the review comments. I don’t mind though it’s fun and I’m learning!

An update on the release of the integration with Home Assistant. The code was reviewed and has been approved and merged into the latest Home Assistant beta build, 2021.9.0b6.

With the 2021.9 release (if you want to use the bundled integration) you will need to remove the custom integration, reboot HA, and run the setup from the Integrations area.

I’m hoping this won’t be too painful :sweat:

5 Likes

Just a heads up to anyone checking this post before migrating to the official one, you need to make some custom additions to your config.yaml file for each output you have (not just the mains). Just wanted to say thanks again for all of the work on this, it’s been great so far and i’m happy that it’s gone official!

EDIT: One other thing to note is that you’ll lose all of your historical data. There doesn’t seem to be a way to tell HA that the name of a sensor has change but that it’s the same data source.

@djuniah What changes do you need to make?

Sorry, i edited my post because I had made a mistake. Things seem to be working now after manually adding all of my outputs to the config.yaml file like they mention on this page: IoTaWatt - Home Assistant

I didn’t realize that it needed to be done for each and every output (which in hindsight makes sense). Also, it seems like any custom outputs aren’t included in the list from the integrations menu. They’re just sensors not tied to anything specific. For example, in iotawatt, I created an output called “Unknown Load” which is the mains minus all of the circuits that I’m monitoring (i don’t monitor all of them) and i had to search outside of the integrations list as it didn’t show up in there.

@djuniah There is a difference between the Inputs and Outputs currently. The underlying issue that there is only a Unique ID for the Inputs. Since only entities in Home Assistant with Unique IDs can be renamed and assigned, the Outputs are not grouped with the Inputs in the Entities page. There is an Issue #55489, which the result is a firmware update will send an ID so the Outputs have a Unique ID in Home Assistant.

Another change between the custom_integration and the official one is the removal of appending iotawatt_{I/O Type}_ to the sensor name. For example if you had sensor.iotawatt_input_spa it would be changed sensor.spa. Was this the reason you had to change the names in your config?

What is mentioned in the https://www.home-assistant.io/integrations/iotawatt/ page is for Solar systems where IoTaWatt is monitoring a single circuit that is both importing and exporting. The creation of two sensors is to split the positive and negative into two sensors so that you can use the sensors in the Energy Dashboard.

Any other issues you may have had?

I’m getting an error (or at least a warning) when adding my sensors as described above - the error/warning states -

Unexpected state class
The following entities do not have the expected state class ‘total_increasing’

  • sensor.iotawatt_output_mainsconsumption_wh (measurement)
  • sensor.iotawatt_output_mainsexport_wh (measurement)

I had to add entries for each CT clamp and output into my config file before they would show up as being eligible for entry in the energy dashboard. It doesn’t seem like it’s just a solar thing. This is the section I was referring to “Add the following to your configuration.yaml file to convert the Watt measurements into kWh:” Without doing that, none of my inputs/outputs were available to be selected on the energy dashboard. The sensor name change wasn’t related to what i had to do that. I assume there’s no way to migrate and keep the old data due to them having unique IDs right?