added nanoleaf plugin
This commit is contained in:
parent
9fca1ed4e1
commit
1a8ed79269
16
debian/control
vendored
16
debian/control
vendored
@ -434,6 +434,21 @@ Description: nymea.io plugin for netatmo
|
|||||||
This package will install the nymea.io plugin for netatmo
|
This package will install the nymea.io plugin for netatmo
|
||||||
|
|
||||||
|
|
||||||
|
Package: nymea-plugin-nanoleaf
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${shlibs:Depends},
|
||||||
|
${misc:Depends},
|
||||||
|
nymea-plugins-translations,
|
||||||
|
Description: nymea.io plugin for nanoleaf
|
||||||
|
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 nanoleaf
|
||||||
|
|
||||||
|
|
||||||
Package: nymea-plugin-networkdetector
|
Package: nymea-plugin-networkdetector
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: ${shlibs:Depends},
|
Depends: ${shlibs:Depends},
|
||||||
@ -845,6 +860,7 @@ Depends: nymea-plugin-anel,
|
|||||||
nymea-plugin-lgsmarttv,
|
nymea-plugin-lgsmarttv,
|
||||||
nymea-plugin-mailnotification,
|
nymea-plugin-mailnotification,
|
||||||
nymea-plugin-texasinstruments,
|
nymea-plugin-texasinstruments,
|
||||||
|
nymea-plugin-nanoleaf,
|
||||||
nymea-plugin-netatmo,
|
nymea-plugin-netatmo,
|
||||||
nymea-plugin-networkdetector,
|
nymea-plugin-networkdetector,
|
||||||
nymea-plugin-openweathermap,
|
nymea-plugin-openweathermap,
|
||||||
|
|||||||
1
debian/nymea-plugin-nanoleaf.install.in
vendored
Normal file
1
debian/nymea-plugin-nanoleaf.install.in
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_devicepluginnanoleaf.so
|
||||||
1
nanoleaf/README.md
Normal file
1
nanoleaf/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Nanoleaf
|
||||||
183
nanoleaf/devicepluginnanoleaf.cpp
Normal file
183
nanoleaf/devicepluginnanoleaf.cpp
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* 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/>. *
|
||||||
|
* *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "devicepluginnanoleaf.h"
|
||||||
|
#include "plugininfo.h"
|
||||||
|
|
||||||
|
#include "network/zeroconf/zeroconfservicebrowser.h"
|
||||||
|
#include "platform/platformzeroconfcontroller.h"
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
DevicePluginNanoleaf::DevicePluginNanoleaf()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::init()
|
||||||
|
{
|
||||||
|
m_zeroconfBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_nanoleafapi._tcp");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::discoverDevices(DeviceDiscoveryInfo *info)
|
||||||
|
{
|
||||||
|
QStringList serialNumbers;
|
||||||
|
foreach (const ZeroConfServiceEntry &entry, m_zeroconfBrowser->serviceEntries()) {
|
||||||
|
if (info->deviceClassId() == lightPanelsDeviceClassId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
//TODO skip duplicated devices
|
||||||
|
|
||||||
|
DeviceDescriptor descriptor(lightPanelsDeviceClassId, entry.name(), entry.hostAddress().toString());
|
||||||
|
ParamList params;
|
||||||
|
|
||||||
|
QString serialNo;
|
||||||
|
QString model;
|
||||||
|
QString firmwareVersion;
|
||||||
|
|
||||||
|
foreach (QString value, entry.txt()) {
|
||||||
|
if (value.contains("id=")) {
|
||||||
|
serialNo = value.split("=").last();
|
||||||
|
} else if (value.contains("md=")) {
|
||||||
|
model = value.split("=").last();
|
||||||
|
} else if (value.contains("srcvers=")) {
|
||||||
|
firmwareVersion = value.split("=").last();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (serialNumbers.contains(serialNo)) {
|
||||||
|
continue; //To avoid duplicated devices
|
||||||
|
}
|
||||||
|
|
||||||
|
Device *existingDevice = myDevices().findByParams(ParamList() << Param(lightPanelsDeviceSerialNoParamTypeId, serialNo));
|
||||||
|
if (existingDevice) {
|
||||||
|
descriptor.setDeviceId(existingDevice->id());
|
||||||
|
}
|
||||||
|
|
||||||
|
serialNumbers.append(serialNo);
|
||||||
|
qCDebug(dcNanoleaf()) << "Have device" << entry.name() << serialNo << model << firmwareVersion;
|
||||||
|
params << Param(lightPanelsDeviceAddressParamTypeId, entry.hostAddress().toString());
|
||||||
|
params << Param(lightPanelsDevicePortParamTypeId, entry.port());
|
||||||
|
params << Param(lightPanelsDeviceModelParamTypeId, model);
|
||||||
|
params << Param(lightPanelsDeviceSerialNoParamTypeId, serialNo);
|
||||||
|
params << Param(lightPanelsDeviceFirmwareVersionParamTypeId, firmwareVersion);
|
||||||
|
descriptor.setParams(params);
|
||||||
|
|
||||||
|
info->addDeviceDescriptor(descriptor);
|
||||||
|
|
||||||
|
}
|
||||||
|
info->finish(Device::DeviceErrorNoError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::startPairing(DevicePairingInfo *info)
|
||||||
|
{
|
||||||
|
info->finish(Device::DeviceErrorNoError, tr("Please press the button"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::confirmPairing(DevicePairingInfo *info, const QString &username, const QString &secret)
|
||||||
|
{
|
||||||
|
Q_UNUSED(username)
|
||||||
|
Q_UNUSED(secret)
|
||||||
|
Nanoleaf *nanoleaf = new Nanoleaf(hardwareManager()->networkManager(), QHostAddress(info->params().paramValue(lightPanelsDeviceAddressParamTypeId).toString()), info->params().paramValue(lightPanelsDevicePortParamTypeId).toInt(), this);
|
||||||
|
nanoleaf->addUser();
|
||||||
|
info->finish(Device::DeviceErrorNoError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::setupDevice(DeviceSetupInfo *info)
|
||||||
|
{
|
||||||
|
Device *device = info->device();
|
||||||
|
if(device->deviceClassId() == lightPanelsDeviceClassId) {
|
||||||
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::postSetupDevice(Device *device)
|
||||||
|
{
|
||||||
|
if (device->deviceClassId() == lightPanelsDeviceClassId) {
|
||||||
|
//TODO get all the information and set the device states
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!m_pluginTimer) {
|
||||||
|
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(5);
|
||||||
|
connect(m_pluginTimer, &PluginTimer::timeout, this, [this]() {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::deviceRemoved(Device *device)
|
||||||
|
{
|
||||||
|
if(device->deviceClassId() == lightPanelsDeviceClassId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myDevices().isEmpty()) {
|
||||||
|
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
|
||||||
|
m_pluginTimer = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::executeAction(DeviceActionInfo *info)
|
||||||
|
{
|
||||||
|
Device *device = info->device();
|
||||||
|
Action action = info->action();
|
||||||
|
|
||||||
|
if (device->deviceClassId() == lightPanelsDeviceClassId) {
|
||||||
|
Nanoleaf *nanoleaf = m_nanoleafConnections.value(device->id());
|
||||||
|
if (action.actionTypeId() == lightPanelsPowerActionTypeId) {
|
||||||
|
bool power = action.param(lightPanelsPowerActionPowerParamTypeId).value().toBool();
|
||||||
|
QUuid requestId = nanoleaf->setPower(power);
|
||||||
|
connect(info, &DeviceActionInfo::aborted,[requestId, this](){m_asyncActions.remove(requestId);});
|
||||||
|
m_asyncActions.insert(requestId, info);
|
||||||
|
|
||||||
|
} else if (action.actionTypeId() == lightPanelsBrightnessActionTypeId) {
|
||||||
|
int brightness = action.param(lightPanelsBrightnessActionBrightnessParamTypeId).value().toInt();
|
||||||
|
QUuid requestId = nanoleaf->setBrightness(brightness);
|
||||||
|
connect(info, &DeviceActionInfo::aborted,[requestId, this](){m_asyncActions.remove(requestId);});
|
||||||
|
m_asyncActions.insert(requestId, info);
|
||||||
|
|
||||||
|
} else if (action.actionTypeId() == lightPanelsColorActionTypeId) {
|
||||||
|
QColor color(action.param(lightPanelsColorActionColorParamTypeId).value().toString());
|
||||||
|
QUuid requestId = nanoleaf->setHue(color);
|
||||||
|
connect(info, &DeviceActionInfo::aborted,[requestId, this](){m_asyncActions.remove(requestId);});
|
||||||
|
m_asyncActions.insert(requestId, info);
|
||||||
|
|
||||||
|
} else if (action.actionTypeId() == lightPanelsColorTemperatureActionTypeId) {
|
||||||
|
int colorTemperature = action.param(lightPanelsColorTemperatureActionColorTemperatureParamTypeId).value().toInt();
|
||||||
|
QUuid requestId = nanoleaf->setColorTemperature(colorTemperature);
|
||||||
|
connect(info, &DeviceActionInfo::aborted,[requestId, this](){m_asyncActions.remove(requestId);});
|
||||||
|
m_asyncActions.insert(requestId, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::getDeviceStates(Nanoleaf *nanoleaf)
|
||||||
|
{
|
||||||
|
nanoleaf->getPower();
|
||||||
|
nanoleaf->getHue();
|
||||||
|
nanoleaf->getColorMode();
|
||||||
|
nanoleaf->getBrightness();
|
||||||
|
nanoleaf->getSaturation();
|
||||||
|
nanoleaf->getColorTemperature();
|
||||||
|
}
|
||||||
|
|
||||||
64
nanoleaf/devicepluginnanoleaf.h
Normal file
64
nanoleaf/devicepluginnanoleaf.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* 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 DEVICEPLUGINNANOLEAF_H
|
||||||
|
#define DEVICEPLUGINNANOLEAF_H
|
||||||
|
|
||||||
|
#include "devices/deviceplugin.h"
|
||||||
|
#include "nanoleaf.h"
|
||||||
|
|
||||||
|
#include "plugintimer.h"
|
||||||
|
#include "network/networkaccessmanager.h"
|
||||||
|
#include "network/zeroconf/zeroconfservicebrowser.h"
|
||||||
|
|
||||||
|
#include <QHostAddress>
|
||||||
|
|
||||||
|
class DevicePluginNanoleaf: public DevicePlugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "devicepluginnanoleaf.json")
|
||||||
|
Q_INTERFACES(DevicePlugin)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DevicePluginNanoleaf();
|
||||||
|
|
||||||
|
void init() override;
|
||||||
|
void discoverDevices(DeviceDiscoveryInfo *info) override;
|
||||||
|
void startPairing(DevicePairingInfo *info) override;
|
||||||
|
void confirmPairing(DevicePairingInfo *info, const QString &username, const QString &secret) override;
|
||||||
|
void setupDevice(DeviceSetupInfo *info) override;
|
||||||
|
void postSetupDevice(Device *device) override;
|
||||||
|
void deviceRemoved(Device *device) override;
|
||||||
|
void executeAction(DeviceActionInfo *info) override;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
ZeroConfServiceBrowser *m_zeroconfBrowser = nullptr;
|
||||||
|
PluginTimer *m_pluginTimer = nullptr;
|
||||||
|
QHash<DeviceId, Nanoleaf*> m_nanoleafConnections;
|
||||||
|
QHash<QUuid, DeviceActionInfo *> m_asyncActions;
|
||||||
|
|
||||||
|
void getDeviceStates(Nanoleaf *nanoleaf);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DEVICEPLUGINNANOLEAF_H
|
||||||
115
nanoleaf/devicepluginnanoleaf.json
Normal file
115
nanoleaf/devicepluginnanoleaf.json
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"name": "Nanoleaf",
|
||||||
|
"displayName": "Nanoleaf",
|
||||||
|
"id": "360867ec-1594-498d-8182-fbab1fe17489",
|
||||||
|
"vendors": [
|
||||||
|
{
|
||||||
|
"id": "3d7fdaa6-7896-419b-8be3-c90c42bcac7f",
|
||||||
|
"name": "nanoleaf",
|
||||||
|
"displayName": "Nanoleaf",
|
||||||
|
"deviceClasses": [
|
||||||
|
{
|
||||||
|
"id": "d44ee383-9fa5-4751-babd-1129ac20896a",
|
||||||
|
"name": "lightPanels",
|
||||||
|
"displayName": "Light panels",
|
||||||
|
"interfaces": ["colorlight", "colortemperaturelight", "connectable"],
|
||||||
|
"createMethods": ["discovery"],
|
||||||
|
"paramTypes": [
|
||||||
|
{
|
||||||
|
"id": "ff57079f-d5ab-4511-8a5c-0726e7b82af6",
|
||||||
|
"name": "address",
|
||||||
|
"displayName": "Address",
|
||||||
|
"type" : "QString"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ba4fd45b-990d-480a-859d-fff7ffba3ba4",
|
||||||
|
"name": "port",
|
||||||
|
"displayName": "Port",
|
||||||
|
"type" : "int",
|
||||||
|
"readOnly": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "353d3c71-0ad2-40d5-99f6-cc305e2073f1",
|
||||||
|
"name": "model",
|
||||||
|
"displayName": "Model",
|
||||||
|
"type" : "QString",
|
||||||
|
"readOnly": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "18be4a5f-e2c2-4070-bc3e-ea9fe64f2276",
|
||||||
|
"name": "serialNo",
|
||||||
|
"displayName": "Serial number",
|
||||||
|
"type" : "QString",
|
||||||
|
"readOnly": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "1b85eebe-3b1a-49a9-bddb-2175d6599b95",
|
||||||
|
"name": "firmwareVersion",
|
||||||
|
"displayName": "Firmware version",
|
||||||
|
"type" : "QString",
|
||||||
|
"readOnly": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateTypes": [
|
||||||
|
{
|
||||||
|
"id": "a3102107-a825-4ec8-a9ec-b2c2a9fb5c89",
|
||||||
|
"name": "connected",
|
||||||
|
"displayName": "Reachable",
|
||||||
|
"displayNameEvent": "Reachable changed",
|
||||||
|
"defaultValue": false,
|
||||||
|
"type": "bool",
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "44bee9ec-513d-4834-991a-ee9ae69d9f2a",
|
||||||
|
"name": "power",
|
||||||
|
"displayName": "Power",
|
||||||
|
"displayNameEvent": "Power changed",
|
||||||
|
"displayNameAction": "Set power",
|
||||||
|
"type": "bool",
|
||||||
|
"defaultValue": false,
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "41248127-844b-40be-87e6-38aee48b6687",
|
||||||
|
"name": "colorTemperature",
|
||||||
|
"displayName": "Color temperature",
|
||||||
|
"displayNameEvent": "Color temperature changed",
|
||||||
|
"displayNameAction": "Set color temperature",
|
||||||
|
"type": "int",
|
||||||
|
"unit": "Mired",
|
||||||
|
"defaultValue": 170,
|
||||||
|
"minValue": 153,
|
||||||
|
"maxValue": 500,
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "d4a52cdc-93b2-44fc-a36c-ae65f1d98f2e",
|
||||||
|
"name": "color",
|
||||||
|
"displayName": "Color",
|
||||||
|
"displayNameEvent": "Color changed",
|
||||||
|
"displayNameAction": "Set color",
|
||||||
|
"type": "QColor",
|
||||||
|
"defaultValue": "#000000",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4e5d6460-d42e-4b7c-a8f3-6e953451c1ef",
|
||||||
|
"name": "brightness",
|
||||||
|
"displayName": "Brightness",
|
||||||
|
"displayNameEvent": "Brightness changed",
|
||||||
|
"displayNameAction": "Set brigtness",
|
||||||
|
"type": "int",
|
||||||
|
"unit": "Percentage",
|
||||||
|
"defaultValue": 0,
|
||||||
|
"minValue": 0,
|
||||||
|
"maxValue": 100,
|
||||||
|
"writable": true
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
213
nanoleaf/nanoleaf.cpp
Normal file
213
nanoleaf/nanoleaf.cpp
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* 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/>. *
|
||||||
|
* *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "nanoleaf.h"
|
||||||
|
#include "extern-plugininfo.h"
|
||||||
|
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QUrlQuery>
|
||||||
|
|
||||||
|
Nanoleaf::Nanoleaf(NetworkAccessManager *networkManager, const QHostAddress &address, int port, QObject *parent) :
|
||||||
|
QObject(parent),
|
||||||
|
m_networkManager(networkManager),
|
||||||
|
m_address(address),
|
||||||
|
m_port(port)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::setIpAddress(const QHostAddress &address)
|
||||||
|
{
|
||||||
|
m_address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHostAddress Nanoleaf::ipAddress()
|
||||||
|
{
|
||||||
|
return m_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::setPort(int port)
|
||||||
|
{
|
||||||
|
m_port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Nanoleaf::port()
|
||||||
|
{
|
||||||
|
return m_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::addUser()
|
||||||
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setPath("/api/v1/new");
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->post(request, "");
|
||||||
|
qDebug(dcNanoleaf()) << "Sending request" << request.url();
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [reply, 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) {
|
||||||
|
emit connectionChanged(false);
|
||||||
|
}
|
||||||
|
if (status == 400 || status == 401) {
|
||||||
|
emit authenticationStatusChanged(false);
|
||||||
|
}
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit connectionChanged(true);
|
||||||
|
emit authenticationStatusChanged(true);
|
||||||
|
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qDebug(dcNanoleaf()) << "Recieved invalide JSON object";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_authToken = data.toVariant().toMap().value("auth_token").toString();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::deleteUser()
|
||||||
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setPath("/api/v1/"+m_authToken);
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->deleteResource(request);
|
||||||
|
qDebug(dcNanoleaf()) << "Sending request" << request.url();
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
||||||
|
reply->deleteLater();
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
if (status != 204 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::getPower()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::getHue()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::getBrightness()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::getSaturation()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::getColorTemperature()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::getColorMode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid Nanoleaf::setPower(bool power)
|
||||||
|
{
|
||||||
|
QUuid requestId = QUuid::createUuid();
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setPath(QString("/api/v1/%1/state/on").arg(m_authToken));
|
||||||
|
|
||||||
|
QVariantMap map;
|
||||||
|
QVariantMap value;
|
||||||
|
value["value"] = power;
|
||||||
|
map.insert("on", value);
|
||||||
|
QJsonDocument body = QJsonDocument::fromVariant(map);
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->put(request, body.toJson());
|
||||||
|
qDebug(dcNanoleaf()) << "Sending request" << request.url();
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
|
||||||
|
reply->deleteLater();
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
if (status != 204 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
emit requestedExecuted(requestId, false);
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit requestedExecuted(requestId, true);
|
||||||
|
});
|
||||||
|
return requestId;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid Nanoleaf::setHue(QColor color)
|
||||||
|
{
|
||||||
|
Q_UNUSED(color);
|
||||||
|
QUuid requestId = QUuid::createUuid();
|
||||||
|
return requestId;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid Nanoleaf::setBrightness(int percentage)
|
||||||
|
{
|
||||||
|
Q_UNUSED(percentage);
|
||||||
|
QUuid requestId = QUuid::createUuid();
|
||||||
|
return requestId;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid Nanoleaf::setSaturation(int percentage)
|
||||||
|
{
|
||||||
|
Q_UNUSED(percentage);
|
||||||
|
QUuid requestId = QUuid::createUuid();
|
||||||
|
return requestId;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid Nanoleaf::setColorTemperature(int mired)
|
||||||
|
{
|
||||||
|
Q_UNUSED(mired);
|
||||||
|
QUuid requestId = QUuid::createUuid();
|
||||||
|
return requestId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
98
nanoleaf/nanoleaf.h
Normal file
98
nanoleaf/nanoleaf.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* 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 NANOLEAF_H
|
||||||
|
#define NANOLEAF_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QUuid>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
#include "network/networkaccessmanager.h"
|
||||||
|
#include "devices/device.h"
|
||||||
|
|
||||||
|
class Nanoleaf : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit Nanoleaf(NetworkAccessManager *networkManager, const QHostAddress &address, int port = 16021, QObject *parent = nullptr);
|
||||||
|
void setIpAddress(const QHostAddress &address);
|
||||||
|
QHostAddress ipAddress();
|
||||||
|
|
||||||
|
void setPort(int port);
|
||||||
|
int port();
|
||||||
|
|
||||||
|
//AUTHORIZATION
|
||||||
|
void addUser();
|
||||||
|
void deleteUser();
|
||||||
|
|
||||||
|
//GET ALL PANEL INFORMATION
|
||||||
|
|
||||||
|
//STATES
|
||||||
|
void getPower();
|
||||||
|
void getHue();
|
||||||
|
void getBrightness();
|
||||||
|
void getSaturation();
|
||||||
|
void getColorTemperature();
|
||||||
|
void getColorMode();
|
||||||
|
|
||||||
|
QUuid setPower(bool power);
|
||||||
|
QUuid setHue(QColor color);
|
||||||
|
QUuid setBrightness(int percentage);
|
||||||
|
QUuid setSaturation(int percentage);
|
||||||
|
QUuid setColorTemperature(int mired);
|
||||||
|
|
||||||
|
|
||||||
|
//EFFECTS
|
||||||
|
|
||||||
|
//PANEL LAYOUT
|
||||||
|
|
||||||
|
//IDENTIFY
|
||||||
|
|
||||||
|
|
||||||
|
//EXTERNAL CONTROL
|
||||||
|
|
||||||
|
|
||||||
|
//RHYTHM
|
||||||
|
|
||||||
|
private:
|
||||||
|
NetworkAccessManager *m_networkManager = nullptr;
|
||||||
|
QString m_authToken;
|
||||||
|
QHostAddress m_address;
|
||||||
|
int m_port;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void connectionChanged(bool connected);
|
||||||
|
void authenticationStatusChanged(bool authenticated);
|
||||||
|
void requestedExecuted(QUuid requestId, bool success);
|
||||||
|
|
||||||
|
void powerReceived(bool power);
|
||||||
|
void brightnessReceived(int percentage);
|
||||||
|
void colorModeReceived();
|
||||||
|
void hueReceived(QColor color);
|
||||||
|
void saturationReceived(int percentage);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NANOLEAF_H
|
||||||
16
nanoleaf/nanoleaf.pro
Normal file
16
nanoleaf/nanoleaf.pro
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
include(../plugins.pri)
|
||||||
|
|
||||||
|
TARGET = $$qtLibraryTarget(nymea_devicepluginnanoleaf)
|
||||||
|
|
||||||
|
QT += network
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
devicepluginnanoleaf.cpp \
|
||||||
|
nanoleaf.cpp \
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
devicepluginnanoleaf.h \
|
||||||
|
nanoleaf.h \
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -28,6 +28,7 @@ PLUGIN_DIRS = \
|
|||||||
lgsmarttv \
|
lgsmarttv \
|
||||||
mailnotification \
|
mailnotification \
|
||||||
mqttclient \
|
mqttclient \
|
||||||
|
nanoleaf \
|
||||||
netatmo \
|
netatmo \
|
||||||
networkdetector \
|
networkdetector \
|
||||||
onewire \
|
onewire \
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user