Fix avea plugin
parent
8a7a24ce97
commit
7dd778628d
|
|
@ -1,4 +1,6 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016-2018 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
|
|
@ -19,8 +21,11 @@
|
|||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "aveabulb.h"
|
||||
#include "aveacolor.h"
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
#include <QDataStream>
|
||||
|
||||
AveaBulb::AveaBulb(Device *device, BluetoothLowEnergyDevice *bluetoothDevice, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_device(device),
|
||||
|
|
@ -40,6 +45,50 @@ BluetoothLowEnergyDevice *AveaBulb::bluetoothDevice()
|
|||
return m_bluetoothDevice;
|
||||
}
|
||||
|
||||
bool AveaBulb::setPower(bool power)
|
||||
{
|
||||
if (!m_bluetoothDevice->connected())
|
||||
return false;
|
||||
|
||||
if (!m_colorService)
|
||||
return false;
|
||||
|
||||
qCDebug(dcElgato()) << "Set power" << (power ? "on" : "off");
|
||||
|
||||
// Sync current color
|
||||
if (power)
|
||||
return syncColor();
|
||||
|
||||
// Power off
|
||||
QByteArray command;
|
||||
QDataStream stream(&command, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
|
||||
quint8 commandId = static_cast<quint8>(ColorMessageColor);
|
||||
quint16 fade = static_cast<quint16>(m_fade);
|
||||
quint16 constant = 0x000a;
|
||||
quint16 white = 0 | 0x8000;
|
||||
quint16 red = 0 | 0x3000;
|
||||
quint16 green = 0 | 0x2000;
|
||||
quint16 blue = 0 | 0x1000;
|
||||
|
||||
stream << commandId << fade << constant << white << red << green << blue;
|
||||
|
||||
qCDebug(dcElgato()) << "Set color data -->" << command.toHex();
|
||||
|
||||
m_colorService->writeCharacteristic(m_colorCharacteristic, command);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool AveaBulb::setBulbName(const QString &name)
|
||||
{
|
||||
m_bulbName = name;
|
||||
|
||||
// TODO:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AveaBulb::setColor(const QColor &color)
|
||||
{
|
||||
if (!m_bluetoothDevice->connected())
|
||||
|
|
@ -48,12 +97,138 @@ bool AveaBulb::setColor(const QColor &color)
|
|||
if (!m_colorService)
|
||||
return false;
|
||||
|
||||
qCDebug(dcElgato()) << "-->" << color.toRgb();
|
||||
|
||||
// Convert rgb to wrgb
|
||||
QByteArray command;
|
||||
command.append(QByteArray::fromHex("35"));
|
||||
QDataStream stream(&command, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
|
||||
qCDebug(dcElgato()) << color << command;
|
||||
m_red = scaleColorValueUp(color.red());
|
||||
m_green = scaleColorValueUp(color.green());
|
||||
m_blue = scaleColorValueUp(color.blue());
|
||||
|
||||
m_color = color;
|
||||
|
||||
return syncColor();
|
||||
}
|
||||
|
||||
bool AveaBulb::setBrightness(int percentage)
|
||||
{
|
||||
if (!m_bluetoothDevice->connected())
|
||||
return false;
|
||||
|
||||
if (!m_colorService)
|
||||
return false;
|
||||
|
||||
quint16 brightnessValue = qRound(4095.0 * percentage / 100.0);
|
||||
qCDebug(dcElgato()) << "Brightness value" << percentage << "% -->" << brightnessValue;
|
||||
|
||||
QByteArray command;
|
||||
QDataStream stream(&command, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
stream << static_cast<quint8>(ColorMessageBrightness);
|
||||
stream << brightnessValue;
|
||||
|
||||
m_colorService->writeCharacteristic(m_colorCharacteristic, command);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AveaBulb::setFade(int fade)
|
||||
{
|
||||
m_fade = fade;
|
||||
return syncColor();
|
||||
}
|
||||
|
||||
bool AveaBulb::setWhite(int white)
|
||||
{
|
||||
m_white = white;
|
||||
return syncColor();
|
||||
}
|
||||
|
||||
bool AveaBulb::setRed(int red)
|
||||
{
|
||||
m_red = red;
|
||||
return syncColor();
|
||||
}
|
||||
|
||||
bool AveaBulb::setGreen(int green)
|
||||
{
|
||||
m_green = green;
|
||||
return syncColor();
|
||||
}
|
||||
|
||||
bool AveaBulb::setBlue(int blue)
|
||||
{
|
||||
m_blue = blue;
|
||||
return syncColor();
|
||||
}
|
||||
|
||||
bool AveaBulb::loadValues()
|
||||
{
|
||||
if (!m_bluetoothDevice->connected())
|
||||
return false;
|
||||
|
||||
if (!m_colorService)
|
||||
return false;
|
||||
|
||||
// Request color
|
||||
m_colorService->writeCharacteristic(m_colorCharacteristic, QByteArray::fromHex("35"));
|
||||
|
||||
// Request brightness
|
||||
m_colorService->writeCharacteristic(m_colorCharacteristic, QByteArray::fromHex("57"));
|
||||
|
||||
// Request name
|
||||
m_colorService->writeCharacteristic(m_colorCharacteristic, QByteArray::fromHex("58"));
|
||||
return true;
|
||||
}
|
||||
|
||||
quint16 AveaBulb::scaleColorValueUp(int colorValue)
|
||||
{
|
||||
return static_cast<quint16>(qRound(4095.0 * colorValue / 255.0));
|
||||
}
|
||||
|
||||
int AveaBulb::scaleColorValueDown(quint16 colorValue)
|
||||
{
|
||||
return qRound(255.0 * colorValue / 4095.0);
|
||||
}
|
||||
|
||||
bool AveaBulb::syncColor()
|
||||
{
|
||||
if (!m_bluetoothDevice->connected())
|
||||
return false;
|
||||
|
||||
if (!m_colorService)
|
||||
return false;
|
||||
|
||||
if (!m_device->stateValue(aveaPowerStateTypeId).toBool()) {
|
||||
qCWarning(dcElgato()) << "Not syncing color because power off";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_device->setStateValue(aveaBlueStateTypeId, m_white);
|
||||
m_device->setStateValue(aveaRedStateTypeId, m_red);
|
||||
m_device->setStateValue(aveaGreenStateTypeId, m_green);
|
||||
m_device->setStateValue(aveaBlueStateTypeId, m_blue);
|
||||
m_device->setStateValue(aveaColorStateTypeId, QColor(scaleColorValueDown(m_red), scaleColorValueDown(m_green), scaleColorValueDown(m_blue)));
|
||||
|
||||
// Convert rgb to wrgb
|
||||
QByteArray command;
|
||||
QDataStream stream(&command, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
|
||||
quint8 commandId = static_cast<quint8>(ColorMessageColor);
|
||||
quint16 fade = static_cast<quint16>(m_fade);
|
||||
quint16 constant = 0x000a;
|
||||
quint16 white = m_white | 0x8000;
|
||||
quint16 red = m_red | 0x3000;
|
||||
quint16 green = m_green | 0x2000;
|
||||
quint16 blue = m_blue | 0x1000;
|
||||
|
||||
stream << commandId << fade << constant << white << red << green << blue;
|
||||
|
||||
qCDebug(dcElgato()) << "----> Sync" << command.toHex();
|
||||
m_colorService->writeCharacteristic(m_colorCharacteristic, command);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +245,6 @@ void AveaBulb::onConnectedChanged(const bool &connected)
|
|||
m_colorService = nullptr;
|
||||
m_imageService = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AveaBulb::onServiceDiscoveryFinished()
|
||||
|
|
@ -119,7 +293,7 @@ void AveaBulb::onColorServiceStateChanged(const QLowEnergyService::ServiceState
|
|||
}
|
||||
|
||||
// Data characteristic
|
||||
m_colorCharacteristic = m_colorService->characteristic(QBluetoothUuid(QUuid("f815e811-456c-6761-746f-4d756e696368")));
|
||||
m_colorCharacteristic = m_colorService->characteristic(colorCharacteristicUuid);
|
||||
if (!m_colorCharacteristic.isValid()) {
|
||||
qCWarning(dcElgato()) << "Invalid color data characteristic.";
|
||||
}
|
||||
|
|
@ -128,37 +302,72 @@ void AveaBulb::onColorServiceStateChanged(const QLowEnergyService::ServiceState
|
|||
QLowEnergyDescriptor notificationDescriptor = m_colorCharacteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||
m_colorService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||
|
||||
// Get current configuration
|
||||
|
||||
// Color
|
||||
m_colorService->writeCharacteristic(m_colorCharacteristic, QByteArray::fromHex("35"));
|
||||
|
||||
// Brightness
|
||||
m_colorService->writeCharacteristic(m_colorCharacteristic, QByteArray::fromHex("57"));
|
||||
|
||||
// Name
|
||||
m_colorService->writeCharacteristic(m_colorCharacteristic, QByteArray::fromHex("58"));
|
||||
|
||||
// Load current configuration
|
||||
loadValues();
|
||||
}
|
||||
|
||||
void AveaBulb::onColorServiceCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value)
|
||||
{
|
||||
qCDebug(dcElgato()) << "Color characteristic changed" << characteristic.uuid().toString() << value;
|
||||
|
||||
if (value.startsWith(QByteArray::fromHex("35"))) {
|
||||
qCDebug(dcElgato()) << "Received color notification";
|
||||
qCDebug(dcElgato()) << " Fade" << value.mid(1, 2);
|
||||
qCDebug(dcElgato()) << " Fixed value" << value.mid(3, 2);
|
||||
qCDebug(dcElgato()) << " White" << value.mid(5, 2);
|
||||
qCDebug(dcElgato()) << " Red" << value.mid(7, 2);
|
||||
qCDebug(dcElgato()) << " Green" << value.mid(9, 2);
|
||||
qCDebug(dcElgato()) << " Blue" << value.mid(11, 2);
|
||||
} else if (value.startsWith(QByteArray::fromHex("57"))) {
|
||||
qCDebug(dcElgato()) << "Received brightness notification";
|
||||
qCDebug(dcElgato()) << " Fade" << value.mid(1, 2);
|
||||
} else if (value.startsWith(QByteArray::fromHex("58"))) {
|
||||
qCDebug(dcElgato()) << "Received name notification";
|
||||
qCDebug(dcElgato()) << " Name" << value.mid(1, value.count() - 2);
|
||||
if (characteristic.uuid() != colorCharacteristicUuid) {
|
||||
qCWarning(dcElgato()) << "Unhandled color service characteristic notification received" << value.toHex();
|
||||
return;
|
||||
}
|
||||
|
||||
//qCDebug(dcElgato()) << "Color characteristic changed" << characteristic.uuid().toString() << value.toHex();
|
||||
|
||||
QByteArray payload = value;
|
||||
QDataStream stream(&payload, QIODevice::ReadOnly);
|
||||
quint8 messageType;
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
stream >> messageType;
|
||||
|
||||
//qCDebug(dcElgato()) << "Message type" << messageType << static_cast<ColorMessage>(messageType);
|
||||
|
||||
switch (messageType) {
|
||||
case ColorMessageColor: {
|
||||
quint16 whiteCurrentValue = 0; quint16 blueCurrentValue = 0; quint16 greenCurrentValue = 0; quint16 redCurrentValue = 0;
|
||||
quint16 whiteTargetValue = 0; quint16 blueTargetValue = 0; quint16 greenTargetValue = 0; quint16 redTargetValue = 0;
|
||||
|
||||
// Read current color
|
||||
stream >> whiteCurrentValue >> blueCurrentValue >> greenCurrentValue >> redCurrentValue;
|
||||
|
||||
// Read target color
|
||||
stream >> whiteTargetValue >> blueTargetValue >> greenTargetValue >> redTargetValue;
|
||||
|
||||
// Convert color values
|
||||
quint16 whiteCurrentAdjustedValue = whiteCurrentValue;
|
||||
quint16 blueCurrentAdjustedValue = blueCurrentValue ^ 0x1000;
|
||||
quint16 greenCurrentAdjustedValue = greenCurrentValue ^ 0x2000;
|
||||
quint16 redCurrentAdjustedValue = redCurrentValue ^ 0x3000;
|
||||
|
||||
qCDebug(dcElgato()) << "Received color notification:";
|
||||
qCDebug(dcElgato()) << " white (current):" << value.mid(1, 2).toHex() << whiteCurrentValue << whiteCurrentAdjustedValue;
|
||||
qCDebug(dcElgato()) << " blue (current):" << value.mid(3, 2).toHex() << blueCurrentValue << blueCurrentAdjustedValue;
|
||||
qCDebug(dcElgato()) << " green (current):" << value.mid(5, 2).toHex() << greenCurrentValue << greenCurrentAdjustedValue;
|
||||
qCDebug(dcElgato()) << " red (current):" << value.mid(7, 2).toHex() << redCurrentValue << redCurrentAdjustedValue;
|
||||
qCDebug(dcElgato()) << " white (target) :" << value.mid(9, 2).toHex() << whiteTargetValue;
|
||||
qCDebug(dcElgato()) << " blue (target) :" << value.mid(11, 2).toHex() << blueTargetValue;
|
||||
qCDebug(dcElgato()) << " green (target) :" << value.mid(13, 2).toHex() << greenTargetValue;
|
||||
qCDebug(dcElgato()) << " red (target) :" << value.mid(15, 2).toHex() << redTargetValue;
|
||||
|
||||
break;
|
||||
}
|
||||
case ColorMessageBrightness: {
|
||||
quint16 brightnessValue = 0;
|
||||
stream >> brightnessValue;
|
||||
int brightnessPercentage = qRound(brightnessValue * 100 / 4095.0);
|
||||
qCDebug(dcElgato()) << "Brightness notification" << value.mid(1, 2).toHex() << brightnessValue << "-->" << brightnessPercentage << "%";
|
||||
m_device->setStateValue(aveaBrightnessStateTypeId, brightnessPercentage);
|
||||
break;
|
||||
}
|
||||
case ColorMessageName: {
|
||||
qCDebug(dcElgato()) << "Name notification:" << value.mid(1, value.count() - 2);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qCWarning(dcElgato()) << "Unhandled color characteristic notification received" << value.toHex();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016-2018 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
|
|
@ -30,22 +32,55 @@
|
|||
#include "hardware/bluetoothlowenergy/bluetoothlowenergydevice.h"
|
||||
|
||||
static QBluetoothUuid colorServiceUuid = QBluetoothUuid(QUuid("f815e810-456c-6761-746f-4d756e696368"));
|
||||
static QBluetoothUuid colorCharacteristicUuid = QBluetoothUuid(QUuid("f815e811-456c-6761-746f-4d756e696368"));
|
||||
|
||||
static QBluetoothUuid imageServiceUuid = QBluetoothUuid(QUuid("f815e500-456c-6761-746f-4d756e696368"));
|
||||
|
||||
class AveaBulb : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ColorMessage {
|
||||
ColorMessageColor = 0x35,
|
||||
ColorMessageBrightness = 0x57,
|
||||
ColorMessageName = 0x58
|
||||
};
|
||||
Q_ENUM(ColorMessage)
|
||||
|
||||
explicit AveaBulb(Device *device, BluetoothLowEnergyDevice *bluetoothDevice, QObject *parent = nullptr);
|
||||
|
||||
Device *device();
|
||||
BluetoothLowEnergyDevice *bluetoothDevice();
|
||||
|
||||
bool setPower(bool power);
|
||||
bool setBulbName(const QString &name);
|
||||
bool setColor(const QColor &color);
|
||||
bool setBrightness(int percentage);
|
||||
bool setFade(int fade);
|
||||
|
||||
bool setWhite(int white);
|
||||
bool setRed(int red);
|
||||
bool setGreen(int green);
|
||||
bool setBlue(int blue);
|
||||
|
||||
bool loadValues();
|
||||
bool syncColor();
|
||||
|
||||
private:
|
||||
Device *m_device;
|
||||
BluetoothLowEnergyDevice *m_bluetoothDevice;
|
||||
Device *m_device = nullptr;
|
||||
BluetoothLowEnergyDevice *m_bluetoothDevice = nullptr;
|
||||
|
||||
QString m_bulbName;
|
||||
QColor m_color;
|
||||
int m_brightness = 0;
|
||||
int m_fade = 0;
|
||||
int m_white = 0;
|
||||
int m_red = 0;
|
||||
int m_green = 0;
|
||||
int m_blue = 0;
|
||||
|
||||
quint16 scaleColorValueUp(int colorValue);
|
||||
int scaleColorValueDown(quint16 colorValue);
|
||||
|
||||
private:
|
||||
QLowEnergyService *m_colorService = nullptr;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,57 @@
|
|||
#include "aveacolor.h"
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016-2018 Simon Stürz <simon.stuerz@guh.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/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
AveaColor::AveaColor(const QColor &color)
|
||||
#include "extern-plugininfo.h"
|
||||
|
||||
AveaColor::AveaColor(const QColor &color):
|
||||
m_color(color)
|
||||
{
|
||||
// Convert rgb to wrgb
|
||||
|
||||
ColorRgbw rgbw = rgbToRgbw(color.red(), color.green(), color.blue());
|
||||
Q_UNUSED(rgbw)
|
||||
qCDebug(dcElgato()) << "Convert color" << m_color.red() << m_color.green() << m_color.blue();
|
||||
|
||||
ColorRgbw rgbw = rgbToRgbw(m_color.red(), m_color.green(), m_color.blue());
|
||||
m_white = rgbw.white;
|
||||
m_red = rgbw.red;
|
||||
m_green = rgbw.green;
|
||||
m_blue = rgbw.blue;
|
||||
}
|
||||
|
||||
AveaColor::AveaColor(uint white, uint red, uint green, uint blue):
|
||||
m_white(white),
|
||||
m_red(red),
|
||||
m_green(green),
|
||||
m_blue(blue)
|
||||
{
|
||||
// Convert rgbw to rgb
|
||||
|
||||
// TODO
|
||||
|
||||
|
||||
}
|
||||
|
||||
QColor AveaColor::color() const
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
uint AveaColor::white() const
|
||||
|
|
@ -68,3 +113,9 @@ ColorRgbw AveaColor::rgbToRgbw(uint red, uint green, uint blue)
|
|||
rgbw.white = getWhite(rgbw);
|
||||
return rgbw;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const AveaColor &color)
|
||||
{
|
||||
dbg.nospace() << "AveaColor(" << color.color() << " | R:" << color.red() << " G:" << color.green() << "B:" << color.blue() << "W:" << color.white() << ")";
|
||||
return dbg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,31 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016-2018 Simon Stürz <simon.stuerz@guh.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 AVEACOLOR_H
|
||||
#define AVEACOLOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QColor>
|
||||
#include <QDebug>
|
||||
|
||||
struct ColorRgbw {
|
||||
uint red;
|
||||
|
|
@ -11,11 +34,13 @@ struct ColorRgbw {
|
|||
uint white;
|
||||
};
|
||||
|
||||
|
||||
class AveaColor
|
||||
{
|
||||
public:
|
||||
AveaColor(const QColor &color);
|
||||
AveaColor(uint white, uint red, uint green, uint blue);
|
||||
|
||||
QColor color() const;
|
||||
|
||||
uint white() const;
|
||||
uint red() const;
|
||||
|
|
@ -25,6 +50,7 @@ public:
|
|||
QByteArray toByteArray();
|
||||
|
||||
private:
|
||||
QColor m_color;
|
||||
uint m_white = 0;
|
||||
uint m_red = 0;
|
||||
uint m_green = 0;
|
||||
|
|
@ -36,4 +62,7 @@ private:
|
|||
ColorRgbw rgbToRgbw(unsigned int red, unsigned int green, unsigned int blue);
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug dbg, const AveaColor &color);
|
||||
|
||||
|
||||
#endif // AVEACOLOR_H
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016-2018 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
|
|
@ -408,6 +410,17 @@ DevicePluginElgato::DevicePluginElgato()
|
|||
|
||||
}
|
||||
|
||||
DevicePluginElgato::~DevicePluginElgato()
|
||||
{
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
|
||||
}
|
||||
|
||||
void DevicePluginElgato::init()
|
||||
{
|
||||
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
|
||||
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginElgato::onPluginTimer);
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError DevicePluginElgato::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
|
|
@ -438,31 +451,86 @@ DeviceManager::DeviceSetupStatus DevicePluginElgato::setupDevice(Device *device)
|
|||
BluetoothLowEnergyDevice *bluetoothDevice = hardwareManager()->bluetoothLowEnergyManager()->registerDevice(deviceInfo, QLowEnergyController::PublicAddress);
|
||||
|
||||
AveaBulb *bulb = new AveaBulb(device, bluetoothDevice, this);
|
||||
|
||||
m_bulbs.insert(device, bulb);
|
||||
bulb->bluetoothDevice()->connectDevice();
|
||||
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
|
||||
void DevicePluginElgato::postSetupDevice(Device *device)
|
||||
{
|
||||
AveaBulb *bulb = m_bulbs.value(device);
|
||||
// Init values for restore
|
||||
bulb->setBrightness(device->stateValue(aveaBrightnessStateTypeId).toInt());
|
||||
bulb->setFade(device->stateValue(aveaFadeStateTypeId).toInt());
|
||||
bulb->setWhite(device->stateValue(aveaWhiteStateTypeId).toInt());
|
||||
bulb->setRed(device->stateValue(aveaRedStateTypeId).toInt());
|
||||
bulb->setGreen(device->stateValue(aveaGreenStateTypeId).toInt());
|
||||
bulb->setBlue(device->stateValue(aveaBlueStateTypeId).toInt());
|
||||
|
||||
bulb->bluetoothDevice()->connectDevice();
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError DevicePluginElgato::executeAction(Device *device, const Action &action)
|
||||
{
|
||||
Q_UNUSED(action)
|
||||
// check deviceClassId
|
||||
if (device->deviceClassId() == aveaDeviceClassId) {
|
||||
AveaBulb *bulb = m_bulbs.value(device);
|
||||
|
||||
Q_UNUSED(bulb)
|
||||
// // check actionTypeId
|
||||
// if (action.actionTypeId() == powerOffActionTypeId) {
|
||||
// bulb->actionPowerOff(action.id());
|
||||
// return DeviceManager::DeviceErrorAsync;
|
||||
// } else if (action.actionTypeId() == colorActionTypeId) {
|
||||
if (action.actionTypeId() == aveaPowerActionTypeId) {
|
||||
bool power = action.param(aveaPowerStateParamTypeId).value().toBool();
|
||||
device->setStateValue(aveaPowerStateTypeId, power);
|
||||
if (!bulb->setPower(power))
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
// return DeviceManager::DeviceErrorNoError;
|
||||
// }
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
} else if (action.actionTypeId() == aveaBrightnessActionTypeId) {
|
||||
int percentage = action.param(aveaBrightnessStateParamTypeId).value().toInt();
|
||||
if (!bulb->setBrightness(percentage))
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
device->setStateValue(aveaBrightnessStateTypeId, percentage);
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
} else if (action.actionTypeId() == aveaColorActionTypeId) {
|
||||
QColor color = action.param(aveaColorStateParamTypeId).value().value<QColor>();
|
||||
if (!bulb->setColor(color))
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
device->setStateValue(aveaColorStateTypeId, color);
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
} else if (action.actionTypeId() == aveaWhiteActionTypeId) {
|
||||
int whiteValue = action.param(aveaWhiteStateParamTypeId).value().toInt();
|
||||
if (!bulb->setWhite(whiteValue))
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
device->setStateValue(aveaWhiteStateTypeId, whiteValue);
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
} else if (action.actionTypeId() == aveaGreenActionTypeId) {
|
||||
int greenValue = action.param(aveaGreenStateParamTypeId).value().toInt();
|
||||
if (!bulb->setGreen(greenValue))
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
} else if (action.actionTypeId() == aveaRedActionTypeId) {
|
||||
int redValue = action.param(aveaRedStateParamTypeId).value().toInt();
|
||||
if (!bulb->setRed(redValue))
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
} else if (action.actionTypeId() == aveaBlueActionTypeId) {
|
||||
int blueValue = action.param(aveaBlueStateParamTypeId).value().toInt();
|
||||
if (!bulb->setBlue(blueValue))
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
} else if (action.actionTypeId() == aveaFadeActionTypeId) {
|
||||
int fadeValue = action.param(aveaFadeStateParamTypeId).value().toInt();
|
||||
device->setStateValue(aveaFadeStateTypeId, fadeValue);
|
||||
if (!bulb->setFade(fadeValue))
|
||||
return DeviceManager::DeviceErrorHardwareNotAvailable;
|
||||
|
||||
return DeviceManager::DeviceErrorNoError;
|
||||
}
|
||||
|
||||
return DeviceManager::DeviceErrorActionTypeNotFound;
|
||||
}
|
||||
|
|
@ -490,6 +558,15 @@ bool DevicePluginElgato::verifyExistingDevices(const QBluetoothDeviceInfo &devic
|
|||
return false;
|
||||
}
|
||||
|
||||
void DevicePluginElgato::onPluginTimer()
|
||||
{
|
||||
foreach (AveaBulb *bulb, m_bulbs.values()) {
|
||||
if (!bulb->bluetoothDevice()->connected()) {
|
||||
bulb->bluetoothDevice()->connectDevice();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginElgato::onBluetoothDiscoveryFinished()
|
||||
{
|
||||
BluetoothDiscoveryReply *reply = static_cast<BluetoothDiscoveryReply *>(sender());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2016-2018 Simon Stürz <simon.stuerz@guh.io> *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
|
|
@ -21,9 +23,10 @@
|
|||
#ifndef DEVICEPLUGINELGATO_H
|
||||
#define DEVICEPLUGINELGATO_H
|
||||
|
||||
#include "aveabulb.h"
|
||||
#include "plugintimer.h"
|
||||
#include "plugin/deviceplugin.h"
|
||||
#include "hardware/bluetoothlowenergy/bluetoothlowenergydevice.h"
|
||||
#include "aveabulb.h"
|
||||
|
||||
class DevicePluginElgato : public DevicePlugin
|
||||
{
|
||||
|
|
@ -34,17 +37,23 @@ class DevicePluginElgato : public DevicePlugin
|
|||
|
||||
public:
|
||||
explicit DevicePluginElgato();
|
||||
~DevicePluginElgato();
|
||||
|
||||
void init() override;
|
||||
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
||||
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
||||
void postSetupDevice(Device *device) override;
|
||||
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
|
||||
private:
|
||||
PluginTimer *m_pluginTimer = nullptr;
|
||||
QHash<Device *, AveaBulb *> m_bulbs;
|
||||
|
||||
bool verifyExistingDevices(const QBluetoothDeviceInfo &deviceInfo);
|
||||
|
||||
private slots:
|
||||
void onPluginTimer();
|
||||
void onBluetoothDiscoveryFinished();
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,37 +1,33 @@
|
|||
{
|
||||
"displayName": "Elgato",
|
||||
"id": "c5c03ad4-bfdb-444a-8eca-2c234c46cc27",
|
||||
"name": "Elgato",
|
||||
"displayName": "Elgato",
|
||||
"vendors": [
|
||||
{
|
||||
"displayName": "Elgato",
|
||||
"name": "elgato",
|
||||
"id": "90a3091d-1053-4f77-8dc3-92e27bbcebe7",
|
||||
"name": "elgato",
|
||||
"displayName": "Elgato",
|
||||
"deviceClasses": [
|
||||
{
|
||||
"id": "164f9602-90ee-4693-bda3-9cafae37603e",
|
||||
"name": "avea",
|
||||
"displayName": "Avea",
|
||||
"deviceIcon": "LightBulb",
|
||||
"criticalStateTypeId": "6d5e792a-c786-40d2-ae35-a48ac6fafcbc",
|
||||
"basicTags": [
|
||||
"Device",
|
||||
"Actuator",
|
||||
"Lighting"
|
||||
],
|
||||
"basicTags": ["Device", "Actuator", "Lighting"],
|
||||
"interfaces": ["connectable"],
|
||||
"createMethods": ["discovery"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "d7a5d96f-33dc-4dc3-a171-b1e89a5e1a4b",
|
||||
"name": "name",
|
||||
"displayName": "name",
|
||||
"displayName": "Name",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine"
|
||||
},
|
||||
{
|
||||
"id": "20932e39-00fd-40e3-8f39-850ba149844e",
|
||||
"name": "macAddress",
|
||||
"displayName": "mac address",
|
||||
"displayName": "MAC address",
|
||||
"type": "QString",
|
||||
"inputType": "MacAddress"
|
||||
}
|
||||
|
|
@ -40,16 +36,27 @@
|
|||
{
|
||||
"id": "6d5e792a-c786-40d2-ae35-a48ac6fafcbc",
|
||||
"name": "connected",
|
||||
"displayName": "connected",
|
||||
"displayNameEvent": "connected changed",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"type": "bool",
|
||||
"cached": false,
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "2b779968-ff4f-4a05-a466-074e14288a8c",
|
||||
"name": "power",
|
||||
"displayName": "Power",
|
||||
"displayNameEvent": "Power changed",
|
||||
"displayNameAction": "Set power",
|
||||
"type": "bool",
|
||||
"writable": true,
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "c38181a0-e19b-423f-8b66-dedda94e89b5",
|
||||
"name": "brightness",
|
||||
"displayName": "Brightness",
|
||||
"displayNameEvent": "brightness changed",
|
||||
"displayNameEvent": "Brightness changed",
|
||||
"displayNameAction": "Set brightness",
|
||||
"type": "int",
|
||||
"defaultValue": 100,
|
||||
|
|
@ -62,14 +69,84 @@
|
|||
{
|
||||
"id": "3f15637a-8272-4714-bd08-04806e05bbef",
|
||||
"name": "color",
|
||||
"displayName": "color",
|
||||
"displayNameEvent": "color changed",
|
||||
"displayName": "Color",
|
||||
"displayNameEvent": "Color changed",
|
||||
"displayNameAction": "Set color",
|
||||
"type": "QColor",
|
||||
"ruleRelevant": false,
|
||||
"eventRuleRelevant": false,
|
||||
"defaultValue": "#000000",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "50f6a224-fb8d-487d-8774-1a0536e5b1aa",
|
||||
"name": "white",
|
||||
"displayName": "white",
|
||||
"displayNameEvent": "white changed",
|
||||
"displayNameAction": "Set white",
|
||||
"type": "int",
|
||||
"defaultValue": 0,
|
||||
"ruleRelevant": false,
|
||||
"minValue": 0,
|
||||
"maxValue": 4095,
|
||||
"eventRuleRelevant": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "50ab71d1-8970-4531-b1ad-f387d01bab90",
|
||||
"name": "red",
|
||||
"displayName": "Red",
|
||||
"displayNameEvent": "Red changed",
|
||||
"displayNameAction": "Set red",
|
||||
"type": "int",
|
||||
"defaultValue": 0,
|
||||
"ruleRelevant": false,
|
||||
"minValue": 0,
|
||||
"maxValue": 4095,
|
||||
"eventRuleRelevant": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "9e8ddebc-33fe-418a-895f-d8148fabcfee",
|
||||
"name": "green",
|
||||
"displayName": "Green",
|
||||
"displayNameEvent": "Green changed",
|
||||
"displayNameAction": "Set green",
|
||||
"type": "int",
|
||||
"defaultValue": 0,
|
||||
"ruleRelevant": false,
|
||||
"minValue": 0,
|
||||
"maxValue": 4095,
|
||||
"eventRuleRelevant": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "f4310747-d468-4d2e-abe4-b5e4d0245dad",
|
||||
"name": "blue",
|
||||
"displayName": "Blue",
|
||||
"displayNameEvent": "Blue changed",
|
||||
"displayNameAction": "Set blue",
|
||||
"type": "int",
|
||||
"defaultValue": 0,
|
||||
"ruleRelevant": false,
|
||||
"minValue": 0,
|
||||
"maxValue": 4095,
|
||||
"eventRuleRelevant": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "01ccda48-44c6-495b-b0a7-c2a0bf5a570d",
|
||||
"name": "fade",
|
||||
"displayName": "Fade",
|
||||
"displayNameEvent": "Fade changed",
|
||||
"displayNameAction": "Set fade",
|
||||
"type": "int",
|
||||
"defaultValue": 0,
|
||||
"ruleRelevant": false,
|
||||
"minValue": 0,
|
||||
"maxValue": 1000,
|
||||
"eventRuleRelevant": false,
|
||||
"writable": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,10 @@ TARGET = $$qtLibraryTarget(nymea_devicepluginelgato)
|
|||
SOURCES += \
|
||||
devicepluginelgato.cpp \
|
||||
aveabulb.cpp \
|
||||
aveacolor.cpp
|
||||
|
||||
HEADERS += \
|
||||
devicepluginelgato.h \
|
||||
aveabulb.h \
|
||||
aveacolor.h
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue