The Droplet device sends point-to-point delta values (volume since last push) that can also be negative. Here’s an official explanation from the vendor’s FAQ:
Q: Why does Droplet’s volume sensor sometimes show negative values?
A: The volume reported by Droplet over local API is point-to-point, meaning that each new value represents the difference in volume recorded since this data was last sent. Even when you’re not using appliances in your home, there can still be activity in your pipes. Droplet tries to be very accurate and is sensitive to small flows, which can include water sloshing back and forth, or slight movement as a result of pressure differences. Small negative values are to be expected, and are reported so that cumulative statistics reported in Home Assistant (or other consumers of the API) can be fully accurate.
Is there a specific reason why you created that vs using utility_meter? utility_meter works even if the source entity is excluded from recorder: it subscribes to state_changed on the event bus and calculates deltas on the fly. It doesn’t query recorder history. Statistics sensors instead won’t work if the source entity is excluded from recorder, they get historical data from recorder.
For my personal needs, I came up with a package, because I wanted more cumulative and statistics sensors. But I think I will create a custom integration that will provide all this to make it easier for the user, it will be configurable (units, tariff, etc.), it won’t require the creation of the point-to-point sensor nor manually creating other sensors/entities.
# Mains Water Meter Package
# Place in /config/packages/mains_water.yaml
input_number:
mains_water_tariff:
name: "Mains Water Tariff"
icon: mdi:cash
unit_of_measurement: "EUR/m³" # ← Change to your currency/unit
min: 0
max: 100
step: 0.01
initial: 2.94
# =============================================================================
# UTILITY METERS
# Track consumption per calendar period (resets at hour/midnight/week/month/year)
# Change the source sensor on the first entry below (&water_source)
# All other entries will automatically use the same sensor (*water_source)
#
# Entity IDs will be: sensor.mains_water_hourly, sensor.mains_water_daily, etc.
# =============================================================================
utility_meter:
mains_water_hourly:
source: &water_source sensor.droplet_water # ← CHANGE THIS TO YOUR WATER SENSOR
name: "Mains Water Hourly"
unique_id: mains_water_um_hourly
cycle: hourly
always_available: true
mains_water_daily:
source: *water_source
name: "Mains Water Daily"
unique_id: mains_water_um_daily
cycle: daily
always_available: true
mains_water_weekly:
source: *water_source
name: "Mains Water Weekly"
unique_id: mains_water_um_weekly
cycle: weekly
always_available: true
mains_water_monthly:
source: *water_source
name: "Mains Water Monthly"
unique_id: mains_water_um_monthly
cycle: monthly
always_available: true
mains_water_yearly:
source: *water_source
name: "Mains Water Yearly"
unique_id: mains_water_um_yearly
cycle: yearly
always_available: true
# =============================================================================
# STATISTICS SENSORS
# Rolling window analytics for trends, patterns, and anomaly detection
#
# Change the flow rate sensor on the first flow entry (&flow_source)
# Utility meter sources are fixed (they reference entities created above)
# =============================================================================
sensor:
# ---------------------------------------------------------------------------
# DAILY CONSUMPTION STATISTICS
# Source: utility meter that resets at midnight
# ---------------------------------------------------------------------------
# Average daily consumption over the past week
# Use: "What's my typical daily usage?" - baseline for comparison
# Alert idea: notify if today's usage exceeds 150% of this value
- platform: statistics
name: "Mains Water Avg Daily (7d)"
unique_id: mains_water_stats_avg_daily_7d
entity_id: &daily_source sensor.mains_water_daily
state_characteristic: mean
max_age: &age_7d
days: 7
# Average daily consumption over the past month
# Use: long-term baseline, seasonal comparison, billing estimate
# More stable than 7d average, smooths out weekday/weekend differences
- platform: statistics
name: "Mains Water Avg Daily (30d)"
unique_id: mains_water_stats_avg_daily_30d
entity_id: *daily_source
state_characteristic: mean
max_age: &age_30d
days: 30
# Highest single-day consumption in the past month
# Use: identify high-usage events (guests, garden watering, pool fill)
# Helps set realistic alert thresholds
- platform: statistics
name: "Mains Water Peak Daily (30d)"
unique_id: mains_water_stats_peak_daily_30d
entity_id: *daily_source
state_characteristic: value_max
max_age: *age_30d
# ---------------------------------------------------------------------------
# HOURLY CONSUMPTION STATISTICS
# Source: utility meter that resets every hour
# ---------------------------------------------------------------------------
# Average hourly consumption over the past 24 hours
# Use: "How much am I using per hour on average?"
# Useful for understanding daily patterns
- platform: statistics
name: "Mains Water Avg Hourly (24h)"
unique_id: mains_water_stats_avg_hourly_24h
entity_id: &hourly_source sensor.mains_water_hourly
state_characteristic: mean
max_age: &age_24h
hours: 24
# Highest single-hour consumption today
# Use: identify peak usage hours (morning shower, dinner prep)
# Helps understand when water demand is highest
- platform: statistics
name: "Mains Water Peak Hourly (24h)"
unique_id: mains_water_stats_peak_hourly_24h
entity_id: *hourly_source
state_characteristic: value_max
max_age: *age_24h
# Highest single-hour consumption this week
# Use: detect unusual high-consumption events
# Alert idea: notify if current hour exceeds this by large margin
- platform: statistics
name: "Mains Water Peak Hourly (7d)"
unique_id: mains_water_stats_peak_hourly_7d
entity_id: *hourly_source
state_characteristic: value_max
max_age: *age_7d
# ---------------------------------------------------------------------------
# FLOW RATE STATISTICS
# Source: instantaneous flow rate sensor (L/min)
# Unlike consumption, this measures how fast water is flowing RIGHT NOW
# ---------------------------------------------------------------------------
# Highest flow rate observed in the past 24 hours
# Use: identify max simultaneous demand (multiple fixtures at once)
# Helps with pipe sizing and pressure considerations
- platform: statistics
name: "Mains Water Peak Flow (24h)"
unique_id: mains_water_stats_peak_flow_24h
entity_id: &flow_source sensor.droplet_flow_rate # ← CHANGE THIS TO YOUR FLOW SENSOR
state_characteristic: value_max
max_age: *age_24h
# Highest flow rate observed in the past week
# Use: understand maximum demand patterns over longer period
# Useful for plumbing capacity planning
- platform: statistics
name: "Mains Water Peak Flow (7d)"
unique_id: mains_water_stats_peak_flow_7d
entity_id: *flow_source
state_characteristic: value_max
max_age: *age_7d
# Average flow rate over the past hour
# Use: smoothed view of recent activity
# High value = sustained water use; low = intermittent or no use
- platform: statistics
name: "Mains Water Avg Flow (1h)"
unique_id: mains_water_stats_avg_flow_1h
entity_id: *flow_source
state_characteristic: mean
max_age: &age_1h
hours: 1
# Minimum flow rate observed in the past 24 hours
# Use: LEAK DETECTION - if minimum > 0, water is always flowing
# Alert idea: if min_flow > 0 for extended period (especially at night),
# there may be a leak (dripping tap, running toilet, pipe leak)
- platform: statistics
name: "Mains Water Min Flow (24h)"
unique_id: mains_water_stats_min_flow_24h
entity_id: *flow_source
state_characteristic: value_min
max_age: *age_24h
# =============================================================================
# COST SENSORS
# =============================================================================
# Cost calculation assumes:
# - Source sensor reports in LITERS (L)
# - Tariff is per CUBIC METER (m³)
# - Divisor is 1000 (1 m³ = 1000 L)
#
# Adjust divisor for your local billing unit:
# | Tariff Unit | Divisor |
# |-------------|---------|
# | /m³ | 1000 |
# | /gal | 3.78541 |
# | /CCF | 2831.68 |
#
# Currency is determined by Home Assistant system settings:
# Settings → System → General → Currency
# =============================================================================
template:
- sensor:
# Today's water cost so far
# Use: daily spending awareness, budget tracking
# Resets at midnight with the daily utility meter
- name: "Mains Water Daily Cost"
unique_id: mains_water_cost_daily
device_class: monetary
state_class: total
icon: mdi:cash
state: "{{ ((states('sensor.mains_water_daily') | float(0)) / 1000 * (states('input_number.mains_water_tariff') | float(0))) | round(2) }}"
availability: "{{ states('sensor.mains_water_daily') not in ['unknown', 'unavailable'] }}"
# This week's water cost so far
# Use: weekly budget tracking, week-over-week comparison
# Resets on Monday at midnight
- name: "Mains Water Weekly Cost"
unique_id: mains_water_cost_weekly
device_class: monetary
state_class: total
icon: mdi:cash
state: "{{ ((states('sensor.mains_water_weekly') | float(0)) / 1000 * (states('input_number.mains_water_tariff') | float(0))) | round(2) }}"
availability: "{{ states('sensor.mains_water_weekly') not in ['unknown', 'unavailable'] }}"
# This month's water cost so far
# Use: billing estimate, compare to utility bill, monthly budget
# Resets on the 1st of each month at midnight
- name: "Mains Water Monthly Cost"
unique_id: mains_water_cost_monthly
device_class: monetary
state_class: total
icon: mdi:cash
state: "{{ ((states('sensor.mains_water_monthly') | float(0)) / 1000 * (states('input_number.mains_water_tariff') | float(0))) | round(2) }}"
availability: "{{ states('sensor.mains_water_monthly') not in ['unknown', 'unavailable'] }}"
# This year's water cost so far
# Use: annual spending overview, year-over-year comparison
# Resets on January 1st at midnight
- name: "Mains Water Yearly Cost"
unique_id: mains_water_cost_yearly
device_class: monetary
state_class: total
icon: mdi:cash
state: "{{ ((states('sensor.mains_water_yearly') | float(0)) / 1000 * (states('input_number.mains_water_tariff') | float(0))) | round(2) }}"
availability: "{{ states('sensor.mains_water_yearly') not in ['unknown', 'unavailable'] }}"