Skip to content

Commit

Permalink
Handle json payload in metric_per_topic mode
Browse files Browse the repository at this point in the history
  • Loading branch information
y-martin authored and Christian Schneider committed Feb 5, 2024
1 parent d562b92 commit 9da7b1b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ E.g let's assume the following MQTT JSON message:
We can now set `json_parsing.seperator` to `/`. This allows us to specify `mqtt_name` as `computed/heat.index`. Keep in mind,
`json_parsing.seperator` is a global setting. This affects all `mqtt_name` fields in your configuration.

Some devices like Shelly Plus H&T publish one metric per-topic in a JSON format:
```
shellies/shellyplusht-xxx/status/humidity:0 {"id": 0,"rh":51.9}
```
You can use PayloadField to extract the desired value.

### Tasmota
An example configuration for the tasmota based Gosund SP111 device is given in [examples/gosund_sp111.yaml](examples/gosund_sp111.yaml).

Expand Down
22 changes: 22 additions & 0 deletions hack/shellyplusht.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
mqtt:
server: tcp://mosquitto:1883
topic_path: shellies/+/sensor/+
device_id_regex: "shellies/(?P<deviceid>.*)/sensor"
metric_per_topic_config:
metric_name_regex: "shellies/(?P<deviceid>.*)/sensor/(?P<metricname>.*)"
qos: 0
cache:
timeout: 24h
metrics:
- prom_name: temperature
# The name of the metric in a MQTT JSON message
mqtt_name: status/temperature:0
# The field to extract in JSON payload
PayloadField: rh
# The prometheus help text for this metric
help: shelly temperature reading
# The prometheus type for this metric. Valid values are: "gauge" and "counter"
type: gauge
# A map of string to string for constant labels. This labels will be attached to every prometheus metric
const_labels:
sensor_type: shellyplusht
1 change: 1 addition & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ type MetricPerTopicConfig struct {
type MetricConfig struct {
PrometheusName string `yaml:"prom_name"`
MQTTName string `yaml:"mqtt_name"`
PayloadField string `yaml:"payload_field"`
SensorNameFilter Regexp `yaml:"sensor_name_filter"`
Help string `yaml:"help"`
ValueType string `yaml:"type"`
Expand Down
14 changes: 13 additions & 1 deletion pkg/metrics/extractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,19 @@ func NewMetricPerTopicExtractor(p Parser, metricNameRegex *config.Regexp) Extrac
return nil, nil
}

m, err := p.parseMetric(config, string(payload))
var rawValue interface{}
if config.PayloadField != "" {
parsed := gojsonq.New(gojsonq.SetSeparator(p.separator)).FromString(string(payload))
rawValue = parsed.Find(config.PayloadField)
parsed.Reset()
if rawValue == nil {
return nil, fmt.Errorf("failed to extract field %s from payload %s", config.PayloadField, payload)
}
} else {
rawValue = string(payload)
}

m, err := p.parseMetric(config, rawValue)
if err != nil {
return nil, fmt.Errorf("failed to parse metric: %w", err)
}
Expand Down

0 comments on commit 9da7b1b

Please sign in to comment.