diff --git a/custom_components/sensus_analytics/manifest.json b/custom_components/sensus_analytics/manifest.json index 8d51fb1..897879a 100644 --- a/custom_components/sensus_analytics/manifest.json +++ b/custom_components/sensus_analytics/manifest.json @@ -1,7 +1,7 @@ { "domain": "sensus_analytics", "name": "Sensus Analytics Integration", - "version": "1.4.0", + "version": "1.4.1", "documentation": "https://github.com/zestysoft/sensus_analytics_integration", "dependencies": [], "codeowners": ["@zestysoft"], diff --git a/custom_components/sensus_analytics/sensor.py b/custom_components/sensus_analytics/sensor.py index bab05cc..8863478 100644 --- a/custom_components/sensus_analytics/sensor.py +++ b/custom_components/sensus_analytics/sensor.py @@ -48,15 +48,24 @@ def __init__(self, coordinator: SensusAnalyticsDataUpdateCoordinator, entry: Con manufacturer="Unknown", model="Water Meter", ) + self.entry = entry def _convert_usage(self, usage): """Convert usage based on the configuration and native unit.""" + if usage is None: + return None usage_unit = self.coordinator.data.get("usageUnit") if usage_unit == "CF" and self.coordinator.config_entry.data.get("unit_type") == "G": - self._attr_native_unit_of_measurement = "G" return round(float(usage) * CF_TO_GALLON) return usage + def _get_usage_unit(self): + """Determine the unit of measurement for usage sensors.""" + usage_unit = self.coordinator.data.get("usageUnit") + if usage_unit == "CF" and self.coordinator.config_entry.data.get("unit_type") == "G": + return "G" + return usage_unit + class SensusAnalyticsDailyUsageSensor(SensusAnalyticsSensorBase): """Representation of the daily usage sensor.""" @@ -66,7 +75,6 @@ def __init__(self, coordinator: SensusAnalyticsDataUpdateCoordinator, entry: Con super().__init__(coordinator, entry) self._attr_name = f"{DEFAULT_NAME} Daily Usage" self._attr_unique_id = f"{self._unique_id}_daily_usage" - self._attr_native_unit_of_measurement = "CF" self._attr_icon = "mdi:water" @property @@ -75,6 +83,11 @@ def native_value(self): daily_usage = self.coordinator.data.get("dailyUsage") return self._convert_usage(daily_usage) + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return self._get_usage_unit() + class SensusAnalyticsUsageUnitSensor(SensusAnalyticsSensorBase): """Representation of the usage unit sensor.""" @@ -90,6 +103,11 @@ def native_value(self): """Return the state of the sensor.""" return self.coordinator.data.get("usageUnit") + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return None # No unit of measurement for this sensor + class SensusAnalyticsMeterAddressSensor(SensusAnalyticsSensorBase): """Representation of the meter address sensor.""" @@ -106,6 +124,11 @@ def native_value(self): """Return the state of the sensor.""" return self.coordinator.data.get("meterAddress1") + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return None # No unit of measurement for this sensor + class SensusAnalyticsLastReadSensor(SensusAnalyticsSensorBase): """Representation of the last read timestamp sensor.""" @@ -126,6 +149,11 @@ def native_value(self): return dt_util.utc_from_timestamp(last_read_ts / 1000).strftime("%Y-%m-%d %H:%M:%S") return None + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return None # No unit of measurement for this sensor + class SensusAnalyticsMeterLongitudeSensor(SensusAnalyticsSensorBase): """Representation of the meter longitude sensor.""" @@ -135,7 +163,6 @@ def __init__(self, coordinator: SensusAnalyticsDataUpdateCoordinator, entry: Con super().__init__(coordinator, entry) self._attr_name = f"{DEFAULT_NAME} Meter Longitude" self._attr_unique_id = f"{self._unique_id}_meter_longitude" - self._attr_native_unit_of_measurement = "°" self._attr_icon = "mdi:longitude" @property @@ -143,6 +170,11 @@ def native_value(self): """Return the state of the sensor.""" return self.coordinator.data.get("meterLong") + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return "°" + class SensusAnalyticsMeterIdSensor(SensusAnalyticsSensorBase): """Representation of the meter ID sensor.""" @@ -159,6 +191,11 @@ def native_value(self): """Return the state of the sensor.""" return self.coordinator.data.get("meterId") + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return None # No unit of measurement for this sensor + class SensusAnalyticsMeterLatitudeSensor(SensusAnalyticsSensorBase): """Representation of the meter latitude sensor.""" @@ -168,7 +205,6 @@ def __init__(self, coordinator: SensusAnalyticsDataUpdateCoordinator, entry: Con super().__init__(coordinator, entry) self._attr_name = f"{DEFAULT_NAME} Meter Latitude" self._attr_unique_id = f"{self._unique_id}_meter_latitude" - self._attr_native_unit_of_measurement = "°" self._attr_icon = "mdi:latitude" @property @@ -176,6 +212,11 @@ def native_value(self): """Return the state of the sensor.""" return self.coordinator.data.get("meterLat") + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return "°" + class SensusAnalyticsLatestReadUsageSensor(SensusAnalyticsSensorBase): """Representation of the latest read usage sensor.""" @@ -185,7 +226,6 @@ def __init__(self, coordinator: SensusAnalyticsDataUpdateCoordinator, entry: Con super().__init__(coordinator, entry) self._attr_name = f"{DEFAULT_NAME} Latest Read Usage" self._attr_unique_id = f"{self._unique_id}_latest_read_usage" - self._attr_native_unit_of_measurement = "CF" self._attr_icon = "mdi:water" @property @@ -194,6 +234,11 @@ def native_value(self): latest_read_usage = self.coordinator.data.get("latestReadUsage") return self._convert_usage(latest_read_usage) + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return self._get_usage_unit() + class SensusAnalyticsLatestReadTimeSensor(SensusAnalyticsSensorBase): """Representation of the latest read time sensor.""" @@ -214,6 +259,11 @@ def native_value(self): return dt_util.utc_from_timestamp(latest_read_time_ts / 1000).strftime("%Y-%m-%d %H:%M:%S") return None + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return None # No unit of measurement for this sensor + class SensusAnalyticsBillingUsageSensor(SensusAnalyticsSensorBase): """Representation of the billing usage sensor.""" @@ -223,7 +273,6 @@ def __init__(self, coordinator: SensusAnalyticsDataUpdateCoordinator, entry: Con super().__init__(coordinator, entry) self._attr_name = f"{DEFAULT_NAME} Billing Usage" self._attr_unique_id = f"{self._unique_id}_billing_usage" - self._attr_native_unit_of_measurement = "CF" self._attr_icon = "mdi:water" @property @@ -232,6 +281,11 @@ def native_value(self): billing_usage = self.coordinator.data.get("billingUsage") return self._convert_usage(billing_usage) + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return self._get_usage_unit() + class SensusAnalyticsBillingCostSensor(SensusAnalyticsSensorBase): """Representation of the billing cost sensor.""" @@ -241,7 +295,6 @@ def __init__(self, coordinator: SensusAnalyticsDataUpdateCoordinator, entry: Con super().__init__(coordinator, entry) self._attr_name = f"{DEFAULT_NAME} Billing Cost" self._attr_unique_id = f"{self._unique_id}_billing_cost" - self._attr_native_unit_of_measurement = "USD" self._attr_icon = "mdi:currency-usd" @property @@ -253,6 +306,11 @@ def native_value(self): usage_gallons = self._convert_usage(usage) return self._calculate_cost(usage_gallons) + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return "USD" + def _calculate_cost(self, usage_gallons): """Calculate the billing cost based on tiers and service fee.""" tier1_gallons = self.coordinator.config_entry.data.get("tier1_gallons") @@ -284,7 +342,6 @@ def __init__(self, coordinator: SensusAnalyticsDataUpdateCoordinator, entry: Con super().__init__(coordinator, entry) self._attr_name = f"{DEFAULT_NAME} Daily Fee" self._attr_unique_id = f"{self._unique_id}_daily_fee" - self._attr_native_unit_of_measurement = "USD" self._attr_icon = "mdi:currency-usd" @property @@ -296,6 +353,11 @@ def native_value(self): usage_gallons = self._convert_usage(usage) return self._calculate_daily_fee(usage_gallons) + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + return "USD" + def _calculate_daily_fee(self, usage_gallons): """Calculate the daily fee based on tiers.""" tier1_gallons = self.coordinator.config_entry.data.get("tier1_gallons")