added effect browsing
This commit is contained in:
parent
1a8ed79269
commit
9e53feb985
@ -40,14 +40,11 @@ void DevicePluginNanoleaf::init()
|
|||||||
m_zeroconfBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_nanoleafapi._tcp");
|
m_zeroconfBrowser = hardwareManager()->zeroConfController()->createServiceBrowser("_nanoleafapi._tcp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DevicePluginNanoleaf::discoverDevices(DeviceDiscoveryInfo *info)
|
void DevicePluginNanoleaf::discoverDevices(DeviceDiscoveryInfo *info)
|
||||||
{
|
{
|
||||||
QStringList serialNumbers;
|
QStringList serialNumbers;
|
||||||
foreach (const ZeroConfServiceEntry &entry, m_zeroconfBrowser->serviceEntries()) {
|
foreach (const ZeroConfServiceEntry &entry, m_zeroconfBrowser->serviceEntries()) {
|
||||||
if (info->deviceClassId() == lightPanelsDeviceClassId) {
|
|
||||||
|
|
||||||
}
|
|
||||||
//TODO skip duplicated devices
|
|
||||||
|
|
||||||
DeviceDescriptor descriptor(lightPanelsDeviceClassId, entry.name(), entry.hostAddress().toString());
|
DeviceDescriptor descriptor(lightPanelsDeviceClassId, entry.name(), entry.hostAddress().toString());
|
||||||
ParamList params;
|
ParamList params;
|
||||||
@ -89,46 +86,108 @@ void DevicePluginNanoleaf::discoverDevices(DeviceDiscoveryInfo *info)
|
|||||||
info->finish(Device::DeviceErrorNoError);
|
info->finish(Device::DeviceErrorNoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DevicePluginNanoleaf::startPairing(DevicePairingInfo *info)
|
void DevicePluginNanoleaf::startPairing(DevicePairingInfo *info)
|
||||||
{
|
{
|
||||||
info->finish(Device::DeviceErrorNoError, tr("Please press the button"));
|
info->finish(Device::DeviceErrorNoError, tr("On the Nanoleaf controller, hold the on-off button for 5-7 seconds until the LED starts flashing."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DevicePluginNanoleaf::confirmPairing(DevicePairingInfo *info, const QString &username, const QString &secret)
|
void DevicePluginNanoleaf::confirmPairing(DevicePairingInfo *info, const QString &username, const QString &secret)
|
||||||
{
|
{
|
||||||
Q_UNUSED(username)
|
Q_UNUSED(username)
|
||||||
Q_UNUSED(secret)
|
Q_UNUSED(secret)
|
||||||
Nanoleaf *nanoleaf = new Nanoleaf(hardwareManager()->networkManager(), QHostAddress(info->params().paramValue(lightPanelsDeviceAddressParamTypeId).toString()), info->params().paramValue(lightPanelsDevicePortParamTypeId).toInt(), this);
|
Nanoleaf *nanoleaf = new Nanoleaf(hardwareManager()->networkManager(), QHostAddress(info->params().paramValue(lightPanelsDeviceAddressParamTypeId).toString()), info->params().paramValue(lightPanelsDevicePortParamTypeId).toInt(), this);
|
||||||
nanoleaf->addUser();
|
connect(nanoleaf, &Nanoleaf::authTokenRecieved, this, &DevicePluginNanoleaf::onAuthTokenReceived);
|
||||||
info->finish(Device::DeviceErrorNoError);
|
connect(nanoleaf, &Nanoleaf::authenticationStatusChanged, this, &DevicePluginNanoleaf::onAuthenticationStatusChanged);
|
||||||
|
connect(nanoleaf, &Nanoleaf::requestExecuted, this, &DevicePluginNanoleaf::onRequestExecuted);
|
||||||
|
connect(nanoleaf, &Nanoleaf::connectionChanged, this, &DevicePluginNanoleaf::onConnectionChanged);
|
||||||
|
|
||||||
|
connect(nanoleaf, &Nanoleaf::brightnessReceived, this, &DevicePluginNanoleaf::onBrightnessReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::powerReceived, this, &DevicePluginNanoleaf::onPowerReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::colorModeReceived, this, &DevicePluginNanoleaf::onColorModeReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::colorTemperatureReceived, this, &DevicePluginNanoleaf::onColorTemperatureReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::saturationReceived, this, &DevicePluginNanoleaf::onSaturationReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::hueReceived, this, &DevicePluginNanoleaf::onHueReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::effectListReceived, this, &DevicePluginNanoleaf::onEffectListReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::selectedEffectReceived, this, &DevicePluginNanoleaf::onSelectedEffectReceived);
|
||||||
|
nanoleaf->addUser(); //push button pairing
|
||||||
|
m_unfinishedNanoleafConnections.insert(info->deviceId(), nanoleaf);
|
||||||
|
m_unfinishedPairing.insert(nanoleaf, info);
|
||||||
|
connect(info, &DevicePairingInfo::aborted, this, [info, this] {
|
||||||
|
Nanoleaf *nanoleaf = m_unfinishedNanoleafConnections.take(info->deviceId());
|
||||||
|
m_unfinishedPairing.remove(nanoleaf);
|
||||||
|
nanoleaf->deleteLater();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DevicePluginNanoleaf::setupDevice(DeviceSetupInfo *info)
|
void DevicePluginNanoleaf::setupDevice(DeviceSetupInfo *info)
|
||||||
{
|
{
|
||||||
Device *device = info->device();
|
Device *device = info->device();
|
||||||
if(device->deviceClassId() == lightPanelsDeviceClassId) {
|
if(device->deviceClassId() == lightPanelsDeviceClassId) {
|
||||||
return info->finish(Device::DeviceErrorNoError);
|
pluginStorage()->beginGroup(device->id().toString());
|
||||||
|
QString token = pluginStorage()->value("authToken").toString();
|
||||||
|
pluginStorage()->endGroup();
|
||||||
|
|
||||||
|
Nanoleaf *nanoleaf;
|
||||||
|
if (m_unfinishedNanoleafConnections.contains(device->id())) {
|
||||||
|
nanoleaf = m_unfinishedNanoleafConnections.take(device->id());
|
||||||
|
m_nanoleafConnections.insert(device->id(), nanoleaf);
|
||||||
|
return info->finish(Device::DeviceErrorNoError);
|
||||||
|
} else {
|
||||||
|
QHostAddress address(device->paramValue(lightPanelsDeviceAddressParamTypeId).toString());
|
||||||
|
int port = device->paramValue(lightPanelsDevicePortParamTypeId).toInt();
|
||||||
|
nanoleaf = new Nanoleaf(hardwareManager()->networkManager(), address, port, this);
|
||||||
|
connect(nanoleaf, &Nanoleaf::authTokenRecieved, this, &DevicePluginNanoleaf::onAuthTokenReceived);
|
||||||
|
|
||||||
|
connect(nanoleaf, &Nanoleaf::authenticationStatusChanged, this, &DevicePluginNanoleaf::onAuthenticationStatusChanged);
|
||||||
|
connect(nanoleaf, &Nanoleaf::requestExecuted, this, &DevicePluginNanoleaf::onRequestExecuted);
|
||||||
|
connect(nanoleaf, &Nanoleaf::connectionChanged, this, &DevicePluginNanoleaf::onConnectionChanged);
|
||||||
|
|
||||||
|
connect(nanoleaf, &Nanoleaf::brightnessReceived, this, &DevicePluginNanoleaf::onBrightnessReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::powerReceived, this, &DevicePluginNanoleaf::onPowerReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::colorModeReceived, this, &DevicePluginNanoleaf::onColorModeReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::saturationReceived, this, &DevicePluginNanoleaf::onSaturationReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::hueReceived, this, &DevicePluginNanoleaf::onHueReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::colorTemperatureReceived, this, &DevicePluginNanoleaf::onColorTemperatureReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::effectListReceived, this, &DevicePluginNanoleaf::onEffectListReceived);
|
||||||
|
connect(nanoleaf, &Nanoleaf::selectedEffectReceived, this, &DevicePluginNanoleaf::onSelectedEffectReceived);
|
||||||
|
nanoleaf->setAuthToken(token);
|
||||||
|
nanoleaf->getControllerInfo(); //we don't care about the controller info, this is just to check if the device is available
|
||||||
|
|
||||||
|
m_nanoleafConnections.insert(device->id(), nanoleaf);
|
||||||
|
m_asyncDeviceSetup.insert(nanoleaf, info);
|
||||||
|
connect(info, &DeviceSetupInfo::aborted, this, [nanoleaf, this](){m_asyncDeviceSetup.remove(nanoleaf);});
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DevicePluginNanoleaf::postSetupDevice(Device *device)
|
void DevicePluginNanoleaf::postSetupDevice(Device *device)
|
||||||
{
|
{
|
||||||
if (device->deviceClassId() == lightPanelsDeviceClassId) {
|
if (device->deviceClassId() == lightPanelsDeviceClassId) {
|
||||||
//TODO get all the information and set the device states
|
//Nanoleaf *nanoleaf = m_nanoleafConnections.value(device->id());
|
||||||
|
//getDeviceStates(nanoleaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!m_pluginTimer) {
|
if(!m_pluginTimer) {
|
||||||
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(5);
|
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(5);
|
||||||
connect(m_pluginTimer, &PluginTimer::timeout, this, [this]() {
|
connect(m_pluginTimer, &PluginTimer::timeout, this, [this]() {
|
||||||
|
foreach (Nanoleaf *nanoleaf, m_nanoleafConnections) {
|
||||||
|
getDeviceStates(nanoleaf);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DevicePluginNanoleaf::deviceRemoved(Device *device)
|
void DevicePluginNanoleaf::deviceRemoved(Device *device)
|
||||||
{
|
{
|
||||||
if(device->deviceClassId() == lightPanelsDeviceClassId) {
|
if(device->deviceClassId() == lightPanelsDeviceClassId) {
|
||||||
|
Nanoleaf *nanoleaf = m_nanoleafConnections.take(device->id());
|
||||||
|
nanoleaf->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myDevices().isEmpty()) {
|
if (myDevices().isEmpty()) {
|
||||||
@ -137,6 +196,7 @@ void DevicePluginNanoleaf::deviceRemoved(Device *device)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DevicePluginNanoleaf::executeAction(DeviceActionInfo *info)
|
void DevicePluginNanoleaf::executeAction(DeviceActionInfo *info)
|
||||||
{
|
{
|
||||||
Device *device = info->device();
|
Device *device = info->device();
|
||||||
@ -171,13 +231,189 @@ void DevicePluginNanoleaf::executeAction(DeviceActionInfo *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::browseDevice(BrowseResult *result)
|
||||||
|
{
|
||||||
|
Device *device = result->device();
|
||||||
|
Nanoleaf *nanoleaf = m_nanoleafConnections.value(device->id());
|
||||||
|
nanoleaf->getEffects();
|
||||||
|
m_asyncBrowseResults.insert(nanoleaf, result);
|
||||||
|
connect(result, &BrowseResult::aborted, this, [nanoleaf, this]{m_asyncBrowseResults.remove(nanoleaf);});
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::browserItem(BrowserItemResult *result)
|
||||||
|
{
|
||||||
|
Q_UNUSED(result)
|
||||||
|
qCDebug(dcNanoleaf()) << "BrowserItem called";
|
||||||
|
//Device *device = result->device();
|
||||||
|
//Nanoleaf *nanoleaf = m_nanoleafConnections.value(device->id());
|
||||||
|
//nanoleaf->setEffect(info.);
|
||||||
|
//result->
|
||||||
|
//m_asyncBrowseItems.insert(nanoleaf, result);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::executeBrowserItem(BrowserActionInfo *info)
|
||||||
|
{
|
||||||
|
Device *device = info->device();
|
||||||
|
Nanoleaf *nanoleaf = m_nanoleafConnections.value(device->id());
|
||||||
|
QUuid requestId = nanoleaf->setEffect(info->browserAction().itemId());
|
||||||
|
m_asyncBrowserItem.insert(requestId, info);
|
||||||
|
connect(info, &BrowserActionInfo::aborted, this, [requestId, this]{m_asyncBrowserItem.remove(requestId);});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DevicePluginNanoleaf::getDeviceStates(Nanoleaf *nanoleaf)
|
void DevicePluginNanoleaf::getDeviceStates(Nanoleaf *nanoleaf)
|
||||||
{
|
{
|
||||||
nanoleaf->getPower();
|
nanoleaf->getPower();
|
||||||
nanoleaf->getHue();
|
nanoleaf->getHue();
|
||||||
nanoleaf->getColorMode();
|
nanoleaf->getColorMode();
|
||||||
nanoleaf->getBrightness();
|
nanoleaf->getBrightness();
|
||||||
nanoleaf->getSaturation();
|
|
||||||
nanoleaf->getColorTemperature();
|
nanoleaf->getColorTemperature();
|
||||||
|
nanoleaf->getSelectedEffect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onAuthTokenReceived(const QString &token)
|
||||||
|
{
|
||||||
|
Nanoleaf *nanoleaf = static_cast<Nanoleaf *>(sender());
|
||||||
|
if (m_unfinishedPairing.contains(nanoleaf)) {
|
||||||
|
DevicePairingInfo *info = m_unfinishedPairing.take(nanoleaf);
|
||||||
|
pluginStorage()->beginGroup(info->deviceId().toString());
|
||||||
|
pluginStorage()->setValue("authToken", token);
|
||||||
|
pluginStorage()->endGroup();
|
||||||
|
info->finish(Device::DeviceErrorNoError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onAuthenticationStatusChanged(bool authenticated)
|
||||||
|
{
|
||||||
|
Nanoleaf *nanoleaf = static_cast<Nanoleaf *>(sender());
|
||||||
|
if (m_asyncDeviceSetup.contains(nanoleaf)) {
|
||||||
|
DeviceSetupInfo *info = m_asyncDeviceSetup.take(nanoleaf);
|
||||||
|
if (authenticated) {
|
||||||
|
info->finish(Device::DeviceErrorNoError);
|
||||||
|
} else {
|
||||||
|
info->finish(Device::DeviceErrorSetupFailed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onRequestExecuted(QUuid requestId, bool success)
|
||||||
|
{
|
||||||
|
if (m_asyncActions.contains(requestId)) {
|
||||||
|
DeviceActionInfo *info = m_asyncActions.take(requestId);
|
||||||
|
if (success) {
|
||||||
|
info->finish(Device::DeviceErrorNoError);
|
||||||
|
} else {
|
||||||
|
info->finish(Device::DeviceErrorHardwareNotAvailable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_asyncBrowserItem.contains(requestId)) {
|
||||||
|
BrowserActionInfo *info = m_asyncBrowserItem.take(requestId);
|
||||||
|
if (success) {
|
||||||
|
info->finish(Device::DeviceErrorNoError);
|
||||||
|
} else {
|
||||||
|
info->finish(Device::DeviceErrorHardwareNotAvailable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onConnectionChanged(bool connected)
|
||||||
|
{
|
||||||
|
Nanoleaf *nanoleaf = static_cast<Nanoleaf *>(sender());
|
||||||
|
Device *device = myDevices().findById(m_nanoleafConnections.key(nanoleaf));
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
device->setStateValue(lightPanelsConnectedStateTypeId, connected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onPowerReceived(bool power)
|
||||||
|
{
|
||||||
|
Nanoleaf *nanoleaf = static_cast<Nanoleaf *>(sender());
|
||||||
|
Device *device = myDevices().findById(m_nanoleafConnections.key(nanoleaf));
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
device->setStateValue(lightPanelsPowerStateTypeId, power);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onBrightnessReceived(int percentage)
|
||||||
|
{
|
||||||
|
Nanoleaf *nanoleaf = static_cast<Nanoleaf *>(sender());
|
||||||
|
Device *device = myDevices().findById(m_nanoleafConnections.key(nanoleaf));
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
device->setStateValue(lightPanelsBrightnessStateTypeId, percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onColorModeReceived(const QString &colorMode)
|
||||||
|
{
|
||||||
|
Nanoleaf *nanoleaf = static_cast<Nanoleaf *>(sender());
|
||||||
|
Device *device = myDevices().findById(m_nanoleafConnections.key(nanoleaf));
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
device->setStateValue(lightPanelsColorModeStateTypeId, colorMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onHueReceived(int hue)
|
||||||
|
{
|
||||||
|
Nanoleaf *nanoleaf = static_cast<Nanoleaf *>(sender());
|
||||||
|
Device *device = myDevices().findById(m_nanoleafConnections.key(nanoleaf));
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
m_hues.insert(device->id(), hue);
|
||||||
|
nanoleaf->getSaturation();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onSaturationReceived(int saturation)
|
||||||
|
{
|
||||||
|
Nanoleaf *nanoleaf = static_cast<Nanoleaf *>(sender());
|
||||||
|
Device *device = myDevices().findById(m_nanoleafConnections.key(nanoleaf));
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
qCDebug(dcNanoleaf()) << "Saturation received" << saturation;
|
||||||
|
QColor color;
|
||||||
|
color.setHsv(m_hues.value(device->id()), saturation, 100);
|
||||||
|
//TODO get hue
|
||||||
|
device->setStateValue(lightPanelsColorStateTypeId, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onEffectListReceived(const QStringList &effects)
|
||||||
|
{
|
||||||
|
Nanoleaf *nanoleaf = static_cast<Nanoleaf *>(sender());
|
||||||
|
Device *device = myDevices().findById(m_nanoleafConnections.key(nanoleaf));
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
qCDebug(dcNanoleaf()) << "Effect list received" << effects;
|
||||||
|
|
||||||
|
if (m_asyncBrowseResults.contains(nanoleaf)) {
|
||||||
|
BrowseResult *result = m_asyncBrowseResults.take(nanoleaf);
|
||||||
|
foreach (QString effect, effects) {
|
||||||
|
BrowserItem item;
|
||||||
|
item.setId(effect);
|
||||||
|
item.setBrowsable(false);
|
||||||
|
item.setExecutable(true);
|
||||||
|
item.setDisplayName(effect);
|
||||||
|
item.setDisabled(false);
|
||||||
|
result->addItem(item);
|
||||||
|
}
|
||||||
|
result->finish(Device::DeviceErrorNoError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onColorTemperatureReceived(int mired)
|
||||||
|
{
|
||||||
|
Nanoleaf *nanoleaf = static_cast<Nanoleaf *>(sender());
|
||||||
|
Device *device = myDevices().findById(m_nanoleafConnections.key(nanoleaf));
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
device->setStateValue(lightPanelsColorTemperatureStateTypeId, mired);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DevicePluginNanoleaf::onSelectedEffectReceived(const QString &effect)
|
||||||
|
{
|
||||||
|
Nanoleaf *nanoleaf = static_cast<Nanoleaf *>(sender());
|
||||||
|
Device *device = myDevices().findById(m_nanoleafConnections.key(nanoleaf));
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
device->setStateValue(lightPanelsEffectNameStateTypeId, effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,14 +51,39 @@ public:
|
|||||||
void deviceRemoved(Device *device) override;
|
void deviceRemoved(Device *device) override;
|
||||||
void executeAction(DeviceActionInfo *info) override;
|
void executeAction(DeviceActionInfo *info) override;
|
||||||
|
|
||||||
|
void browseDevice(BrowseResult *result) override;
|
||||||
|
void browserItem(BrowserItemResult *result) override;
|
||||||
|
void executeBrowserItem(BrowserActionInfo *info) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ZeroConfServiceBrowser *m_zeroconfBrowser = nullptr;
|
ZeroConfServiceBrowser *m_zeroconfBrowser = nullptr;
|
||||||
PluginTimer *m_pluginTimer = nullptr;
|
PluginTimer *m_pluginTimer = nullptr;
|
||||||
QHash<DeviceId, Nanoleaf*> m_nanoleafConnections;
|
QHash<DeviceId, Nanoleaf*> m_nanoleafConnections;
|
||||||
|
QHash<DeviceId, Nanoleaf*> m_unfinishedNanoleafConnections;
|
||||||
QHash<QUuid, DeviceActionInfo *> m_asyncActions;
|
QHash<QUuid, DeviceActionInfo *> m_asyncActions;
|
||||||
|
QHash<Nanoleaf *, DevicePairingInfo *> m_unfinishedPairing;
|
||||||
|
QHash<Nanoleaf *, DeviceSetupInfo *> m_asyncDeviceSetup;
|
||||||
|
|
||||||
|
QHash<Nanoleaf *, BrowseResult *> m_asyncBrowseResults;
|
||||||
|
QHash<QUuid, BrowserActionInfo *> m_asyncBrowserItem;
|
||||||
|
QHash<DeviceId, int> m_hues;
|
||||||
|
|
||||||
void getDeviceStates(Nanoleaf *nanoleaf);
|
void getDeviceStates(Nanoleaf *nanoleaf);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onAuthTokenReceived(const QString &token);
|
||||||
|
void onAuthenticationStatusChanged(bool authenticated);
|
||||||
|
void onRequestExecuted(QUuid requestId, bool success);
|
||||||
|
void onConnectionChanged(bool connected);
|
||||||
|
|
||||||
|
void onPowerReceived(bool power);
|
||||||
|
void onBrightnessReceived(int percentage);
|
||||||
|
void onColorModeReceived(const QString &colorMode);
|
||||||
|
void onHueReceived(int hue);
|
||||||
|
void onSaturationReceived(int percentage);
|
||||||
|
void onEffectListReceived(const QStringList &effects);
|
||||||
|
void onColorTemperatureReceived(int mired);
|
||||||
|
void onSelectedEffectReceived(const QString &effect);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEVICEPLUGINNANOLEAF_H
|
#endif // DEVICEPLUGINNANOLEAF_H
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
"displayName": "Light panels",
|
"displayName": "Light panels",
|
||||||
"interfaces": ["colorlight", "colortemperaturelight", "connectable"],
|
"interfaces": ["colorlight", "colortemperaturelight", "connectable"],
|
||||||
"createMethods": ["discovery"],
|
"createMethods": ["discovery"],
|
||||||
|
"setupMethod": "pushButton",
|
||||||
|
"browsable": true,
|
||||||
"paramTypes": [
|
"paramTypes": [
|
||||||
{
|
{
|
||||||
"id": "ff57079f-d5ab-4511-8a5c-0726e7b82af6",
|
"id": "ff57079f-d5ab-4511-8a5c-0726e7b82af6",
|
||||||
@ -105,7 +107,25 @@
|
|||||||
"minValue": 0,
|
"minValue": 0,
|
||||||
"maxValue": 100,
|
"maxValue": 100,
|
||||||
"writable": true
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bdd2ea1e-9ef9-4967-9678-2c601b826199",
|
||||||
|
"name": "colorMode",
|
||||||
|
"displayName": "Color mode",
|
||||||
|
"displayNameEvent": "Color mode changed",
|
||||||
|
"displayNameAction": "Set color",
|
||||||
|
"type": "QString",
|
||||||
|
"defaultValue": "Color temperature",
|
||||||
|
"writable": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "57f9831e-1b98-41c1-a21c-6073ff327237",
|
||||||
|
"name": "effectName",
|
||||||
|
"displayName": "Effect name",
|
||||||
|
"displayNameEvent": "Effect name changed",
|
||||||
|
"displayNameAction": "Set color",
|
||||||
|
"type": "QString",
|
||||||
|
"defaultValue": "-"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,15 +57,27 @@ int Nanoleaf::port()
|
|||||||
return m_port;
|
return m_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::setAuthToken(const QString &token)
|
||||||
|
{
|
||||||
|
m_authToken = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Nanoleaf::authToken()
|
||||||
|
{
|
||||||
|
return m_authToken;
|
||||||
|
}
|
||||||
|
|
||||||
void Nanoleaf::addUser()
|
void Nanoleaf::addUser()
|
||||||
{
|
{
|
||||||
QUrl url;
|
QUrl url;
|
||||||
url.setHost(m_address.toString());
|
url.setHost(m_address.toString());
|
||||||
url.setPort(m_port);
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
url.setPath("/api/v1/new");
|
url.setPath("/api/v1/new");
|
||||||
|
|
||||||
QNetworkRequest request;
|
QNetworkRequest request;
|
||||||
request.setUrl(url);
|
request.setUrl(url);
|
||||||
|
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
|
||||||
QNetworkReply *reply = m_networkManager->post(request, "");
|
QNetworkReply *reply = m_networkManager->post(request, "");
|
||||||
qDebug(dcNanoleaf()) << "Sending request" << request.url();
|
qDebug(dcNanoleaf()) << "Sending request" << request.url();
|
||||||
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
||||||
@ -77,14 +89,13 @@ void Nanoleaf::addUser()
|
|||||||
if (reply->error() == QNetworkReply::HostNotFoundError) {
|
if (reply->error() == QNetworkReply::HostNotFoundError) {
|
||||||
emit connectionChanged(false);
|
emit connectionChanged(false);
|
||||||
}
|
}
|
||||||
if (status == 400 || status == 401) {
|
if (status >= 400 && status <= 410) {
|
||||||
emit authenticationStatusChanged(false);
|
emit authenticationStatusChanged(false);
|
||||||
}
|
}
|
||||||
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit connectionChanged(true);
|
emit connectionChanged(true);
|
||||||
emit authenticationStatusChanged(true);
|
|
||||||
|
|
||||||
QJsonParseError error;
|
QJsonParseError error;
|
||||||
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||||
@ -94,6 +105,9 @@ void Nanoleaf::addUser()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_authToken = data.toVariant().toMap().value("auth_token").toString();
|
m_authToken = data.toVariant().toMap().value("auth_token").toString();
|
||||||
|
|
||||||
|
emit authTokenRecieved(m_authToken);
|
||||||
|
emit authenticationStatusChanged(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +116,7 @@ void Nanoleaf::deleteUser()
|
|||||||
QUrl url;
|
QUrl url;
|
||||||
url.setHost(m_address.toString());
|
url.setHost(m_address.toString());
|
||||||
url.setPort(m_port);
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
url.setPath("/api/v1/"+m_authToken);
|
url.setPath("/api/v1/"+m_authToken);
|
||||||
|
|
||||||
QNetworkRequest request;
|
QNetworkRequest request;
|
||||||
@ -116,37 +131,225 @@ void Nanoleaf::deleteUser()
|
|||||||
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
emit authenticationStatusChanged(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::getControllerInfo()
|
||||||
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath("/api/v1/"+m_authToken);
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->get(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();
|
||||||
|
emit authenticationStatusChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit connectionChanged(true);
|
||||||
|
emit authenticationStatusChanged(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nanoleaf::getPower()
|
void Nanoleaf::getPower()
|
||||||
{
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath("/api/v1/"+m_authToken+"/state/on");
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->get(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 != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
emit connectionChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qDebug(dcNanoleaf()) << "Recieved invalide JSON object";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool power = data.toVariant().toMap().value("value").toBool();
|
||||||
|
emit connectionChanged(true);
|
||||||
|
emit powerReceived(power);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nanoleaf::getHue()
|
void Nanoleaf::getHue()
|
||||||
{
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath("/api/v1/"+m_authToken+"/state/hue");
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->get(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 != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qDebug(dcNanoleaf()) << "Recieved invalide JSON object";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int hue = data.toVariant().toMap().value("value").toBool();
|
||||||
|
emit connectionChanged(true);
|
||||||
|
emit hueReceived(hue);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nanoleaf::getBrightness()
|
void Nanoleaf::getBrightness()
|
||||||
{
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath("/api/v1/"+m_authToken+"/state/brightness");
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->get(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
||||||
|
reply->deleteLater();
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qDebug(dcNanoleaf()) << "Recieved invalide JSON object";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int brightness = data.toVariant().toMap().value("value").toInt();
|
||||||
|
emit connectionChanged(true);
|
||||||
|
emit brightnessReceived(brightness);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nanoleaf::getSaturation()
|
void Nanoleaf::getSaturation()
|
||||||
{
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath("/api/v1/"+m_authToken+"/state/sat");
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->get(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
||||||
|
reply->deleteLater();
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qDebug(dcNanoleaf()) << "Recieved invalide JSON object";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int brightness = data.toVariant().toMap().value("value").toInt();
|
||||||
|
emit connectionChanged(true);
|
||||||
|
emit saturationReceived(brightness);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nanoleaf::getColorTemperature()
|
void Nanoleaf::getColorTemperature()
|
||||||
{
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath("/api/v1/"+m_authToken+"/state/ct");
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->get(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
||||||
|
reply->deleteLater();
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
emit connectionChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qDebug(dcNanoleaf()) << "Recieved invalide JSON object";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int mired = data.toVariant().toMap().value("value").toInt();
|
||||||
|
emit connectionChanged(true);
|
||||||
|
emit colorTemperatureReceived(mired);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nanoleaf::getColorMode()
|
void Nanoleaf::getColorMode()
|
||||||
{
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath("/api/v1/"+m_authToken+"/state/colorMode");
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->get(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
||||||
|
reply->deleteLater();
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
emit connectionChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qDebug(dcNanoleaf()) << "Recieved invalide JSON object";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString colorMode = data.toVariant().toMap().value("value").toString();
|
||||||
|
emit connectionChanged(true);
|
||||||
|
emit colorModeReceived(colorMode);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QUuid Nanoleaf::setPower(bool power)
|
QUuid Nanoleaf::setPower(bool power)
|
||||||
@ -155,7 +358,8 @@ QUuid Nanoleaf::setPower(bool power)
|
|||||||
QUrl url;
|
QUrl url;
|
||||||
url.setHost(m_address.toString());
|
url.setHost(m_address.toString());
|
||||||
url.setPort(m_port);
|
url.setPort(m_port);
|
||||||
url.setPath(QString("/api/v1/%1/state/on").arg(m_authToken));
|
url.setScheme("http");
|
||||||
|
url.setPath(QString("/api/v1/%1/state").arg(m_authToken));
|
||||||
|
|
||||||
QVariantMap map;
|
QVariantMap map;
|
||||||
QVariantMap value;
|
QVariantMap value;
|
||||||
@ -165,6 +369,7 @@ QUuid Nanoleaf::setPower(bool power)
|
|||||||
|
|
||||||
QNetworkRequest request;
|
QNetworkRequest request;
|
||||||
request.setUrl(url);
|
request.setUrl(url);
|
||||||
|
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
|
||||||
QNetworkReply *reply = m_networkManager->put(request, body.toJson());
|
QNetworkReply *reply = m_networkManager->put(request, body.toJson());
|
||||||
qDebug(dcNanoleaf()) << "Sending request" << request.url();
|
qDebug(dcNanoleaf()) << "Sending request" << request.url();
|
||||||
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
|
connect(reply, &QNetworkReply::finished, this, [requestId, reply, this] {
|
||||||
@ -172,11 +377,12 @@ QUuid Nanoleaf::setPower(bool power)
|
|||||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
if (status != 204 || reply->error() != QNetworkReply::NoError) {
|
if (status != 204 || reply->error() != QNetworkReply::NoError) {
|
||||||
emit requestedExecuted(requestId, false);
|
emit requestExecuted(requestId, false);
|
||||||
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit requestedExecuted(requestId, true);
|
emit connectionChanged(true);
|
||||||
|
emit requestExecuted(requestId, true);
|
||||||
});
|
});
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
@ -190,8 +396,35 @@ QUuid Nanoleaf::setHue(QColor color)
|
|||||||
|
|
||||||
QUuid Nanoleaf::setBrightness(int percentage)
|
QUuid Nanoleaf::setBrightness(int percentage)
|
||||||
{
|
{
|
||||||
Q_UNUSED(percentage);
|
|
||||||
QUuid requestId = QUuid::createUuid();
|
QUuid requestId = QUuid::createUuid();
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath(QString("/api/v1/%1/state").arg(m_authToken));
|
||||||
|
|
||||||
|
QVariantMap map;
|
||||||
|
QVariantMap value;
|
||||||
|
value["value"] = percentage;
|
||||||
|
map.insert("brightness", value);
|
||||||
|
QJsonDocument body = QJsonDocument::fromVariant(map);
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
|
||||||
|
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 requestExecuted(requestId, false);
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit requestExecuted(requestId, true);
|
||||||
|
});
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,6 +432,34 @@ QUuid Nanoleaf::setSaturation(int percentage)
|
|||||||
{
|
{
|
||||||
Q_UNUSED(percentage);
|
Q_UNUSED(percentage);
|
||||||
QUuid requestId = QUuid::createUuid();
|
QUuid requestId = QUuid::createUuid();
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath(QString("/api/v1/%1/state/sat").arg(m_authToken));
|
||||||
|
|
||||||
|
QVariantMap map;
|
||||||
|
QVariantMap value;
|
||||||
|
value["value"] = percentage;
|
||||||
|
map.insert("sat", value);
|
||||||
|
QJsonDocument body = QJsonDocument::fromVariant(map);
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
|
||||||
|
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 requestExecuted(requestId, false);
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit requestExecuted(requestId, true);
|
||||||
|
});
|
||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,5 +470,99 @@ QUuid Nanoleaf::setColorTemperature(int mired)
|
|||||||
return requestId;
|
return requestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::getEffects()
|
||||||
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath("/api/v1/"+m_authToken+"/effects/effectsList");
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->get(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
||||||
|
reply->deleteLater();
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
emit connectionChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument data = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||||
|
if (error.error != QJsonParseError::NoError) {
|
||||||
|
qDebug(dcNanoleaf()) << "Recieved invalide JSON object";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QStringList effects;
|
||||||
|
foreach (QVariant effect, data.toVariant().toList()) {
|
||||||
|
effects.append(effect.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
emit connectionChanged(true);
|
||||||
|
emit effectListReceived(effects);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Nanoleaf::getSelectedEffect()
|
||||||
|
{
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath("/api/v1/"+m_authToken+"/effects/select");
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
QNetworkReply *reply = m_networkManager->get(request);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [reply, this] {
|
||||||
|
reply->deleteLater();
|
||||||
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
||||||
|
if (status != 200 || reply->error() != QNetworkReply::NoError) {
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
emit connectionChanged(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString effect = reply->readAll();
|
||||||
|
emit connectionChanged(true);
|
||||||
|
emit selectedEffectReceived(effect);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QUuid Nanoleaf::setEffect(const QString &effect)
|
||||||
|
{
|
||||||
|
QUuid requestId = QUuid::createUuid();
|
||||||
|
QUrl url;
|
||||||
|
url.setHost(m_address.toString());
|
||||||
|
url.setPort(m_port);
|
||||||
|
url.setScheme("http");
|
||||||
|
url.setPath(QString("/api/v1/%1/effects").arg(m_authToken));
|
||||||
|
|
||||||
|
QVariantMap map;
|
||||||
|
map.insert("select", effect);
|
||||||
|
QJsonDocument body = QJsonDocument::fromVariant(map);
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
|
||||||
|
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 requestExecuted(requestId, false);
|
||||||
|
qCWarning(dcNanoleaf()) << "Request error:" << status << reply->errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit requestExecuted(requestId, true);
|
||||||
|
});
|
||||||
|
return requestId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -44,11 +44,15 @@ public:
|
|||||||
void setPort(int port);
|
void setPort(int port);
|
||||||
int port();
|
int port();
|
||||||
|
|
||||||
|
void setAuthToken(const QString &token);
|
||||||
|
QString authToken();
|
||||||
|
|
||||||
//AUTHORIZATION
|
//AUTHORIZATION
|
||||||
void addUser();
|
void addUser();
|
||||||
void deleteUser();
|
void deleteUser();
|
||||||
|
|
||||||
//GET ALL PANEL INFORMATION
|
//GET ALL PANEL INFORMATION
|
||||||
|
void getControllerInfo();
|
||||||
|
|
||||||
//STATES
|
//STATES
|
||||||
void getPower();
|
void getPower();
|
||||||
@ -66,6 +70,9 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//EFFECTS
|
//EFFECTS
|
||||||
|
void getEffects();
|
||||||
|
void getSelectedEffect();
|
||||||
|
QUuid setEffect(const QString &effect);
|
||||||
|
|
||||||
//PANEL LAYOUT
|
//PANEL LAYOUT
|
||||||
|
|
||||||
@ -86,13 +93,17 @@ private:
|
|||||||
signals:
|
signals:
|
||||||
void connectionChanged(bool connected);
|
void connectionChanged(bool connected);
|
||||||
void authenticationStatusChanged(bool authenticated);
|
void authenticationStatusChanged(bool authenticated);
|
||||||
void requestedExecuted(QUuid requestId, bool success);
|
void requestExecuted(QUuid requestId, bool success);
|
||||||
|
|
||||||
|
void authTokenRecieved(const QString &token);
|
||||||
void powerReceived(bool power);
|
void powerReceived(bool power);
|
||||||
void brightnessReceived(int percentage);
|
void brightnessReceived(int percentage);
|
||||||
void colorModeReceived();
|
void colorModeReceived(const QString &colorMode);
|
||||||
void hueReceived(QColor color);
|
void hueReceived(int hue);
|
||||||
void saturationReceived(int percentage);
|
void saturationReceived(int percentage);
|
||||||
|
void effectListReceived(const QStringList &effects);
|
||||||
|
void colorTemperatureReceived(int mired);
|
||||||
|
void selectedEffectReceived(const QString &effect);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NANOLEAF_H
|
#endif // NANOLEAF_H
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user