AQI: Update to new interface specification

master
Michael Zanetti 2022-10-10 23:18:11 +02:00
parent da48352f5d
commit 08a31ea904
3 changed files with 111 additions and 69 deletions

View File

@ -34,6 +34,67 @@
#include <QNetworkAccessManager>
// The API reports American AQI index values, but nymea interfaces require actual values
QList<QPair<int,double>> pm10AQI = {
{55,54},
{100,154},
{150,254},
{200,354},
{300,424},
{400,504},
{500,604}
};
QList<QPair<int,double>> pm25AQI = {
{50,12},
{100,35.4},
{150,55.4},
{200,150.4},
{300,250.4},
{400,350.4},
{500,500}
};
QList<QPair<int,double>> so2AQI = {
{50,35},
{100,75},
{150,185},
{200,304},
{300,604},
{400,804},
{500,1004}
};
QList<QPair<int,double>> no2AQI = {
{50,53},
{100,100},
{150,360},
{200,649},
{300,1294},
{400,1649},
{500,2049}
};
QList<QPair<int,double>> o3AQI = {
{50,54},
{100,70},
{150,85},
{200,105},
{300,200},
{400,504},
{500,604}
};
QList<QPair<int,double>> 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 &paramTypeId, const QVariant &value) {
@ -144,6 +205,26 @@ bool IntegrationPluginAqi::createAqiConnection()
return true;
}
double IntegrationPluginAqi::convertFromAQI(int aqi, const QList<QPair<int, double>> &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"));
}
}
}

View File

@ -36,6 +36,8 @@
#include "network/networkaccessmanager.h"
#include "airqualityindex.h"
#include "extern-plugininfo.h"
#include <QTimer>
#include <QUrl>
#include <QHostAddress>
@ -65,6 +67,8 @@ private:
QString getApiKey();
bool createAqiConnection();
double convertFromAQI(int aqi, const QList<QPair<int, double> > &map) const;
private slots:
void onPluginTimer();
void onRequestExecuted(QUuid requestId, bool success);

View File

@ -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