#include "OpenMetrics.h" OpenMetrics::OpenMetrics(Measurements &measure, Configuration &config, WifiConnector &wifiConnector, AgApiClient &apiClient) : measure(measure), config(config), wifiConnector(wifiConnector), apiClient(apiClient) {} OpenMetrics::~OpenMetrics() {} void OpenMetrics::setAirGradient(AirGradient *ag) { this->ag = ag; } const char *OpenMetrics::getApiContentType(void) { return "application/openmetrics-text; version=1.0.0; charset=utf-8"; } const char *OpenMetrics::getApi(void) { return "/metrics"; } String OpenMetrics::getPayload(void) { String response; String current_metric_name; const auto add_metric = [&](const String &name, const String &help, const String &type, const String &unit = "") { current_metric_name = "airgradient_" + name; if (!unit.isEmpty()) current_metric_name += "_" + unit; response += "# HELP " + current_metric_name + " " + help + "\n"; response += "# TYPE " + current_metric_name + " " + type + "\n"; if (!unit.isEmpty()) response += "# UNIT " + current_metric_name + " " + unit + "\n"; }; const auto add_metric_point = [&](const String &labels, const String &value) { response += current_metric_name + "{" + labels + "} " + value + "\n"; }; add_metric("info", "AirGradient device information", "info"); add_metric_point("airgradient_serial_number=\"" + ag->deviceId() + "\",airgradient_device_type=\"" + ag->getBoardName() + "\",airgradient_library_version=\"" + ag->getVersion() + "\"", "1"); add_metric("config_ok", "1 if the AirGradient device was able to successfully fetch its " "configuration from the server", "gauge"); add_metric_point("", apiClient.isFetchConfigurationFailed() ? "0" : "1"); add_metric( "post_ok", "1 if the AirGradient device was able to successfully send to the server", "gauge"); add_metric_point("", apiClient.isPostToServerFailed() ? "0" : "1"); add_metric( "wifi_rssi", "WiFi signal strength from the AirGradient device perspective, in dBm", "gauge", "dbm"); add_metric_point("", String(wifiConnector.RSSI())); // Initialize default invalid value for each measurements float _temp = utils::getInvalidTemperature(); float _hum = utils::getInvalidHumidity(); int pm01 = utils::getInvalidPmValue(); int pm25 = utils::getInvalidPmValue(); int pm10 = utils::getInvalidPmValue(); int pm03PCount = utils::getInvalidPmValue(); int co2 = utils::getInvalidCO2(); int atmpCompensated = utils::getInvalidTemperature(); int rhumCompensated = utils::getInvalidHumidity(); int tvoc = utils::getInvalidVOC(); int tvocRaw = utils::getInvalidVOC(); int nox = utils::getInvalidNOx(); int noxRaw = utils::getInvalidNOx(); if (config.hasSensorSHT) { _temp = measure.getFloat(Measurements::Temperature); _hum = measure.getFloat(Measurements::Humidity); atmpCompensated = _temp; rhumCompensated = _hum; } if (config.hasSensorPMS1) { pm01 = measure.get(Measurements::PM01); float correctedPm = measure.getCorrectedPM25(false, 1); pm25 = round(correctedPm); pm10 = measure.get(Measurements::PM10); pm03PCount = measure.get(Measurements::PM03_PC); } if (config.hasSensorSGP) { tvoc = measure.get(Measurements::TVOC); tvocRaw = measure.get(Measurements::TVOCRaw); nox = measure.get(Measurements::NOx); noxRaw = measure.get(Measurements::NOxRaw); } if (config.hasSensorS8) { co2 = measure.get(Measurements::CO2); } if (config.hasSensorPMS1) { if (utils::isValidPm(pm01)) { add_metric("pm1", "PM1.0 concentration as measured by the AirGradient PMS " "sensor, in micrograms per cubic meter", "gauge", "ugm3"); add_metric_point("", String(pm01)); } if (utils::isValidPm(pm25)) { add_metric("pm2d5", "PM2.5 concentration as measured by the AirGradient PMS " "sensor, in micrograms per cubic meter", "gauge", "ugm3"); add_metric_point("", String(pm25)); } if (utils::isValidPm(pm10)) { add_metric("pm10", "PM10 concentration as measured by the AirGradient PMS " "sensor, in micrograms per cubic meter", "gauge", "ugm3"); add_metric_point("", String(pm10)); } if (utils::isValidPm03Count(pm03PCount)) { add_metric("pm0d3", "PM0.3 concentration as measured by the AirGradient PMS " "sensor, in number of particules per 100 milliliters", "gauge", "p100ml"); add_metric_point("", String(pm03PCount)); } } if (config.hasSensorSGP) { if (utils::isValidVOC(tvoc)) { add_metric("tvoc_index", "The processed Total Volatile Organic Compounds (TVOC) index " "as measured by the AirGradient SGP sensor", "gauge"); add_metric_point("", String(tvoc)); } if (utils::isValidVOC(tvocRaw)) { add_metric("tvoc_raw", "The raw input value to the Total Volatile Organic Compounds " "(TVOC) index as measured by the AirGradient SGP sensor", "gauge"); add_metric_point("", String(tvocRaw)); } if (utils::isValidNOx(nox)) { add_metric("nox_index", "The processed Nitrous Oxide (NOx) index as measured by the " "AirGradient SGP sensor", "gauge"); add_metric_point("", String(nox)); } if (utils::isValidNOx(noxRaw)) { add_metric("nox_raw", "The raw input value to the Nitrous Oxide (NOx) index as " "measured by the AirGradient SGP sensor", "gauge"); add_metric_point("", String(noxRaw)); } } if (utils::isValidCO2(co2)) { add_metric("co2", "Carbon dioxide concentration as measured by the AirGradient S8 " "sensor, in parts per million", "gauge", "ppm"); add_metric_point("", String(co2)); } if (utils::isValidTemperature(_temp)) { add_metric( "temperature", "The ambient temperature as measured by the AirGradient SHT / PMS " "sensor, in degrees Celsius", "gauge", "celsius"); add_metric_point("", String(_temp)); } if (utils::isValidTemperature(atmpCompensated)) { add_metric("temperature_compensated", "The compensated ambient temperature as measured by the " "AirGradient SHT / PMS " "sensor, in degrees Celsius", "gauge", "celsius"); add_metric_point("", String(atmpCompensated)); } if (utils::isValidHumidity(_hum)) { add_metric( "humidity", "The relative humidity as measured by the AirGradient SHT sensor", "gauge", "percent"); add_metric_point("", String(_hum)); } if (utils::isValidHumidity(rhumCompensated)) { add_metric("humidity_compensated", "The compensated relative humidity as measured by the " "AirGradient SHT / PMS sensor", "gauge", "percent"); add_metric_point("", String(rhumCompensated)); } response += "# EOF\n"; return response; }