diff --git a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp index 706d55fb..1ad8b639 100644 --- a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp +++ b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp @@ -299,41 +299,46 @@ StateTypeId sunsetStateTypeId = StateTypeId("a1dddc3d-549f-4f20-b78b-be850548f28 DevicePluginOpenweathermap::DevicePluginOpenweathermap() { m_openweaher = new OpenWeatherMap(this); - connect(m_openweaher, SIGNAL(searchResultReady(QList)), this, SLOT(searchResultsReady(QList))); - connect(m_openweaher, SIGNAL(weatherDataReady(QByteArray)), this, SLOT(weatherDataReady(QByteArray))); + connect(m_openweaher, &OpenWeatherMap::searchResultReady, this, &DevicePluginOpenweathermap::searchResultsReady); + connect(m_openweaher, &OpenWeatherMap::weatherDataReady, this, &DevicePluginOpenweathermap::weatherDataReady); } QPair DevicePluginOpenweathermap::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) { - if(deviceClassId == openweathermapDeviceClassId){ + if(deviceClassId != openweathermapDeviceClassId){ + return report(DeviceManager::DeviceErrorDeviceClassNotFound); + } - QString location; - foreach (const Param ¶m, params) { - if (param.name() == "location") { - location = param.value().toString(); - } - } - qDebug() << "Searching for... " << location; - if (location.isEmpty()){ - m_openweaher->searchAutodetect(); - }else{ - m_openweaher->search(location); + QString location; + foreach (const Param ¶m, params) { + if (param.name() == "location") { + location = param.value().toString(); } + } + + // if we have an empty search string, perform an autodetection of the location with the WAN ip... + if (location.isEmpty()){ + m_openweaher->searchAutodetect(); return report(DeviceManager::DeviceErrorAsync); }else{ return report(DeviceManager::DeviceErrorDeviceClassNotFound); } + + // otherwise search the given string + m_openweaher->search(location); + return report(DeviceManager::DeviceErrorAsync); } QPair DevicePluginOpenweathermap::setupDevice(Device *device) { foreach (Device *deviceListDevice, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) { if(deviceListDevice->paramValue("id").toString() == device->paramValue("id").toString()){ - return reportDeviceSetup(DeviceManager::DeviceSetupStatusFailure,QString("Location " + device->paramValue("location").toString() + "allready in added")); + return reportDeviceSetup(DeviceManager::DeviceSetupStatusFailure,QString("Location " + device->paramValue("location").toString() + " already added.")); } } - m_openweaher->update(device->paramValue("id").toString()); + device->setName("Weather from OpenWeatherMap (" + device->paramValue("location").toString() + ")"); + m_openweaher->update(device->paramValue("id").toString(), device->id()); return reportDeviceSetup(DeviceManager::DeviceSetupStatusSuccess); } @@ -345,9 +350,8 @@ DeviceManager::HardwareResources DevicePluginOpenweathermap::requiredHardware() QPair DevicePluginOpenweathermap::executeAction(Device *device, const Action &action) { - qDebug() << "execute action " << updateWeatherActionTypeId.toString(); if(action.actionTypeId() == updateWeatherActionTypeId){ - m_openweaher->update(device->paramValue("id").toString()); + m_openweaher->update(device->paramValue("id").toString(), device->id()); } return report(); } @@ -355,7 +359,7 @@ QPair DevicePluginOpenweathermap::executeAc void DevicePluginOpenweathermap::guhTimer() { foreach (Device *device, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) { - m_openweaher->update(device->paramValue("id").toString()); + m_openweaher->update(device->paramValue("id").toString(), device->id()); } } @@ -377,7 +381,7 @@ void DevicePluginOpenweathermap::searchResultsReady(const QList &ci emit devicesDiscovered(openweathermapDeviceClassId,retList); } -void DevicePluginOpenweathermap::weatherDataReady(const QByteArray &data) +void DevicePluginOpenweathermap::weatherDataReady(const QByteArray &data, const DeviceId &deviceId) { QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error); @@ -390,7 +394,7 @@ void DevicePluginOpenweathermap::weatherDataReady(const QByteArray &data) QVariantMap dataMap = jsonDoc.toVariant().toMap(); foreach (Device *device, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) { - if(device->paramValue("id").toString() == dataMap.value("id").toString()){ + if(device->id() == deviceId){ if(dataMap.contains("clouds")){ int cloudiness = dataMap.value("clouds").toMap().value("all").toInt(); diff --git a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.h b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.h index 96f9e8fd..7a3ff0a4 100644 --- a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.h +++ b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.h @@ -44,7 +44,7 @@ public: private slots: void searchResultsReady(const QList &cityList); - void weatherDataReady(const QByteArray &data); + void weatherDataReady(const QByteArray &data, const DeviceId &deviceId); public slots: diff --git a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.json b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.json index cdc8e1eb..7ae04a92 100644 --- a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.json +++ b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.json @@ -1,14 +1,14 @@ { - "name": "Openweathermap", + "name": "OpenWeatherMap", "id": "bc6af567-2338-41d5-aac1-462dec6e4783", "vendors": [ { - "name": "Openweathermap", + "name": "OpenWeatherMap", "id": "bf1e96f0-9650-4e7c-a56c-916d54d18e7a", "deviceClasses": [ { "deviceClassId": "985195aa-17ad-4530-88a4-cdd753d747d7", - "name": "Weather from openweathermap", + "name": "Weather from OpenWeatherMap", "createMethods": ["discovery"], "discoveryParamTypes": [ { @@ -33,7 +33,7 @@ "actionTypes": [ { "id": "cfbc6504-d86f-4856-8dfa-97b6fbb385e4", - "name": "Update" + "name": "update" } ], "stateTypes": [ diff --git a/plugins/deviceplugins/openweathermap/openweathermap.cpp b/plugins/deviceplugins/openweathermap/openweathermap.cpp index 0026e115..a71ad4af 100644 --- a/plugins/deviceplugins/openweathermap/openweathermap.cpp +++ b/plugins/deviceplugins/openweathermap/openweathermap.cpp @@ -24,18 +24,18 @@ OpenWeatherMap::OpenWeatherMap(QObject *parent) : QObject(parent) { m_manager = new QNetworkAccessManager(this); - - connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*))); + connect(m_manager, &QNetworkAccessManager::finished, this, &OpenWeatherMap::replyFinished); } -void OpenWeatherMap::update(QString id) +void OpenWeatherMap::update(QString id, DeviceId deviceId) { m_cityId = id; QString urlString = "http://api.openweathermap.org/data/2.5/weather?id="+ m_cityId + "&mode=json&units=metric"; QNetworkRequest weatherRequest; weatherRequest.setUrl(QUrl(urlString)); - m_weatherReply = m_manager->get(weatherRequest); + QNetworkReply *weatherReply = m_manager->get(weatherRequest); + m_weatherReplys.insert(weatherReply, deviceId); } void OpenWeatherMap::searchAutodetect() @@ -56,6 +56,16 @@ void OpenWeatherMap::search(QString searchString) m_searchReply = m_manager->get(searchRequest); } +void OpenWeatherMap::searchGeoLocation(double lat, double lon) +{ + QString urlString = "http://api.openweathermap.org/data/2.5/find?lat=" + QString::number(lat) + "&lon=" + QString::number(lon) + "cnt=5&type=like&units=metric&mode=json"; + QNetworkRequest searchRequest; + searchRequest.setUrl(QUrl(urlString)); + qDebug() << "search URL " << urlString; + + m_searchGeoReply = m_manager->get(searchRequest); +} + void OpenWeatherMap::processLocationResponse(QByteArray data) { QJsonParseError error; @@ -64,26 +74,33 @@ void OpenWeatherMap::processLocationResponse(QByteArray data) if(error.error != QJsonParseError::NoError) { qWarning() << "failed to parse data" << data << ":" << error.errorString(); } - //qDebug() << jsonDoc.toJson(); + // qDebug() << jsonDoc.toJson(); + // search by geographic coordinates QVariantMap dataMap = jsonDoc.toVariant().toMap(); + if(dataMap.contains("countryCode")){ + m_country = dataMap.value("countryCode").toString(); + } if(dataMap.contains("city")){ - search(dataMap.value("city").toString()); + m_cityName = dataMap.value("city").toString(); + } + if(dataMap.contains("query")){ + m_wanIp = QHostAddress(dataMap.value("query").toString()); + } + if(dataMap.contains("lon") && dataMap.contains("lat")){ + qDebug() << "Autodetection of location: " << m_cityName << "(" << m_country << ")" << m_wanIp; + searchGeoLocation(dataMap.value("lat").toDouble(),dataMap.value("lon").toDouble()); } } void OpenWeatherMap::processSearchResponse(QByteArray data) { - - // TODO: return here...remove the rest from here... - QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error); if(error.error != QJsonParseError::NoError) { qWarning() << "failed to parse data" << data << ":" << error.errorString(); } - //qDebug() << jsonDoc.toJson(); QVariantMap dataMap = jsonDoc.toVariant().toMap(); qDebug() << "----------------------------------------"; @@ -110,7 +127,7 @@ void OpenWeatherMap::processSearchResponse(QByteArray data) emit searchResultReady(cityList); } -void OpenWeatherMap::processSearchLocationResponse(QByteArray data) +void OpenWeatherMap::processSearchGeoResponse(QByteArray data) { QJsonParseError error; QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error); @@ -118,26 +135,40 @@ void OpenWeatherMap::processSearchLocationResponse(QByteArray data) if(error.error != QJsonParseError::NoError) { qWarning() << "failed to parse data" << data << ":" << error.errorString(); } + //qDebug() << jsonDoc.toJson(); - QList cityList; QVariantMap dataMap = jsonDoc.toVariant().toMap(); + qDebug() << "----------------------------------------"; + qDebug() << "openweathermap search results"; + qDebug() << "----------------------------------------"; + QList cityList; if(dataMap.contains("list")){ QVariantList list = dataMap.value("list").toList(); foreach (QVariant key, list) { QVariantMap elemant = key.toMap(); + qDebug() << elemant.value("name").toString(); + if(elemant.value("sys").toMap().value("country").toString().isEmpty()){ + qDebug() << m_country; + }else{ + qDebug() << elemant.value("sys").toMap().value("country").toString(); + } + qDebug() << elemant.value("id").toString(); + qDebug() << "--------------------------------------"; QVariantMap city; city.insert("name",elemant.value("name").toString()); - city.insert("country", elemant.value("sys").toMap().value("country").toString()); + if(elemant.value("sys").toMap().value("country").toString().isEmpty()){ + city.insert("country",m_country); + }else{ + city.insert("country", elemant.value("sys").toMap().value("country").toString()); + } city.insert("id",elemant.value("id").toString()); cityList.append(city); - - m_cityId = elemant.value("id").toString(); - search(m_cityName); - return; } } + qDebug() << "----------------------------------------"; + emit searchResultReady(cityList); } void OpenWeatherMap::replyFinished(QNetworkReply *reply) @@ -145,31 +176,37 @@ void OpenWeatherMap::replyFinished(QNetworkReply *reply) int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); QByteArray data; - if(reply == m_locationReply && status == 200){ - data = reply->readAll(); - processLocationResponse(data); - m_locationReply->deleteLater(); - return; - } + if(reply->error() == QNetworkReply::NoError){ + if(reply == m_locationReply){ + data = reply->readAll(); + processLocationResponse(data); + delete m_locationReply; + return; + } - if(reply == m_searchReply && status == 200){ - data = reply->readAll(); - processSearchResponse(data); - m_searchReply->deleteLater(); - return; - } + if(reply == m_searchReply){ + data = reply->readAll(); + processSearchResponse(data); + delete m_searchReply; + return; + } - if(reply == m_searchLocationReply && status == 200){ - data = reply->readAll(); - processSearchLocationResponse(data); - m_searchLocationReply->deleteLater(); - return; - } + if(reply == m_searchGeoReply){ + data = reply->readAll(); + processSearchGeoResponse(data); + delete m_searchGeoReply; + return; + } - if(reply == m_weatherReply && status == 200){ - data = reply->readAll(); - emit weatherDataReady(data); - m_weatherReply->deleteLater(); - return; + if(m_weatherReplys.contains(reply)){ + data = reply->readAll(); + DeviceId deviceId = m_weatherReplys.value(reply); + emit weatherDataReady(data, deviceId); + m_weatherReplys.take(reply); + delete reply; + } + }else{ + qWarning() << "ERROR: OpenWeatherMap reply error code: " << status << reply->errorString(); + delete reply; } } diff --git a/plugins/deviceplugins/openweathermap/openweathermap.h b/plugins/deviceplugins/openweathermap/openweathermap.h index e818e756..ba1e62e6 100644 --- a/plugins/deviceplugins/openweathermap/openweathermap.h +++ b/plugins/deviceplugins/openweathermap/openweathermap.h @@ -25,35 +25,43 @@ #include #include #include +#include #include +#include "plugin/deviceplugin.h" + class OpenWeatherMap : public QObject { Q_OBJECT public: explicit OpenWeatherMap(QObject *parent = 0); - void update(QString id); + void update(QString id, DeviceId deviceId); void searchAutodetect(); void search(QString searchString); + void searchGeoLocation(double lat, double lon); private: QNetworkAccessManager *m_manager; QString m_cityName; + QString m_country; QString m_cityId; + QHostAddress m_wanIp; QNetworkReply *m_locationReply; - QNetworkReply *m_searchLocationReply; QNetworkReply *m_weatherReply; QNetworkReply *m_searchReply; + QNetworkReply *m_searchGeoReply; void processLocationResponse(QByteArray data); void processSearchResponse(QByteArray data); - void processSearchLocationResponse(QByteArray data); + void processSearchGeoResponse(QByteArray data); + + QHash m_weatherReplys; signals: void searchResultReady(const QList &cityList); - void weatherDataReady(const QByteArray &data); + void weatherDataReady(const QByteArray &data, const DeviceId &deviceId); public slots: