From fcfd65295f72c3d57cf50d89e8794aff13d34e0b Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Tue, 10 Apr 2018 22:00:38 +0200 Subject: [PATCH] Add CCS811 --- README.md | 17 ++++++++- mos.yml | 7 ++++ src/ccs811_drv.c | 72 +++++++++++++++++++++++++++++++++++ src/mgos_prometheus_sensors.c | 2 + 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/ccs811_drv.c diff --git a/README.md b/README.md index d8bf687..0782fb5 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ address on the bus, normally `0x40`, but configurable with `sensors.htu21df_i2ca in `mos.yml`. The chip is polled with a period of `sensors.htu21df_period` which defaults to 3 seconds, each sensor reading takes approximately 105ms. -Please see the upstream [source](https://github.com/mongoose-os-libs/si7021-i2c) +Please see the upstream [source](https://github.com/mongoose-os-libs/htu21df-i2c) for more information on the driver. Reported values (all types are gauges): @@ -125,3 +125,18 @@ temperature{sensor="0",type="HTU21DF"} 18.5 humidity{sensor="0",type="HTU21DF"} 55.8 ``` +### CCS811 + +This is using `ccs811-i2c` library; one sensor is allowed based on I2C +address on the bus, normally `0x5A`, but configurable with `sensors.ccs811_i2caddr` +in `mos.yml`. The chip is polled with a period of `sensors.ccs811_period` +which defaults to 3 seconds, each sensor reading takes approximately 5ms. + +Please see the upstream [source](https://github.com/mongoose-os-libs/ccs811-i2c) +for more information on the driver. + +Reported values (all types are gauges): +``` +eco2{sensor="0",type="CCS811"} 7992 +tvoc{sensor="0",type="CCS811"} 1156 +``` diff --git a/mos.yml b/mos.yml index c37c58d..a0cdf21 100644 --- a/mos.yml +++ b/mos.yml @@ -30,6 +30,8 @@ config_schema: - ["sensors.si7021_period", "i", 3, {title: "Sample period in seconds for SI7021 sensor"}] - ["sensors.mcp9808_i2caddr", "i", 0x18, {title: "I2C Address for MCP9808 sensor"}] - ["sensors.mcp9808_period", "i", 3, {title: "Sample period in seconds for MCP9808 sensor"}] + - ["sensors.ccs811_i2caddr", "i", 0x5a, {title: "I2C Address for CCS811 sensor"}] + - ["sensors.ccs811_period", "i", 3, {title: "Sample period in seconds for CCS811 sensor"}] - ["sensors.pushgateway_period", "i", 10, {title: "Period in seconds for Prometheus Pushgateway POSTs"}] - ["prometheus.pushgateway", "prometheus.example.net:9091"] @@ -39,6 +41,11 @@ config_schema: # - origin: https://github.com/mongoose-os-libs/dht # - origin: https://github.com/mongoose-os-libs/veml6075-i2c # - origin: https://github.com/mongoose-os-libs/bme280 +# - origin: https://github.com/mongoose-os-libs/sht31-i2c +# - origin: https://github.com/mongoose-os-libs/si7021-i2c +# - origin: https://github.com/mongoose-os-libs/htu21df-i2c +# - origin: https://github.com/mongoose-os-libs/mcp9808-i2c +# - origin: https://github.com/mongoose-os-libs/ccs811-i2c libs: - origin: https://github.com/mongoose-os-libs/prometheus-metrics version: latest diff --git a/src/ccs811_drv.c b/src/ccs811_drv.c new file mode 100644 index 0000000..e5d4b67 --- /dev/null +++ b/src/ccs811_drv.c @@ -0,0 +1,72 @@ +#include "mgos.h" + +#ifdef MGOS_HAVE_CCS811_I2C +#include "mgos_ccs811.h" +#include "mgos_config.h" +#include "mgos_prometheus_metrics.h" +#include "mgos_prometheus_sensors.h" + +static struct mgos_ccs811 *s_ccs811; + +static void ccs811_prometheus_metrics(struct mg_connection *nc, void *user_data) { + struct mgos_ccs811_stats stats; + + mgos_prometheus_metrics_printf(nc, GAUGE, + "eco2", "Effective CO2 in ppm", + "{sensor=\"0\",type=\"CCS811\"} %f", mgos_ccs811_get_eco2(s_ccs811)); + mgos_prometheus_metrics_printf(nc, GAUGE, + "tvoc", "Total Volatile Organic Compounds in ppb", + "{sensor=\"0\",type=\"CCS811\"} %f", mgos_ccs811_get_tvoc(s_ccs811)); + + if (mgos_ccs811_getStats(s_ccs811, &stats)) { + mgos_prometheus_metrics_printf(nc, COUNTER, + "sensor_read_total", "Total reads from sensor", + "{sensor=\"0\",type=\"CCS811\"} %u", stats.read); + mgos_prometheus_metrics_printf(nc, COUNTER, + "sensor_read_success_total", "Total successful reads from sensor", + "{sensor=\"0\",type=\"CCS811\"} %u", stats.read_success); + mgos_prometheus_metrics_printf(nc, COUNTER, + "sensor_read_success_cached_total", "Total successful cached reads from sensor", + "{sensor=\"0\",type=\"CCS811\"} %u", stats.read_success_cached); + uint32_t errors = stats.read - stats.read_success - stats.read_success_cached; + mgos_prometheus_metrics_printf(nc, COUNTER, + "sensor_read_error_total", "Total unsuccessful reads from sensor", + "{sensor=\"0\",type=\"CCS811\"} %u", errors); + mgos_prometheus_metrics_printf(nc, COUNTER, + "sensor_read_success_usecs_total", "Total microseconds spent in reads from sensor", + "{sensor=\"0\",type=\"CCS811\"} %f", stats.read_success_usecs); + } + + (void)user_data; +} + +static void ccs811_timer_cb(void *user_data) { + float eco2, tvoc; + struct mgos_ccs811_stats stats_before, stats_after; + uint32_t usecs = 0; + + mgos_ccs811_getStats(s_ccs811, &stats_before); + eco2 = mgos_ccs811_get_eco2(s_ccs811); + tvoc = mgos_ccs811_get_tvoc(s_ccs811); + mgos_ccs811_getStats(s_ccs811, &stats_after); + + usecs = stats_after.read_success_usecs - stats_before.read_success_usecs; + LOG(LL_INFO, ("CCS811 sensor=0 eCO2=%.0fppm TVOC=%.0fppb usecs=%u", eco2, tvoc, usecs)); + + (void)user_data; +} + +void ccs811_drv_init() { + s_ccs811 = mgos_ccs811_create(mgos_i2c_get_global(), mgos_sys_config_get_sensors_ccs811_i2caddr()); + if (s_ccs811) { + mgos_set_timer(mgos_sys_config_get_sensors_ccs811_period() * 1000, true, ccs811_timer_cb, NULL); + mgos_prometheus_metrics_add_handler(ccs811_prometheus_metrics, NULL); + } +} + +#else +void ccs811_drv_init() { + LOG(LL_ERROR, ("CCS811 disabled, include library in mos.yml to enable")); +} + +#endif diff --git a/src/mgos_prometheus_sensors.c b/src/mgos_prometheus_sensors.c index 2795b77..dbecb04 100644 --- a/src/mgos_prometheus_sensors.c +++ b/src/mgos_prometheus_sensors.c @@ -9,6 +9,7 @@ void sht31_drv_init(); void si7021_drv_init(); void htu21df_drv_init(); void mcp9808_drv_init(); +void ccs811_drv_init(); static void pushgateway_timer(void *user_data) { mgos_prometheus_metrics_push(MGOS_APP, mgos_sys_config_get_device_id()); @@ -23,6 +24,7 @@ bool mgos_prometheus_sensors_init(void) { sht31_drv_init(); htu21df_drv_init(); mcp9808_drv_init(); + ccs811_drv_init(); if (mgos_sys_config_get_sensors_pushgateway_period() > 0) { mgos_set_timer(mgos_sys_config_get_sensors_pushgateway_period() * 1000, true, pushgateway_timer, NULL);