diff --git a/kubernetes/apps/home-assistant/bgp-service.yaml b/kubernetes/apps/home-assistant/bgp-service.yaml index 8a847f38..a926e369 100644 --- a/kubernetes/apps/home-assistant/bgp-service.yaml +++ b/kubernetes/apps/home-assistant/bgp-service.yaml @@ -29,6 +29,13 @@ spec: selector: app.kubernetes.io/name: home-assistant ports: - - name: http + # Port name MUST NOT be "http": the `home-assistant` ServiceMonitor + # selects Services by label `app.kubernetes.io/name: home-assistant` + # (which this Service also carries) and scrapes the endpoint named + # `http`. If this port were named `http`, Prometheus would scrape HA a + # second time via this LB (:8123) in addition to the intended proxy + # Service (:8124) — producing duplicate `homeassistant_sensor_*` + # series and breaking every vector-matching PromQL query. + - name: ha port: 8123 targetPort: 8123 diff --git a/kubernetes/apps/monitoring/dashboards/heatpump-roi.json b/kubernetes/apps/monitoring/dashboards/heatpump-roi.json index 1f6b2517..7f548f60 100644 --- a/kubernetes/apps/monitoring/dashboards/heatpump-roi.json +++ b/kubernetes/apps/monitoring/dashboards/heatpump-roi.json @@ -1,6 +1,6 @@ { "annotations": {"list": []}, - "description": "Heat Pump ROI Analysis - Viessmann Vitocal 250-A", + "description": "Heat Pump ROI Analysis - Viessmann Vitocal 250-A. All panels read from InfluxDB (bucket suedstr28), which is authoritative and live. After the 2026-07 ViCare->open3e/MQTT migration the heat-pump/PV entities were renamed; panels query the current entity_ids and, where an entity was renamed, UNION the pre-migration e3_* series with the post-migration series so history stays unbroken.", "editable": true, "fiscalYearStartMonth": 0, "graphTooltip": 1, @@ -8,7 +8,7 @@ "links": [], "panels": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "blue", "value": null}]}, "unit": "currencyEUR"}, "overrides": [] @@ -16,12 +16,12 @@ "gridPos": {"h": 4, "w": 4, "x": 0, "y": 0}, "id": 1, "options": {"colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "vector(${investment_cost})", "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "import \"array\"\narray.from(rows: [{_time: now(), _value: float(v: \"${investment_cost}\")}])", "refId": "A"}], "title": "Investment Cost", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "orange", "value": null}]}, "unit": "currencyEUR"}, "overrides": [] @@ -29,13 +29,13 @@ "gridPos": {"h": 4, "w": 4, "x": 4, "y": 0}, "id": 2, "options": {"colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "vector(6650)", "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "import \"array\"\narray.from(rows: [{_time: now(), _value: 6650.0}])", "refId": "A"}], "title": "Oil Baseline (Annual)", "description": "Based on 2022-2023 oil orders: ~5,000L at ~1.33 EUR/L average", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "green", "value": null}]}, "unit": "currencyEUR"}, "overrides": [] @@ -43,13 +43,13 @@ "gridPos": {"h": 4, "w": 4, "x": 8, "y": 0}, "id": 3, "options": {"colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "(\n (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n) * ${solar_price} + on() (\n 1 - (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n) * on() homeassistant_input_number_state_eur_per_kwh{entity=\"input_number.strompreis\"}", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and (r.entity_id == \"vitocharge_vx3_vx3_pv_production_total\" or r.entity_id == \"vitocharge_vx3_vx3_grid_feed_in_energy\" or r.entity_id == \"vitocharge_vx3_vx3_grid_supplied_energy\")) |> last() |> keep(columns: [\"entity_id\", \"_value\"]) |> pivot(rowKey: [], columnKey: [\"entity_id\"], valueColumn: \"_value\") |> map(fn: (r) => ({_time: now(), self: r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, total: r.vitocharge_vx3_vx3_grid_supplied_energy + r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy})) |> map(fn: (r) => ({_time: r._time, _value: (r.self / r.total) * ${solar_price} + (1.0 - r.self / r.total) * ${grid_price}}))", "refId": "A"}], "title": "Blended Price", - "description": "Actual weighted average from Vitocharge data: solar self-consumption @ €${solar_price}, grid @ strompreis", + "description": "Weighted average: solar self-consumption @ EUR ${solar_price}, grid @ EUR ${grid_price}. Self-consumption ratio from Vitocharge PV/grid counters.", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "purple", "value": null}]}, "unit": "kwh"}, "overrides": [] @@ -57,12 +57,12 @@ "gridPos": {"h": 4, "w": 4, "x": 12, "y": 0}, "id": 4, "options": {"colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_heating_energy_consumption_total\"} + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_dhw_energy_consumption_total\"}", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and (r.entity_id == \"e3_vitocal_heating_energy_consumption_total\" or r.entity_id == \"e3_vitocal_dhw_energy_consumption_total\")) |> last() |> keep(columns: [\"_value\"]) |> group() |> sum()", "refId": "A"}], "title": "Total Consumption", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "green", "value": null}, {"color": "yellow", "value": 3000}, {"color": "red", "value": 5000}]}, "unit": "currencyEUR"}, "overrides": [] @@ -70,12 +70,12 @@ "gridPos": {"h": 4, "w": 4, "x": 16, "y": 0}, "id": 5, "options": {"colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "(homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_heating_energy_consumption_total\"} + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_dhw_energy_consumption_total\"}) * on() (\n (\n (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * ${solar_price} + on() (\n 1 - (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * on() homeassistant_input_number_state_eur_per_kwh{entity=\"input_number.strompreis\"}\n)", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and (r.entity_id == \"e3_vitocal_heating_energy_consumption_total\" or r.entity_id == \"e3_vitocal_dhw_energy_consumption_total\" or r.entity_id == \"vitocharge_vx3_vx3_pv_production_total\" or r.entity_id == \"vitocharge_vx3_vx3_grid_feed_in_energy\" or r.entity_id == \"vitocharge_vx3_vx3_grid_supplied_energy\")) |> last() |> keep(columns: [\"entity_id\", \"_value\"]) |> pivot(rowKey: [], columnKey: [\"entity_id\"], valueColumn: \"_value\") |> map(fn: (r) => ({_time: now(), self: r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, total: r.vitocharge_vx3_vx3_grid_supplied_energy + r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, cons: r.e3_vitocal_heating_energy_consumption_total + r.e3_vitocal_dhw_energy_consumption_total})) |> map(fn: (r) => ({_time: r._time, _value: r.cons * ((r.self / r.total) * ${solar_price} + (1.0 - r.self / r.total) * ${grid_price})}))", "refId": "A"}], "title": "Running Cost (Total)", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "green", "value": null}]}, "unit": "currencyEUR"}, "overrides": [] @@ -83,12 +83,12 @@ "gridPos": {"h": 4, "w": 4, "x": 20, "y": 0}, "id": 6, "options": {"colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "(homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_heating_energy_consumption_this_year\"} + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_dhw_energy_consumption_this_year\"}) * on() (\n (\n (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * ${solar_price} + on() (\n 1 - (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * on() homeassistant_input_number_state_eur_per_kwh{entity=\"input_number.strompreis\"}\n)", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and (r.entity_id == \"vitocal_250_a_vitocal_heating_electric_energy_year\" or r.entity_id == \"vitocal_250_a_vitocal_dhw_electric_energy_year\" or r.entity_id == \"vitocharge_vx3_vx3_pv_production_total\" or r.entity_id == \"vitocharge_vx3_vx3_grid_feed_in_energy\" or r.entity_id == \"vitocharge_vx3_vx3_grid_supplied_energy\")) |> last() |> keep(columns: [\"entity_id\", \"_value\"]) |> pivot(rowKey: [], columnKey: [\"entity_id\"], valueColumn: \"_value\") |> map(fn: (r) => ({_time: now(), self: r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, total: r.vitocharge_vx3_vx3_grid_supplied_energy + r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, cons: r.vitocal_250_a_vitocal_heating_electric_energy_year + r.vitocal_250_a_vitocal_dhw_electric_energy_year})) |> map(fn: (r) => ({_time: r._time, _value: r.cons * ((r.self / r.total) * ${solar_price} + (1.0 - r.self / r.total) * ${grid_price})}))", "refId": "A"}], "title": "Cost This Year", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "decimals": 1, "mappings": [], "max": 5, "min": 1, "thresholds": {"mode": "absolute", "steps": [{"color": "red", "value": null}, {"color": "yellow", "value": 2.5}, {"color": "green", "value": 3}]}}, "overrides": [] @@ -96,12 +96,12 @@ "gridPos": {"h": 5, "w": 3, "x": 0, "y": 4}, "id": 7, "options": {"minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "showThresholdLabels": false, "showThresholdMarkers": true}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_state{entity=\"sensor.e3_vitocal_seasonal_performance_factor\"}", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"vitocal_250_a_vitocal_scop_total\") |> last() |> keep(columns: [\"_value\"])", "refId": "A"}], "title": "Overall SPF", "type": "gauge" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "decimals": 1, "mappings": [], "max": 5, "min": 1, "thresholds": {"mode": "absolute", "steps": [{"color": "red", "value": null}, {"color": "yellow", "value": 2.5}, {"color": "green", "value": 3}]}}, "overrides": [] @@ -109,12 +109,12 @@ "gridPos": {"h": 5, "w": 3, "x": 3, "y": 4}, "id": 8, "options": {"minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "showThresholdLabels": false, "showThresholdMarkers": true}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_state{entity=\"sensor.e3_vitocal_seasonal_performance_factor_heating\"}", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"vitocal_250_a_vitocal_scop_heating\") |> last() |> keep(columns: [\"_value\"])", "refId": "A"}], "title": "Heating SPF", "type": "gauge" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "decimals": 1, "mappings": [], "max": 5, "min": 1, "thresholds": {"mode": "absolute", "steps": [{"color": "red", "value": null}, {"color": "yellow", "value": 2.5}, {"color": "green", "value": 3}]}}, "overrides": [] @@ -122,12 +122,12 @@ "gridPos": {"h": 5, "w": 3, "x": 6, "y": 4}, "id": 9, "options": {"minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "showThresholdLabels": false, "showThresholdMarkers": true}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_state{entity=\"sensor.e3_vitocal_seasonal_performance_factor_domestic_hot_water\"}", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"vitocal_250_a_vitocal_scop_dhw\") |> last() |> keep(columns: [\"_value\"])", "refId": "A"}], "title": "DHW SPF", "type": "gauge" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "green", "value": null}]}, "unit": "currencyEUR"}, "overrides": [] @@ -135,13 +135,13 @@ "gridPos": {"h": 5, "w": 4, "x": 9, "y": 4}, "id": 10, "options": {"colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "6650 - ((homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_heating_energy_consumption_this_year\"} + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_dhw_energy_consumption_this_year\"}) * on() (\n (\n (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * ${solar_price} + on() (\n 1 - (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * on() homeassistant_input_number_state_eur_per_kwh{entity=\"input_number.strompreis\"}\n) * 12 / (month(vector(time())) + (day_of_month(vector(time())) / 30)))", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "import \"date\"\nfrom(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and (r.entity_id == \"vitocal_250_a_vitocal_heating_electric_energy_year\" or r.entity_id == \"vitocal_250_a_vitocal_dhw_electric_energy_year\" or r.entity_id == \"vitocharge_vx3_vx3_pv_production_total\" or r.entity_id == \"vitocharge_vx3_vx3_grid_feed_in_energy\" or r.entity_id == \"vitocharge_vx3_vx3_grid_supplied_energy\")) |> last() |> keep(columns: [\"entity_id\", \"_value\"]) |> pivot(rowKey: [], columnKey: [\"entity_id\"], valueColumn: \"_value\") |> map(fn: (r) => ({_time: now(), self: r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, total: r.vitocharge_vx3_vx3_grid_supplied_energy + r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, costYearRaw: r.vitocal_250_a_vitocal_heating_electric_energy_year + r.vitocal_250_a_vitocal_dhw_electric_energy_year})) |> map(fn: (r) => ({_time: r._time, _value: 6650.0 - ((r.costYearRaw * ((r.self / r.total) * ${solar_price} + (1.0 - r.self / r.total) * ${grid_price})) * 12.0 / (float(v: date.month(t: now())) + float(v: date.monthDay(t: now())) / 30.0))}))", "refId": "A"}], "title": "Projected Annual Savings", "description": "Oil baseline minus projected annual electricity cost", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "decimals": 1, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "green", "value": null}, {"color": "yellow", "value": 15}, {"color": "red", "value": 20}]}, "unit": "short"}, "overrides": [] @@ -149,13 +149,13 @@ "gridPos": {"h": 5, "w": 4, "x": 13, "y": 4}, "id": 11, "options": {"colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "${investment_cost} / (6650 - ((homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_heating_energy_consumption_this_year\"} + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_dhw_energy_consumption_this_year\"}) * on() (\n (\n (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * ${solar_price} + on() (\n 1 - (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * on() homeassistant_input_number_state_eur_per_kwh{entity=\"input_number.strompreis\"}\n) * 12 / (month(vector(time())) + (day_of_month(vector(time())) / 30))))", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "import \"date\"\nfrom(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and (r.entity_id == \"vitocal_250_a_vitocal_heating_electric_energy_year\" or r.entity_id == \"vitocal_250_a_vitocal_dhw_electric_energy_year\" or r.entity_id == \"vitocharge_vx3_vx3_pv_production_total\" or r.entity_id == \"vitocharge_vx3_vx3_grid_feed_in_energy\" or r.entity_id == \"vitocharge_vx3_vx3_grid_supplied_energy\")) |> last() |> keep(columns: [\"entity_id\", \"_value\"]) |> pivot(rowKey: [], columnKey: [\"entity_id\"], valueColumn: \"_value\") |> map(fn: (r) => ({_time: now(), self: r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, total: r.vitocharge_vx3_vx3_grid_supplied_energy + r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, costYearRaw: r.vitocal_250_a_vitocal_heating_electric_energy_year + r.vitocal_250_a_vitocal_dhw_electric_energy_year})) |> map(fn: (r) => ({_time: r._time, _value: float(v: \"${investment_cost}\") / (6650.0 - ((r.costYearRaw * ((r.self / r.total) * ${solar_price} + (1.0 - r.self / r.total) * ${grid_price})) * 12.0 / (float(v: date.month(t: now())) + float(v: date.monthDay(t: now())) / 30.0)))}))", "refId": "A"}], "title": "Payback Period (Years)", "description": "Investment / Annual Savings", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "green", "value": null}]}, "unit": "currencyEUR"}, "overrides": [] @@ -163,13 +163,13 @@ "gridPos": {"h": 5, "w": 4, "x": 17, "y": 4}, "id": 12, "options": {"colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "(6650 * (time() - 1727740800) / 31536000) - ((homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_heating_energy_consumption_total\"} + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_dhw_energy_consumption_total\"}) * on() (\n (\n (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * ${solar_price} + on() (\n 1 - (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * on() homeassistant_input_number_state_eur_per_kwh{entity=\"input_number.strompreis\"}\n))", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and (r.entity_id == \"e3_vitocal_heating_energy_consumption_total\" or r.entity_id == \"e3_vitocal_dhw_energy_consumption_total\" or r.entity_id == \"vitocharge_vx3_vx3_pv_production_total\" or r.entity_id == \"vitocharge_vx3_vx3_grid_feed_in_energy\" or r.entity_id == \"vitocharge_vx3_vx3_grid_supplied_energy\")) |> last() |> keep(columns: [\"entity_id\", \"_value\"]) |> pivot(rowKey: [], columnKey: [\"entity_id\"], valueColumn: \"_value\") |> map(fn: (r) => ({_time: now(), self: r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, total: r.vitocharge_vx3_vx3_grid_supplied_energy + r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, cons: r.e3_vitocal_heating_energy_consumption_total + r.e3_vitocal_dhw_energy_consumption_total})) |> map(fn: (r) => ({_time: r._time, _value: (6650.0 * (float(v: uint(v: now()) - uint(v: 2024-10-01T00:00:00Z)) / 1000000000.0) / 31536000.0) - (r.cons * ((r.self / r.total) * ${solar_price} + (1.0 - r.self / r.total) * ${grid_price}))}))", "refId": "A"}], "title": "Savings Since Install", "description": "Oil baseline prorated since Oct 2024 minus actual costs", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "decimals": 1, "mappings": [], "max": 100, "min": 0, "thresholds": {"mode": "absolute", "steps": [{"color": "red", "value": null}, {"color": "yellow", "value": 25}, {"color": "green", "value": 50}]}, "unit": "percent"}, "overrides": [] @@ -177,7 +177,7 @@ "gridPos": {"h": 5, "w": 3, "x": 21, "y": 4}, "id": 40, "options": {"minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "showThresholdLabels": false, "showThresholdMarkers": true}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "((6650 * (time() - 1727740800) / 31536000) - ((homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_heating_energy_consumption_total\"} + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_dhw_energy_consumption_total\"}) * on() (\n (\n (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * ${solar_price} + on() (\n 1 - (homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n / on() (homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_import_from_grid\"} / 1000 + on() homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocharge_03_solar_energy_production_total\"} - on() homeassistant_sensor_energy_wh{entity=\"sensor.e3_vitocharge_03_energy_export_to_grid\"} / 1000)\n ) * on() homeassistant_input_number_state_eur_per_kwh{entity=\"input_number.strompreis\"}\n))) / ${investment_cost} * 100", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and (r.entity_id == \"e3_vitocal_heating_energy_consumption_total\" or r.entity_id == \"e3_vitocal_dhw_energy_consumption_total\" or r.entity_id == \"vitocharge_vx3_vx3_pv_production_total\" or r.entity_id == \"vitocharge_vx3_vx3_grid_feed_in_energy\" or r.entity_id == \"vitocharge_vx3_vx3_grid_supplied_energy\")) |> last() |> keep(columns: [\"entity_id\", \"_value\"]) |> pivot(rowKey: [], columnKey: [\"entity_id\"], valueColumn: \"_value\") |> map(fn: (r) => ({_time: now(), self: r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, total: r.vitocharge_vx3_vx3_grid_supplied_energy + r.vitocharge_vx3_vx3_pv_production_total / 1000.0 - r.vitocharge_vx3_vx3_grid_feed_in_energy, cons: r.e3_vitocal_heating_energy_consumption_total + r.e3_vitocal_dhw_energy_consumption_total})) |> map(fn: (r) => ({_time: r._time, _value: ((6650.0 * (float(v: uint(v: now()) - uint(v: 2024-10-01T00:00:00Z)) / 1000000000.0) / 31536000.0) - (r.cons * ((r.self / r.total) * ${solar_price} + (1.0 - r.self / r.total) * ${grid_price}))) / float(v: \"${investment_cost}\") * 100.0}))", "refId": "A"}], "title": "ROI Progress", "description": "Percentage of investment recovered through savings", "type": "gauge" @@ -187,7 +187,7 @@ "gridPos": {"h": 1, "w": 24, "x": 0, "y": 9}, "id": 30, "panels": [], - "title": "Historical Data (InfluxDB - Oct 2024 to Sep 2025)", + "title": "Historical Data (InfluxDB - full history)", "type": "row" }, { @@ -244,7 +244,7 @@ "targets": [ { "datasource": {"type": "influxdb", "uid": "influxdb"}, - "query": "// Heat pump consumption (cumulative)\nheatpump_heating = from(bucket: \"suedstr28\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._measurement == \"kWh\" and r.entity_id == \"e3_vitocal_heating_energy_consumption_total\" and r._field == \"value\")\n |> aggregateWindow(every: 1d, fn: last, createEmpty: false)\n |> keep(columns: [\"_time\", \"_value\"])\n\nheatpump_dhw = from(bucket: \"suedstr28\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._measurement == \"kWh\" and r.entity_id == \"e3_vitocal_dhw_energy_consumption_total\" and r._field == \"value\")\n |> aggregateWindow(every: 1d, fn: last, createEmpty: false)\n |> keep(columns: [\"_time\", \"_value\"])\n\n// Grid import (Wh -> kWh)\ngrid_import = from(bucket: \"suedstr28\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r.entity_id == \"e3_vitocharge_03_energy_import_from_grid\" and r._field == \"value\")\n |> aggregateWindow(every: 1d, fn: last, createEmpty: false)\n |> map(fn: (r) => ({_time: r._time, _value: r._value / 1000.0}))\n |> keep(columns: [\"_time\", \"_value\"])\n\n// Grid export (Wh -> kWh)\ngrid_export = from(bucket: \"suedstr28\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r.entity_id == \"e3_vitocharge_03_energy_export_to_grid\" and r._field == \"value\")\n |> aggregateWindow(every: 1d, fn: last, createEmpty: false)\n |> map(fn: (r) => ({_time: r._time, _value: r._value / 1000.0}))\n |> keep(columns: [\"_time\", \"_value\"])\n\n// Solar production (already kWh)\nsolar_prod = from(bucket: \"suedstr28\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r.entity_id == \"e3_vitocharge_03_solar_energy_production_total\" and r._field == \"value\")\n |> aggregateWindow(every: 1d, fn: last, createEmpty: false)\n |> keep(columns: [\"_time\", \"_value\"])\n\n// Chain joins (Flux only supports 2-way joins)\njoin1 = join(tables: {h: heatpump_heating, d: heatpump_dhw}, on: [\"_time\"])\njoin2 = join(tables: {j1: join1, gi: grid_import}, on: [\"_time\"])\njoin3 = join(tables: {j2: join2, ge: grid_export}, on: [\"_time\"])\njoin(tables: {j3: join3, sp: solar_prod}, on: [\"_time\"])\n |> map(fn: (r) => {\n heatpump = r._value_h + r._value_d\n self_consumption = r._value_sp - r._value_ge\n total_consumption = r._value_gi + self_consumption\n solar_ratio = if total_consumption > 0.0 then self_consumption / total_consumption else 0.0\n return {_time: r._time, _value: heatpump * ((1.0 - solar_ratio) * 0.3271 + solar_ratio * ${solar_price})}\n })\n |> rename(columns: {_value: \"Electricity Cost\"})", + "query": "// Heat pump consumption (survivor utility_meters, continuous)\nheatpump_heating = from(bucket: \"suedstr28\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._measurement == \"kWh\" and r.entity_id == \"e3_vitocal_heating_energy_consumption_total\" and r._field == \"value\")\n |> aggregateWindow(every: 1d, fn: last, createEmpty: false)\n |> keep(columns: [\"_time\", \"_value\"])\n\nheatpump_dhw = from(bucket: \"suedstr28\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._measurement == \"kWh\" and r.entity_id == \"e3_vitocal_dhw_energy_consumption_total\" and r._field == \"value\")\n |> aggregateWindow(every: 1d, fn: last, createEmpty: false)\n |> keep(columns: [\"_time\", \"_value\"])\n\n// Grid import: old ViCare (Wh) UNION new open3e (kWh) -> normalize to kWh\ngrid_import = union(tables: [\n from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r.entity_id == \"e3_vitocharge_03_energy_import_from_grid\" and r._field == \"value\") |> map(fn: (r) => ({_time: r._time, _value: r._value / 1000.0})),\n from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r.entity_id == \"vitocharge_vx3_vx3_grid_supplied_energy\" and r._field == \"value\") |> map(fn: (r) => ({_time: r._time, _value: r._value}))])\n |> aggregateWindow(every: 1d, fn: last, createEmpty: false)\n |> keep(columns: [\"_time\", \"_value\"])\n\n// Grid export: old ViCare (Wh) UNION new open3e (kWh) -> normalize to kWh\ngrid_export = union(tables: [\n from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r.entity_id == \"e3_vitocharge_03_energy_export_to_grid\" and r._field == \"value\") |> map(fn: (r) => ({_time: r._time, _value: r._value / 1000.0})),\n from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r.entity_id == \"vitocharge_vx3_vx3_grid_feed_in_energy\" and r._field == \"value\") |> map(fn: (r) => ({_time: r._time, _value: r._value}))])\n |> aggregateWindow(every: 1d, fn: last, createEmpty: false)\n |> keep(columns: [\"_time\", \"_value\"])\n\n// Solar production: old ViCare (kWh) UNION new open3e (Wh) -> normalize to kWh\nsolar_prod = union(tables: [\n from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r.entity_id == \"e3_vitocharge_03_solar_energy_production_total\" and r._field == \"value\") |> map(fn: (r) => ({_time: r._time, _value: r._value})),\n from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r.entity_id == \"vitocharge_vx3_vx3_pv_production_total\" and r._field == \"value\") |> map(fn: (r) => ({_time: r._time, _value: r._value / 1000.0}))])\n |> aggregateWindow(every: 1d, fn: last, createEmpty: false)\n |> keep(columns: [\"_time\", \"_value\"])\n\n// Chain joins (Flux only supports 2-way joins)\njoin1 = join(tables: {h: heatpump_heating, d: heatpump_dhw}, on: [\"_time\"])\njoin2 = join(tables: {j1: join1, gi: grid_import}, on: [\"_time\"])\njoin3 = join(tables: {j2: join2, ge: grid_export}, on: [\"_time\"])\njoin(tables: {j3: join3, sp: solar_prod}, on: [\"_time\"])\n |> map(fn: (r) => {\n heatpump = r._value_h + r._value_d\n self_consumption = r._value_sp - r._value_ge\n total_consumption = r._value_gi + self_consumption\n solar_ratio = if total_consumption > 0.0 then self_consumption / total_consumption else 0.0\n return {_time: r._time, _value: heatpump * ((1.0 - solar_ratio) * ${grid_price} + solar_ratio * ${solar_price})}\n })\n |> rename(columns: {_value: \"Electricity Cost\"})", "refId": "A" }, { @@ -254,7 +254,7 @@ } ], "title": "Historical Cost Comparison", - "description": "Actual electricity cost vs what oil would have cost", + "description": "Actual electricity cost vs what oil would have cost. Solar/grid series union pre-migration ViCare (e3_*) with post-migration open3e (vitocharge_vx3_*), unit-normalized to kWh.", "type": "timeseries" }, { @@ -262,11 +262,11 @@ "gridPos": {"h": 1, "w": 24, "x": 0, "y": 20}, "id": 31, "panels": [], - "title": "Current Data (Prometheus - Real-time)", + "title": "Recent Data (InfluxDB)", "type": "row" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": { "color": {"mode": "palette-classic"}, @@ -275,25 +275,28 @@ "thresholds": {"mode": "absolute", "steps": [{"color": "green", "value": null}]}, "unit": "kwh" }, - "overrides": [] + "overrides": [ + {"matcher": {"id": "byName", "options": "Heating Total"}, "properties": [{"id": "color", "value": {"fixedColor": "red", "mode": "fixed"}}]}, + {"matcher": {"id": "byName", "options": "DHW Total"}, "properties": [{"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}}]} + ] }, "gridPos": {"h": 8, "w": 12, "x": 0, "y": 21}, "id": 13, "options": {"legend": {"calcs": ["mean", "max", "lastNotNull"], "displayMode": "table", "placement": "right", "showLegend": true}, "tooltip": {"mode": "multi", "sort": "desc"}}, "targets": [ - {"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_heating_energy_consumption_total\"}", "legendFormat": "Heating Total", "refId": "A"}, - {"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_dhw_energy_consumption_total\"}", "legendFormat": "DHW Total", "refId": "B"} + {"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"e3_vitocal_heating_energy_consumption_total\") |> aggregateWindow(every: 1h, fn: last, createEmpty: false) |> keep(columns: [\"_time\", \"_value\"]) |> rename(columns: {_value: \"Heating Total\"})", "refId": "A"}, + {"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"e3_vitocal_dhw_energy_consumption_total\") |> aggregateWindow(every: 1h, fn: last, createEmpty: false) |> keep(columns: [\"_time\", \"_value\"]) |> rename(columns: {_value: \"DHW Total\"})", "refId": "B"} ], "timeFrom": "7d", "title": "Cumulative Energy Consumption (Recent)", "type": "timeseries" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": { "color": {"mode": "palette-classic"}, - "custom": {"axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", "fillOpacity": 20, "gradientMode": "none", "hideFrom": {"legend": false, "tooltip": false, "viz": false}, "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, "scaleDistribution": {"type": "linear"}, "showPoints": "never", "spanNulls": false, "stacking": {"group": "A", "mode": "none"}, "thresholdsStyle": {"mode": "off"}}, + "custom": {"axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "bars", "fillOpacity": 60, "gradientMode": "none", "hideFrom": {"legend": false, "tooltip": false, "viz": false}, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, "scaleDistribution": {"type": "linear"}, "showPoints": "never", "spanNulls": false, "stacking": {"group": "A", "mode": "none"}, "thresholdsStyle": {"mode": "off"}}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "green", "value": null}]}, "unit": "kwh" @@ -302,21 +305,22 @@ }, "gridPos": {"h": 8, "w": 12, "x": 12, "y": 21}, "id": 15, - "options": {"legend": {"calcs": ["mean", "lastNotNull"], "displayMode": "table", "placement": "right", "showLegend": true}, "tooltip": {"mode": "multi", "sort": "desc"}}, + "options": {"legend": {"calcs": ["mean", "sum"], "displayMode": "table", "placement": "right", "showLegend": true}, "tooltip": {"mode": "multi", "sort": "desc"}}, "targets": [ - {"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_heating_energy_consumption_last_seven_days\"}", "legendFormat": "Heating (7 days)", "refId": "A"}, - {"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_dhw_energy_consumption_last_seven_days\"}", "legendFormat": "DHW (7 days)", "refId": "B"} + {"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"e3_vitocal_heating_energy_consumption_total\") |> aggregateWindow(every: 1d, fn: last, createEmpty: false) |> difference(nonNegative: true) |> keep(columns: [\"_time\", \"_value\"]) |> rename(columns: {_value: \"Heating (daily)\"})", "refId": "A"}, + {"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"e3_vitocal_dhw_energy_consumption_total\") |> aggregateWindow(every: 1d, fn: last, createEmpty: false) |> difference(nonNegative: true) |> keep(columns: [\"_time\", \"_value\"]) |> rename(columns: {_value: \"DHW (daily)\"})", "refId": "B"} ], - "timeFrom": "7d", - "title": "Weekly Consumption", + "timeFrom": "14d", + "title": "Daily Consumption", + "description": "Daily kWh consumed (delta of cumulative counters). Replaces the retired *_last_seven_days sensors.", "type": "timeseries" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": { "color": {"mode": "palette-classic"}, - "custom": {"axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", "fillOpacity": 20, "gradientMode": "none", "hideFrom": {"legend": false, "tooltip": false, "viz": false}, "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, "scaleDistribution": {"type": "linear"}, "showPoints": "never", "spanNulls": false, "stacking": {"group": "A", "mode": "none"}, "thresholdsStyle": {"mode": "off"}}, + "custom": {"axisCenteredZero": false, "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", "hideFrom": {"legend": false, "tooltip": false, "viz": false}, "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, "scaleDistribution": {"type": "linear"}, "showPoints": "never", "spanNulls": true, "stacking": {"group": "A", "mode": "none"}, "thresholdsStyle": {"mode": "off"}}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "green", "value": null}]}, "unit": "short" @@ -327,16 +331,16 @@ "id": 16, "options": {"legend": {"calcs": ["mean", "min", "max"], "displayMode": "table", "placement": "right", "showLegend": true}, "tooltip": {"mode": "multi", "sort": "desc"}}, "targets": [ - {"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_state{entity=\"sensor.e3_vitocal_seasonal_performance_factor\"}", "legendFormat": "Overall SPF", "refId": "A"}, - {"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_state{entity=\"sensor.e3_vitocal_seasonal_performance_factor_heating\"}", "legendFormat": "Heating SPF", "refId": "B"}, - {"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_state{entity=\"sensor.e3_vitocal_seasonal_performance_factor_domestic_hot_water\"}", "legendFormat": "DHW SPF", "refId": "C"} + {"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "union(tables: [from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"e3_vitocal_seasonal_performance_factor\") |> map(fn: (r) => ({_time: r._time, _value: r._value})), from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"vitocal_250_a_vitocal_scop_total\") |> map(fn: (r) => ({_time: r._time, _value: r._value}))]) |> aggregateWindow(every: 6h, fn: last, createEmpty: false) |> keep(columns: [\"_time\", \"_value\"]) |> rename(columns: {_value: \"Overall SPF\"})", "refId": "A"}, + {"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "union(tables: [from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"e3_vitocal_seasonal_performance_factor_heating\") |> map(fn: (r) => ({_time: r._time, _value: r._value})), from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"vitocal_250_a_vitocal_scop_heating\") |> map(fn: (r) => ({_time: r._time, _value: r._value}))]) |> aggregateWindow(every: 6h, fn: last, createEmpty: false) |> keep(columns: [\"_time\", \"_value\"]) |> rename(columns: {_value: \"Heating SPF\"})", "refId": "B"}, + {"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "union(tables: [from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"e3_vitocal_seasonal_performance_factor_domestic_hot_water\") |> map(fn: (r) => ({_time: r._time, _value: r._value})), from(bucket: \"suedstr28\") |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"vitocal_250_a_vitocal_scop_dhw\") |> map(fn: (r) => ({_time: r._time, _value: r._value}))]) |> aggregateWindow(every: 6h, fn: last, createEmpty: false) |> keep(columns: [\"_time\", \"_value\"]) |> rename(columns: {_value: \"DHW SPF\"})", "refId": "C"} ], - "timeFrom": "7d", + "timeFrom": "90d", "title": "Seasonal Performance Factor Over Time", "type": "timeseries" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "blue", "value": null}]}, "unit": "kwh"}, "overrides": [] @@ -344,12 +348,12 @@ "gridPos": {"h": 4, "w": 6, "x": 0, "y": 37}, "id": 17, "options": {"colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_heating_energy_consumption_this_year\"}", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"vitocal_250_a_vitocal_heating_electric_energy_year\") |> last() |> keep(columns: [\"_value\"])", "refId": "A"}], "title": "Heating This Year", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "blue", "value": null}]}, "unit": "kwh"}, "overrides": [] @@ -357,12 +361,12 @@ "gridPos": {"h": 4, "w": 6, "x": 6, "y": 37}, "id": 18, "options": {"colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_dhw_energy_consumption_this_year\"}", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -30d) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"vitocal_250_a_vitocal_dhw_electric_energy_year\") |> last() |> keep(columns: [\"_value\"])", "refId": "A"}], "title": "DHW This Year", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "purple", "value": null}]}, "unit": "kwh"}, "overrides": [] @@ -370,12 +374,12 @@ "gridPos": {"h": 4, "w": 6, "x": 12, "y": 37}, "id": 19, "options": {"colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_heating_energy_consumption_last_seven_days\"}", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -7d) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"e3_vitocal_heating_energy_consumption_total\") |> spread() |> keep(columns: [\"_value\"])", "refId": "A"}], "title": "Heating Last 7 Days", "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": {"type": "influxdb", "uid": "influxdb"}, "fieldConfig": { "defaults": {"color": {"mode": "thresholds"}, "mappings": [], "thresholds": {"mode": "absolute", "steps": [{"color": "purple", "value": null}]}, "unit": "kwh"}, "overrides": [] @@ -383,7 +387,7 @@ "gridPos": {"h": 4, "w": 6, "x": 18, "y": 37}, "id": 20, "options": {"colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "auto", "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, "textMode": "auto"}, - "targets": [{"datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "homeassistant_sensor_energy_kwh{entity=\"sensor.e3_vitocal_dhw_energy_consumption_last_seven_days\"}", "instant": true, "refId": "A"}], + "targets": [{"datasource": {"type": "influxdb", "uid": "influxdb"}, "query": "from(bucket: \"suedstr28\") |> range(start: -7d) |> filter(fn: (r) => r._field == \"value\" and r.entity_id == \"e3_vitocal_dhw_energy_consumption_total\") |> spread() |> keep(columns: [\"_value\"])", "refId": "A"}], "title": "DHW Last 7 Days", "type": "stat" } @@ -395,7 +399,7 @@ "templating": {"list": [ { "current": {"selected": true, "text": "72968", "value": "72968"}, - "description": "Heat pump investment cost (excluding water softener €9,225)", + "description": "Heat pump investment cost (excluding water softener EUR 9,225)", "hide": 0, "label": "Investment", "name": "investment_cost", @@ -416,6 +420,18 @@ ], "query": "0.08", "type": "custom" + }, + { + "current": {"selected": true, "text": "0.3271", "value": "0.3271"}, + "description": "Grid electricity price EUR/kWh (replaces the retired live input_number.strompreis read)", + "hide": 0, + "label": "Grid Price", + "name": "grid_price", + "options": [ + {"selected": true, "text": "0.3271", "value": "0.3271"} + ], + "query": "0.3271", + "type": "custom" } ]}, "time": {"from": "2024-10-01T00:00:00.000Z", "to": "now"},