diff --git a/Readme.md b/Readme.md index 079fda7..259d396 100644 --- a/Readme.md +++ b/Readme.md @@ -186,6 +186,8 @@ metrics: - prom_name: humidity # The name of the metric in a MQTT JSON message mqtt_name: humidity + # The scale of the metric in a MQTT JSON message (prom_value = mqtt_value * scale) + mqtt_value_scale: 100 # The prometheus help text for this metric help: DHT22 humidity reading # The prometheus type for this metric. Valid values are: "gauge" and "counter" diff --git a/pkg/config/config.go b/pkg/config/config.go index 728665c..07a27a2 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -135,6 +135,7 @@ type MetricConfig struct { ValueType string `yaml:"type"` ConstantLabels map[string]string `yaml:"const_labels"` StringValueMapping *StringValueMappingConfig `yaml:"string_value_mapping"` + MQTTValueScale float64 `yaml:"mqtt_value_scale"` } // StringValueMappingConfig defines the mapping from string to float diff --git a/pkg/metrics/parser.go b/pkg/metrics/parser.go index 8a465ce..c08da3b 100644 --- a/pkg/metrics/parser.go +++ b/pkg/metrics/parser.go @@ -94,6 +94,11 @@ func (p *Parser) parseMetric(metricPath string, deviceID string, value interface } else { return Metric{}, fmt.Errorf("got data with unexpectd type: %T ('%s')", value, value) } + + if cfg.MQTTValueScale != 0 { + metricValue = metricValue * cfg.MQTTValueScale + } + return Metric{ Description: cfg.PrometheusDescription(), Value: metricValue, diff --git a/pkg/metrics/parser_test.go b/pkg/metrics/parser_test.go index fa82f75..8d6a680 100644 --- a/pkg/metrics/parser_test.go +++ b/pkg/metrics/parser_test.go @@ -1,11 +1,12 @@ package metrics import ( - "github.com/hikhvar/mqtt2prometheus/pkg/config" - "github.com/prometheus/client_golang/prometheus" "reflect" "testing" "time" + + "github.com/hikhvar/mqtt2prometheus/pkg/config" + "github.com/prometheus/client_golang/prometheus" ) func TestParser_parseMetric(t *testing.T) { @@ -50,6 +51,32 @@ func TestParser_parseMetric(t *testing.T) { Topic: "", }, }, + { + name: "scaled string value", + fields: fields{ + map[string][]config.MetricConfig{ + "temperature": []config.MetricConfig{ + { + PrometheusName: "temperature", + ValueType: "gauge", + MQTTValueScale: 0.01, + }, + }, + }, + }, + args: args{ + metricPath: "temperature", + deviceID: "dht22", + value: "12.6", + }, + want: Metric{ + Description: prometheus.NewDesc("temperature", "", []string{"sensor", "topic"}, nil), + ValueType: prometheus.GaugeValue, + Value: 0.126, + IngestTime: testNow(), + Topic: "", + }, + }, { name: "string value failure", fields: fields{ @@ -94,6 +121,58 @@ func TestParser_parseMetric(t *testing.T) { Topic: "", }, }, + { + name: "scaled float value", + fields: fields{ + map[string][]config.MetricConfig{ + "humidity": []config.MetricConfig{ + { + PrometheusName: "humidity", + ValueType: "gauge", + MQTTValueScale: 0.01, + }, + }, + }, + }, + args: args{ + metricPath: "humidity", + deviceID: "dht22", + value: 12.6, + }, + want: Metric{ + Description: prometheus.NewDesc("humidity", "", []string{"sensor", "topic"}, nil), + ValueType: prometheus.GaugeValue, + Value: 0.126, + IngestTime: testNow(), + Topic: "", + }, + }, + { + name: "negative scaled float value", + fields: fields{ + map[string][]config.MetricConfig{ + "humidity": []config.MetricConfig{ + { + PrometheusName: "humidity", + ValueType: "gauge", + MQTTValueScale: -2, + }, + }, + }, + }, + args: args{ + metricPath: "humidity", + deviceID: "dht22", + value: 12.6, + }, + want: Metric{ + Description: prometheus.NewDesc("humidity", "", []string{"sensor", "topic"}, nil), + ValueType: prometheus.GaugeValue, + Value: -25.2, + IngestTime: testNow(), + Topic: "", + }, + }, { name: "bool value true", fields: fields{ @@ -119,6 +198,32 @@ func TestParser_parseMetric(t *testing.T) { Topic: "", }, }, + { + name: "scaled bool value", + fields: fields{ + map[string][]config.MetricConfig{ + "enabled": []config.MetricConfig{ + { + PrometheusName: "enabled", + ValueType: "gauge", + MQTTValueScale: 0.5, + }, + }, + }, + }, + args: args{ + metricPath: "enabled", + deviceID: "dht22", + value: true, + }, + want: Metric{ + Description: prometheus.NewDesc("enabled", "", []string{"sensor", "topic"}, nil), + ValueType: prometheus.GaugeValue, + Value: 0.5, + IngestTime: testNow(), + Topic: "", + }, + }, { name: "bool value false", fields: fields{