added scene browsing

This commit is contained in:
nymea 2019-10-10 13:48:32 +02:00 committed by Boernsman
parent 4354fdc7af
commit e29afcb8e3
4 changed files with 118 additions and 32 deletions

View File

@ -25,6 +25,9 @@
#include "plugininfo.h"
#include "hardware/bluetoothlowenergy/bluetoothlowenergymanager.h"
#include <QColor>
#include <QRgb>
DevicePluginLukeRoberts::DevicePluginLukeRoberts()
{
@ -140,7 +143,7 @@ void DevicePluginLukeRoberts::executeAction(DeviceActionInfo *info)
if (!power) {
lamp->selectScene(0); //Scene 0 is the off scene
} else {
lamp.
lamp->selectScene(0xff); // Scene 0xff is the default scene
}
} else if (action.actionTypeId() == modelFBrightnessActionTypeId) {
@ -148,9 +151,12 @@ void DevicePluginLukeRoberts::executeAction(DeviceActionInfo *info)
lamp->modifyBrightness(brightness);
} else if (action.actionTypeId() == modelFColorActionTypeId) {
QColor rgb = QColor::fromRgb(QRgb(action.param(modelFColorActionColorParamTypeId).value().toInt()));
lamp->setImmediateLight(0, rgb.saturation(), rgb.hue(), rgb.lightness());
} else if (action.actionTypeId() == modelFColorTemperatureActionTypeId) {
int kelvin = action.param(modelFColorTemperatureActionColorTemperatureParamTypeId).value().toInt();
lamp->modifyColorTemperature(kelvin);
}
}
@ -172,6 +178,49 @@ void DevicePluginLukeRoberts::deviceRemoved(Device *device)
}
}
void DevicePluginLukeRoberts::browseDevice(BrowseResult *result)
{
LukeRoberts *lamp = m_lamps.key(result->device());
if (!lamp) {
result->finish(Device::DeviceErrorHardwareNotAvailable);
return;
}
qDebug(dcLukeRoberts()) << "Browse device called";
m_pendingBrowseResults.insert(lamp, result);
lamp->getSceneList();
}
void DevicePluginLukeRoberts::browserItem(BrowserItemResult *result)
{
LukeRoberts *lamp = m_lamps.key(result->device());
if (!lamp) {
result->finish(Device::DeviceErrorHardwareNotAvailable);
return;
}
qDebug(dcLukeRoberts()) << "Browse item called";
}
void DevicePluginLukeRoberts::executeBrowserItem(BrowserActionInfo *info)
{
LukeRoberts *lamp = m_lamps.key(info->device());
if (!lamp) {
info->finish(Device::DeviceErrorHardwareNotAvailable);
return;
}
lamp->selectScene(info->browserAction().itemId().toInt());
info->finish(Device::DeviceErrorNoError);
}
void DevicePluginLukeRoberts::executeBrowserItemAction(BrowserItemActionInfo *info)
{
LukeRoberts *lamp = m_lamps.key(info->device());
if (!lamp) {
info->finish(Device::DeviceErrorHardwareNotAvailable);
return;
}
}
void DevicePluginLukeRoberts::onReconnectTimeout()
{
@ -200,6 +249,22 @@ void DevicePluginLukeRoberts::onDeviceInformationChanged(const QString &firmware
//device->setStateValue(modelFSoftwareRevisionStateTypeId, softwareRevision);
}
void DevicePluginLukeRoberts::onSceneListReceived(QList<LukeRoberts::Scene> scenes)
{
LukeRoberts *lamp = static_cast<LukeRoberts *>(sender());
if (m_pendingBrowseResults.contains(lamp)) {
BrowseResult *result = m_pendingBrowseResults.value(lamp);
foreach (LukeRoberts::Scene scene, scenes) {
BrowserItem item;
item.setId(QString::number(scene.id));
item.setDisplayName(scene.name);
item.setBrowsable(false);
item.setExecutable(true);
item.setIcon(BrowserItem::BrowserIconApplication);
result->addItem(item);
}
}
}
void DevicePluginLukeRoberts::onStatusCodeReceived(LukeRoberts::StatusCodes statusCode)
{

View File

@ -47,11 +47,19 @@ public:
void deviceRemoved(Device *device) override;
void browseDevice(BrowseResult *result) override;
void browserItem(BrowserItemResult *result) override;
void executeBrowserItem(BrowserActionInfo *info) override;
void executeBrowserItemAction(BrowserItemActionInfo *info) override;
private:
QHash<LukeRoberts *, Device *> m_lamps;
PluginTimer *m_reconnectTimer = nullptr;
bool m_autoSymbolMode = true;
QHash<LukeRoberts *, BrowseResult *> m_pendingBrowseResults;
QHash<int, BrowserActionInfo*> m_pendingBrowserActions;
QHash<int, BrowserItemActionInfo*> m_pendingBrowserItemActions;
private slots:
void onPluginConfigurationChanged(const ParamTypeId &paramTypeId, const QVariant &value);
void onReconnectTimeout();
@ -59,6 +67,8 @@ private slots:
void onConnectedChanged(bool connected);
void onStatusCodeReceived(LukeRoberts::StatusCodes statusCode);
void onDeviceInformationChanged(const QString &firmwareRevision, const QString &hardwareRevision, const QString &softwareRevision);
void onSceneListReceived(QList<LukeRoberts::Scene> scenes);
};
#endif // DEVICEPLUGINLUKEROBERTS_H

View File

@ -62,6 +62,12 @@ void LukeRoberts::queryScene(uint8_t id)
m_controlService->writeCharacteristic(m_externalApiEndpoint, data);
}
void LukeRoberts::getSceneList()
{
m_sceneList.clear();
queryScene(0); //get first scene
}
/*
* duration in ms, 0 for infinite
@ -128,7 +134,7 @@ void LukeRoberts::setNextSceneByBrightness(int8_t direction)
data.append(0xa0); //Prefix
data.append(0x02); //Protocol version V2
data.append(0x06); //Opcode "Next Scene by Brightness"
data << direction; //1 selects the next brighter scene and -1 selects the next less bright scene.
data.append(direction); //1 selects the next brighter scene and -1 selects the next less bright scene.
m_controlService->writeCharacteristic(m_externalApiEndpoint, data);
}
@ -280,6 +286,17 @@ void LukeRoberts::onExternalApiEndpointCharacteristicChanged(const QLowEnergyCha
if (characteristic.uuid() == m_externalApiEndpoint.uuid()) {
qCDebug(dcLukeRoberts()) << "Data received" << value;
}
if (value.length() > 4) { //its a scene
if (value.at(2) != 0xff) { //check it we are already at the end of the list
queryScene(value.at(2));
} else {
emit sceneListReceived(m_sceneList);
}
}
qCDebug(dcLukeRoberts()) << "Service characteristic changed" << characteristic.name() << value.toHex();
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2016-2018 Simon Stürz <simon.stuerz@guh.io> *
* Copyright (C) 2019 Bernhard Trinens <bernhard.trinnes@nymea.io> *
* *
* This file is part of nymea. *
* *
@ -20,8 +20,8 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef NUIMO_H
#define NUIMO_H
#ifndef LUKEROBERTS_H
#define LUKEROBERTS_H
#include <QObject>
#include <QTimer>
@ -32,6 +32,22 @@
#include "hardware/bluetoothlowenergy/bluetoothlowenergydevice.h"
inline QByteArray &operator<<(QByteArray &l, quint8 r)
{
l.append(r);
return l;
}
inline QByteArray &operator<<(QByteArray &l, quint16 r)
{
return l<<quint8(r>>8)<<quint8(r);
}
inline QByteArray &operator<<(QByteArray &l, quint32 r)
{
return l<<quint16(r>>16)<<quint16(r);
}
class LukeRoberts : public QObject
{
Q_OBJECT
@ -61,7 +77,7 @@ enum Opcode {
struct Scene {
int8_t id;
QString nama;
QString name;
};
explicit LukeRoberts(BluetoothLowEnergyDevice *bluetoothDevice, QObject *parent = nullptr);
@ -88,6 +104,8 @@ private:
QLowEnergyCharacteristic m_deviceInfoCharacteristic;
QLowEnergyCharacteristic m_externalApiEndpoint;
QList<Scene> m_sceneList;
void printService(QLowEnergyService *service);
void onLongPressTimer();
@ -108,28 +126,4 @@ private slots:
void onExternalApiEndpointCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &value);
};
QByteArray &operator<<(QByteArray &l, quint8 r)
{
l.append(r);
return l;
}
QByteArray &operator<<(QByteArray &l, qint8 r)
{
l.append(r);
return l;
}
QByteArray &operator<<(QByteArray &l, quint16 r)
{
return l<<quint8(r>>8)<<quint8(r);
}
QByteArray &operator<<(QByteArray &l, quint32 r)
{
return l<<quint16(r>>16)<<quint16(r);
}
#endif // NUIMO_H
#endif // LUKEROBERTS_H