New Plugin: Boblight

pull/96/head
Michael Zanetti 2019-01-06 21:03:32 +01:00
parent 80171412ce
commit 5cb4e1407a
12 changed files with 1108 additions and 1 deletions

89
boblight/bobchannel.cpp Normal file
View File

@ -0,0 +1,89 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "bobchannel.h"
BobChannel::BobChannel(const int &id, QObject *parent) :
QObject(parent),
m_id(id)
{
m_animation = new QPropertyAnimation(this, "finalColor", this);
m_animation->setDuration(500);
m_animation->setEasingCurve(QEasingCurve::InOutQuad);
}
int BobChannel::id() const
{
return m_id;
}
QColor BobChannel::color() const
{
return m_color;
}
void BobChannel::setColor(const QColor &color)
{
m_color = color;
emit colorChanged();
if (m_animation->state() == QPropertyAnimation::Running) {
m_animation->stop();
}
m_animation->setStartValue(m_finalColor);
m_animation->setEndValue(color);
m_animation->start();
}
bool BobChannel::power() const
{
return m_power;
}
void BobChannel::setPower(bool power)
{
if (power != m_power) {
m_power = power;
emit powerChanged();
if (m_animation->state() == QPropertyAnimation::Running) {
m_animation->stop();
}
QColor target = m_color;
target.setAlpha(target.alpha() * (m_power ? 1 : 0));
m_animation->setStartValue(m_finalColor);
m_animation->setEndValue(target);
m_animation->start();
}
}
QColor BobChannel::finalColor() const
{
return m_finalColor;
}
void BobChannel::setFinalColor(const QColor &color)
{
m_finalColor = color;
emit finalColorChanged();
}

66
boblight/bobchannel.h Normal file
View File

