センサで取得したCO2濃度のexporterを作ってprometheus + grafanaで可視化してみた
以前 https://blog.kefiwild.com/posts/raspberry_pi_co2_sense_mh16z/ で作ったMH-16Z CO2センサを使って、今回CO2濃度の推移を可視化してみました
prometheus exporter を作って、promtheus + grafana でCO2濃度のグラフを作りました
prometheus exporter の作成
以前作った https://github.com/kefi550/mh-z16-go これをライブラリとして整えて、
prometheus exporter として https://github.com/kefi550/co2-exporter を作りました
type prometheusExporter struct {
co2 *prometheus.Desc
sensorPortName string
}
func NewPrometheusExporter(sensorPortName string) *prometheusExporter {
return &prometheusExporter{
co2: prometheus.NewDesc(
"co2_ppm",
"co2 concentration ppm",
nil, nil,
),
sensorPortName: sensorPortName,
}
}
func (pe *prometheusExporter) Describe(ch chan<- *prometheus.Desc) {
ch <- pe.co2
}
func (pe *prometheusExporter) Collect(ch chan<- prometheus.Metric) {
value, err := getCo2Command(pe.sensorPortName)
if err != nil {
fmt.Println(err)
return
}
ch <- prometheus.MustNewConstMetric(pe.co2, prometheus.GaugeValue, value)
}
func getCo2Command(sensorPortName string) (float64, error) {
sensor, err := mhz16.Open(sensorPortName)
if err != nil {
return 0, fmt.Errorf("cant open mhz16 %w", err)
}
defer sensor.Close()
out, err := sensor.GetCo2()
if err != nil {
fmt.Println(err)
return 0, err
}
result := float64(out)
return result, nil
}
func main() {
portName := kingpin.Arg("port", "portName").Required().ExistingFile()
kingpin.Parse()
registry := prometheus.NewRegistry()
exporter := NewPrometheusExporter(*portName)
registry.MustRegister(exporter)
http.Handle("/metrics", promhttp.HandlerFor(registry, promhttp.HandlerOpts{}))
http.ListenAndServe(":2112", nil)
}
単にセンサで取得した値をそのままGaugeとしてexportするもの
こんな感じで動くものができました
$ curl http://192.168.0.31:2112/metrics
# HELP co2_ppm co2 concentration ppm
# TYPE co2_ppm gauge
co2_ppm 1352
grafanaで可視化
prometheusにメトリクスが入ってきた
grafanaでグラフを作成
感想
- いつの間にかCO2濃度が高くなって、いつの間にか眠くなる、眠るっていう状況が、CO2濃度が可視化されると改善されそう
- golangでライブラリを書いたの初めてだったので、いろいろつまずいたけど基本的なことを多く学べた
- 今回は超絶単純なexporterだったけどはじめてprometheus exporter作ってみて、かんたん、便利
今後の展望
- しきい値設定してアラートしたい
- 他の部屋とかでもセンシングしたいが、ラズパイの数にも限りがあるので、M5 stackなどでセンシングする -> AWS IoTとか使ってみたい