mirror of https://github.com/nymea/nymea.git
206 lines
9.0 KiB
C++
206 lines
9.0 KiB
C++
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* *
|
|
* 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/>. *
|
|
* *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
/*!
|
|
\page openweathermap.html
|
|
\title Open Weather Map
|
|
|
|
\ingroup plugins
|
|
\ingroup services
|
|
|
|
This plugin alows you to get the current weather data from \l{http://www.openweathermap.org}.
|
|
The plugin offers two different search methods: if the user searches for a empty string,
|
|
the plugin makes an autodetction with the WAN ip and offers the user the found autodetectresult.
|
|
The autodetection function uses the geolocation of your WAN ip and searches all available weather
|
|
stations in a radius of 2.5 km. Otherwise the plugin returns the list of the found search results
|
|
from the search string.
|
|
|
|
\underline{NOTE}: If you are using a VPN connection, the autodetection will show the results around of your VPN location.
|
|
|
|
\chapter Plugin properties
|
|
Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses}
|
|
and \l{Vendor}{Vendors} of this \l{DevicePlugin}.
|
|
|
|
Each \l{DeviceClass} has a list of \l{ParamType}{paramTypes}, \l{ActionType}{actionTypes}, \l{StateType}{stateTypes}
|
|
and \l{EventType}{eventTypes}. The \l{DeviceClass::CreateMethod}{createMethods} parameter describes how the \l{Device}
|
|
will be created in the system. A device can have more than one \l{DeviceClass::CreateMethod}{CreateMethod}.
|
|
The \l{DeviceClass::SetupMethod}{setupMethod} describes the setup method of the \l{Device}.
|
|
The detailed implementation of each \l{DeviceClass} can be found in the source code.
|
|
|
|
\quotefile plugins/deviceplugins/openweathermap/devicepluginopenweathermap.json
|
|
*/
|
|
|
|
|
|
#include "devicepluginopenweathermap.h"
|
|
|
|
#include "plugin/device.h"
|
|
#include "devicemanager.h"
|
|
#include "plugininfo.h"
|
|
|
|
#include <QDebug>
|
|
#include <QJsonDocument>
|
|
#include <QVariantMap>
|
|
#include <QDateTime>
|
|
|
|
|
|
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)
|
|
{
|
|
if(deviceClassId != openweathermapDeviceClassId){
|
|
return report(DeviceManager::DeviceErrorDeviceClassNotFound);
|
|
}
|
|
|
|
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();
|
|
} else {
|
|
m_openweaher->search(location);
|
|
}
|
|
return DeviceManager::DeviceErrorAsync;
|
|
}
|
|
|
|
DeviceManager::DeviceSetupStatus DevicePluginOpenweathermap::setupDevice(Device *device)
|
|
{
|
|
foreach (Device *deviceListDevice, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) {
|
|
if(deviceListDevice->paramValue("id").toString() == device->paramValue("id").toString()){
|
|
qWarning() << QString("Location " + device->paramValue("location").toString() + "already in added");
|
|
return DeviceManager::DeviceSetupStatusFailure;
|
|
}
|
|
}
|
|
|
|
device->setName("Weather from OpenWeatherMap (" + device->paramValue("location").toString() + ")");
|
|
m_openweaher->update(device->paramValue("id").toString(), device->id());
|
|
|
|
return DeviceManager::DeviceSetupStatusSuccess;
|
|
}
|
|
|
|
DeviceManager::HardwareResources DevicePluginOpenweathermap::requiredHardware() const
|
|
{
|
|
return DeviceManager::HardwareResourceTimer;
|
|
}
|
|
|
|
DeviceManager::DeviceError DevicePluginOpenweathermap::executeAction(Device *device, const Action &action)
|
|
{
|
|
if(action.actionTypeId() == updateWeatherActionTypeId){
|
|
m_openweaher->update(device->paramValue("id").toString(), device->id());
|
|
}
|
|
return DeviceManager::DeviceErrorNoError;
|
|
}
|
|
|
|
void DevicePluginOpenweathermap::guhTimer()
|
|
{
|
|
foreach (Device *device, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) {
|
|
m_openweaher->update(device->paramValue("id").toString(), device->id());
|
|
}
|
|
}
|
|
|
|
void DevicePluginOpenweathermap::searchResultsReady(const QList<QVariantMap> &cityList)
|
|
{
|
|
QList<DeviceDescriptor> retList;
|
|
foreach (QVariantMap elemant, cityList) {
|
|
DeviceDescriptor descriptor(openweathermapDeviceClassId, elemant.value("name").toString(),elemant.value("country").toString());
|
|
ParamList params;
|
|
Param locationParam("location", elemant.value("name"));
|
|
params.append(locationParam);
|
|
Param countryParam("country", elemant.value("country"));
|
|
params.append(countryParam);
|
|
Param idParam("id", elemant.value("id"));
|
|
params.append(idParam);
|
|
descriptor.setParams(params);
|
|
retList.append(descriptor);
|
|
}
|
|
emit devicesDiscovered(openweathermapDeviceClassId,retList);
|
|
}
|
|
|
|
void DevicePluginOpenweathermap::weatherDataReady(const QByteArray &data, const DeviceId &deviceId)
|
|
{
|
|
QJsonParseError error;
|
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
|
|
|
if(error.error != QJsonParseError::NoError) {
|
|
qWarning() << "failed to parse data" << data << ":" << error.errorString();
|
|
return;
|
|
}
|
|
|
|
QVariantMap dataMap = jsonDoc.toVariant().toMap();
|
|
|
|
foreach (Device *device, deviceManager()->findConfiguredDevices(openweathermapDeviceClassId)) {
|
|
if(device->id() == deviceId){
|
|
|
|
if(dataMap.contains("clouds")){
|
|
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("main")){
|
|
double temperatur = dataMap.value("main").toMap().value("temp").toDouble();
|
|
double temperaturMax = dataMap.value("main").toMap().value("temp_max").toDouble();
|
|
double temperaturMin = dataMap.value("main").toMap().value("temp_min").toDouble();
|
|
double pressure = dataMap.value("main").toMap().value("pressure").toDouble();
|
|
int humidity = dataMap.value("main").toMap().value("humidity").toInt();
|
|
|
|
device->setStateValue(temperatureStateTypeId,temperatur);
|
|
device->setStateValue(temperatureMinStateTypeId,temperaturMin);
|
|
device->setStateValue(temperatureMaxStateTypeId,temperaturMax);
|
|
device->setStateValue(pressureStateTypeId,pressure);
|
|
device->setStateValue(humidityStateTypeId,humidity);
|
|
}
|
|
|
|
if(dataMap.contains("sys")){
|
|
uint sunrise = dataMap.value("sys").toMap().value("sunrise").toUInt();
|
|
uint sunset = dataMap.value("sys").toMap().value("sunset").toUInt();
|
|
|
|
device->setStateValue(sunriseStateTypeId,sunrise);
|
|
device->setStateValue(sunsetStateTypeId,sunset);
|
|
}
|
|
|
|
if(dataMap.contains("weather")){
|
|
QString description = dataMap.value("weather").toMap().value("description").toString();
|
|
device->setStateValue(weatherDescriptionStateTypeId,description);
|
|
}
|
|
|
|
if(dataMap.contains("wind")){
|
|
int windDirection = dataMap.value("wind").toMap().value("deg").toInt();
|
|
double windSpeed = dataMap.value("wind").toMap().value("speed").toDouble();
|
|
|
|
device->setStateValue(windDirectionStateTypeId,windDirection);
|
|
device->setStateValue(windSpeedStateTypeId,windSpeed);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|