aqi: Add Qt6 support

This commit is contained in:
Simon Stürz 2025-08-07 14:38:10 +02:00
parent 2575f43518
commit 3257413b74
5 changed files with 63 additions and 39 deletions

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Copyright 2013 - 2025, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@ -54,8 +54,9 @@ QUuid AirQualityIndex::searchByName(const QString &name)
{
if (m_apiKey.isEmpty()) {
qCWarning(dcAirQualityIndex()) << "API key is not set, not sending request";
return "";
return QUuid();
}
QUuid requestId = QUuid::createUuid();;
QUrl url;
url.setUrl(m_baseUrl);
@ -75,13 +76,14 @@ QUuid AirQualityIndex::searchByName(const QString &name)
// Check HTTP status code
if (status != 200 || reply->error() != QNetworkReply::NoError) {
if (status == 400) {
if (status == 400)
qCWarning(dcAirQualityIndex()) << "Request error due to exceeded request quota";
}
requestExecuted(requestId, false);
emit requestExecuted(requestId, false);
qCWarning(dcAirQualityIndex()) << "Request error:" << status << reply->errorString();
return;
}
QByteArray rawData = reply->readAll();
qCDebug(dcAirQualityIndex()) << "Search response" << rawData;
@ -95,7 +97,7 @@ QUuid AirQualityIndex::searchByName(const QString &name)
QList<Station> stations;
QVariantList stationList = doc.toVariant().toMap().value("data").toList();
foreach (QVariant stationVariant, stationList) {
foreach (const QVariant &stationVariant, stationList) {
Station station;
station.aqi = stationVariant.toMap().value("aqi").toInt();
station.idx = stationVariant.toMap().value("idx").toInt();
@ -107,10 +109,11 @@ QUuid AirQualityIndex::searchByName(const QString &name)
station.location.longitude = stationVariant.toMap().value("city").toMap().value("geo").toList().last().toDouble();
stations.append(station);
}
if (!stations.isEmpty())
emit stationsReceived(requestId, stations);
requestExecuted(requestId, true);
emit requestExecuted(requestId, true);
});
return requestId;
}
@ -119,18 +122,23 @@ QUuid AirQualityIndex::getDataByIp()
{
if (m_apiKey.isEmpty()) {
qCWarning(dcAirQualityIndex()) << "API key is not set, not sending request";
return "";
return QUuid();
}
QUuid requestId = QUuid::createUuid();
QUrl url;
url.setUrl(m_baseUrl);
url.setPath("/feed/here/");
QUrlQuery query;
query.addQueryItem("token", m_apiKey);
url.setQuery(query);
QNetworkRequest request;
request.setUrl(url);
request.setRawHeader("User-Agent", "nymea");
qCDebug(dcAirQualityIndex()) << "Get data by IP request" << url.toString();
QNetworkReply *reply = m_networkAccessManager->get(request);
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
@ -139,17 +147,20 @@ QUuid AirQualityIndex::getDataByIp()
// Check HTTP status code
if (status != 200 || reply->error() != QNetworkReply::NoError) {
if (status == 400) {
if (status == 400)
qCWarning(dcAirQualityIndex()) << "Request error due to exceeded request quota";
}
requestExecuted(requestId, false);
emit requestExecuted(requestId, false);
qCWarning(dcAirQualityIndex()) << "Request error:" << status << reply->errorString();
return;
}
if (!parseData(requestId, reply->readAll()))
requestExecuted(requestId, false);
requestExecuted(requestId, true);
emit requestExecuted(requestId, false);
emit requestExecuted(requestId, true);
});
return requestId;
}
@ -157,19 +168,23 @@ QUuid AirQualityIndex::getDataByGeolocation(double lat, double lng)
{
if (m_apiKey.isEmpty()) {
qCWarning(dcAirQualityIndex()) << "API key is not set, not sending request";
return "";
return QUuid();
}
QUuid requestId = QUuid::createUuid();
QUrl url;
url.setUrl(m_baseUrl);
url.setPath(QString("/feed/geo:%1;%2/").arg(lat).arg(lng));
QUrlQuery query;
query.addQueryItem("token", m_apiKey);
url.setQuery(query);
QNetworkRequest request;
request.setUrl(url);
request.setRawHeader("User-Agent", "nymea");
qCDebug(dcAirQualityIndex()) << "Get data by geo location request" << url.toString();
QNetworkReply *reply = m_networkAccessManager->get(request);
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
@ -178,21 +193,22 @@ QUuid AirQualityIndex::getDataByGeolocation(double lat, double lng)
// Check HTTP status code
if (status != 200 || reply->error() != QNetworkReply::NoError) {
if (status == 400) {
if (status == 400)
qCWarning(dcAirQualityIndex()) << "Request error due to exceeded request quota";
}
requestExecuted(requestId, false);
emit requestExecuted(requestId, false);
qCWarning(dcAirQualityIndex()) << "Request error:" << status << reply->errorString();
return;
}
if (!parseData(requestId, reply->readAll()))
requestExecuted(requestId, false);
requestExecuted(requestId, true);
emit requestExecuted(requestId, false);
emit requestExecuted(requestId, true);
});
return requestId;
}
bool AirQualityIndex::parseData(QUuid requestId, const QByteArray &data)
{
qCDebug(dcAirQualityIndex()) << "Parsing data" << data;
@ -211,8 +227,8 @@ bool AirQualityIndex::parseData(QUuid requestId, const QByteArray &data)
}
Station station;
station.aqi = doc.toVariant().toMap().value("data").toMap().value("aqi").toInt();
station.idx = doc.toVariant().toMap().value("data").toMap().value("idx").toInt();
station.aqi = doc.toVariant().toMap().value("data").toMap().value("aqi").toInt();
station.idx = doc.toVariant().toMap().value("data").toMap().value("idx").toInt();
QVariantMap city = doc.toVariant().toMap().value("data").toMap().value("city").toMap();
if (city["geo"].toList().length() == 2) {
@ -241,6 +257,7 @@ bool AirQualityIndex::parseData(QUuid requestId, const QByteArray &data)
aqiData.co = iaqi["co"].toMap().value("v").toDouble();
aqiData.temperature = iaqi["t"].toMap().value("v").toDouble();
aqiData.windSpeed = iaqi["w"].toMap().value("v").toDouble();
emit dataReceived(requestId, aqiData);
return true;
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Copyright 2013 - 2025, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@ -31,12 +31,13 @@
#ifndef AIRQUALITYINDEX_H
#define AIRQUALITYINDEX_H
#include "network/networkaccessmanager.h"
#include <QObject>
#include <QUuid>
#include <QTime>
#include <network/networkaccessmanager.h>
class AirQualityIndex : public QObject
{
Q_OBJECT
@ -70,6 +71,7 @@ public:
};
explicit AirQualityIndex(NetworkAccessManager *networkAccessManager, const QString &apiKey, QObject *parent = nullptr);
void setApiKey(const QString &apiKey);
QUuid searchByName(const QString &name);
QUuid getDataByIp();

View File

@ -1,12 +1,12 @@
include(../plugins.pri)
QT+= network
QT *= network
SOURCES += \
airqualityindex.cpp \
integrationpluginaqi.cpp \
integrationpluginaqi.cpp
HEADERS += \
airqualityindex.h \
integrationpluginaqi.h \
integrationpluginaqi.h

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Copyright 2013 - 2025, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@ -30,7 +30,8 @@
#include "integrationpluginaqi.h"
#include "plugininfo.h"
#include "nymeasettings.h"
#include <nymeasettings.h>
#include <QNetworkAccessManager>
@ -122,7 +123,8 @@ void IntegrationPluginAqi::discoverThings(ThingDiscoveryInfo *info)
if(!createAqiConnection()) {
return info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("API key is not available."));
}
connect(info, &ThingDiscoveryInfo::aborted, [this] {
connect(info, &ThingDiscoveryInfo::aborted, this, [this] {
if (myThings().filterByThingClassId(airQualityIndexThingClassId).isEmpty()) {
m_aqiConnection->deleteLater();
m_aqiConnection = nullptr;
@ -133,7 +135,9 @@ void IntegrationPluginAqi::discoverThings(ThingDiscoveryInfo *info)
}
QUuid requestId = m_aqiConnection->getDataByIp();
m_asyncDiscovery.insert(requestId, info);
connect(info, &ThingDiscoveryInfo::aborted, [=] {m_asyncDiscovery.remove(requestId);});
connect(info, &ThingDiscoveryInfo::aborted, this, [this, requestId] {
m_asyncDiscovery.remove(requestId);
});
}
void IntegrationPluginAqi::setupThing(ThingSetupInfo *info)
@ -148,7 +152,7 @@ void IntegrationPluginAqi::setupThing(ThingSetupInfo *info)
QUuid requestId = m_aqiConnection->getDataByGeolocation(latitude, longitude);
m_asyncSetups.insert(requestId, info);
connect(info, &ThingSetupInfo::aborted, [requestId, this] {
connect(info, &ThingSetupInfo::aborted, this, [requestId, this] {
m_asyncSetups.remove(requestId);
if (myThings().filterByThingClassId(airQualityIndexThingClassId).isEmpty()) {
m_aqiConnection->deleteLater();
@ -219,6 +223,7 @@ double IntegrationPluginAqi::convertFromAQI(int aqi, const QList<QPair<int, doub
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;
@ -253,7 +258,6 @@ void IntegrationPluginAqi::onAirQualityDataReceived(QUuid requestId, AirQualityI
if (!thing)
return;
thing->setStateValue(airQualityIndexConnectedStateTypeId, true);
thing->setStateValue(airQualityIndexHumidityStateTypeId, data.humidity);
thing->setStateValue(airQualityIndexTemperatureStateTypeId, data.temperature);
@ -284,7 +288,6 @@ void IntegrationPluginAqi::onAirQualityStationsReceived(QUuid requestId, QList<A
info->finish(Thing::ThingErrorNoError);
}
if (m_asyncRequests.contains(requestId)) {
Thing * thing = myThings().findById(m_asyncRequests.value(requestId));
if (!thing) {

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2020, nymea GmbH
* Copyright 2013 - 2025, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
@ -31,11 +31,11 @@
#ifndef INTEGRATIONPLUGINAQI_H
#define INTEGRATIONPLUGINAQI_H
#include "plugintimer.h"
#include "integrations/integrationplugin.h"
#include "network/networkaccessmanager.h"
#include "airqualityindex.h"
#include <plugintimer.h>
#include <integrations/integrationplugin.h>
#include <network/networkaccessmanager.h>
#include "airqualityindex.h"
#include "extern-plugininfo.h"
#include <QTimer>
@ -64,6 +64,7 @@ private:
QHash<QUuid, ThingDiscoveryInfo *> m_asyncDiscovery;
QHash<QUuid, ThingSetupInfo *> m_asyncSetups;
QHash<QUuid, ThingId> m_asyncRequests;
QString getApiKey();
bool createAqiConnection();
@ -74,6 +75,7 @@ private slots:
void onRequestExecuted(QUuid requestId, bool success);
void onAirQualityDataReceived(QUuid requestId, AirQualityIndex::AirQualityData data);
void onAirQualityStationsReceived(QUuid requestId, QList<AirQualityIndex::Station> stations);
};
#endif // INTEGRATIONPLUGINAQI_H