diff --git a/README.md b/README.md index 39c19ed..d539fec 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,7 @@ Import the [dashboard](grafana/dashboard.json) or use id `16804` and import from | tibber_power_consumption_previous_hour | Total power consumption previous hour | Gauge | | tibber_power_consumption_previous_day | Total power consumption yesterday | Gauge | | tibber_power_consumption_reactive | Current reactive consumption | Gauge | +| tibber_power_cost_day | Total power cost today | Gauge | | tibber_power_cost_day_total | Total power cost today | Counter | | tibber_power_cost_previous_hour | Total power cost previous hour | Gauge | | tibber_power_cost_previous_day | Total power cost yesterday | Gauge | @@ -139,6 +140,7 @@ Import the [dashboard](grafana/dashboard.json) or use id `16804` and import from | tibber_power_production_day_total | Total power production today | Counter | | tibber_power_production_previous_hour | Total power production previous hour | Gauge | | tibber_power_production_previous_day | Total power production yesterday | Gauge | +| tibber_power_production_reward_day | Total power production reward today | Gauge | | tibber_power_production_reward_day_total | Total power production reward today | Counter | | tibber_power_production_reactive | Current net reactive production | Gauge | | tibber_power_factor | Current power factor (active power / apparent power) | Gauge | diff --git a/charts/tibber-exporter/Chart.yaml b/charts/tibber-exporter/Chart.yaml index 31574d8..5fec049 100644 --- a/charts/tibber-exporter/Chart.yaml +++ b/charts/tibber-exporter/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: tibber-exporter -version: 3.2.0 +version: 3.3.0 description: Tibber exporter type: application keywords: diff --git a/internal/home/home.go b/internal/home/home.go index 74ab36a..229b6c3 100644 --- a/internal/home/home.go +++ b/internal/home/home.go @@ -17,6 +17,11 @@ type Measurements struct { LiveMeasurement tibber.LiveMeasurement `graphql:"liveMeasurement(homeId: $id)"` } +type GaugeValues struct { + CostToday float64 + RewardToday *float64 +} + type Home struct { Id graphql.ID Prices tibber.Prices `graphql:"home(id: $id)"` @@ -24,6 +29,7 @@ type Home struct { PreviousDay tibber.PreviousPower Measurements Measurements TimestampedValues tibber.TimestampedValues + GaugeValues GaugeValues } func New(id graphql.ID) *Home { @@ -186,6 +192,7 @@ func (h *Home) SubscribeMeasurements(ctx context.Context, hc *http.Client, wsUrl log.Printf("Accumulated cost lower than stored value: %f(%s) < %f(%s)\n", m.LiveMeasurement.AccumulatedCost, m.LiveMeasurement.Timestamp, h.Measurements.LiveMeasurement.AccumulatedCost, h.Measurements.LiveMeasurement.Timestamp) } + h.GaugeValues.CostToday = m.LiveMeasurement.AccumulatedCost if m.LiveMeasurement.AccumulatedProduction >= h.Measurements.LiveMeasurement.AccumulatedProduction || m.LiveMeasurement.Timestamp.YearDay() != h.Measurements.LiveMeasurement.Timestamp.YearDay() { h.Measurements.LiveMeasurement.AccumulatedProduction = m.LiveMeasurement.AccumulatedProduction @@ -202,6 +209,7 @@ func (h *Home) SubscribeMeasurements(ctx context.Context, hc *http.Client, wsUrl *m.LiveMeasurement.AccumulatedReward, m.LiveMeasurement.Timestamp, *h.Measurements.LiveMeasurement.AccumulatedReward, h.Measurements.LiveMeasurement.Timestamp) } } + h.GaugeValues.RewardToday = m.LiveMeasurement.AccumulatedReward if m.LiveMeasurement.CurrentL1 != nil { h.TimestampedValues.CurrentL1.Timestamp = m.LiveMeasurement.Timestamp h.TimestampedValues.CurrentL1.Value = *m.LiveMeasurement.CurrentL1 diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index 70747d6..17292bd 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -47,11 +47,13 @@ const maxAge = 5 type MeasurementCollector struct { measurements *tibber.LiveMeasurement timestampedValues *tibber.TimestampedValues + gaugeValues *home.GaugeValues consumption *prometheus.Desc consumptionMin *prometheus.Desc consumptionMax *prometheus.Desc consumptionAvg *prometheus.Desc consumptionTotal *prometheus.Desc + costToday *prometheus.Desc costTotal *prometheus.Desc current *prometheus.Desc voltage *prometheus.Desc @@ -60,16 +62,18 @@ type MeasurementCollector struct { productionMin *prometheus.Desc productionMax *prometheus.Desc productionTotal *prometheus.Desc + rewardToday *prometheus.Desc rewardTotal *prometheus.Desc consumptionReactive *prometheus.Desc productionReactive *prometheus.Desc powerFactor *prometheus.Desc } -func NewMeasurementCollector(homeId string, m *tibber.LiveMeasurement, tv *tibber.TimestampedValues) *MeasurementCollector { +func NewMeasurementCollector(homeId string, m *tibber.LiveMeasurement, tv *tibber.TimestampedValues, g *home.GaugeValues) *MeasurementCollector { return &MeasurementCollector{ measurements: m, timestampedValues: tv, + gaugeValues: g, consumption: prometheus.NewDesc( "tibber_power_consumption", "Power consumption", @@ -100,6 +104,12 @@ func NewMeasurementCollector(homeId string, m *tibber.LiveMeasurement, tv *tibbe nil, prometheus.Labels{"home_id": homeId}, ), + costToday: prometheus.NewDesc( + "tibber_power_cost_day", + "Total power cost since midnight", + nil, + prometheus.Labels{"home_id": homeId}, + ), costTotal: prometheus.NewDesc( "tibber_power_cost_day_total", "Total power cost since midnight", @@ -148,6 +158,12 @@ func NewMeasurementCollector(homeId string, m *tibber.LiveMeasurement, tv *tibbe nil, prometheus.Labels{"home_id": homeId}, ), + rewardToday: prometheus.NewDesc( + "tibber_power_production_reward_day", + "Total power production reward since midnight", + nil, + prometheus.Labels{"home_id": homeId}, + ), rewardTotal: prometheus.NewDesc( "tibber_power_production_reward_day_total", "Total power production reward since midnight", @@ -181,6 +197,7 @@ func (c *MeasurementCollector) Describe(ch chan<- *prometheus.Desc) { ch <- c.consumptionMax ch <- c.consumptionAvg ch <- c.consumptionTotal + ch <- c.costToday ch <- c.costTotal ch <- c.current ch <- c.voltage @@ -189,6 +206,7 @@ func (c *MeasurementCollector) Describe(ch chan<- *prometheus.Desc) { ch <- c.productionMin ch <- c.productionMax ch <- c.productionTotal + ch <- c.rewardToday ch <- c.rewardTotal ch <- c.consumptionReactive ch <- c.productionReactive @@ -241,6 +259,14 @@ func (c *MeasurementCollector) Collect(ch chan<- prometheus.Metric) { c.measurements.AccumulatedConsumption, ), ) + ch <- prometheus.NewMetricWithTimestamp( + c.measurements.Timestamp, + prometheus.MustNewConstMetric( + c.costToday, + prometheus.GaugeValue, + c.gaugeValues.CostToday, + ), + ) ch <- prometheus.NewMetricWithTimestamp( c.measurements.Timestamp, prometheus.MustNewConstMetric( @@ -364,6 +390,16 @@ func (c *MeasurementCollector) Collect(ch chan<- prometheus.Metric) { c.measurements.AccumulatedProduction, ), ) + if c.gaugeValues.RewardToday != nil { + ch <- prometheus.NewMetricWithTimestamp( + c.measurements.Timestamp, + prometheus.MustNewConstMetric( + c.rewardToday, + prometheus.GaugeValue, + *c.gaugeValues.RewardToday, + ), + ) + } if c.measurements.AccumulatedReward != nil { ch <- prometheus.NewMetricWithTimestamp( c.measurements.Timestamp, diff --git a/main.go b/main.go index 6f99121..c3aa99d 100644 --- a/main.go +++ b/main.go @@ -133,7 +133,7 @@ func main() { if (s.Features.RealTimeConsumptionEnabled || slices.Contains(liveMeasurements, string(s.Id))) && !slices.Contains(disableLiveMeasurements, string(s.Id)) { log.Printf("Starting live measurements monitoring of home %v\n", s.Id) go h.SubscribeMeasurements(ctx, hc, wsUrl, token) - prometheus.MustRegister(metrics.NewMeasurementCollector(string(s.Id), &h.Measurements.LiveMeasurement, &h.TimestampedValues)) + prometheus.MustRegister(metrics.NewMeasurementCollector(string(s.Id), &h.Measurements.LiveMeasurement, &h.TimestampedValues, &h.GaugeValues)) started = append(started, string(s.Id)) } else { log.Printf("Live measurements not available for home %v\n", s.Id)