I finalized the package with all the bells & whistles. Then I created a dashboard, while waiting for the superbowl:
And in case someone needs it:
Package Code
# Mains Water Meter Package v3
# by @alexdelprete (Feb 2025)
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 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
delta_values: true
net_consumption: true
always_available: true
mains_water_daily:
source: *water_source
name: "Mains Water Daily"
unique_id: mains_water_um_daily
cycle: daily
delta_values: true
net_consumption: true
always_available: true
mains_water_weekly:
source: *water_source
name: "Mains Water Weekly"
unique_id: mains_water_um_weekly
cycle: weekly
delta_values: true
net_consumption: true
always_available: true
mains_water_monthly:
source: *water_source
name: "Mains Water Monthly"
unique_id: mains_water_um_monthly
cycle: monthly
delta_values: true
net_consumption: true
always_available: true
mains_water_yearly:
source: *water_source
name: "Mains Water Yearly"
unique_id: mains_water_um_yearly
cycle: yearly
delta_values: true
net_consumption: true
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
# =============================================================================
# LIFETIME ACCUMULATOR
# =============================================================================
# Trigger-based sensor that accumulates all water consumption since creation.
# Never resets - suitable for Energy Dashboard as primary water sensor.
#
# How it works:
# - Triggers on every sensor.droplet_water state change
# - Adds the delta (trigger.to_state.state) to current total (this.state)
# - Persists via core.restore_state across HA restarts
#
# Calibration: Use Developer Tools → States to set initial value if needed
# =============================================================================
template:
- trigger:
- platform: state
entity_id: sensor.droplet_water # Same source as utility meters
not_to: [unavailable, unknown]
sensor:
- name: "Mains Water Lifetime"
unique_id: mains_water_lifetime
state: >
{{ (this.state | float(0) + trigger.to_state.state | float(0)) | round(2) }}
state_class: total
device_class: water
unit_of_measurement: "L"
# =============================================================================
# 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 must be explicitly set via unit_of_measurement (template sensors
# do NOT inherit from HA system settings despite device_class: monetary).
# Change "EUR" below to match your currency code.
#
# To find your currency code, check:
# Settings → System → General → Currency
# =============================================================================
- 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
unit_of_measurement: "EUR"
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
unit_of_measurement: "EUR"
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
unit_of_measurement: "EUR"
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
unit_of_measurement: "EUR"
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'] }}"
# Lifetime water cost (never resets)
# Use: total spending since meter installation
# Note: this replaces the broken auto-generated Energy Dashboard cost sensor
- name: "Mains Water Lifetime Cost"
unique_id: mains_water_cost_lifetime
device_class: monetary
state_class: total
unit_of_measurement: "EUR"
icon: mdi:cash
state: "{{ ((states('sensor.mains_water_lifetime') | float(0)) / 1000 * (states('input_number.mains_water_tariff') | float(0))) | round(2) }}"
availability: "{{ states('sensor.mains_water_lifetime') not in ['unknown', 'unavailable'] }}"
