diff --git a/homeassistant/components/growatt_server/sensor.py b/homeassistant/components/growatt_server/sensor.py index ac19d91b24d..d6b74b78475 100644 --- a/homeassistant/components/growatt_server/sensor.py +++ b/homeassistant/components/growatt_server/sensor.py @@ -159,7 +159,7 @@ class GrowattInverter(SensorEntity): @property def native_value(self): """Return the state of the sensor.""" - result = self.probe.get_data(self.entity_description.api_key) + result = self.probe.get_data(self.entity_description) if self.entity_description.precision is not None: result = round(result, self.entity_description.precision) return result @@ -168,7 +168,7 @@ class GrowattInverter(SensorEntity): def native_unit_of_measurement(self) -> str | None: """Return the unit of measurement of the sensor, if any.""" if self.entity_description.currency: - return self.probe.get_data("currency") + return self.probe.get_currency() return super().native_unit_of_measurement def update(self) -> None: @@ -187,6 +187,7 @@ class GrowattData: self.device_id = device_id self.plant_id = None self.data = {} + self.previous_values = {} self.username = username self.password = password @@ -254,9 +255,61 @@ class GrowattData: **mix_detail, **dashboard_values_for_mix, } + _LOGGER.debug( + "Finished updating data for %s (%s)", + self.device_id, + self.growatt_type, + ) except json.decoder.JSONDecodeError: _LOGGER.error("Unable to fetch data from Growatt server") - def get_data(self, variable): + def get_currency(self): + """Get the currency.""" + return self.data.get("currency") + + def get_data(self, entity_description): """Get the data.""" - return self.data.get(variable) + _LOGGER.debug( + "Data request for: %s", + entity_description.name, + ) + variable = entity_description.api_key + api_value = self.data.get(variable) + previous_value = self.previous_values.get(variable) + return_value = api_value + + # If we have a 'drop threshold' specified, then check it and correct if needed + if ( + entity_description.previous_value_drop_threshold is not None + and previous_value is not None + and api_value is not None + ): + _LOGGER.debug( + "%s - Drop threshold specified (%s), checking for drop... API Value: %s, Previous Value: %s", + entity_description.name, + entity_description.previous_value_drop_threshold, + api_value, + previous_value, + ) + diff = float(api_value) - float(previous_value) + + # Check if the value has dropped (negative value i.e. < 0) and it has only dropped by a + # small amount, if so, use the previous value. + # Note - The energy dashboard takes care of drops within 10% of the current value, + # however if the value is low e.g. 0.2 and drops by 0.1 it classes as a reset. + if -(entity_description.previous_value_drop_threshold) <= diff < 0: + _LOGGER.debug( + "Diff is negative, but only by a small amount therefore not a nightly reset, " + "using previous value (%s) instead of api value (%s)", + previous_value, + api_value, + ) + return_value = previous_value + else: + _LOGGER.debug( + "%s - No drop detected, using API value", entity_description.name + ) + + self.previous_values[variable] = return_value + + return return_value diff --git a/homeassistant/components/growatt_server/sensor_types/mix.py b/homeassistant/components/growatt_server/sensor_types/mix.py index 6cb61ea2e08..75d816fdf60 100644 --- a/homeassistant/components/growatt_server/sensor_types/mix.py +++ b/homeassistant/components/growatt_server/sensor_types/mix.py @@ -241,5 +241,6 @@ MIX_SENSOR_TYPES: tuple[GrowattSensorEntityDescription, ...] = ( native_unit_of_measurement=ENERGY_KILO_WATT_HOUR, device_class=SensorDeviceClass.ENERGY, state_class=SensorStateClass.TOTAL_INCREASING, + previous_value_drop_threshold=0.2, ), ) diff --git a/homeassistant/components/growatt_server/sensor_types/sensor_entity_description.py b/homeassistant/components/growatt_server/sensor_types/sensor_entity_description.py index 04822fca35b..08a20209098 100644 --- a/homeassistant/components/growatt_server/sensor_types/sensor_entity_description.py +++ b/homeassistant/components/growatt_server/sensor_types/sensor_entity_description.py @@ -19,3 +19,4 @@ class GrowattSensorEntityDescription(SensorEntityDescription, GrowattRequiredKey precision: int | None = None currency: bool = False + previous_value_drop_threshold: float | None = None