updated and fixed openweathermap plugin
This commit is contained in:
parent
957a42955a
commit
6e93853830
@ -60,15 +60,12 @@
|
|||||||
|
|
||||||
DevicePluginOpenweathermap::DevicePluginOpenweathermap()
|
DevicePluginOpenweathermap::DevicePluginOpenweathermap()
|
||||||
{
|
{
|
||||||
m_openweaher = new OpenWeatherMap(this);
|
|
||||||
connect(m_openweaher, &OpenWeatherMap::searchResultReady, this, &DevicePluginOpenweathermap::searchResultsReady);
|
|
||||||
connect(m_openweaher, &OpenWeatherMap::weatherDataReady, this, &DevicePluginOpenweathermap::weatherDataReady);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceManager::DeviceError DevicePluginOpenweathermap::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
DeviceManager::DeviceError DevicePluginOpenweathermap::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
||||||
{
|
{
|
||||||
if(deviceClassId != openweathermapDeviceClassId){
|
if (deviceClassId != openweathermapDeviceClassId) {
|
||||||
return report(DeviceManager::DeviceErrorDeviceClassNotFound);
|
return DeviceManager::DeviceErrorDeviceClassNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString location;
|
QString location;
|
||||||
@ -80,15 +77,19 @@ DeviceManager::DeviceError DevicePluginOpenweathermap::discoverDevices(const Dev
|
|||||||
|
|
||||||
// if we have an empty search string, perform an autodetection of the location with the WAN ip...
|
// if we have an empty search string, perform an autodetection of the location with the WAN ip...
|
||||||
if (location.isEmpty()){
|
if (location.isEmpty()){
|
||||||
m_openweaher->searchAutodetect();
|
searchAutodetect();
|
||||||
} else {
|
} else {
|
||||||
m_openweaher->search(location);
|
search(location);
|
||||||
}
|
}
|
||||||
return DeviceManager::DeviceErrorAsync;
|
return DeviceManager::DeviceErrorAsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceManager::DeviceSetupStatus DevicePluginOpenweathermap::setupDevice(Device *device)
|
DeviceManager::DeviceSetupStatus DevicePluginOpenweathermap::setupDevice(Device *device)
|
||||||
{
|
{
|
||||||
|
if (device->deviceClassId() != openweathermapDeviceClassId) {
|
||||||
|
return DeviceManager::DeviceSetupStatusFailure;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (Device *deviceListDevice, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) {
|
foreach (Device *deviceListDevice, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) {
|
||||||
if(deviceListDevice->paramValue("id").toString() == device->paramValue("id").toString()){
|
if(deviceListDevice->paramValue("id").toString() == device->paramValue("id").toString()){
|
||||||
qWarning() << QString("Location " + device->paramValue("location").toString() + "already in added");
|
qWarning() << QString("Location " + device->paramValue("location").toString() + "already in added");
|
||||||
@ -97,32 +98,213 @@ DeviceManager::DeviceSetupStatus DevicePluginOpenweathermap::setupDevice(Device
|
|||||||
}
|
}
|
||||||
|
|
||||||
device->setName("Weather from OpenWeatherMap (" + device->paramValue("location").toString() + ")");
|
device->setName("Weather from OpenWeatherMap (" + device->paramValue("location").toString() + ")");
|
||||||
m_openweaher->update(device->paramValue("id").toString(), device->id());
|
update();
|
||||||
|
|
||||||
return DeviceManager::DeviceSetupStatusSuccess;
|
return DeviceManager::DeviceSetupStatusSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceManager::HardwareResources DevicePluginOpenweathermap::requiredHardware() const
|
DeviceManager::HardwareResources DevicePluginOpenweathermap::requiredHardware() const
|
||||||
{
|
{
|
||||||
return DeviceManager::HardwareResourceTimer;
|
return DeviceManager::HardwareResourceTimer | DeviceManager::HardwareResourceNetworkManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceManager::DeviceError DevicePluginOpenweathermap::executeAction(Device *device, const Action &action)
|
DeviceManager::DeviceError DevicePluginOpenweathermap::executeAction(Device *device, const Action &action)
|
||||||
{
|
{
|
||||||
if(action.actionTypeId() == updateWeatherActionTypeId){
|
if(action.actionTypeId() == updateWeatherActionTypeId){
|
||||||
m_openweaher->update(device->paramValue("id").toString(), device->id());
|
update(device);
|
||||||
}
|
}
|
||||||
return DeviceManager::DeviceErrorNoError;
|
return DeviceManager::DeviceErrorNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginOpenweathermap::guhTimer()
|
void DevicePluginOpenweathermap::deviceRemoved(Device *device)
|
||||||
{
|
{
|
||||||
foreach (Device *device, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) {
|
// check if a device gets removed while we still have a reply!
|
||||||
m_openweaher->update(device->paramValue("id").toString(), device->id());
|
foreach (Device *d, m_weatherReplies.values()) {
|
||||||
|
if (d->id() == device->id()) {
|
||||||
|
QNetworkReply *reply = m_weatherReplies.key(device);
|
||||||
|
m_weatherReplies.take(reply);
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginOpenweathermap::searchResultsReady(const QList<QVariantMap> &cityList)
|
void DevicePluginOpenweathermap::networkManagerReplyReady(QNetworkReply *reply)
|
||||||
|
{
|
||||||
|
if (reply->error()) {
|
||||||
|
qWarning() << "ERROR: OpenWeatherMap reply error: " << reply->errorString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_autodetectionReplies.contains(reply)) {
|
||||||
|
QByteArray data = reply->readAll();
|
||||||
|
m_autodetectionReplies.removeOne(reply);
|
||||||
|
processAutodetectResponse(data);
|
||||||
|
} else if (m_searchReplies.contains(reply)) {
|
||||||
|
QByteArray data = reply->readAll();
|
||||||
|
m_searchReplies.removeOne(reply);
|
||||||
|
processSearchResponse(data);
|
||||||
|
} else if (m_searchGeoReplies.contains(reply)) {
|
||||||
|
QByteArray data = reply->readAll();
|
||||||
|
m_searchGeoReplies.removeOne(reply);
|
||||||
|
processGeoSearchResponse(data);
|
||||||
|
} else if (m_weatherReplies.contains(reply)) {
|
||||||
|
QByteArray data = reply->readAll();
|
||||||
|
Device* device = m_weatherReplies.take(reply);
|
||||||
|
processWeatherData(data, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginOpenweathermap::guhTimer()
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginOpenweathermap::update()
|
||||||
|
{
|
||||||
|
foreach (Device *device, myDevices()) {
|
||||||
|
QString cityId = device->paramValue("id").toString();
|
||||||
|
QString urlString = "http://api.openweathermap.org/data/2.5/weather?id="+ cityId + "&mode=json&units=metric";
|
||||||
|
QNetworkRequest weatherRequest;
|
||||||
|
weatherRequest.setUrl(QUrl(urlString));
|
||||||
|
|
||||||
|
QNetworkReply *reply = networkManagerGet(weatherRequest);
|
||||||
|
m_weatherReplies.insert(reply, device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginOpenweathermap::update(Device *device)
|
||||||
|
{
|
||||||
|
QString cityId = device->paramValue("id").toString();
|
||||||
|
QString urlString = "http://api.openweathermap.org/data/2.5/weather?id="+ cityId + "&mode=json&units=metric";
|
||||||
|
QNetworkRequest weatherRequest;
|
||||||
|
weatherRequest.setUrl(QUrl(urlString));
|
||||||
|
|
||||||
|
QNetworkReply *reply = networkManagerGet(weatherRequest);
|
||||||
|
m_weatherReplies.insert(reply, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginOpenweathermap::searchAutodetect()
|
||||||
|
{
|
||||||
|
QString urlString = "http://ip-api.com/json";
|
||||||
|
QNetworkRequest locationRequest;
|
||||||
|
locationRequest.setUrl(QUrl(urlString));
|
||||||
|
|
||||||
|
QNetworkReply *reply = networkManagerGet(locationRequest);
|
||||||
|
m_autodetectionReplies.append(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginOpenweathermap::search(QString searchString)
|
||||||
|
{
|
||||||
|
QString urlString = "http://api.openweathermap.org/data/2.5/find?q=" + searchString + "&type=like&units=metric&mode=json";
|
||||||
|
QNetworkRequest searchRequest;
|
||||||
|
searchRequest.setUrl(QUrl(urlString));
|
||||||
|
|
||||||
|
QNetworkReply *reply = networkManagerGet(searchRequest);
|
||||||
|
m_searchReplies.append(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginOpenweathermap::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));
|
||||||
|
|
||||||
|
QNetworkReply *reply = networkManagerGet(searchRequest);
|
||||||
|
m_searchGeoReplies.append(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginOpenweathermap::processAutodetectResponse(QByteArray data)
|
||||||
|
{
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||||
|
|
||||||
|
if(error.error != QJsonParseError::NoError) {
|
||||||
|
qWarning() << "failed to parse data" << data << ":" << error.errorString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// search by geographic coordinates
|
||||||
|
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
||||||
|
if (dataMap.contains("countryCode")) {
|
||||||
|
m_country = dataMap.value("countryCode").toString();
|
||||||
|
}
|
||||||
|
if (dataMap.contains("city")) {
|
||||||
|
m_cityName = dataMap.value("city").toString();
|
||||||
|
}
|
||||||
|
if (dataMap.contains("query")) {
|
||||||
|
m_wanIp = QHostAddress(dataMap.value("query").toString());
|
||||||
|
}
|
||||||
|
if (dataMap.contains("lon") && dataMap.contains("lat")) {
|
||||||
|
m_longitude = dataMap.value("lon").toDouble();
|
||||||
|
m_latitude = dataMap.value("lat").toDouble();
|
||||||
|
qDebug() << "----------------------------------------";
|
||||||
|
qDebug() << "Autodetection of location: ";
|
||||||
|
qDebug() << "----------------------------------------";
|
||||||
|
qDebug() << " name:" << m_cityName;
|
||||||
|
qDebug() << " country:" << m_country;
|
||||||
|
qDebug() << " WAN IP:" << m_wanIp.toString();
|
||||||
|
qDebug() << " latitude:" << m_latitude;
|
||||||
|
qDebug() << " longitude:" << m_longitude;
|
||||||
|
qDebug() << "----------------------------------------";
|
||||||
|
searchGeoLocation(m_latitude, m_longitude);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginOpenweathermap::processSearchResponse(QByteArray data)
|
||||||
|
{
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||||
|
|
||||||
|
if(error.error != QJsonParseError::NoError) {
|
||||||
|
qWarning() << "failed to parse data" << data << ":" << error.errorString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
||||||
|
QList<QVariantMap> cityList;
|
||||||
|
if (dataMap.contains("list")) {
|
||||||
|
QVariantList list = dataMap.value("list").toList();
|
||||||
|
foreach (QVariant key, list) {
|
||||||
|
QVariantMap elemant = key.toMap();
|
||||||
|
QVariantMap city;
|
||||||
|
city.insert("name",elemant.value("name").toString());
|
||||||
|
city.insert("country", elemant.value("sys").toMap().value("country").toString());
|
||||||
|
city.insert("id",elemant.value("id").toString());
|
||||||
|
cityList.append(city);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processSearchResults(cityList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginOpenweathermap::processGeoSearchResponse(QByteArray data)
|
||||||
|
{
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||||
|
|
||||||
|
if(error.error != QJsonParseError::NoError) {
|
||||||
|
qWarning() << "failed to parse data" << data << ":" << error.errorString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
||||||
|
QList<QVariantMap> cityList;
|
||||||
|
if (dataMap.contains("list")) {
|
||||||
|
QVariantList list = dataMap.value("list").toList();
|
||||||
|
foreach (QVariant key, list) {
|
||||||
|
QVariantMap elemant = key.toMap();
|
||||||
|
QVariantMap city;
|
||||||
|
city.insert("name",elemant.value("name").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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processSearchResults(cityList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginOpenweathermap::processSearchResults(const QList<QVariantMap> &cityList)
|
||||||
{
|
{
|
||||||
QList<DeviceDescriptor> retList;
|
QList<DeviceDescriptor> retList;
|
||||||
foreach (QVariantMap elemant, cityList) {
|
foreach (QVariantMap elemant, cityList) {
|
||||||
@ -137,68 +319,63 @@ void DevicePluginOpenweathermap::searchResultsReady(const QList<QVariantMap> &ci
|
|||||||
descriptor.setParams(params);
|
descriptor.setParams(params);
|
||||||
retList.append(descriptor);
|
retList.append(descriptor);
|
||||||
}
|
}
|
||||||
emit devicesDiscovered(openweathermapDeviceClassId,retList);
|
emit devicesDiscovered(openweathermapDeviceClassId, retList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicePluginOpenweathermap::weatherDataReady(const QByteArray &data, const DeviceId &deviceId)
|
void DevicePluginOpenweathermap::processWeatherData(const QByteArray &data, Device *device)
|
||||||
{
|
{
|
||||||
QJsonParseError error;
|
QJsonParseError error;
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||||
|
|
||||||
if(error.error != QJsonParseError::NoError) {
|
if (error.error != QJsonParseError::NoError) {
|
||||||
qWarning() << "failed to parse data" << data << ":" << error.errorString();
|
qWarning() << "failed to parse weather data for device " << device->name() << ": " << data << ":" << error.errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
||||||
|
|
||||||
foreach (Device *device, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) {
|
if (dataMap.contains("clouds")) {
|
||||||
if(device->id() == deviceId){
|
int cloudiness = dataMap.value("clouds").toMap().value("all").toInt();
|
||||||
|
device->setStateValue(cloudinessStateTypeId, cloudiness);
|
||||||
|
}
|
||||||
|
if (dataMap.contains("dt")) {
|
||||||
|
uint lastUpdate = dataMap.value("dt").toUInt();
|
||||||
|
device->setStateValue(updateTimeStateTypeId, lastUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
if(dataMap.contains("clouds")){
|
if (dataMap.contains("main")) {
|
||||||
int cloudiness = dataMap.value("clouds").toMap().value("all").toInt();
|
double temperatur = dataMap.value("main").toMap().value("temp").toDouble();
|
||||||
device->setStateValue(cloudinessStateTypeId,cloudiness);
|
double temperaturMax = dataMap.value("main").toMap().value("temp_max").toDouble();
|
||||||
}
|
double temperaturMin = dataMap.value("main").toMap().value("temp_min").toDouble();
|
||||||
if(dataMap.contains("dt")){
|
double pressure = dataMap.value("main").toMap().value("pressure").toDouble();
|
||||||
uint lastUpdate = dataMap.value("dt").toUInt();
|
int humidity = dataMap.value("main").toMap().value("humidity").toInt();
|
||||||
device->setStateValue(updateTimeStateTypeId,lastUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dataMap.contains("main")){
|
device->setStateValue(temperatureStateTypeId, temperatur);
|
||||||
double temperatur = dataMap.value("main").toMap().value("temp").toDouble();
|
device->setStateValue(temperatureMinStateTypeId, temperaturMin);
|
||||||
double temperaturMax = dataMap.value("main").toMap().value("temp_max").toDouble();
|
device->setStateValue(temperatureMaxStateTypeId, temperaturMax);
|
||||||
double temperaturMin = dataMap.value("main").toMap().value("temp_min").toDouble();
|
device->setStateValue(pressureStateTypeId, pressure);
|
||||||
double pressure = dataMap.value("main").toMap().value("pressure").toDouble();
|
device->setStateValue(humidityStateTypeId, humidity);
|
||||||
int humidity = dataMap.value("main").toMap().value("humidity").toInt();
|
}
|
||||||
|
|
||||||
device->setStateValue(temperatureStateTypeId,temperatur);
|
if (dataMap.contains("sys")) {
|
||||||
device->setStateValue(temperatureMinStateTypeId,temperaturMin);
|
uint sunrise = dataMap.value("sys").toMap().value("sunrise").toUInt();
|
||||||
device->setStateValue(temperatureMaxStateTypeId,temperaturMax);
|
uint sunset = dataMap.value("sys").toMap().value("sunset").toUInt();
|
||||||
device->setStateValue(pressureStateTypeId,pressure);
|
|
||||||
device->setStateValue(humidityStateTypeId,humidity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dataMap.contains("sys")){
|
device->setStateValue(sunriseStateTypeId, sunrise);
|
||||||
uint sunrise = dataMap.value("sys").toMap().value("sunrise").toUInt();
|
device->setStateValue(sunsetStateTypeId, sunset);
|
||||||
uint sunset = dataMap.value("sys").toMap().value("sunset").toUInt();
|
}
|
||||||
|
|
||||||
device->setStateValue(sunriseStateTypeId,sunrise);
|
if (dataMap.contains("weather")) {
|
||||||
device->setStateValue(sunsetStateTypeId,sunset);
|
QString description = dataMap.value("weather").toMap().value("description").toString();
|
||||||
}
|
device->setStateValue(weatherDescriptionStateTypeId, description);
|
||||||
|
}
|
||||||
|
|
||||||
if(dataMap.contains("weather")){
|
if (dataMap.contains("wind")) {
|
||||||
QString description = dataMap.value("weather").toMap().value("description").toString();
|
int windDirection = dataMap.value("wind").toMap().value("deg").toInt();
|
||||||
device->setStateValue(weatherDescriptionStateTypeId,description);
|
double windSpeed = dataMap.value("wind").toMap().value("speed").toDouble();
|
||||||
}
|
|
||||||
|
|
||||||
if(dataMap.contains("wind")){
|
device->setStateValue(windDirectionStateTypeId, windDirection);
|
||||||
int windDirection = dataMap.value("wind").toMap().value("deg").toInt();
|
device->setStateValue(windSpeedStateTypeId, windSpeed);
|
||||||
double windSpeed = dataMap.value("wind").toMap().value("speed").toDouble();
|
|
||||||
|
|
||||||
device->setStateValue(windDirectionStateTypeId,windDirection);
|
|
||||||
device->setStateValue(windSpeedStateTypeId,windSpeed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,8 +20,6 @@
|
|||||||
#define DEVICEPLUGINOPENWEATHERMAP_H
|
#define DEVICEPLUGINOPENWEATHERMAP_H
|
||||||
|
|
||||||
#include "plugin/deviceplugin.h"
|
#include "plugin/deviceplugin.h"
|
||||||
#include "openweathermap.h"
|
|
||||||
|
|
||||||
|
|
||||||
class DevicePluginOpenweathermap : public DevicePlugin
|
class DevicePluginOpenweathermap : public DevicePlugin
|
||||||
{
|
{
|
||||||
@ -33,20 +31,40 @@ class DevicePluginOpenweathermap : public DevicePlugin
|
|||||||
public:
|
public:
|
||||||
explicit DevicePluginOpenweathermap();
|
explicit DevicePluginOpenweathermap();
|
||||||
|
|
||||||
OpenWeatherMap *m_openweaher;
|
|
||||||
|
|
||||||
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
||||||
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
||||||
DeviceManager::HardwareResources requiredHardware() const override;
|
DeviceManager::HardwareResources requiredHardware() const override;
|
||||||
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
|
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
|
||||||
|
|
||||||
|
void deviceRemoved(Device *device) override;
|
||||||
|
void networkManagerReplyReady(QNetworkReply *reply) override;
|
||||||
void guhTimer() override;
|
void guhTimer() override;
|
||||||
|
|
||||||
private slots:
|
private:
|
||||||
void searchResultsReady(const QList<QVariantMap> &cityList);
|
QList<QNetworkReply *> m_autodetectionReplies;
|
||||||
void weatherDataReady(const QByteArray &data, const DeviceId &deviceId);
|
QList<QNetworkReply *> m_searchReplies;
|
||||||
|
QList<QNetworkReply *> m_searchGeoReplies;
|
||||||
|
QHash<QNetworkReply *, Device *> m_weatherReplies;
|
||||||
|
|
||||||
public slots:
|
// Autodetection data
|
||||||
|
QHostAddress m_wanIp;
|
||||||
|
QString m_country;
|
||||||
|
QString m_cityName;
|
||||||
|
double m_longitude;
|
||||||
|
double m_latitude;
|
||||||
|
|
||||||
|
void update();
|
||||||
|
void update(Device *device);
|
||||||
|
void searchAutodetect();
|
||||||
|
void search(QString searchString);
|
||||||
|
void searchGeoLocation(double lat, double lon);
|
||||||
|
|
||||||
|
void processAutodetectResponse(QByteArray data);
|
||||||
|
void processSearchResponse(QByteArray data);
|
||||||
|
void processGeoSearchResponse(QByteArray data);
|
||||||
|
|
||||||
|
void processSearchResults(const QList<QVariantMap> &cityList);
|
||||||
|
void processWeatherData(const QByteArray &data, Device *device);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,212 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
* *
|
|
||||||
* This file is part of guh. *
|
|
||||||
* *
|
|
||||||
* Guh is free software: you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation, version 2 of the License. *
|
|
||||||
* *
|
|
||||||
* Guh is distributed in the hope that it will be useful, *
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
||||||
* GNU General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU General Public License *
|
|
||||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
|
||||||
* *
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#include "openweathermap.h"
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QDateTime>
|
|
||||||
|
|
||||||
OpenWeatherMap::OpenWeatherMap(QObject *parent) :
|
|
||||||
QObject(parent)
|
|
||||||
{
|
|
||||||
m_manager = new QNetworkAccessManager(this);
|
|
||||||
connect(m_manager, &QNetworkAccessManager::finished, this, &OpenWeatherMap::replyFinished);
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
QNetworkReply *weatherReply = m_manager->get(weatherRequest);
|
|
||||||
m_weatherReplys.insert(weatherReply, deviceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenWeatherMap::searchAutodetect()
|
|
||||||
{
|
|
||||||
QString urlString = "http://ip-api.com/json";
|
|
||||||
QNetworkRequest locationRequest;
|
|
||||||
locationRequest.setUrl(QUrl(urlString));
|
|
||||||
|
|
||||||
m_locationReply = m_manager->get(locationRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenWeatherMap::search(QString searchString)
|
|
||||||
{
|
|
||||||
QString urlString = "http://api.openweathermap.org/data/2.5/find?q=" + searchString + "&type=like&units=metric&mode=json";
|
|
||||||
QNetworkRequest searchRequest;
|
|
||||||
searchRequest.setUrl(QUrl(urlString));
|
|
||||||
|
|
||||||
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;
|
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
|
||||||
|
|
||||||
if(error.error != QJsonParseError::NoError) {
|
|
||||||
qWarning() << "failed to parse data" << data << ":" << error.errorString();
|
|
||||||
}
|
|
||||||
// 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")){
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
QJsonParseError error;
|
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
|
||||||
|
|
||||||
if(error.error != QJsonParseError::NoError) {
|
|
||||||
qWarning() << "failed to parse data" << data << ":" << error.errorString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
|
||||||
qDebug() << "----------------------------------------";
|
|
||||||
qDebug() << "openweathermap search results";
|
|
||||||
qDebug() << "----------------------------------------";
|
|
||||||
QList<QVariantMap> cityList;
|
|
||||||
if(dataMap.contains("list")){
|
|
||||||
QVariantList list = dataMap.value("list").toList();
|
|
||||||
foreach (QVariant key, list) {
|
|
||||||
QVariantMap elemant = key.toMap();
|
|
||||||
qDebug() << elemant.value("name").toString();
|
|
||||||
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());
|
|
||||||
city.insert("id",elemant.value("id").toString());
|
|
||||||
cityList.append(city);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qDebug() << "----------------------------------------";
|
|
||||||
emit searchResultReady(cityList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenWeatherMap::processSearchGeoResponse(QByteArray data)
|
|
||||||
{
|
|
||||||
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() << "----------------------------------------";
|
|
||||||
qDebug() << "openweathermap search results";
|
|
||||||
qDebug() << "----------------------------------------";
|
|
||||||
QList<QVariantMap> 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());
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qDebug() << "----------------------------------------";
|
|
||||||
emit searchResultReady(cityList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenWeatherMap::replyFinished(QNetworkReply *reply)
|
|
||||||
{
|
|
||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
QByteArray data;
|
|
||||||
|
|
||||||
if(reply->error() == QNetworkReply::NoError){
|
|
||||||
if(reply == m_locationReply){
|
|
||||||
data = reply->readAll();
|
|
||||||
processLocationResponse(data);
|
|
||||||
delete m_locationReply;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(reply == m_searchReply){
|
|
||||||
data = reply->readAll();
|
|
||||||
processSearchResponse(data);
|
|
||||||
delete m_searchReply;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(reply == m_searchGeoReply){
|
|
||||||
data = reply->readAll();
|
|
||||||
processSearchGeoResponse(data);
|
|
||||||
delete m_searchGeoReply;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,74 +0,0 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
||||||
* *
|
|
||||||
* This file is part of guh. *
|
|
||||||
* *
|
|
||||||
* Guh is free software: you can redistribute it and/or modify *
|
|
||||||
* it under the terms of the GNU General Public License as published by *
|
|
||||||
* the Free Software Foundation, version 2 of the License. *
|
|
||||||
* *
|
|
||||||
* Guh is distributed in the hope that it will be useful, *
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
||||||
* GNU General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU General Public License *
|
|
||||||
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
|
||||||
* *
|
|
||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
||||||
|
|
||||||
#ifndef OPENWEATHERMAP_H
|
|
||||||
#define OPENWEATHERMAP_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QVariantMap>
|
|
||||||
#include <QHostAddress>
|
|
||||||
#include <QUrl>
|
|
||||||
|
|
||||||
#include "plugin/deviceplugin.h"
|
|
||||||
|
|
||||||
class OpenWeatherMap : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit OpenWeatherMap(QObject *parent = 0);
|
|
||||||
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_weatherReply;
|
|
||||||
QNetworkReply *m_searchReply;
|
|
||||||
QNetworkReply *m_searchGeoReply;
|
|
||||||
|
|
||||||
void processLocationResponse(QByteArray data);
|
|
||||||
void processSearchResponse(QByteArray data);
|
|
||||||
void processSearchGeoResponse(QByteArray data);
|
|
||||||
|
|
||||||
QHash<QNetworkReply*,DeviceId> m_weatherReplys;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void searchResultReady(const QList<QVariantMap> &cityList);
|
|
||||||
void weatherDataReady(const QByteArray &data, const DeviceId &deviceId);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void replyFinished(QNetworkReply *reply);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // OPENWEATHERMAP_H
|
|
||||||
@ -6,10 +6,8 @@ QT+= network
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
devicepluginopenweathermap.cpp \
|
devicepluginopenweathermap.cpp \
|
||||||
openweathermap.cpp
|
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
devicepluginopenweathermap.h \
|
devicepluginopenweathermap.h \
|
||||||
openweathermap.h
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user