added OpenUV

master
Boernsman 2019-12-31 00:48:23 +01:00
parent 9fca1ed4e1
commit 05194f95ec
8 changed files with 432 additions and 0 deletions

16
debian/control vendored
View File

@ -469,6 +469,21 @@ Description: nymea.io plugin for one wire devices
This package will install the nymea.io plugin for one wire devices
Package: nymea-plugin-openuv
Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
nymea-plugins-translations,
Description: nymea.io plugin for OpenUV
The nymea daemon is a plugin based IoT (Internet of Things) server. The
server works like a translator for devices, things and services and
allows them to interact.
With the powerful rule engine you are able to connect any device available
in the system and create individual scenes and behaviors for your environment.
.
This package will install the nymea.io plugin for OpenUV
Package: nymea-plugin-openweathermap
Architecture: any
Depends: ${shlibs:Depends},
@ -847,6 +862,7 @@ Depends: nymea-plugin-anel,
nymea-plugin-texasinstruments,
nymea-plugin-netatmo,
nymea-plugin-networkdetector,
nymea-plugin-openuv,
nymea-plugin-openweathermap,
nymea-plugin-philipshue,
nymea-plugin-pushbullet,

1
debian/nymea-plugin-openuv.install.in vendored Normal file
View File

@ -0,0 +1 @@
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_devicepluginopenuv.so

View File

@ -31,6 +31,7 @@ PLUGIN_DIRS = \
netatmo \
networkdetector \
onewire \
openuv \
openweathermap \
osdomotics \
philipshue \

6
openuv/README.md Normal file
View File

@ -0,0 +1,6 @@
# OpenUV
Get the current UV index for your location.
The save exposure time is not available for all regions. If all save exposure times are zero it due to unavailability of this information

View File

