センサで取得した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とか使ってみたい