diff --git a/debian/guh-plugins.install b/debian/guh-plugins.install index 58f93046..e321b7ee 100644 --- a/debian/guh-plugins.install +++ b/debian/guh-plugins.install @@ -14,3 +14,5 @@ usr/lib/guh/plugins/libguh_deviceplugindatetime.so usr/lib/guh/plugins/libguh_deviceplugingenericelements.so usr/lib/guh/plugins/libguh_deviceplugincommandlauncher.so usr/lib/guh/plugins/libguh_devicepluginunitec.so +usr/lib/guh/plugins/libguh_devicepluginleynew.so +usr/lib/guh/plugins/libguh_deviceplugintune.so diff --git a/plugins/deviceplugins/deviceplugins.pro b/plugins/deviceplugins/deviceplugins.pro index 4b9f4b19..94dae701 100644 --- a/plugins/deviceplugins/deviceplugins.pro +++ b/plugins/deviceplugins/deviceplugins.pro @@ -14,6 +14,8 @@ SUBDIRS += elro \ genericelements \ commandlauncher \ unitec \ + leynew \ + tune \ diff --git a/plugins/deviceplugins/tune/deviceplugintune.cpp b/plugins/deviceplugins/tune/deviceplugintune.cpp new file mode 100644 index 00000000..5f91ebc8 --- /dev/null +++ b/plugins/deviceplugins/tune/deviceplugintune.cpp @@ -0,0 +1,165 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * 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 . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include +#include +#include + +#include "deviceplugintune.h" +#include "devicemanager.h" +#include "plugininfo.h" + +DevicePluginTune::DevicePluginTune() +{ + m_manager = new TuneManager(31337, this); + + connect(m_manager, &TuneManager::tuneConnectionStatusChanged, this, &DevicePluginTune::tuneConnectionStatusChanged); + connect(m_manager, &TuneManager::dataReady, this, &DevicePluginTune::tuneDataAvailable); + + m_manager->start(); +} + +DeviceManager::HardwareResources DevicePluginTune::requiredHardware() const +{ + return DeviceManager::HardwareResourceNone; +} + +DeviceManager::DeviceSetupStatus DevicePluginTune::setupDevice(Device *device) +{ + if (!m_manager->tuneAvailable()) { + qWarning() << "WARNING: tune not connected!"; + } + + // check index position + int position = device->paramValue("position").toInt(); + if (position >= myDevices().count()) { + device->setParamValue("position", myDevices().count()); + } else { + foreach (Device *d, myDevices()) { + int currentPosition = d->paramValue("position").toInt(); + if (currentPosition >= position) { + d->setParamValue("position", currentPosition + 1); + } + } + } + + // mood + if (device->deviceClassId() == moodDeviceClassId) { + device->setName(device->paramValue("name").toString() + " (Mood)"); + return DeviceManager::DeviceSetupStatusSuccess; + } + + // todo + if (device->deviceClassId() == todoDeviceClassId) { + device->setName(device->paramValue("name").toString() + " (Todo)"); + return DeviceManager::DeviceSetupStatusSuccess; + } + + return DeviceManager::DeviceSetupStatusFailure; +} + +void DevicePluginTune::deviceRemoved(Device *device) +{ + int position = device->paramValue("position").toInt(); + + foreach (Device *d, myDevices()) { + int currentPosition = d->paramValue("position").toInt(); + if (currentPosition >= position ) { + d->setParamValue("position", currentPosition - 1); + } + } + sync(); +} + +bool DevicePluginTune::sync() +{ + // sync with devices with tune + if (!m_manager->tuneAvailable()) { + return false; + } + + QVariantMap message; + QVariantList devices; + foreach (Device* device, myDevices()) { + qDebug() << "device id" << device->id(); + QVariantMap d; + d.insert("name", device->paramValue("name")); + d.insert("id", device->id()); + d.insert("deviceClassId", device->deviceClassId()); + d.insert("pos", device->paramValue("position")); + d.insert("icon", device->paramValue("icon")); + devices.append(d); + } + message.insert("devices", devices); + + QJsonDocument jsonDoc = QJsonDocument::fromVariant(message); + QByteArray data = jsonDoc.toJson(QJsonDocument::Compact); + + qDebug() << data; + + m_manager->sendData(data); + + return true; +} + +void DevicePluginTune::tuneConnectionStatusChanged(const bool &connected) +{ + if (connected) { + sync(); + } +} + +void DevicePluginTune::tuneDataAvailable(const QByteArray &data) +{ + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error); + + if(error.error != QJsonParseError::NoError) { + qDebug() << "failed to parse data" << data << ":" << error.errorString(); + } + qDebug() << jsonDoc.toJson(); + +} + +DeviceManager::DeviceError DevicePluginTune::executeAction(Device *device, const Action &action) +{ + if (!m_manager->tuneAvailable()) { + return DeviceManager::DeviceErrorHardwareNotAvailable; + } + + // Mood + if (device->deviceClassId() == moodDeviceClassId) { + if (action.actionTypeId() == toggleActionTypeId) { + bool currentState = device->stateValue(activeStateTypeId).toBool(); + device->setStateValue(activeStateTypeId, !currentState); + return DeviceManager::DeviceErrorNoError; + } + return DeviceManager::DeviceErrorActionTypeNotFound; + } + + // Todo + if (device->deviceClassId() == todoDeviceClassId) { + if (action.actionTypeId() == pressActionTypeId) { + emit emitEvent(Event(pressedEventTypeId, device->id())); + return DeviceManager::DeviceErrorNoError; + } + } + + return DeviceManager::DeviceErrorDeviceClassNotFound; +} + diff --git a/plugins/deviceplugins/tune/deviceplugintune.h b/plugins/deviceplugins/tune/deviceplugintune.h new file mode 100644 index 00000000..708fc056 --- /dev/null +++ b/plugins/deviceplugins/tune/deviceplugintune.h @@ -0,0 +1,52 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * 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 . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef DEVICEPLUGINTUNE_H +#define DEVICEPLUGINTUNE_H + +#include "plugin/deviceplugin.h" +#include "tunemanager.h" + +class DevicePluginTune : public DevicePlugin +{ + Q_OBJECT + + Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "deviceplugintune.json") + Q_INTERFACES(DevicePlugin) + +public: + explicit DevicePluginTune(); + + DeviceManager::HardwareResources requiredHardware() const override; + DeviceManager::DeviceSetupStatus setupDevice(Device *device) override; + void deviceRemoved(Device *device) override; + +private: + TuneManager *m_manager; + bool sync(); + +private slots: + void tuneConnectionStatusChanged(const bool &connected); + void tuneDataAvailable(const QByteArray &data); + +public slots: + DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; + +}; + +#endif // DEVICEPLUGINTUNE_H diff --git a/plugins/deviceplugins/tune/deviceplugintune.json b/plugins/deviceplugins/tune/deviceplugintune.json new file mode 100644 index 00000000..11966d17 --- /dev/null +++ b/plugins/deviceplugins/tune/deviceplugintune.json @@ -0,0 +1,142 @@ +{ + "name": "Tune", + "id": "826c8f4a-e2e1-4891-84d4-2c7a46ab1eea", + "vendors": [ + { + "name": "Tune", + "id": "9ba2d9dc-b975-46bb-9e83-dbbd03ccab6c", + "deviceClasses": [ + { + "deviceClassId": "a5bd9e14-c169-416b-9b60-9453b1403a97", + "idName": "mood", + "name": "Mood", + "createMethods": ["user"], + "paramTypes": [ + { + "name": "name", + "type": "QString", + "inputType": "TextLine" + }, + { + "name": "position", + "type": "int" + }, + { + "name": "icon", + "type": "QString", + "allowedValues": [ + "IconCouch", + "IconWork", + "IconToilet", + "IconSex", + "IconDrinking", + "IconEating", + "IconSmoking" + ] + } + ], + "stateTypes": [ + { + "id": "535ed312-16de-47f2-bf3a-5661f7b86a42", + "idName": "active", + "name": "active", + "type": "bool", + "defaultValue": false + }, + { + "id": "cb8a89c2-dc12-4965-b047-57896058b421", + "idName": "value", + "name": "value", + "type": "uint", + "defaultValue": 50 + } + ], + "actionTypes": [ + { + "id": "768b6a17-731b-4976-bc9e-15c04eff7df3", + "idName": "toggle", + "name": "toggle" + }, + { + "id": "fe942f70-b8fb-413b-8feb-2dd924b9f649", + "idName": "setValue", + "name": "set value", + "paramTypes": [ + { + "name": "percentage", + "type": "uint", + "minimumValue": 0, + "maximumValue": 100 + } + ] + } + ] + }, + { + "deviceClassId": "56c14ef8-3a19-432f-9d9f-dc7e1d489312", + "idName": "todo", + "name": "ToDo", + "createMethods": ["user"], + "paramTypes": [ + { + "name": "name", + "type": "QString", + "inputType": "TextLine" + }, + { + "name": "position", + "type": "int" + }, + { + "name": "icon", + "type": "QString", + "allowedValues": [ + "IconCouch", + "IconWork", + "IconToilet", + "IconSex", + "IconDrinking", + "IconEating", + "IconSmoking" + ] + } + ], + "eventTypes": [ + { + "id": "52b66edc-df40-42ef-a39c-aa2b77fdf42e", + "idName": "pressed", + "name": "pressed" + }, + { + "id": "277f10fd-3fc3-4229-904a-661b6f1cac54", + "idName": "todoLeft", + "name": "left" + }, + { + "id": "a510968e-f313-4880-95bd-786bd3bcb357", + "idName": "todoRight", + "name": "right" + } + ], + "actionTypes": [ + { + "id": "1a2dac4d-26b3-496f-a4c2-8cb90c75e026", + "idName": "press", + "name": "press" + }, + { + "id": "0c461c5a-1334-4559-816b-73b5b2afb3ba", + "idName": "tickLeft", + "name": "tick left" + }, + { + "id": "a67cda4a-2c6f-4815-818a-08094dfcc453", + "idName": "tickRight", + "name": "tick right" + } + ] + } + ] + } + ] +} diff --git a/plugins/deviceplugins/tune/tune.pro b/plugins/deviceplugins/tune/tune.pro new file mode 100644 index 00000000..5e11d9a5 --- /dev/null +++ b/plugins/deviceplugins/tune/tune.pro @@ -0,0 +1,13 @@ +include(../../plugins.pri) + +TARGET = $$qtLibraryTarget(guh_deviceplugintune) + +SOURCES += \ + deviceplugintune.cpp \ + tunemanager.cpp + +HEADERS += \ + deviceplugintune.h \ + tunemanager.h + + diff --git a/plugins/deviceplugins/tune/tunemanager.cpp b/plugins/deviceplugins/tune/tunemanager.cpp new file mode 100644 index 00000000..e65a2a32 --- /dev/null +++ b/plugins/deviceplugins/tune/tunemanager.cpp @@ -0,0 +1,117 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * 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 . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "tunemanager.h" + +TuneManager::TuneManager(int port, QObject *parent) : + QObject(parent), + m_server(0), + m_tune(0), + m_port(port), + m_connected(false) +{ +} + +bool TuneManager::tuneAvailable() +{ + return m_connected; +} + +bool TuneManager::sendData(const QByteArray &data) +{ + if (m_connected) { + m_tune->write(data + '\n'); + return true; + } + return false; +} + +void TuneManager::tuneConnected() +{ + + + QTcpSocket *socket = m_server->nextPendingConnection(); + + if (m_tune) { + qWarning() << "--> ATTENTION: tune allready connected! connection refused."; + socket->disconnect(); + delete socket; + return; + } + + m_tune = socket; + + connect(m_tune, &QTcpSocket::readyRead, this, &TuneManager::readData); + connect(m_tune, &QTcpSocket::disconnected, this, &TuneManager::tuneDisconnected); + + qDebug() << " --> tune connected:" << m_tune->peerAddress().toString() << m_port; + m_connected = true; + emit tuneConnectionStatusChanged(true); +} + +void TuneManager::tuneDisconnected() +{ + qWarning() << " --> tune disconnected:" << m_tune->peerAddress().toString(); + m_connected = false; + emit tuneConnectionStatusChanged(false); + delete m_tune; + m_tune = 0; +} + +void TuneManager::readData() +{ + QByteArray message; + while (m_tune->canReadLine()) { + QByteArray dataLine = m_tune->readLine(); + qDebug() << " --> tune line in:" << dataLine; + message.append(dataLine); + if (dataLine.endsWith('\n')) { + emit dataReady(message); + message.clear(); + } + } +} + +bool TuneManager::start() +{ + if(!m_server) { + m_server = new QTcpServer(this); + } + + m_server->setMaxPendingConnections(1); + + QHostAddress localhost = QHostAddress(QHostAddress::LocalHost); + if(!m_server->listen(localhost, m_port)) { + qWarning() << "ERROR: Tune server can not listen on" << localhost << m_port; + delete m_server; + return false; + } + qDebug() << " --> Tune server started" << localhost << m_port; + connect(m_server, &QTcpServer::newConnection, this, &TuneManager::tuneConnected); + return true; +} + +void TuneManager::stop() +{ + qDebug() << " --> close Tune server" << m_server->serverAddress().toString(); + m_server->close(); + delete m_server; + m_server = 0; + m_connected = false; + emit tuneConnectionStatusChanged(false); +} diff --git a/plugins/deviceplugins/tune/tunemanager.h b/plugins/deviceplugins/tune/tunemanager.h new file mode 100644 index 00000000..f462984c --- /dev/null +++ b/plugins/deviceplugins/tune/tunemanager.h @@ -0,0 +1,59 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * 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 . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef TUNEMANAGER_H +#define TUNEMANAGER_H + +#include +#include +#include +#include +#include +#include + +class TuneManager : public QObject +{ + Q_OBJECT +public: + explicit TuneManager(int port = 31337, QObject *parent = 0); + + bool tuneAvailable(); + bool sendData(const QByteArray &data); + +private: + QTcpServer *m_server; + QTcpSocket *m_tune; + + int m_port; + int m_connected; + +signals: + void dataReady(const QByteArray &data); + void tuneConnectionStatusChanged(const bool &connectionStatus); + +private slots: + void tuneConnected(); + void tuneDisconnected(); + void readData(); + +public slots: + bool start(); + void stop(); +}; + +#endif // TUNEMANAGER_H