added initial unipi plug-in

This commit is contained in:
Bernhard Trinnes 2018-02-15 12:28:46 +01:00 committed by Michael Zanetti
parent 5afc972310
commit d223ca9caf
5 changed files with 695 additions and 0 deletions

View File

@ -36,11 +36,13 @@ PLUGIN_DIRS = \
tasmota \
tcpcommander \
udpcommander \
unipi \
unitec \
wakeonlan \
wemo \
ws2812 \
CONFIG+=all
message(============================================)

392
unipi/devicepluginunipi.cpp Normal file
View File

@ -0,0 +1,392 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2017 Bernhard Trinnes <bernhard.trinnes@guh.io> *
* *
* 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 "devicepluginunipi.h"
#include "plugininfo.h"
#include <QJsonDocument>
DevicePluginUniPi::DevicePluginUniPi()
{
}
void DevicePluginUniPi::init()
{
}
void DevicePluginUniPi::createAutoDevice(GPIOType gpioType, DeviceId parentDeviceId, QString deviceName)
{
ParamList params;
switch(gpioType){
case relay : {
QList<DeviceDescriptor> relayOutputDescriptors;
DeviceDescriptor descriptor(relayOutputDeviceClassId, "Relay Output", deviceName);
params.append(Param(relayOutputRelayNumberParamTypeId, deviceName));
params.append(Param(relayOutputParentIdParamTypeId, parentDeviceId));
descriptor.setParams(params);
relayOutputDescriptors.append(descriptor);
emit autoDevicesAppeared(relayOutputDeviceClassId, relayOutputDescriptors);
break;
}
case digitalOutput : {
QList<DeviceDescriptor> digitalOutputDescriptors;
DeviceDescriptor descriptor(digitalOutputDeviceClassId, "Digital Output", deviceName);
params.append(Param(digitalOutputDigitalOutputNumberParamTypeId, deviceName));
params.append(Param(digitalOutputParentIdParamTypeId, parentDeviceId));
descriptor.setParams(params);
digitalOutputDescriptors.append(descriptor);
emit autoDevicesAppeared(digitalOutputDeviceClassId, digitalOutputDescriptors);
break;
}
case digitalInput: {
QList<DeviceDescriptor> digitalInputDescriptors;
DeviceDescriptor descriptor(digitalInputDeviceClassId, "Digital Input", deviceName);
params.append(Param(digitalInputDigitalInputNumberParamTypeId, deviceName));
params.append(Param(digitalInputParentIdParamTypeId, parentDeviceId));
descriptor.setParams(params);
digitalInputDescriptors.append(descriptor);
emit autoDevicesAppeared(digitalInputDeviceClassId, digitalInputDescriptors);
break;
}
case analogOutput: {
QList<DeviceDescriptor> analogOutputDescriptors;
DeviceDescriptor descriptor(analogOutputDeviceClassId, "Analog Output", deviceName);
params.append(Param(analogOutputAnalogOutputNumberParamTypeId, deviceName));
params.append(Param(analogOutputParentIdParamTypeId, parentDeviceId));
descriptor.setParams(params);
analogOutputDescriptors.append(descriptor);
emit autoDevicesAppeared(analogOutputDeviceClassId, analogOutputDescriptors);
break;
}
case analogInput: {
QList<DeviceDescriptor> analogInputDescriptors;
DeviceDescriptor descriptor(analogInputDeviceClassId, "Analog Input", deviceName);
params.append(Param(analogInputAnalogInputNumberParamTypeId, deviceName));
params.append(Param(analogInputParentIdParamTypeId, parentDeviceId));
descriptor.setParams(params);
analogInputDescriptors.append(descriptor);
emit autoDevicesAppeared(analogInputDeviceClassId, analogInputDescriptors);
break;
}
default:
break;
}
}
DeviceManager::DeviceSetupStatus DevicePluginUniPi::setupDevice(Device *device)
{
if (device->deviceClassId() == neuronDeviceClassId) {
int port = device->paramValue(neuronPortParamTypeId).toInt();
m_webSocket = new QWebSocket();
connect(m_webSocket, &QWebSocket::connected, this, &DevicePluginUniPi::onWebSocketConnected);
connect(m_webSocket, &QWebSocket::disconnected, this, &DevicePluginUniPi::onWebSocketDisconnected);
QUrl url = QUrl("ws://localhost/ws");
url.setPort(port);
qDebug(dcUniPi()) << "Conneting to:" << url.toString();
m_webSocket->open(url);
m_parentId = device->id();
return DeviceManager::DeviceSetupStatusSuccess;
}
if (device->deviceClassId() == relayOutputDeviceClassId) {
device->setName(QString("Relay Ouput %1").arg(device->paramValue(relayOutputRelayNumberParamTypeId).toString()));
device->setParentId(device->paramValue(relayOutputParentIdParamTypeId).toString());
return DeviceManager::DeviceSetupStatusSuccess;
}
if (device->deviceClassId() == digitalOutputDeviceClassId) {
device->setName(QString("Digital Output %1").arg(device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()));
device->setParentId(device->paramValue(digitalOutputParentIdParamTypeId).toString());
return DeviceManager::DeviceSetupStatusSuccess;
}
if (device->deviceClassId() == digitalInputDeviceClassId) {
device->setName(QString("Digital Input %1").arg(device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString()));
device->setParentId(device->paramValue(digitalInputParentIdParamTypeId).toString());
return DeviceManager::DeviceSetupStatusSuccess;
}
if (device->deviceClassId() == analogInputDeviceClassId) {
device->setName(QString("Analog Input %1").arg(device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()));
device->setParentId(device->paramValue(analogInputParentIdParamTypeId).toString());
return DeviceManager::DeviceSetupStatusSuccess;
}
if (device->deviceClassId() == analogOutputDeviceClassId) {
device->setName(QString("Analog Output %1").arg(device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()));
device->setParentId(device->paramValue(analogOutputParentIdParamTypeId).toString());
return DeviceManager::DeviceSetupStatusSuccess;
}
return DeviceManager::DeviceSetupStatusFailure;
}
void DevicePluginUniPi::postSetupDevice(Device *device)
{
Q_UNUSED(device);
}
DeviceManager::DeviceError DevicePluginUniPi::executeAction(Device *device, const Action &action)
{
if (device->deviceClassId() == relayOutputDeviceClassId) {
if (action.actionTypeId() == relayOutputRelayStatusActionTypeId) {
QString relayNumber = device->paramValue(relayOutputRelayNumberParamTypeId).toString();
int stateValue = action.param(relayOutputRelayStatusStateParamTypeId).value().toInt();
QJsonObject json;
json["cmd"] = "set";
json["dev"] = "relay";
json["circuit"] = relayNumber;
json["value"] = stateValue;
QJsonDocument doc(json);
QByteArray bytes = doc.toJson(QJsonDocument::Compact);
qDebug(dcUniPi()) << "Send command" << bytes;
m_webSocket->sendBinaryMessage(bytes);
return DeviceManager::DeviceErrorNoError;
}
return DeviceManager::DeviceErrorActionTypeNotFound;
}
if (device->deviceClassId() == digitalOutputDeviceClassId) {
if (action.actionTypeId() == digitalOutputDigitalOutputStatusActionTypeId) {
int digitalOutputNumber = device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toInt();
int stateValue = action.param(digitalOutputDigitalOutputStatusStateParamTypeId).value().toInt();
QJsonObject json;
json["cmd"] = "set";
json["dev"] = "do";
json["circuit"] = digitalOutputNumber;
json["value"] = stateValue;
QJsonDocument doc(json);
QByteArray bytes = doc.toJson();
m_webSocket->sendTextMessage(bytes);
return DeviceManager::DeviceErrorNoError;
}
return DeviceManager::DeviceErrorActionTypeNotFound;
}
if (device->deviceClassId() == analogOutputDeviceClassId) {
if (action.actionTypeId() == analogOutputAnalogOutputValueActionTypeId) {
int analogOutputNumber = device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toInt();
double analogValue = device->paramValue(analogOutputAnalogOutputValueStateParamTypeId).toDouble();
QJsonObject json;
json["cmd"] = "set";
json["dev"] = "ao";
json["circuit"] = analogOutputNumber;
json["value"] = analogValue;
QJsonDocument doc(json);
QByteArray bytes = doc.toJson();
m_webSocket->sendTextMessage(bytes);
return DeviceManager::DeviceErrorNoError;
}
return DeviceManager::DeviceErrorActionTypeNotFound;
}
return DeviceManager::DeviceErrorDeviceClassNotFound;
}
void DevicePluginUniPi::deviceRemoved(Device *device)
{
Q_UNUSED(device);
m_webSocket->close();
m_webSocket->deleteLater();
}
void DevicePluginUniPi::onWebSocketConnected()
{
qDebug(dcUniPi()) << "WebSocket connected";
connect(m_webSocket, &QWebSocket::textMessageReceived,
this, &DevicePluginUniPi::onWebSocketTextMessageReceived);
QJsonObject json;
json["cmd"] = "all";
QJsonDocument doc(json);
QByteArray bytes = doc.toJson();
m_webSocket->sendTextMessage(bytes);
}
void DevicePluginUniPi::onWebSocketDisconnected()
{
qDebug(dcUniPi()) << "WebSocket disconnected";
//send signal device Setup was successfull
}
void DevicePluginUniPi::onWebSocketTextMessageReceived(QString message)
{
QJsonArray array;
QJsonObject obj;
QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8());
// check validity of the document
if(!doc.isNull()) {
if(doc.isObject()) {
obj = doc.object();
} else if (doc.isArray()){
array = doc.array();
}else {
qDebug(dcUniPi()) << "Document is not an object nor an array";
}
} else {
qDebug(dcUniPi()) << "Invalid JSON";
}
for (int levelIndex = 0; levelIndex < array.size(); ++levelIndex) {
obj = array[levelIndex].toObject();
if (obj["cmd"] == "all") {
//read model number
qDebug(dcUniPi()) << message;
}
if (obj["dev"] == "relay") {
qDebug(dcUniPi()) << "Relay:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt();
bool newDevice = true;
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == relayOutputDeviceClassId) {
if (obj["circuit"] == device->paramValue(relayOutputRelayNumberParamTypeId).toString()) {
device->setStateValue(relayOutputRelayStatusStateTypeId, QVariant(obj["value"].toInt()).toBool());
newDevice = false;
break;
}
}
}
if (newDevice) {
qDebug(dcUniPi()) << "New Device detected";
createAutoDevice(GPIOType::relay, m_parentId, obj["circuit"].toString());
}
}
if (obj["dev"] == "input") {
qDebug(dcUniPi()) << "Input:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt();
bool newDevice = true;
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == digitalInputDeviceClassId) {
if (obj["circuit"] == device->paramValue(digitalInputDigitalInputNumberParamTypeId).toString()) {
device->setStateValue(digitalInputDigitalInputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool());
newDevice = false;
break;
}
}
}
if (newDevice){
//New Device detected
createAutoDevice(GPIOType::digitalInput, m_parentId, obj["circuit"].toString());
}
}
if (obj["dev"] == "output") {
qDebug(dcUniPi()) << "Output:" << obj["dev"].toString() << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toInt();
bool newDevice = true;
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == digitalOutputDeviceClassId) {
if (obj["circuit"] == device->paramValue(digitalOutputDigitalOutputNumberParamTypeId).toString()) {
device->setStateValue(digitalOutputDigitalOutputStatusStateTypeId, QVariant(obj["value"].toInt()).toBool());
newDevice = false;
break;
}
}
}
if (newDevice){
//New Device detected
createAutoDevice(GPIOType::digitalOutput, m_parentId, obj["circuit"].toString());
}
}
if (obj["dev"] == "ao") {
qDebug(dcUniPi()) << "Analog Output:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble();
bool newDevice = true;
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == analogOutputDeviceClassId) {
if (obj["circuit"] == device->paramValue(analogOutputAnalogOutputNumberParamTypeId).toString()) {
device->setStateValue(analogOutputAnalogOutputValueStateTypeId, obj["value"].toDouble());
newDevice = false;
break;
}
}
}
if (newDevice){
//New Device detected
createAutoDevice(GPIOType::analogOutput, m_parentId, obj["circuit"].toString());
}
}
if (obj["dev"] == "ai") {
qDebug(dcUniPi()) << "Analog Input:" << obj["dev"] << "Circuit:" << obj["circuit"].toString() << "Value:" << obj["value"].toDouble();
bool newDevice = true;
foreach (Device *device, myDevices()) {
if (device->deviceClassId() == analogInputDeviceClassId) {
if (obj["circuit"] == device->paramValue(analogInputAnalogInputNumberParamTypeId).toString()) {
device->setStateValue(analogInputAnalogInputValueStateTypeId, obj["value"].toDouble());
newDevice = false;
break;
}
}
}
if (newDevice){
//New Device detected
createAutoDevice(GPIOType::analogInput, m_parentId, obj["circuit"].toString());
}
}
}
}

