From 08a31ea9041f3a6dee207e19fa171a9d97412944 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Mon, 10 Oct 2022 23:18:11 +0200 Subject: [PATCH] AQI: Update to new interface specification --- aqi/integrationpluginaqi.cpp | 114 ++++++++++++++++++++++++++-------- aqi/integrationpluginaqi.h | 4 ++ aqi/integrationpluginaqi.json | 62 ++++++------------ 3 files changed, 111 insertions(+), 69 deletions(-) diff --git a/aqi/integrationpluginaqi.cpp b/aqi/integrationpluginaqi.cpp index 4acb1528..1d5261b5 100644 --- a/aqi/integrationpluginaqi.cpp +++ b/aqi/integrationpluginaqi.cpp @@ -34,6 +34,67 @@ #include +// The API reports American AQI index values, but nymea interfaces require actual values +QList> pm10AQI = { + {55,54}, + {100,154}, + {150,254}, + {200,354}, + {300,424}, + {400,504}, + {500,604} +}; + +QList> pm25AQI = { + {50,12}, + {100,35.4}, + {150,55.4}, + {200,150.4}, + {300,250.4}, + {400,350.4}, + {500,500} +}; + +QList> so2AQI = { + {50,35}, + {100,75}, + {150,185}, + {200,304}, + {300,604}, + {400,804}, + {500,1004} +}; + +QList> no2AQI = { + {50,53}, + {100,100}, + {150,360}, + {200,649}, + {300,1294}, + {400,1649}, + {500,2049} +}; + +QList> o3AQI = { + {50,54}, + {100,70}, + {150,85}, + {200,105}, + {300,200}, + {400,504}, + {500,604} +}; + +QList> coAQI = { + {50,4.4}, + {100,9.4}, + {150,12.4}, + {200,15.4}, + {300,30.4}, + {400,40.4}, + {500,50.4} +}; + IntegrationPluginAqi::IntegrationPluginAqi() { connect(this, &IntegrationPluginAqi::configValueChanged, this, [this] (const ParamTypeId ¶mTypeId, const QVariant &value) { @@ -144,6 +205,26 @@ bool IntegrationPluginAqi::createAqiConnection() return true; } +double IntegrationPluginAqi::convertFromAQI(int aqi, const QList> &map) const +{ + int il = 0, ih = 0; + double vl = 0, vh = 0; + + int index = 0; + while (aqi > map.at(index).first && index < map.count()) { + index++; + } + + if (index > 0) { + il = map.at(index - 1).first; + vl = map.at(index - 1).second; + } + ih = map.at(index).first; + vh = map.at(index).second; + double value = (aqi - il) * (vh - vl) / (ih - il) + vl; + return value; +} + void IntegrationPluginAqi::thingRemoved(Thing *thing) { Q_UNUSED(thing) @@ -172,37 +253,18 @@ void IntegrationPluginAqi::onAirQualityDataReceived(QUuid requestId, AirQualityI if (!thing) return; + thing->setStateValue(airQualityIndexConnectedStateTypeId, true); - thing->setStateValue(airQualityIndexCoStateTypeId, data.co); thing->setStateValue(airQualityIndexHumidityStateTypeId, data.humidity); thing->setStateValue(airQualityIndexTemperatureStateTypeId, data.temperature); thing->setStateValue(airQualityIndexPressureStateTypeId, data.pressure); - thing->setStateValue(airQualityIndexO3StateTypeId, data.o3); - thing->setStateValue(airQualityIndexNo2StateTypeId, data.no2); - thing->setStateValue(airQualityIndexSo2StateTypeId, data.so2); - thing->setStateValue(airQualityIndexPm10StateTypeId, data.pm10); - thing->setStateValue(airQualityIndexPm25StateTypeId, data.pm25); + thing->setStateValue(airQualityIndexCoStateTypeId, convertFromAQI(data.co, coAQI)); + thing->setStateValue(airQualityIndexO3StateTypeId, convertFromAQI(data.o3, o3AQI)); + thing->setStateValue(airQualityIndexNo2StateTypeId, convertFromAQI(data.no2, no2AQI)); + thing->setStateValue(airQualityIndexSo2StateTypeId, convertFromAQI(data.so2, so2AQI)); + thing->setStateValue(airQualityIndexPm10StateTypeId, convertFromAQI(data.pm10, pm10AQI)); + thing->setStateValue(airQualityIndexPm25StateTypeId, convertFromAQI(data.pm25, pm25AQI)); thing->setStateValue(airQualityIndexWindSpeedStateTypeId, data.windSpeed); - - if (data.pm25 <= 50.00) { - thing->setStateValue(airQualityIndexAirQualityStateTypeId, "Good"); - thing->setStateValue(airQualityIndexCautionaryStatementStateTypeId, tr("None")); - } else if ((data.pm25 > 50.00) && (data.pm25 <= 100.00)) { - thing->setStateValue(airQualityIndexAirQualityStateTypeId, "Moderate"); - thing->setStateValue(airQualityIndexCautionaryStatementStateTypeId, tr("Active children and adults, and people with respiratory disease, such as asthma, should limit prolonged outdoor exertion.")); - } else if ((data.pm25 > 100.00) && (data.pm25 <= 150.00)) { - thing->setStateValue(airQualityIndexAirQualityStateTypeId, "Unhealthy for Sensitive Groups"); - thing->setStateValue(airQualityIndexCautionaryStatementStateTypeId, tr("Active children and adults, and people with respiratory disease, such as asthma, should limit prolonged outdoor exertion.")); - } else if ((data.pm25 > 150.00) && (data.pm25 <= 200.00)) { - thing->setStateValue(airQualityIndexAirQualityStateTypeId, "Unhealthy"); - thing->setStateValue(airQualityIndexCautionaryStatementStateTypeId, tr("Active children and adults, and people with respiratory disease, such as asthma, should avoid prolonged outdoor exertion; everyone else, especially children, should limit prolonged outdoor exertion")); - } else if ((data.pm25 > 200.00) && (data.pm25 <= 300.00)) { - thing->setStateValue(airQualityIndexAirQualityStateTypeId, "Very Unhealthy"); - thing->setStateValue(airQualityIndexCautionaryStatementStateTypeId, tr("Active children and adults, and people with respiratory disease, such as asthma, should avoid all outdoor exertion; everyone else, especially children, should limit outdoor exertion.")); - } else { - thing->setStateValue(airQualityIndexAirQualityStateTypeId, "Hazardous"); - thing->setStateValue(airQualityIndexCautionaryStatementStateTypeId, tr("Everyone should avoid all outdoor exertion")); - } } } diff --git a/aqi/integrationpluginaqi.h b/aqi/integrationpluginaqi.h index 8ca2c2c9..b3c115e0 100644 --- a/aqi/integrationpluginaqi.h +++ b/aqi/integrationpluginaqi.h @@ -36,6 +36,8 @@ #include "network/networkaccessmanager.h" #include "airqualityindex.h" +#include "extern-plugininfo.h" + #include #include #include @@ -65,6 +67,8 @@ private: QString getApiKey(); bool createAqiConnection(); + double convertFromAQI(int aqi, const QList > &map) const; + private slots: void onPluginTimer(); void onRequestExecuted(QUuid requestId, bool success); diff --git a/aqi/integrationpluginaqi.json b/aqi/integrationpluginaqi.json index 349b79ab..fb21aaaa 100644 --- a/aqi/integrationpluginaqi.json +++ b/aqi/integrationpluginaqi.json @@ -22,7 +22,7 @@ "id": "23ea32c9-38b0-4155-bacc-3afa8c09f6ee", "name": "airQualityIndex", "displayName": "Air quality index", - "interfaces": ["windspeedsensor", "humiditysensor", "pressuresensor", "temperaturesensor", "connectable"], + "interfaces": ["o3sensor", "cosensor", "no2sensor", "pm10sensor", "pm25sensor", "windspeedsensor", "humiditysensor", "pressuresensor", "temperaturesensor", "connectable"], "createMethods": ["discovery", "user"], "paramTypes": [ { @@ -45,40 +45,14 @@ "id": "7b9135cd-2461-4d33-b2b3-3dc600983895", "name": "connected", "displayName": "Connected", - "displayNameEvent": "Connected changed", "type": "bool", "defaultValue": false, "cached": false }, - { - "id": "33a3329a-4117-4488-aa18-91c76056ed6e", - "name": "airQuality", - "displayName": "Air quality", - "displayNameEvent": "Air quality changed", - "type": "QString", - "possibleValues": [ - "Good", - "Moderate", - "Unhealthy for Sensitive Groups", - "Unhealthy", - "Very unhealthy", - "Hazardous" - ], - "defaultValue": "Good" - }, - { - "id": "cfece671-4e88-4c49-9456-e3f8f7c79ab3", - "name": "cautionaryStatement", - "displayName": "Cautionary statement", - "displayNameEvent": "Cautionary statement changed", - "type": "QString", - "defaultValue": "-" - }, { "id": "8385f3d5-62f7-482e-927c-b5d61a70d607", "name": "stationName", "displayName": "Station name", - "displayNameEvent": "Station name changed", "type": "QString", "defaultValue": "Undefined" }, @@ -86,50 +60,56 @@ "id": "bc8c4c83-d229-4be4-8732-bc4f2390f399", "name": "pm25", "displayName": "Fine particles pollution level (PM2.5)", - "displayNameEvent": "Fine particles pollution level (PM2.5) changed", - "type": "int", - "defaultValue": 0 + "type": "double", + "defaultValue": 0, + "unit": "MicroGrammPerCubicalMeter", + "minValue": 0, + "maxValue": 500 }, { "id": "24b41ec4-e26b-4dfb-b52c-8e2b1bbdafc6", "name": "pm10", "displayName": "Coarse dust particles pollution level (PM10)", - "displayNameEvent": "Coarse dust particles pollution level (PM10) changed", - "type": "int", + "type": "double", + "unit": "MicroGrammPerCubicalMeter", + "minValue": 0, + "maxValue": 500, "defaultValue": 0 }, { "id": "4e88526d-009f-4820-9a84-09b3646d23c9", "name": "o3", "displayName": "Ozone level (O3)", - "displayNameEvent": "Ozone level (O3) changed", - "unit": "", + "unit": "MicroGrammPerCubicalMeter", "type": "double", + "minValue": 0, + "maxValue": 500, "defaultValue": 0 }, { "id": "6ed6c505-f36e-44c4-a982-f395b04e539b", "name": "no2", "displayName": "Nitrogen Dioxide level (NO2)", - "displayNameEvent": "Nitrogen Dioxide level (NO2) changed", - "unit": "", + "unit": "MicroGrammPerCubicalMeter", "type": "double", + "minValue": 0, + "maxValue": 800, "defaultValue": 0 }, { "id": "54ac72f3-6444-46a8-a43d-210c2a6fbfb5", "name": "co", "displayName": "Carbon monoxide level (CO)", - "displayNameEvent": "Carbon monoxide level (CO) changed", - "unit": "", + "unit": "PartsPerMillion", "type": "double", + "minValue": 0, + "maxValue": 255, "defaultValue": 0 }, { "id": "f3a05e65-a9b3-48fd-be43-688d4c293cc9", "name": "so2", "displayName": "Sulfur dioxide level (SO2)", - "displayNameEvent": "Sulfur dioxide level (SO2) changed", "unit": "", "type": "double", "defaultValue": 0 @@ -138,7 +118,6 @@ "id": "94219802-0a82-4761-99b3-c6b6dfc096db", "name": "temperature", "displayName": "Temperature", - "displayNameEvent": "Temperature changed", "unit": "DegreeCelsius", "type": "double", "defaultValue": 0 @@ -147,7 +126,6 @@ "id": "4fc45fca-25ab-45a0-b862-817eea1f51e3", "name": "humidity", "displayName": "Humidity", - "displayNameEvent": "Humidity changed", "unit": "Percentage", "type": "double", "maxValue": 100, @@ -158,7 +136,6 @@ "id": "5f799040-08f8-44d1-aa0a-4cab7caad839", "name": "pressure", "displayName": "Pressure", - "displayNameEvent": "Pressure changed", "unit": "MilliBar", "type": "double", "defaultValue": 0 @@ -167,7 +144,6 @@ "id": "c4366608-2511-428b-964e-2ad9e37f8f3c", "name": "windSpeed", "displayName": "Wind speed", - "displayNameEvent": "Wind speed changed", "unit": "MeterPerSecond", "type": "double", "defaultValue": 0