@ -0,0 +1,173 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2020 Berhard Trinnes <bernhard.trinnes@nymea.io> *
* *
* This file is part of nymea. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "devicepluginopenuv.h"
#include "devices/device.h"
#include "plugininfo.h"
#include <QDebug>
#include <QJsonDocument>
#include <QVariantMap>
#include <QUrl>
#include <QUrlQuery>
#include <QDateTime>
#include <QTimeZone>
DevicePluginOpenUv::DevicePluginOpenUv()
{
}
void DevicePluginOpenUv::init()
{
m_apiKey = configValue(openUvPluginApiKeyParamTypeId).toByteArray();
connect(this, &DevicePluginOpenUv::configValueChanged, this, [this]{
m_apiKey = configValue(openUvPluginApiKeyParamTypeId).toByteArray();
});
}
void DevicePluginOpenUv::discoverDevices(DeviceDiscoveryInfo *info)
{
QNetworkRequest request(QUrl("http://ip-api.com/json"));
QNetworkReply* reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
connect(reply, &QNetworkReply::finished, info, [this, reply, info]() {
if (reply->error() != QNetworkReply::NoError) {
qCWarning(dcOpenUv()) << "Error fetching geolocation from ip-api:" << reply->error() << reply->errorString();
info->finish(Device::DeviceErrorHardwareFailure, QT_TR_NOOP("Failed to fetch data from the internet."));
return;
}
QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qCWarning(dcOpenUv()) << "Failed to parse json from ip-api:" << error.error << error.errorString();
info->finish(Device::DeviceErrorHardwareFailure, QT_TR_NOOP("The server returned unexpected data."));
return;
}
if (!jsonDoc.toVariant().toMap().contains("lat") || !jsonDoc.toVariant().toMap().contains("lon")) {
qCWarning(dcOpenUv()) << "Reply missing geolocation info" << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented));
info->finish(Device::DeviceErrorHardwareFailure, QT_TR_NOOP("The server returned unexpected data."));
return;
}
qreal lat = jsonDoc.toVariant().toMap().value("lat").toDouble();
qreal lon = jsonDoc.toVariant().toMap().value("lon").toDouble();
DeviceDescriptor descriptor(info->deviceClassId(), tr("OpenUV location"), jsonDoc.toVariant().toMap().value("city").toString());
ParamList params;
params.append(Param(openUvDeviceLatitudeParamTypeId, lat));
params.append(Param(openUvDeviceLongitudeParamTypeId, lon));
descriptor.setParams(params);
info->addDeviceDescriptor(descriptor);
info->finish(Device::DeviceErrorNoError);
});
}
void DevicePluginOpenUv::setupDevice(DeviceSetupInfo *info)
{
if (m_apiKey.isEmpty() || m_apiKey == "-") {
info->finish(Device::DeviceErrorSetupFailed, tr("API key is missing, add your OpenUV API key in the plug-in configs"));
return;
}
if (!m_pluginTimer) {
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(60 * 60);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginOpenUv::onPluginTimer);
}
info->finish(Device::DeviceErrorNoError);
}
void DevicePluginOpenUv::postSetupDevice(Device *device)
{
getUvIndex(device);
}
void DevicePluginOpenUv::deviceRemoved(Device *device)
{
Q_UNUSED(device);
if (myDevices().isEmpty()) {
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
m_pluginTimer = nullptr;
}
}
void DevicePluginOpenUv::getUvIndex(Device *device)
{
qCDebug(dcOpenUv()) << "Refresh data for" << device->name();
QUrl url("https://api.openuv.io/api/v1/uv");
QUrlQuery query;
query.addQueryItem("lat", device->paramValue(openUvDeviceLatitudeParamTypeId).toString());
query.addQueryItem("lng", device->paramValue(openUvDeviceLongitudeParamTypeId).toString());
url.setQuery(query);
QNetworkRequest request;
request.setUrl(url);
request.setRawHeader("x-access-token", m_apiKey);
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, this, [reply, device, this] {
reply->deleteLater();
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// Check HTTP status code
if (status != 200 || reply->error() != QNetworkReply::NoError) {
if (reply->error() == QNetworkReply::HostNotFoundError) {
device->setStateValue(openUvConnectedStateTypeId, false);
}
qCWarning(dcOpenUv()) << "Request error:" << status << reply->errorString();
return;
}
device->setStateValue(openUvConnectedStateTypeId, true);
QJsonParseError error;
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qDebug(dcOpenUv()) << "Recieved invalide JSON object";
return;
}
QVariantMap result = data.toVariant().toMap().value("result").toMap();
device->setStateValue(openUvUvStateTypeId, result["uv"].toDouble());
device->setStateValue(openUvUvMaxStateTypeId, result["uv_max"].toDouble());
device->setStateValue(openUvOzoneStateTypeId, result["ozone"].toDouble());
device->setStateValue(openUvUvTimeStateTypeId, QDateTime::fromString(result["uv_time"].toString(),Qt::DateFormat::ISODateWithMs).toSecsSinceEpoch());
device->setStateValue(openUvOzoneTimeStateTypeId, QDateTime::fromString(result["ozone_time"].toString(),Qt::DateFormat::ISODateWithMs).toSecsSinceEpoch());
device->setStateValue(openUvUvMaxTimeStateTypeId, QDateTime::fromString(result["uv_max_time"].toString(),Qt::DateFormat::ISODateWithMs).toSecsSinceEpoch());
QVariantMap safeExposureTimes = result["safe_exposure_time"].toMap();
device->setStateValue(openUvSafeExposureTimeSt1StateTypeId, safeExposureTimes["st1"].toInt());
device->setStateValue(openUvSafeExposureTimeSt2StateTypeId, safeExposureTimes["st2"].toInt());
device->setStateValue(openUvSafeExposureTimeSt3StateTypeId, safeExposureTimes["st3"].toInt());
device->setStateValue(openUvSafeExposureTimeSt4StateTypeId, safeExposureTimes["st4"].toInt());
device->setStateValue(openUvSafeExposureTimeSt5StateTypeId, safeExposureTimes["st5"].toInt());
device->setStateValue(openUvSafeExposureTimeSt6StateTypeId, safeExposureTimes["st6"].toInt());
});
}
void DevicePluginOpenUv::onPluginTimer()
{
foreach (Device *device, myDevices()) {
getUvIndex(device);
}
}

View File

@ -0,0 +1,60 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2020 Bernhard Trinnes <bernhard.trinnes@nymea.io> *
* *
* This file is part of nymea. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library 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 *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef DEVICEPLUGINOPENUV_H
#define DEVICEPLUGINOPENUV_H
#include "plugintimer.h"
#include "devices/deviceplugin.h"
#include "network/networkaccessmanager.h"
#include <QTimer>
#include <QHostAddress>
class DevicePluginOpenUv : public DevicePlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "devicepluginopenuv.json")
Q_INTERFACES(DevicePlugin)
public:
explicit DevicePluginOpenUv();
void init() override;
void discoverDevices(DeviceDiscoveryInfo *info) override;
void setupDevice(DeviceSetupInfo *info) override;
void postSetupDevice(Device *device)override;
void deviceRemoved(Device *device) override;
void getUvIndex(Device *device);
private:
PluginTimer *m_pluginTimer = nullptr;
QByteArray m_apiKey;
void searchGeoLocation(double lat, double lon, const QString &country, DeviceDiscoveryInfo *info);
private slots:
void onPluginTimer();
};
#endif // DEVICEPLUGINOPENUV_H

View File