66
unipi/devicepluginunipi.h Normal file
View File

@ -0,0 +1,66 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2017 Bernhard Trinnes <bernhard.trinnes@guh.io> *
* *
* 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 DEVICEPLUGINUNIPI_H
#define DEVICEPLUGINUNIPI_H
#include "plugin/deviceplugin.h"
#include "devicemanager.h"
#include <QtWebSockets/QtWebSockets>
class DevicePluginUniPi : public DevicePlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "devicepluginunipi.json")
Q_INTERFACES(DevicePlugin)
public:
explicit DevicePluginUniPi();
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void postSetupDevice(Device *device) override;
void deviceRemoved(Device *device) override;
void init() override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private:
enum GPIOType {
relay,
digitalInput,
digitalOutput,
analogInput,
analogOutput
};
DeviceId m_parentId;
QWebSocket *m_webSocket;
void createAutoDevice(GPIOType gpioType, DeviceId parentDeviceId, QString deviceName);
private slots:
void onWebSocketConnected();
void onWebSocketDisconnected();
void onWebSocketTextMessageReceived(QString message);
};
#endif // DEVICEPLUGINUNIPI_H

View File

@ -0,0 +1,224 @@
{
"displayName": "uni pi",
"name": "UniPi",
"id": "26cba644-35ae-40a6-9c48-924198893a5f",
"vendors": [
{
"displayName": "UniPi",
"name": "unipi",
"id": "c82bfe27-d14d-40bd-b12f-ddba214b5fc5",
"deviceClasses": [
{
"id": "f1663756-657d-4dbd-9568-e2edf513589f",
"name": "neuron",
"displayName": "Neuron",
"deviceIcon": "Gateway",
"createMethods": ["user"],
"interface": [],
"basicTags": [
"Device",
"Gateway"
],
"paramTypes": [
{
"id": "5329655d-7e91-4b16-9abf-2abc82bf1b3c",
"name": "port",
"displayName": "port",
"type": "int",
"defaultValue": "8080"
}
],
"actionTypes": [
],
"stateTypes": [
]
},
{
"id": "58f9db7f-fd33-45af-8c98-047b67ae5267",
"name": "relayOutput",
"displayName": "Relay Output",
"deviceIcon": "Power",
"createMethods": ["auto"],
"interface": [],
"basicTags": [
"Device"
],
"paramTypes": [
{
"id": "7a09e3ad-452c-4bf4-a00c-f8114ed9a7a1",
"name": "relayNumber",
"displayName": "relay number",
"type": "QString"
},
{
"id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c",
"name": "parentId",
"displayName": "parent ID",
"type": "QString"
}
],
"stateTypes": [
{
"id": "f9c01e7b-0523-4cac-905a-d5b20028e021",
"name": "relayStatus",
"displayName": "relay",
"type": "bool",
"displayNameAction": "set relay",
"displayNameEvent": "relay changed",
"defaultValue": false,
"writable": true
}
]
},
{
"id": "0bec278a-98f1-416b-b496-6d00740f178a",
"name": "digitalInput",
"displayName": "digital input",
"deviceIcon": "Switch",
"createMethods": ["auto"],
"interface": [],
"basicTags": [
"Sensor"
],
"paramTypes": [
{
"id": "9c84d9b8-fdc7-41c1-9559-08f061ffc7a6",
"name": "digitalInputNumber",
"displayName": "input number",
"type": "int"
},
{
"id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c",
"name": "parentId",
"displayName": "parent ID",
"type": "QString"
}
],
"stateTypes": [
{
"id": "fa4f2764-b7ff-45e7-993b-b6af1840fd3d",
"name": "digitalInputStatus",
"displayName": "input",
"type": "bool",
"defaultValue": false,
"displayNameEvent": "input changed"
}
]
},
{
"id": "f3a3c5ed-461a-4ca8-930b-df3af821b9e0",
"name": "digitalOutput",
"displayName": "digital output",
"deviceIcon": "Power",
"createMethods": ["auto"],
"interface": [],
"basicTags": [
"Device"
],
"paramTypes": [
{
"id": "c01d5bde-de5d-42c5-b462-79745827875a",
"name": "digitalOutputNumber",
"displayName": "input number",
"type": "QString"
},
{
"id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c",
"name": "parentId",
"displayName": "parent ID",
"type": "QString"
}
],
"stateTypes": [
{
"id": "470a0e30-a170-47ed-9ed3-c41db919555f",
"name": "digitalOutputStatus",
"displayName": "digital output",
"type": "bool",
"displayNameAction": "set digital output",
"displayNameEvent": "digital output changed",
"defaultValue": false,
"writable": true
}
]
},
{
"id": "9094a69f-f475-4050-a345-5ab52cb19774",
"name": "analogOutput",
"displayName": "Analog Output",
"deviceIcon": "Power",
"createMethods": ["auto"],
"interface": [],
"basicTags": [
"Device"
],
"paramTypes": [
{
"id": "46e606cc-67ee-4891-bc39-8fb0565c87da",
"name": "analogOutputNumber",
"displayName": "analog output number",
"type": "QString"
},
{
"id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c",
"name": "parentId",
"displayName": "parent ID",
"type": "QString"
}
],
"stateTypes": [
{
"id": "6d825eb8-6d2a-4ac3-9125-9df8173116c9",
"name": "analogOutputValue",
"displayName": "analog output",
"type": "double",
"unit": "Volt",
"displayNameAction": "set analog output",
"displayNameEvent": "analog output changed",
"minValue": 0.00,
"maxValue": 10.00,
"defaultValue": 0.00,
"writable": true
}
]
},
{
"id": "06abd6a4-e655-4243-bc9c-9bd4ef5be2e6",
"name": "analogInput",
"displayName": "Analog Input",
"deviceIcon": "Power",
"createMethods": ["auto"],
"interface": [],
"basicTags": [
"Sensor"
],
"paramTypes": [
{
"id": "cc6eb664-9fd2-457d-9d0d-0eb9703db4a2",
"name": "analogInputNumber",
"displayName": "analog input number",
"type": "QString"
},
{
"id": "ebbf4c9c-25a9-45c1-be72-cc01aaea959c",
"name": "parentId",
"displayName": "parent ID",
"type": "QString"
}
],
"stateTypes": [
{
"id": "2296f575-cc53-48ef-9086-6a412abfdde5",
"name": "analogInputValue",
"displayName": "analog output",
"type": "double",
"unit": "Volt",
"displayNameEvent": "analog input changed",
"defaultValue": 0.00
}
]
}
]
}
]
}

11
unipi/unipi.pro Normal file
View File

@ -0,0 +1,11 @@
include(../plugins.pri)
TARGET = $$qtLibraryTarget(guh_devicepluginunipi)
SOURCES += \
devicepluginunipi.cpp \
HEADERS += \
devicepluginunipi.h \