@ -0,0 +1,66 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef BOBCHANNEL_H
#define BOBCHANNEL_H
#include <QColor>
#include <QObject>
#include <QPropertyAnimation>
class BobChannel : public QObject
{
Q_OBJECT
Q_PROPERTY(bool power READ power WRITE setPower NOTIFY powerChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
// don't directly write to this, the propertyAnimation requires a writable property tho...
Q_PROPERTY(QColor finalColor READ finalColor WRITE setFinalColor NOTIFY finalColorChanged)
public:
explicit BobChannel(const int &id, QObject *parent = 0);
int id() const;
QColor color() const;
void setColor(const QColor &color);
bool power() const;
void setPower(bool power);
QColor finalColor() const;
void setFinalColor(const QColor &color);
private:
QPropertyAnimation *m_animation;
int m_id;
bool m_power = false;
QColor m_color = Qt::white;
QColor m_finalColor = Qt::black;
signals:
void colorChanged();
void brightnessChanged();
void finalColorChanged();
void powerChanged();
};
#endif // BOBCHANNEL_H

181
boblight/bobclient.cpp Normal file
View File

@ -0,0 +1,181 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "bobclient.h"
#include "extern-plugininfo.h"
#include "libboblight/boblight.h"
#include <QDebug>
#include <QtConcurrent>
BobClient::BobClient(const QString &host, const int &port, QObject *parent) :
QObject(parent),
m_host(host),
m_port(port),
m_connected(false)
{
m_syncTimer = new QTimer(this);
m_syncTimer->setSingleShot(false);
m_syncTimer->setInterval(50);
connect(m_syncTimer, SIGNAL(timeout()), this, SLOT(sync()));
}
BobClient::~BobClient()
{
if (m_boblight) {
boblight_destroy(m_boblight);
}
}
bool BobClient::connectToBoblight()
{
if (connected()) {
return true;
}
m_boblight = boblight_init();
//try to connect, if we can't then bitch to stderr and destroy boblight
if (!boblight_connect(m_boblight, m_host.toLatin1().data(), m_port, 1000000)) {
qCWarning(dcBoblight) << "Failed to connect:" << boblight_geterror(m_boblight);
boblight_destroy(m_boblight);
m_boblight = nullptr;
setConnected(false);
return false;
}
qCDebug(dcBoblight) << "Connected to boblightd successfully.";
boblight_setpriority(m_boblight, m_priority);
for (int i = 0; i < lightsCount(); ++i) {
BobChannel *channel = new BobChannel(i, this);
channel->setColor(QColor(255,255,255,0));
connect(channel, SIGNAL(colorChanged()), this, SLOT(sync()));
m_channels.insert(i, channel);
}
setConnected(true);
return true;
}
bool BobClient::connected()
{
return m_connected;
}
void BobClient::setPriority(int priority)
{
m_priority = priority;
if (connected()) {
qCDebug(dcBoblight) << "setting priority to" << priority << boblight_setpriority(m_boblight, priority);
}
emit priorityChanged(priority);
}
void BobClient::setPower(int channel, bool power)
{
qCDebug(dcBoblight()) << "BobClient: setPower" << channel << power;
m_channels.value(channel)->setPower(power);
emit powerChanged(channel, power);
}
BobChannel *BobClient::getChannel(const int &id)
{
foreach (BobChannel *channel, m_channels) {
if (channel->id() == id)
return channel;
}
return 0;
}
void BobClient::setColor(int channel, QColor color)
{
if (channel == -1) {
for (int i = 0; i < lightsCount(); ++i) {
setColor(i, color);
}
} else {
BobChannel *c = getChannel(channel);
if (c) {
c->setColor(color);
qCDebug(dcBoblight) << "set channel" << channel << "to color" << color;
emit colorChanged(channel, color);
}
}
}
void BobClient::setBrightness(int channel, int brightness)
{
QColor color = m_channels.value(channel)->color();
color.setAlpha(qRound(brightness * 255.0 / 100));
m_channels.value(channel)->setColor(color);
emit brightnessChanged(channel, brightness);
if (brightness > 0) {
m_channels.value(channel)->setPower(true);
emit powerChanged(channel, true);
}
}
void BobClient::sync()
{
if (!m_connected)
return;
foreach (BobChannel *channel, m_channels) {
int rgb[3];
rgb[0] = channel->finalColor().red() * channel->finalColor().alphaF();
rgb[1] = channel->finalColor().green() * channel->finalColor().alphaF();
rgb[2] = channel->finalColor().blue() * channel->finalColor().alphaF();
boblight_addpixel(m_boblight, channel->id(), rgb);
}
if (!boblight_sendrgb(m_boblight, 1, NULL)) {
qCWarning(dcBoblight) << "Boblight connection error:" << boblight_geterror(m_boblight);
boblight_destroy(m_boblight);
qDeleteAll(m_channels);
m_channels.clear();
setConnected(false);
}
}
void BobClient::setConnected(bool connected)
{
m_connected = connected;
emit connectionChanged();
// if disconnected, delete all channels
if (!connected) {
m_syncTimer->stop();
qDeleteAll(m_channels);
} else {
m_syncTimer->start();
}
}
int BobClient::lightsCount()
{
return boblight_getnrlights(m_boblight);
}
QColor BobClient::currentColor(const int &channel)
{
return getChannel(channel)->color();
}

79
boblight/bobclient.h Normal file
View File

@ -0,0 +1,79 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef BOBCLIENT_H
#define BOBCLIENT_H
#include <QObject>
#include <QTimer>
#include <QMap>
#include <QColor>
#include <QTime>
#include <bobchannel.h>
class BobClient : public QObject
{
Q_OBJECT
public:
explicit BobClient(const QString &host = "127.0.0.1", const int &port = 19333, QObject *parent = 0);
~BobClient();
bool connectToBoblight();
bool connected();
int lightsCount();
QColor currentColor(const int &channel);
void setPriority(int priority);
void setPower(int channel, bool power);
void setColor(int channel, QColor color);
void setBrightness(int channel, int brightness);
private:
void *m_boblight = nullptr;
QTimer *m_syncTimer;
QString m_host;
int m_port;
bool m_connected;
int m_priority = 128;
QMap<int, QColor> m_colors;
QMap<int, BobChannel *> m_channels;
BobChannel *getChannel(const int &id);
private slots:
void sync();
void setConnected(bool connected);
signals:
void connectionChanged();
void powerChanged(int channel, bool power);
void brightnessChanged(int channel, int brightness);
void colorChanged(int channel, const QColor &color);
void priorityChanged(int priority);
};
#endif // BOBCLIENT_H

20
boblight/boblight.pro Normal file
View File

@ -0,0 +1,20 @@
include(/usr/include/nymea/plugin.pri)
QT += dbus bluetooth concurrent
CONFIG += c++11
TARGET = $$qtLibraryTarget(nymea_devicepluginboblight)
LIBS += -lboblight
SOURCES += \
devicepluginboblight.cpp \
bobclient.cpp \
bobchannel.cpp
HEADERS += \
devicepluginboblight.h \
bobclient.h \
bobchannel.h

View File

@ -0,0 +1,306 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\page boblight.html
\title Boblight
\ingroup plugins
\ingroup network
This plugin allows to communicate with a \l{https://code.google.com/p/boblight/}{boblight} server
running on localhost:19333. If a boblight server is running ,the configured light devices from the server will
appear automatically in guh.
\chapter Plugin properties
Following JSON file contains the definition and the description of all available \l{DeviceClass}{DeviceClasses}
and \l{Vendor}{Vendors} of this \l{DevicePlugin}.
Each \l{DeviceClass} has a list of \l{ParamType}{paramTypes}, \l{ActionType}{actionTypes}, \l{StateType}{stateTypes}
and \l{EventType}{eventTypes}. The \l{DeviceClass::CreateMethod}{createMethods} parameter describes how the \l{Device}
will be created in the system. A device can have more than one \l{DeviceClass::CreateMethod}{CreateMethod}.
The \l{DeviceClass::SetupMethod}{setupMethod} describes the setup method of the \l{Device}.
The detailed implementation of each \l{DeviceClass} can be found in the source code.
\note If a \l{StateType} has the parameter \tt{"writable": {...}}, an \l{ActionType} with the same uuid and \l{ParamType}{ParamTypes}
will be created automatically.
\quotefile plugins/deviceplugins/boblight/devicepluginboblight.json
*/
#include "devicepluginboblight.h"
#include "plugin/device.h"
#include "devicemanager.h"
#include "bobclient.h"
#include "plugininfo.h"
#include "plugintimer.h"
#include <QDebug>
#include <QStringList>
#include <QtMath>
DevicePluginBoblight::DevicePluginBoblight()
{
}
void DevicePluginBoblight::init()
{
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(15);
connect(m_pluginTimer, &PluginTimer::timeout, this, &DevicePluginBoblight::guhTimer);
}
void DevicePluginBoblight::deviceRemoved(Device *device)
{
if (device->deviceClassId() == boblightServerDeviceClassId) {
BobClient *client = m_bobClients.take(device->id());
client->deleteLater();
}
}
void DevicePluginBoblight::startMonitoringAutoDevices()
{
m_canCreateAutoDevices = true;
qCDebug(dcBoblight()) << "Populating auto devices" << myDevices().count();
QHash<DeviceId, int> parentDevices;
QHash<DeviceId, Device*> deviceIds;
foreach (Device *device, myDevices()) {
deviceIds.insert(device->id(), device);
if (device->deviceClassId() == boblightServerDeviceClassId) {
qWarning() << "Device" << device->id() << "is bridge";
if (!parentDevices.contains(device->id())) {
parentDevices[device->id()] = 0;
}
} else if (device->deviceClassId() == boblightDeviceClassId) {
qWarning() << "Device" << device->id() << "is child to bridge" << device->parentId();
parentDevices[device->parentId()] += 1;
}
}
qWarning() << "have bridge devices:" << parentDevices.count();
QList<DeviceDescriptor> descriptors;
foreach (const DeviceId &id, parentDevices.keys()) {
if (parentDevices.value(id) < deviceIds.value(id)->paramValue(boblightServerDeviceChannelsParamTypeId).toInt()) {
for (int i = parentDevices.value(id); i < deviceIds.value(id)->paramValue(boblightServerDeviceChannelsParamTypeId).toInt(); i++) {
DeviceDescriptor descriptor(boblightDeviceClassId, deviceIds.value(id)->name() + " " + QString::number(i + 1), QString(), id);
descriptor.setParams(ParamList() << Param(boblightDeviceChannelParamTypeId, i));
qCDebug(dcBoblight()) << "Adding new boblight channel" << i + 1;
descriptors.append(descriptor);
}
}
}
if (!descriptors.isEmpty()) {
emit autoDevicesAppeared(boblightDeviceClassId, descriptors);
}
}
void DevicePluginBoblight::guhTimer()
{
foreach (BobClient *client, m_bobClients) {
if (!client->connected()) {
client->connectToBoblight();
}
}
}
void DevicePluginBoblight::onPowerChanged(int channel, bool power)
{
qCDebug(dcBoblight()) << "power changed" << channel << power;
BobClient *sndr = dynamic_cast<BobClient*>(sender());
foreach (Device* device, myDevices()) {
if (m_bobClients.value(device->parentId()) == sndr && device->paramValue(boblightDeviceChannelParamTypeId).toInt() == channel) {
qCWarning(dcBoblight()) << "setting state power" << power;
device->setStateValue(boblightPowerStateTypeId, power);
}
}
}
void DevicePluginBoblight::onBrightnessChanged(int channel, int brightness)
{
BobClient *sndr = dynamic_cast<BobClient*>(sender());
foreach (Device* device, myDevices()) {
if (m_bobClients.value(device->parentId()) == sndr && device->paramValue(boblightDeviceChannelParamTypeId).toInt() == channel) {
device->setStateValue(boblightBrightnessStateTypeId, brightness);
}
}
}
void DevicePluginBoblight::onColorChanged(int channel, const QColor &color)
{
BobClient *sndr = dynamic_cast<BobClient*>(sender());
foreach (Device* device, myDevices()) {
if (m_bobClients.value(device->parentId()) == sndr && device->paramValue(boblightDeviceChannelParamTypeId).toInt() == channel) {
device->setStateValue(boblightColorStateTypeId, color);
}
}
}
void DevicePluginBoblight::onPriorityChanged(int priority)
{
BobClient *sndr = dynamic_cast<BobClient*>(sender());
foreach (Device* device, myDevices()) {
if (m_bobClients.value(device->id()) == sndr) {
device->setStateValue(boblightServerPriorityStateTypeId, priority);
}
}
}
QColor DevicePluginBoblight::tempToRgb(int temp)
{
// 153 cold: 0.839216, 1, 0.827451
// 500 warm: 0.870588, 1, 0.266667
// => 0 : 214,255,212
// 100 : 222,255,67
// r => 0 : 214 = 100 : 222
// => temp : (x-214) = 100 : (255 - 214)
// => x = temp * (255-214) / 100
// r = x + 214
int red = temp * 41 / 100 + 214;
int green = 255;
// b => 0 : 212 = 100 : 67
// => temp : (212 - x) = 100 : (212 - 145)
// => x = temp * 145 / 100
// g = 212 - x
int blue = 212 - temp * 145 / 100;
qWarning() << "temp:" << temp << "rgb" << red << green << blue;
return QColor(red, green, blue);
}
DeviceManager::DeviceSetupStatus DevicePluginBoblight::setupDevice(Device *device)
{
if (device->deviceClassId() == boblightServerDeviceClassId) {
BobClient *bobClient = new BobClient(device->paramValue(boblightServerDeviceHostAddressParamTypeId).toString(), device->paramValue(boblightServerDevicePortParamTypeId).toInt(), this);
bool connected = bobClient->connectToBoblight();
if (!connected) {
qCWarning(dcBoblight()) << "Error connecting to boblight...";
} else {
qCDebug(dcBoblight()) << "Connected to boblight";
}
bobClient->setPriority(device->stateValue(boblightServerPriorityStateTypeId).toInt());
device->setStateValue(boblightServerConnectedStateTypeId, connected);
m_bobClients.insert(device->id(), bobClient);
connect(bobClient, &BobClient::connectionChanged, this, &DevicePluginBoblight::onConnectionChanged);
connect(bobClient, &BobClient::powerChanged, this, &DevicePluginBoblight::onPowerChanged);
connect(bobClient, &BobClient::brightnessChanged, this, &DevicePluginBoblight::onBrightnessChanged);
connect(bobClient, &BobClient::colorChanged, this, &DevicePluginBoblight::onColorChanged);
connect(bobClient, &BobClient::priorityChanged, this, &DevicePluginBoblight::onPriorityChanged);
} else if (device->deviceClassId() == boblightDeviceClassId) {
BobClient *bobClient = m_bobClients.value(device->parentId());
device->setStateValue(boblightConnectedStateTypeId, bobClient->connected());
m_bobClients.insert(device->id(), bobClient);
}
return DeviceManager::DeviceSetupStatusSuccess;
}
void DevicePluginBoblight::postSetupDevice(Device *device)
{
if (device->deviceClassId() == boblightServerDeviceClassId && m_canCreateAutoDevices) {
startMonitoringAutoDevices();
}
if (device->deviceClassId() == boblightDeviceClassId) {
BobClient *bobClient = m_bobClients.value(device->parentId());
if (bobClient && bobClient->connected()) {
device->setStateValue(boblightConnectedStateTypeId, bobClient->connected());
QColor color = device->stateValue(boblightColorStateTypeId).value<QColor>();
int brightness = device->stateValue(boblightBrightnessStateTypeId).toInt();
bool power = device->stateValue(boblightPowerStateTypeId).toBool();
bobClient->setColor(device->paramValue(boblightDeviceChannelParamTypeId).toInt(), color);
bobClient->setBrightness(device->paramValue(boblightDeviceChannelParamTypeId).toInt(), brightness);
bobClient->setPower(device->paramValue(boblightDeviceChannelParamTypeId).toInt(), power);
}
}
}
DeviceManager::DeviceError DevicePluginBoblight::executeAction(Device *device, const Action &action)
{
if (!device->setupComplete()) {
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
qCDebug(dcBoblight()) << "Execute action for boblight" << action.params();
if (device->deviceClassId() == boblightServerDeviceClassId) {
BobClient *bobClient = m_bobClients.value(device->id());
if (!bobClient || !bobClient->connected()) {
qCWarning(dcBoblight()) << "Boblight on" << device->paramValue(boblightServerDeviceHostAddressParamTypeId).toString() << "not connected";
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
if (action.actionTypeId() == boblightServerPriorityActionTypeId) {
bobClient->setPriority(action.param(boblightServerPriorityActionPriorityParamTypeId).value().toInt());
return DeviceManager::DeviceErrorNoError;
}
qCWarning(dcBoblight()) << "Unhandled action" << action.actionTypeId() << "for BoblightServer device" << device;
return DeviceManager::DeviceErrorActionTypeNotFound;
}
if (device->deviceClassId() == boblightDeviceClassId) {
BobClient *bobClient = m_bobClients.value(device->parentId());
if (!bobClient || !bobClient->connected()) {
qCWarning(dcBoblight()) << "Boblight not connected";
return DeviceManager::DeviceErrorHardwareNotAvailable;
}
if (action.actionTypeId() == boblightPowerActionTypeId) {
bobClient->setPower(device->paramValue(boblightDeviceChannelParamTypeId).toInt(), action.param(boblightPowerActionPowerParamTypeId).value().toBool());
return DeviceManager::DeviceErrorNoError;
}
if (action.actionTypeId() == boblightColorActionTypeId) {
bobClient->setColor(device->paramValue(boblightDeviceChannelParamTypeId).toInt(), action.param(boblightColorActionColorParamTypeId).value().value<QColor>());
return DeviceManager::DeviceErrorNoError;
}
if (action.actionTypeId() == boblightBrightnessActionTypeId) {
bobClient->setBrightness(device->paramValue(boblightDeviceChannelParamTypeId).toInt(), action.param(boblightBrightnessActionBrightnessParamTypeId).value().toInt());
return DeviceManager::DeviceErrorNoError;
}
if (action.actionTypeId() == boblightColorTemperatureActionTypeId) {
bobClient->setColor(device->paramValue(boblightDeviceChannelParamTypeId).toInt(), tempToRgb(action.param(boblightColorTemperatureActionColorTemperatureParamTypeId).value().toInt()));
return DeviceManager::DeviceErrorNoError;
}
return DeviceManager::DeviceErrorActionTypeNotFound;
}
return DeviceManager::DeviceErrorDeviceClassNotFound;
}
void DevicePluginBoblight::onConnectionChanged()
{
BobClient *bobClient = static_cast<BobClient *>(sender());
qCDebug(dcBoblight()) << "Connection changed. BobClient:" << bobClient << bobClient->connected() << m_bobClients.keys(bobClient);
foreach (const DeviceId &deviceId, m_bobClients.keys(bobClient)) {
foreach (Device *device, myDevices()) {
if (device->id() == deviceId || device->parentId() == deviceId) {
device->setStateValue(boblightConnectedStateTypeId, bobClient->connected());
break;
}
}
}
}

View File

@ -0,0 +1,68 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef DEVICEPLUGINBOBLIGHT_H
#define DEVICEPLUGINBOBLIGHT_H
#include "plugin/deviceplugin.h"
#include "bobclient.h"
class BobClient;
class PluginTimer;
class DevicePluginBoblight : public DevicePlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "devicepluginboblight.json")
Q_INTERFACES(DevicePlugin)
public:
explicit DevicePluginBoblight();
void init() override;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void postSetupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void startMonitoringAutoDevices() override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private slots:
void onConnectionChanged();
void guhTimer();
void onPowerChanged(int channel, bool power);
void onBrightnessChanged(int channel, int brightness);
void onColorChanged(int channel, const QColor &color);
void onPriorityChanged(int priority);
private:
QColor tempToRgb(int temp);
private:
PluginTimer *m_pluginTimer = nullptr;
QHash<DeviceId, BobClient*> m_bobClients;
bool m_canCreateAutoDevices = false;
};
#endif // DEVICEPLUGINBOBLIGHT_H

View File

@ -0,0 +1,138 @@
{
"id": "d5271bea-1362-4cc6-888f-2ebe80bad46a",
"name": "Boblight",
"displayName": "Boblight",
"vendors": [
{
"id": "f0c9dd91-c2b0-4cd0-b161-a17fee9d2303",
"name": "boblight",
"displayName": "Boblight",
"deviceClasses": [
{
"id": "f267a7f4-ed75-4026-9b97-98884d7f4399",
"name": "boblightServer",
"displayName": "Boblight server",
"createMethods": ["user"],
"interfaces": ["gateway", "connectable"],
"paramTypes": [
{
"id": "de82ea8c-2f1e-4b93-b85a-f6a0b7f87e4a",
"name": "hostAddress",
"displayName": "Host Address",
"type" : "QString",
"inputType": "IPv4Address",
"defaultValue": "127.0.0.1"
},
{
"id": "8cbe5ef8-6b45-441e-9051-08d48f3948da",
"name": "port",
"displayName": "Port",
"type" : "int",
"defaultValue": 19333
},
{
"id": "277f2458-d932-4a6e-a7bb-58814ab99663",
"name": "channels",
"displayName": "Channels",
"type": "int",
"defaultValue": 1
}
],
"stateTypes": [
{
"id": "638fb9ec-4797-4ef6-a9b6-d935f1c49e17",
"name": "connected",
"displayName": "connected",
"displayNameEvent": "Connected changed",
"defaultValue": false,
"type": "bool"
},
{
"id": "60d345e8-757c-4bc2-a96b-31121fc84356",
"name": "priority",
"displayName": "Priority",
"displayNameEvent": "Priority changed",
"displayNameAction": "Set priority",
"type": "int",
"defaultValue": 128,
"minValue": 0,
"maxValue": 256,
"writable": true
}
]
},
{
"id": "05347200-416e-4b75-b4e3-6f913a2a7e76",
"name": "boblight",
"displayName": "Boblight",
"createMethods": ["auto"],
"interfaces": ["colorlight", "connectable"],
"paramTypes": [
{
"id": "7b5b784d-d623-4a2e-b081-9be84b1ce1a8",
"name": "channel",
"displayName": "Channel",
"type": "int",
"defaultValue": -1
}
],
"stateTypes": [
{
"id": "bb40f1bd-62b9-485e-86a1-b0c820a93b8a",
"name": "connected",
"displayName": "connected",
"defaultValue": false,
"displayNameEvent": "Connected changed",
"type": "bool"
},
{
"id": "95aec7b5-247a-42a2-8748-273b034b988c",
"name": "power",
"displayName": "Power",
"defaultValue": false,
"type": "bool",
"displayNameEvent": "Power changed",
"displayNameAction": "Set power",
"writable": true
},
{
"id": "0a92eab5-233c-4081-840b-15578091365c",
"name": "brightness",
"displayName": "Brightness",
"defaultValue": 100,
"type": "int",
"displayNameEvent": "Brightness changed",
"displayNameAction": "Set brightness",
"writable": true,
"minValue": 0,
"maxValue": 100
},
{
"id": "b6f24e6f-d2a8-4f22-b40f-3a0e38bdabe0",
"name": "colorTemperature",
"displayName": "Color Temperature",
"defaultValue": 0,
"type": "int",
"displayNameEvent": "Color Temperature changed",
"displayNameAction": "Set color temperature",
"writable": true,
"minValue": 0,
"maxValue": 100
},
{
"id": "a213d2d1-bd29-4a16-8459-520aa919ae67",
"name": "color",
"displayName": "Color",
"defaultValue": "#ffffff",
"type": "QColor",
"displayNameEvent": "Color changed",
"displayNameAction": "Set color",
"writable": true
}
]
}
]
}
]
}

View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1">
<context>
<name>Boblight</name>
<message>
<source>Boblight</source>
<extracomment>The name of the plugin Boblight (d5271bea-1362-4cc6-888f-2ebe80bad46a)
----------
The name of the vendor (f0c9dd91-c2b0-4cd0-b161-a17fee9d2303)
----------
The name of the DeviceClass (05347200-416e-4b75-b4e3-6f913a2a7e76)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Boblight server</source>
<extracomment>The name of the DeviceClass (f267a7f4-ed75-4026-9b97-98884d7f4399)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Host Address</source>
<extracomment>The name of the paramType (de82ea8c-2f1e-4b93-b85a-f6a0b7f87e4a) of boblightServer</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Port</source>
<extracomment>The name of the paramType (8cbe5ef8-6b45-441e-9051-08d48f3948da) of boblightServer</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Channels</source>
<extracomment>The name of the paramType (277f2458-d932-4a6e-a7bb-58814ab99663) of boblightServer</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Connected changed</source>
<extracomment>The name of the autocreated EventType (638fb9ec-4797-4ef6-a9b6-d935f1c49e17)
----------
The name of the autocreated EventType (bb40f1bd-62b9-485e-86a1-b0c820a93b8a)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>connected</source>
<extracomment>The name of the ParamType of the autocreated EventType (638fb9ec-4797-4ef6-a9b6-d935f1c49e17) of DeviceClass boblightServer
----------
The name of the ParamType of the autocreated EventType (bb40f1bd-62b9-485e-86a1-b0c820a93b8a) of DeviceClass boblight</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Priority changed</source>
<extracomment>The name of the autocreated EventType (60d345e8-757c-4bc2-a96b-31121fc84356)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Priority</source>
<extracomment>The name of the ParamType of the autocreated EventType (60d345e8-757c-4bc2-a96b-31121fc84356) of DeviceClass boblightServer
----------
The name of the autocreated ParamType of the writable StateType (60d345e8-757c-4bc2-a96b-31121fc84356) of DeviceClass boblightServer</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Set priority</source>
<extracomment>The name of the autocreated ActionType (60d345e8-757c-4bc2-a96b-31121fc84356)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Channel</source>
<extracomment>The name of the paramType (7b5b784d-d623-4a2e-b081-9be84b1ce1a8) of boblight</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Power changed</source>
<extracomment>The name of the autocreated EventType (95aec7b5-247a-42a2-8748-273b034b988c)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Power</source>
<extracomment>The name of the ParamType of the autocreated EventType (95aec7b5-247a-42a2-8748-273b034b988c) of DeviceClass boblight
----------
The name of the autocreated ParamType of the writable StateType (95aec7b5-247a-42a2-8748-273b034b988c) of DeviceClass boblight</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Set power</source>
<extracomment>The name of the autocreated ActionType (95aec7b5-247a-42a2-8748-273b034b988c)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Brightness changed</source>
<extracomment>The name of the autocreated EventType (0a92eab5-233c-4081-840b-15578091365c)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Brightness</source>
<extracomment>The name of the ParamType of the autocreated EventType (0a92eab5-233c-4081-840b-15578091365c) of DeviceClass boblight
----------
The name of the autocreated ParamType of the writable StateType (0a92eab5-233c-4081-840b-15578091365c) of DeviceClass boblight</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Set brightness</source>
<extracomment>The name of the autocreated ActionType (0a92eab5-233c-4081-840b-15578091365c)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Color Temperature changed</source>
<extracomment>The name of the autocreated EventType (b6f24e6f-d2a8-4f22-b40f-3a0e38bdabe0)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Color Temperature</source>
<extracomment>The name of the ParamType of the autocreated EventType (b6f24e6f-d2a8-4f22-b40f-3a0e38bdabe0) of DeviceClass boblight
----------
The name of the autocreated ParamType of the writable StateType (b6f24e6f-d2a8-4f22-b40f-3a0e38bdabe0) of DeviceClass boblight</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Set color temperature</source>
<extracomment>The name of the autocreated ActionType (b6f24e6f-d2a8-4f22-b40f-3a0e38bdabe0)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Color changed</source>
<extracomment>The name of the autocreated EventType (a213d2d1-bd29-4a16-8459-520aa919ae67)</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Color</source>
<extracomment>The name of the ParamType of the autocreated EventType (a213d2d1-bd29-4a16-8459-520aa919ae67) of DeviceClass boblight
----------
The name of the autocreated ParamType of the writable StateType (a213d2d1-bd29-4a16-8459-520aa919ae67) of DeviceClass boblight</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Set color</source>
<extracomment>The name of the autocreated ActionType (a213d2d1-bd29-4a16-8459-520aa919ae67)</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
</TS>

20
debian/control vendored
View File

@ -45,6 +45,23 @@ Description: nymea.io plugin for awattar
This package will install the nymea.io plugin for awattar
Package: nymea-plugin-boblight
Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
nymea-plugins-translations,
Description: nymea.io plugin for boblight
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 boblight. Boblight allows
controlling LEDs via home-brew controllers. See https://github.com/arvydas/boblight
for informations on boblight.
Package: nymea-plugin-commandlauncher
Architecture: any
Depends: ${shlibs:Depends},
@ -700,7 +717,8 @@ Description: Plugins for nymea IoT server - the default plugin collection
Package: nymea-plugins-maker
Section: libs
Architecture: all
Depends: nymea-plugin-commandlauncher,
Depends: nymea-plugin-boblight,
nymea-plugin-commandlauncher,
nymea-plugin-udpcommander,
nymea-plugin-tcpcommander,
nymea-plugin-httpcommander,

View File

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

View File

@ -3,6 +3,7 @@ TEMPLATE = subdirs
PLUGIN_DIRS = \
avahimonitor \
awattar \
boblight \
commandlauncher \
conrad \
datetime \