powersync-plugins/senic/devicepluginsenic.cpp

217 lines
9.0 KiB
C++

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* 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/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "devicepluginsenic.h"
#include "devices/device.h"
#include "plugininfo.h"
#include "hardware/bluetoothlowenergy/bluetoothlowenergymanager.h"
DevicePluginSenic::DevicePluginSenic()
{
}
void DevicePluginSenic::init()
{
m_reconnectTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
connect(m_reconnectTimer, &PluginTimer::timeout, this, &DevicePluginSenic::onReconnectTimeout);
}
Device::DeviceError DevicePluginSenic::discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params)
{
Q_UNUSED(params)
if (deviceClassId != nuimoDeviceClassId)
return Device::DeviceErrorDeviceClassNotFound;
if (!hardwareManager()->bluetoothLowEnergyManager()->available())
return Device::DeviceErrorHardwareNotAvailable;
if (!hardwareManager()->bluetoothLowEnergyManager()->enabled())
return Device::DeviceErrorHardwareNotAvailable;
BluetoothDiscoveryReply *reply = hardwareManager()->bluetoothLowEnergyManager()->discoverDevices();
connect(reply, &BluetoothDiscoveryReply::finished, this, &DevicePluginSenic::onBluetoothDiscoveryFinished);
return Device::DeviceErrorAsync;
}
Device::DeviceSetupStatus DevicePluginSenic::setupDevice(Device *device)
{
qCDebug(dcSenic()) << "Setup device" << device->name() << device->params();
QString name = device->paramValue(nuimoDeviceNameParamTypeId).toString();
QBluetoothAddress address = QBluetoothAddress(device->paramValue(nuimoDeviceMacParamTypeId).toString());
QBluetoothDeviceInfo deviceInfo = QBluetoothDeviceInfo(address, name, 0);
BluetoothLowEnergyDevice *bluetoothDevice = hardwareManager()->bluetoothLowEnergyManager()->registerDevice(deviceInfo, QLowEnergyController::RandomAddress);
Nuimo *nuimo = new Nuimo(device, bluetoothDevice, this);
connect(nuimo, &Nuimo::buttonPressed, this, &DevicePluginSenic::onButtonPressed);
connect(nuimo, &Nuimo::buttonReleased, this, &DevicePluginSenic::onButtonReleased);
connect(nuimo, &Nuimo::swipeDetected, this, &DevicePluginSenic::onSwipeDetected);
connect(nuimo, &Nuimo::rotationValueChanged, this, &DevicePluginSenic::onRotationValueChanged);
m_nuimos.insert(nuimo, device);
nuimo->bluetoothDevice()->connectDevice();
return Device::DeviceSetupStatusSuccess;
}
Device::DeviceError DevicePluginSenic::executeAction(Device *device, const Action &action)
{
QPointer<Nuimo> nuimo = m_nuimos.key(device);
if (nuimo.isNull())
return Device::DeviceErrorHardwareFailure;
if (!nuimo->bluetoothDevice()->connected()) {
return Device::DeviceErrorHardwareNotAvailable;
}
if (action.actionTypeId() == nuimoShowLogoActionTypeId) {
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Up")
nuimo->showImage(Nuimo::MatrixTypeUp);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Down")
nuimo->showImage(Nuimo::MatrixTypeDown);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Left")
nuimo->showImage(Nuimo::MatrixTypeLeft);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Right")
nuimo->showImage(Nuimo::MatrixTypeRight);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Play")
nuimo->showImage(Nuimo::MatrixTypePlay);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Pause")
nuimo->showImage(Nuimo::MatrixTypePause);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Stop")
nuimo->showImage(Nuimo::MatrixTypeStop);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Music")
nuimo->showImage(Nuimo::MatrixTypeStop);
if (action.param(nuimoShowLogoActionLogoParamTypeId).value().toString() == "Heart")
nuimo->showImage(Nuimo::MatrixTypeHeart);
return Device::DeviceErrorNoError;
}
return Device::DeviceErrorActionTypeNotFound;
}
void DevicePluginSenic::deviceRemoved(Device *device)
{
if (!m_nuimos.values().contains(device))
return;
Nuimo *nuimo = m_nuimos.key(device);
m_nuimos.take(nuimo);
delete nuimo;
}
bool DevicePluginSenic::verifyExistingDevices(const QBluetoothDeviceInfo &deviceInfo)
{
foreach (Device *device, myDevices()) {
if (device->paramValue(nuimoDeviceMacParamTypeId).toString() == deviceInfo.address().toString())
return true;
}
return false;
}
void DevicePluginSenic::onReconnectTimeout()
{
foreach (Nuimo *nuimo, m_nuimos.keys()) {
if (!nuimo->bluetoothDevice()->connected()) {
nuimo->bluetoothDevice()->connectDevice();
}
}
}
void DevicePluginSenic::onBluetoothDiscoveryFinished()
{
BluetoothDiscoveryReply *reply = static_cast<BluetoothDiscoveryReply *>(sender());
if (reply->error() != BluetoothDiscoveryReply::BluetoothDiscoveryReplyErrorNoError) {
qCWarning(dcSenic()) << "Bluetooth discovery error:" << reply->error();
reply->deleteLater();
emit devicesDiscovered(nuimoDeviceClassId, QList<DeviceDescriptor>());
return;
}
QList<DeviceDescriptor> deviceDescriptors;
foreach (const QBluetoothDeviceInfo &deviceInfo, reply->discoveredDevices()) {
if (deviceInfo.name().contains("Nuimo")) {
if (!verifyExistingDevices(deviceInfo)) {
DeviceDescriptor descriptor(nuimoDeviceClassId, "Nuimo", deviceInfo.address().toString());
ParamList params;
params.append(Param(nuimoDeviceNameParamTypeId, deviceInfo.name()));
params.append(Param(nuimoDeviceMacParamTypeId, deviceInfo.address().toString()));
descriptor.setParams(params);
deviceDescriptors.append(descriptor);
}
}
}
reply->deleteLater();
emit devicesDiscovered(nuimoDeviceClassId, deviceDescriptors);
}
void DevicePluginSenic::onButtonPressed()
{
Nuimo *nuimo = static_cast<Nuimo *>(sender());
Device *device = m_nuimos.value(nuimo);
emitEvent(Event(nuimoPressedEventTypeId, device->id(), ParamList() << Param(nuimoPressedEventButtonNameParamTypeId, "")));
}
void DevicePluginSenic::onButtonReleased()
{
// TODO: user timer for detekt long pressed (if needed)
}
void DevicePluginSenic::onSwipeDetected(const Nuimo::SwipeDirection &direction)
{
Nuimo *nuimo = static_cast<Nuimo *>(sender());
Device *device = m_nuimos.value(nuimo);
switch (direction) {
case Nuimo::SwipeDirectionLeft:
emitEvent(Event(nuimoPressedEventTypeId, device->id(), ParamList() << Param(nuimoPressedEventButtonNameParamTypeId, "")));
break;
case Nuimo::SwipeDirectionRight:
emitEvent(Event(nuimoPressedEventTypeId, device->id(), ParamList() << Param(nuimoPressedEventButtonNameParamTypeId, "")));
break;
case Nuimo::SwipeDirectionUp:
emitEvent(Event(nuimoPressedEventTypeId, device->id(), ParamList() << Param(nuimoPressedEventButtonNameParamTypeId, "")));
break;
case Nuimo::SwipeDirectionDown:
emitEvent(Event(nuimoPressedEventTypeId, device->id(), ParamList() << Param(nuimoPressedEventButtonNameParamTypeId, "")));
break;
}
}
void DevicePluginSenic::onRotationValueChanged(const uint &value)
{
Nuimo *nuimo = static_cast<Nuimo *>(sender());
Device *device = m_nuimos.value(nuimo);
device->setStateValue(nuimoRotationStateTypeId, value);
}