From a7b78521f1e2ec9be05060635fed324a5293709d Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Mon, 26 Mar 2018 15:07:17 +0200 Subject: [PATCH] Add BME280 Sensor - Plumb BME280 all the way through to Prometheus. - Add README detailing the diff between BME280 and BMP280 - Refactor source files to be *_drv.c to avoid naming clashes with upstream libraries. --- README.md | 1 - mos.yml | 3 ++ src/bme280_drv.c | 64 ++++++++++++++++++++++++++++++ src/{dht.c => dht_drv.c} | 37 +++++------------ src/mgos_prometheus_sensors.c | 10 +++-- src/{veml6075.c => veml6075_drv.c} | 25 +++--------- 6 files changed, 87 insertions(+), 53 deletions(-) create mode 100644 src/bme280_drv.c rename src/{dht.c => dht_drv.c} (69%) rename src/{veml6075.c => veml6075_drv.c} (68%) diff --git a/README.md b/README.md index badba04..bf6d0e0 100644 --- a/README.md +++ b/README.md @@ -41,4 +41,3 @@ UV{band="UVA",sensor="0",type="VEML6075"} 0 UV{band="UVB",sensor="0",type="VEML6075"} 2 UVIndex{sensor="0",type="VEML6075"} 0.00125 ``` - diff --git a/mos.yml b/mos.yml index f627150..b15a10c 100644 --- a/mos.yml +++ b/mos.yml @@ -20,6 +20,8 @@ config_schema: - ["sensors.dht_period", "i", 3, {title: "Sample period in seconds for DHT sensors"}] - ["sensors.veml6075_i2caddr", "i", 0x10, {title: "I2C Address for VEML6075 sensor"}] - ["sensors.veml6075_period", "i", 3, {title: "Sample period in seconds for VEML6075 sensor"}] + - ["sensors.bme280_i2caddr", "i", 0x77, {title: "I2C Address for BME280 sensor"}] + - ["sensors.bme280_period", "i", 3, {title: "Sample period in seconds for BME280 sensor"}] - ["sensors.pushgateway_period", "i", 10, {title: "Period in seconds for Prometheus Pushgateway POSTs"}] - ["prometheus.pushgateway", "prometheus.example.net:9091"] @@ -28,6 +30,7 @@ config_schema: # Note: To use sensor libraries, include one or more of these in your application mos.yml: # - 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 libs: - origin: https://github.com/mongoose-os-libs/prometheus-metrics diff --git a/src/bme280_drv.c b/src/bme280_drv.c new file mode 100644 index 0000000..001c48e --- /dev/null +++ b/src/bme280_drv.c @@ -0,0 +1,64 @@ +#include "mgos.h" + +#ifdef MGOS_HAVE_BME280 +#include "mgos_bme280.h" +#include "mgos_config.h" +#include "mgos_prometheus_metrics.h" +#include "mgos_prometheus_sensors.h" + +static struct mgos_bme280 *s_bme280; +static struct mgos_bme280_data s_bme280_data; + +static void bme280_prometheus_metrics(struct mg_connection *nc, void *user_data) { + + if (!s_bme280) return; + + mgos_prometheus_metrics_printf(nc, GAUGE, + "pressure", "Barometer pressure in HPa", + "{sensor=\"0\", type=\"BME280\"} %f", s_bme280_data.press); + + mgos_prometheus_metrics_printf(nc, GAUGE, + "temperature", "Temperature in Celcius", + "{sensor=\"0\",type=\"BME280\"} %f", s_bme280_data.temp); + + if (mgos_bme280_is_bme280(s_bme280)) { + mgos_prometheus_metrics_printf(nc, GAUGE, + "humidity", "Relative humidity in percent", + "{sensor=\"0\",type=\"BME280\"} %f", s_bme280_data.humid); + } + + (void) user_data; +} + +static void bme280_timer_cb(void *user_data) { + double start; + uint32_t usecs=0; + + start=mgos_uptime(); + mgos_bme280_read(s_bme280, &s_bme280_data); + usecs=1000000*(mgos_uptime()-start); + + if (mgos_bme280_is_bme280(s_bme280)) { + LOG(LL_INFO, ("sensor=0 humidity=%.1f%% temperature=%.1fC pressure=%.1fHPa usecs=%u", s_bme280_data.humid, s_bme280_data.temp, s_bme280_data.press, usecs)); + } else { + LOG(LL_INFO, ("sensor=0 temperature=%.1fC pressure=%.1fHPa usecs=%u", s_bme280_data.temp, s_bme280_data.press, usecs)); + } + + (void) user_data; +} + +void bme280_drv_init() { + s_bme280 = mgos_bme280_i2c_create(mgos_sys_config_get_sensors_bme280_i2caddr()); + if (s_bme280) { + mgos_set_timer(mgos_sys_config_get_sensors_bme280_period()*1000, true, bme280_timer_cb, NULL); + mgos_prometheus_metrics_add_handler(bme280_prometheus_metrics, NULL); + } else { + LOG(LL_ERROR, ("Could not create BME280 sensor on I2C address 0x%02x", mgos_sys_config_get_sensors_bme280_i2caddr())); + } +} + +#else +void bme280_drv_init() { + LOG(LL_ERROR, ("BME280 disabled, include library in mos.yml to enable")); +} +#endif diff --git a/src/dht.c b/src/dht_drv.c similarity index 69% rename from src/dht.c rename to src/dht_drv.c index 7cfe8fd..960457e 100644 --- a/src/dht.c +++ b/src/dht_drv.c @@ -19,36 +19,17 @@ struct dht_sensor { static struct dht_sensor *s_dht_sensor[MAX_DHT]; static int s_num_dht = 0; -static void print_chunk(struct mg_connection *nc, char *name, char *fmt, ...) { - char chunk[500]; - int chunklen=0; - va_list ap; - - snprintf(chunk, sizeof(chunk), "%s%s", name, fmt[0]=='{' ? "" : " "); - va_start(ap, fmt); - vsnprintf(chunk+strlen(chunk), sizeof(chunk)-strlen(chunk), fmt, ap); - va_end(ap); - strncat(chunk, "\n", sizeof(chunk)); - chunklen=strlen(chunk); - LOG(LL_DEBUG, ("Chunk '%s' with length %d", chunk, chunklen)); - mg_printf(nc, "%X\r\n%s\r\n", chunklen, chunk); - -} - static void dht_prometheus_metrics(struct mg_connection *nc, void *user_data) { int i; - // BUG -- repeated HELP and TYPE makes Prometheus parser bork :( - mgos_prometheus_metrics_printf(nc, GAUGE, - "temperature", "Temperature in celcius", - "{sensor=\"0\",type=\"DHT\"} %f", s_dht_sensor[0]->temp); - mgos_prometheus_metrics_printf(nc, GAUGE, - "humidity", "Relative humidity percentage", - "{sensor=\"0\",type=\"DHT\"} %f", s_dht_sensor[0]->humidity); + for (i=0; itemp); + mgos_prometheus_metrics_printf(nc, GAUGE, + "humidity", "Relative humidity percentage", + "{sensor=\"%d\",type=\"DHT\"} %f", i, s_dht_sensor[i]->humidity); - for (i=1; itemp); - print_chunk(nc, "humidity", "{sensor=\"%d\",type=\"DHT\"} %f", i, s_dht_sensor[i]->humidity); } (void) user_data; @@ -106,7 +87,7 @@ float mgos_prometheus_sensors_dht_get_humidity(uint8_t idx) { return s_dht_sensor[idx]->humidity; } -void dht_init() { +void dht_drv_init() { char *tok; memset(s_dht_sensor, 0, sizeof (struct mgos_dht_sensor *) * MAX_DHT); @@ -124,7 +105,7 @@ void dht_init() { } #else -void dht_init() { +void dht_drv_init() { LOG(LL_ERROR, ("DHT disabled, include library in mos.yml to enable")); } #endif diff --git a/src/mgos_prometheus_sensors.c b/src/mgos_prometheus_sensors.c index eddd85a..6411f7e 100644 --- a/src/mgos_prometheus_sensors.c +++ b/src/mgos_prometheus_sensors.c @@ -2,8 +2,9 @@ #include "mgos_prometheus_metrics.h" #include "mgos_prometheus_sensors.h" -void dht_init(); -void veml6075_init(); +void dht_drv_init(); +void veml6075_drv_init(); +void bme280_drv_init(); static void pushgateway_timer(void *user_data) { mgos_prometheus_metrics_push(MGOS_APP, mgos_sys_config_get_device_id()); @@ -11,8 +12,9 @@ static void pushgateway_timer(void *user_data) { } bool mgos_prometheus_sensors_init(void) { - dht_init(); - veml6075_init(); + dht_drv_init(); + veml6075_drv_init(); + bme280_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); return true; diff --git a/src/veml6075.c b/src/veml6075_drv.c similarity index 68% rename from src/veml6075.c rename to src/veml6075_drv.c index 3604f34..7a085db 100644 --- a/src/veml6075.c +++ b/src/veml6075_drv.c @@ -8,28 +8,13 @@ static struct mgos_veml6075 *s_veml6075; -static void print_chunk(struct mg_connection *nc, char *name, char *fmt, ...) { - char chunk[500]; - int chunklen=0; - va_list ap; - - snprintf(chunk, sizeof(chunk), "%s%s", name, fmt[0]=='{' ? "" : " "); - va_start(ap, fmt); - vsnprintf(chunk+strlen(chunk), sizeof(chunk)-strlen(chunk), fmt, ap); - va_end(ap); - strncat(chunk, "\n", sizeof(chunk)); - chunklen=strlen(chunk); -// LOG(LL_DEBUG, ("Chunk '%s' with length %d", chunk, chunklen)); - mg_printf(nc, "%X\r\n%s\r\n", chunklen, chunk); -} - static void veml6075_prometheus_metrics(struct mg_connection *nc, void *user_data) { - // BUG -- repeated HELP and TYPE makes Prometheus parser bork :( mgos_prometheus_metrics_printf(nc, GAUGE, "UV", "Ultra Violet light intensity, in sensor counts", "{band=\"UVA\",type=\"VEML6075\", sensor=\"0\"} %f", mgos_veml6075_getUVA(s_veml6075)); - print_chunk(nc, "UV", "{band=\"UVB\",type=\"VEML6075\", sensor=\"0\"} %f", mgos_veml6075_getUVB(s_veml6075)); - + mgos_prometheus_metrics_printf(nc, GAUGE, + "UV", "Ultra Violet light intensity, in sensor counts", + "{band=\"UVB\",type=\"VEML6075\", sensor=\"0\"} %f", mgos_veml6075_getUVB(s_veml6075)); mgos_prometheus_metrics_printf(nc, GAUGE, "UVIndex", "2: Low, 5.5 Moderate, 7.5 High, 10.5 Very High, else Extreme", "{sensor=\"0\",type=\"VEML6075\"} %f", mgos_veml6075_getUVIndex(s_veml6075)); @@ -52,7 +37,7 @@ static void veml6075_timer_cb(void *user_data) { (void) user_data; } -void veml6075_init() { +void veml6075_drv_init() { s_veml6075 = mgos_veml6075_create(mgos_sys_config_get_sensors_veml6075_i2caddr()); if (s_veml6075) { mgos_set_timer(mgos_sys_config_get_sensors_veml6075_period()*1000, true, veml6075_timer_cb, NULL); @@ -61,7 +46,7 @@ void veml6075_init() { } #else -void veml6075_init() { +void veml6075_drv_init() { LOG(LL_ERROR, ("VEML6075 disabled, include library in mos.yml to enable")); } #endif