@ -0,0 +1,162 @@
{
"name": "OpenUv",
"displayName": "OpenUV",
"id": "9b7d9cc8-77df-4197-a6fc-8a365747a3b1",
"paramTypes": [
{
"id": "cbb8e9d1-22b6-40ab-bbff-26abb2ed416f",
"name": "apiKey",
"displayName": "API key",
"type": "QString",
"inputType": "TextLine",
"defaultValue": "-"
}
],
"vendors": [
{
"name": "openUv",
"displayName": "OpenUV",
"id": "73560db6-af79-41f0-85a8-e9c9907647c8",
"deviceClasses": [
{
"id": "37e17c00-91e1-4276-a1e3-12283d2cae4c",
"name": "openUv",
"displayName": "UV Index",
"interfaces": ["connectable"],
"createMethods": ["discovery", "user"],
"paramTypes": [
{
"id": "35869967-20f2-4106-ba2e-90293bd460db",
"name": "latitude",
"displayName": "Latitude",
"type": "QString",
"inputType": "TextLine"
},
{
"id": "b97dfec9-f9e7-489d-b3db-7e70938def1a",
"name": "longitude",
"displayName": "Longitude",
"type": "QString",
"inputType": "TextLine"
}
],
"stateTypes": [
{
"id": "47c7dd57-3592-4d05-af4c-1034268223e1",
"name": "connected",
"displayName": "Connected",
"displayNameEvent": "Connected changed",
"type": "bool",
"defaultValue": false
},
{
"id": "1d63cee1-3e28-4e90-ad4f-acbc2081ea8c",
"name": "uv",
"displayName": "UV index",
"displayNameEvent": "UV index changed",
"type": "int",
"defaultValue": 0
},
{
"id": "35c799a1-d4b5-4d26-8b63-d884cf96ff2c",
"name": "uvTime",
"displayName": "UV time",
"displayNameEvent": "UV time changed",
"unit": "UnixTime",
"type": "int",
"defaultValue": 0
},
{
"id": "59fe2255-3b61-44f0-84eb-afa6eea838c2",
"name": "uvMax",
"displayName": "UV day max index",
"displayNameEvent": "UV day max index changed",
"type": "int",
"defaultValue": 0
},
{
"id": "4abd1745-c290-4685-bed4-108d31721b67",
"name": "uvMaxTime",
"displayName": "UV maximum time",
"displayNameEvent": "UV maximum time changed",
"unit": "UnixTime",
"type": "int",
"defaultValue": 0
},
{
"id": "48e51a7c-edbb-499e-95a0-6789bf51437c",
"name": "ozone",
"displayName": "Ozone",
"displayNameEvent": "Ozone changed",
"type": "int",
"defaultValue": 0
},
{
"id": "27a48154-218f-4a27-aefb-41d943ecf7e8",
"name": "ozoneTime",
"displayName": "Ozone time",
"displayNameEvent": "Ozone time changed",
"unit": "UnixTime",
"type": "int",
"defaultValue": 0
},
{
"id": "13bc0387-acfe-4461-85c8-46f5e93ee0aa",
"name": "safeExposureTimeSt1",
"displayName": "Safe exposure time skin type 1",
"displayNameEvent": "Safe exposure time skin type 1 changed",
"unit": "Minutes",
"type": "int",
"defaultValue": 0
},
{
"id": "0a60b028-97c9-4231-90a4-95ace8c6cf28",
"name": "safeExposureTimeSt2",
"displayName": "Safe exposure time skin type 2",
"displayNameEvent": "Safe exposure time skin type 2 changed",
"unit": "Minutes",
"type": "int",
"defaultValue": 0
},
{
"id": "fb9c63aa-8ec6-479d-bd87-75865b8fcd77",
"name": "safeExposureTimeSt3",
"displayName": "Safe exposure time skin type 3",
"displayNameEvent": "Safe exposure time skin type 3 changed",
"unit": "Minutes",
"type": "int",
"defaultValue": 0
},
{
"id": "31fc498f-1f17-4443-b0f8-65aff70bbf1c",
"name": "safeExposureTimeSt4",
"displayName": "Safe exposure time skin type 4",
"displayNameEvent": "Safe exposure time skin type 4 changed",
"unit": "Minutes",
"type": "int",
"defaultValue": 0
},
{
"id": "268637f0-73a9-4945-ace9-fc2bfc250675",
"name": "safeExposureTimeSt5",
"displayName": "Safe exposure time skin type 5",
"displayNameEvent": "Safe exposure time skin type 5 changed",
"unit": "Minutes",
"type": "int",
"defaultValue": 0
},
{
"id": "fd98313c-a6fb-4cff-8478-7399d33e7794",
"name": "safeExposureTimeSt6",
"displayName": "Safe exposure time skin type 6",
"displayNameEvent": "Safe exposure time skin type 6 changed",
"unit": "Minutes",
"type": "int",
"defaultValue": 0
}
]
}
]
}
]
}

13
openuv/openuv.pro Normal file
View File

@ -0,0 +1,13 @@
include(../plugins.pri)
TARGET = $$qtLibraryTarget(nymea_devicepluginopenuv)
QT+= network
SOURCES += \
devicepluginopenuv.cpp \
HEADERS += \
devicepluginopenuv.h \