New Plugin: ANEL Elektronik NET-PwrCtrl
parent
b42740de52
commit
6640316cf3
|
|
@ -0,0 +1,13 @@
|
|||
include(../plugins.pri)
|
||||
|
||||
QT += network
|
||||
|
||||
TARGET = $$qtLibraryTarget(nymea_devicepluginanel)
|
||||
|
||||
SOURCES += \
|
||||
devicepluginanel.cpp \
|
||||
anelpanel.cpp
|
||||
|
||||
HEADERS += \
|
||||
devicepluginanel.h \
|
||||
anelpanel.h
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#include "anelpanel.h"
|
||||
|
||||
AnelPanel::AnelPanel(const QHostAddress &hostAddress, QObject *parent) : QObject(parent)
|
||||
{
|
||||
Q_UNUSED(hostAddress)
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef ANELPANEL_H
|
||||
#define ANELPANEL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
#include <QUdpSocket>
|
||||
|
||||
class AnelPanel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AnelPanel(const QHostAddress &hostAddress, QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
// QUdpSocket *m_receiveSocket = nullptr;
|
||||
// QUdpSocket *m_
|
||||
};
|
||||
|
||||
#endif // ANELPANEL_H
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2018 Michael Zanetti <michael.zanetti@nymea.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/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*!
|
||||
\page tasmota.html
|
||||
\title ANEL Elektronik devices
|
||||
\brief Plugin for ANEL Elektronik NET-PwrCtrl network controlled power sockets.
|
||||
|
||||
\ingroup plugins
|
||||
\ingroup nymea-plugins-maker
|
||||
|
||||
This plugin allows to make use of ANEL Elektronik NET-PwrCtrl controlled powet sockets.
|
||||
|
||||
See https://anel-elektronik.de/ for a detailed description of the devices.
|
||||
|
||||
\chapter Plugin properties
|
||||
When adding a device it will detect the type of the panel and create a gateway device and a powersocket
|
||||
device for each of the available sockets on the panel.
|
||||
|
||||
\quotefile plugins/deviceplugins/tasmota/devicepluginanel.json
|
||||
*/
|
||||
|
||||
#include "devicepluginanel.h"
|
||||
#include "plugininfo.h"
|
||||
#include "plugintimer.h"
|
||||
|
||||
#include <QNetworkDatagram>
|
||||
#include <network/networkaccessmanager.h>
|
||||
#include <QNetworkReply>
|
||||
#include <QAuthenticator>
|
||||
|
||||
DevicePluginAnel::DevicePluginAnel()
|
||||
{
|
||||
m_connectedStateTypeIdMap.insert(netPwrCtlDeviceClassId, netPwrCtlConnectedStateTypeId);
|
||||
m_connectedStateTypeIdMap.insert(socketDeviceClassId, socketConnectedStateTypeId);
|
||||
|
||||
m_nam = new QNetworkAccessManager(this);
|
||||
connect(m_nam, &QNetworkAccessManager::authenticationRequired, this, [](QNetworkReply* reply, QAuthenticator *authenticator){
|
||||
qCDebug(dcAnelElektronik()) << "Auth required";
|
||||
Q_UNUSED(reply)
|
||||
authenticator->setUser("admin");
|
||||
authenticator->setPassword("anel");
|
||||
});
|
||||
}
|
||||
|
||||
DevicePluginAnel::~DevicePluginAnel()
|
||||
{
|
||||
}
|
||||
|
||||
void DevicePluginAnel::init()
|
||||
{
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError DevicePluginAnel::discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms)
|
||||
{
|
||||
Q_UNUSED(deviceClassId)
|
||||
Q_UNUSED(params)
|
||||
|
||||
QUdpSocket *searchSocket = new QUdpSocket(this);
|
||||
|
||||
// Note: This will fail, and it's not a problem, but it is required to force the socket to stick to IPv4...
|
||||
searchSocket->bind(QHostAddress::AnyIPv4, 30303);
|
||||
|
||||
QString discoveryString = "Durchsuchen: Wer ist da?";
|
||||
qint64 len = searchSocket->writeDatagram(discoveryString.toUtf8(), QHostAddress("255.255.255.255"), 30303);
|
||||
if (len != discoveryString.length()) {
|
||||
searchSocket->deleteLater();
|
||||
qCWarning(dcAnelElektronik()) << "Error sending discovery";
|
||||
return DeviceManager::DeviceErrorHardwareFailure;
|
||||
}
|
||||
|
||||
QTimer::singleShot(2000, this, [this, searchSocket](){
|
||||
QList<DeviceDescriptor> descriptorList;
|
||||
while(searchSocket->hasPendingDatagrams()) {
|
||||
QNetworkDatagram datagram = searchSocket->receiveDatagram();
|
||||
qCDebug(dcAnelElektronik()) << "Have datagram:" << datagram.data();
|
||||
if (!datagram.data().startsWith("NET-CONTROL")) {
|
||||
qCDebug(dcAnelElektronik()) << "Failed to parse discovery datagram from" << datagram.senderAddress() << datagram.data();
|
||||
continue;
|
||||
}
|
||||
QStringList parts = QString(datagram.data()).split("\r\n");
|
||||
if (parts.count() != 4) {
|
||||
qCDebug(dcAnelElektronik()) << "Failed to parse discovery datagram from" << datagram.senderAddress() << datagram.data();
|
||||
continue;
|
||||
}
|
||||
qCDebug(dcAnelElektronik()) << "Found NET-CONTROL:" << datagram.senderAddress() << parts.at(2) << parts.at(3) << datagram.senderAddress().protocol();
|
||||
DeviceDescriptor d(netPwrCtlDeviceClassId, parts.at(2), datagram.senderAddress().toString());
|
||||
ParamList params;
|
||||
params << Param(netPwrCtlDeviceIpAddressParamTypeId, datagram.senderAddress().toString());
|
||||
params << Param(netPwrCtlDevicePortParamTypeId, parts.at(3).toInt());
|
||||
d.setParams(params);
|
||||
descriptorList << d;
|
||||
}
|
||||
emit devicesDiscovered(netPwrCtlDeviceClassId, descriptorList);
|
||||
searchSocket->deleteLater();
|
||||
});
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
}
|
||||
|
||||
DeviceManager::DeviceSetupStatus DevicePluginAnel::setupDevice(Device *device)
|
||||
{
|
||||
if (device->deviceClassId() == netPwrCtlDeviceClassId) {
|
||||
// int sendPort = device->paramValue(netPwrCtlHomeDeviceSendPortParamTypeId).toInt();
|
||||
// int receivePort = device->paramValue(netPwrCtlHomeDeviceReceivePortParamTypeId).toInt();
|
||||
|
||||
|
||||
QNetworkRequest request;
|
||||
request.setUrl(QUrl("http://" + device->paramValue(netPwrCtlDeviceIpAddressParamTypeId).toString() + ":" + device->paramValue(netPwrCtlDevicePortParamTypeId).toString() + "/strg.cfg"));
|
||||
QNetworkReply *reply = m_nam->get(request);
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
connect(reply, &QNetworkReply::finished, device, [this, device, reply](){
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcAnelElektronik()) << "Error fetching state for" << device->name();
|
||||
device->setStateValue(netPwrCtlConnectedStateTypeId, false);
|
||||
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
|
||||
return;
|
||||
}
|
||||
device->setStateValue(netPwrCtlConnectedStateTypeId, true);
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
|
||||
QStringList parts = QString(data).split(';');
|
||||
|
||||
int startIndex = parts.indexOf("end") - 58;
|
||||
if (startIndex < 0 || !parts.at(startIndex + 1).startsWith("NET-CONTROL")) {
|
||||
qCWarning(dcAnelElektronik()) << "Bad data from panel:" << data << "Length:" << parts.length();
|
||||
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
// At this point we're done with gathering information about the panel. Setup defintely succeeded for the gateway device
|
||||
emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusSuccess);
|
||||
|
||||
// If we haven't set up childs for this gateway yet, let's do it now
|
||||
foreach (Device *child, myDevices()) {
|
||||
if (child->parentId() == device->id()) {
|
||||
// Already have childs for this panel. We're done here
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Example reply:
|
||||
|
||||
// NET-PWRCTRL_04.5; // device name
|
||||
// NET-CONTROL ; // hostname
|
||||
// 10.10.10.132; // IP
|
||||
// 255.255.255.0; // Netmask
|
||||
// 10.10.10.1; // Gateway
|
||||
// 00:04:A3:0B:0C:3A; // MAC
|
||||
// 80; // Webcontrol port
|
||||
// ; // Temp
|
||||
// H; // Type
|
||||
// ; // ?? (Skipped by upstream code)
|
||||
|
||||
// Following fields are repeated 1 times each, one for each socket
|
||||
|
||||
// Nr. 1; // Name 1
|
||||
// 1; // Stand
|
||||
// 0; // Dis
|
||||
// Anfangsstatus; // Info
|
||||
// ; // TK
|
||||
|
||||
// end;
|
||||
// NET - Power Control"
|
||||
|
||||
|
||||
// Lets add the child devices now
|
||||
int childs = -1;
|
||||
QString type = parts.at(startIndex + 8);
|
||||
if (type == "H") {
|
||||
childs = 3;
|
||||
} else {
|
||||
childs = 8;
|
||||
}
|
||||
|
||||
QList<DeviceDescriptor> descriptorList;
|
||||
for (int i = 0; i < childs; i++) {
|
||||
QString deviceName = parts.at(startIndex + 10 + i);
|
||||
DeviceDescriptor d(socketDeviceClassId, deviceName, device->name(), device->id());
|
||||
d.setParams(ParamList() << Param(socketDeviceNumberParamTypeId, i));
|
||||
descriptorList << d;
|
||||
}
|
||||
emit autoDevicesAppeared(socketDeviceClassId, descriptorList);
|
||||
});
|
||||
|
||||
return DeviceManager::DeviceSetupStatusAsync;
|
||||
}
|
||||
|
||||
if (device->deviceClassId() == socketDeviceClassId) {
|
||||
qCDebug(dcAnelElektronik()) << "Setting up" << device->name();
|
||||
if (!m_pollTimer) {
|
||||
m_pollTimer = hardwareManager()->pluginTimerManager()->registerTimer(2);
|
||||
connect(m_pollTimer, &PluginTimer::timeout, this, &DevicePluginAnel::refreshStates);
|
||||
}
|
||||
return DeviceManager::DeviceSetupStatusSuccess;
|
||||
}
|
||||
|
||||
qCWarning(dcAnelElektronik) << "Unhandled DeviceClass in setupDevice" << device->deviceClassId();
|
||||
return DeviceManager::DeviceSetupStatusFailure;
|
||||
}
|
||||
|
||||
void DevicePluginAnel::deviceRemoved(Device *device)
|
||||
{
|
||||
qCDebug(dcAnelElektronik) << "Device removed" << device->name();
|
||||
if (myDevices().isEmpty()) {
|
||||
hardwareManager()->pluginTimerManager()->unregisterTimer(m_pollTimer);
|
||||
m_pollTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DeviceManager::DeviceError DevicePluginAnel::executeAction(Device *device, const Action &action)
|
||||
{
|
||||
if (device->deviceClassId() == socketDeviceClassId) {
|
||||
|
||||
Device *parentDevice = myDevices().findById(device->parentId());
|
||||
|
||||
if (action.actionTypeId() == socketPowerActionTypeId) {
|
||||
QUrl url("http://" + parentDevice->paramValue(netPwrCtlDeviceIpAddressParamTypeId).toString() + ":" + parentDevice->paramValue(netPwrCtlDevicePortParamTypeId).toString() + "/ctrl.htm");
|
||||
QNetworkRequest request(url);
|
||||
QByteArray data = QString("F%1=%2").arg(device->paramValue(socketDeviceNumberParamTypeId).toString(), action.param(socketPowerActionPowerParamTypeId).value().toBool() == true ? "1" : "0").toUtf8();
|
||||
QNetworkReply *reply = m_nam->post(request, data);
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
connect(reply, &QNetworkReply::finished, device, [this, reply, action](){
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcAnelElektronik()) << "Execute action failed:" << reply->error() << reply->errorString();
|
||||
emit actionExecutionFinished(action.id(), DeviceManager::DeviceErrorHardwareNotAvailable);
|
||||
}
|
||||
qCDebug(dcAnelElektronik()) << "Execute action done.";
|
||||
emit actionExecutionFinished(action.id(), DeviceManager::DeviceErrorNoError);
|
||||
});
|
||||
return DeviceManager::DeviceErrorAsync;
|
||||
}
|
||||
}
|
||||
return DeviceManager::DeviceErrorDeviceClassNotFound;
|
||||
}
|
||||
|
||||
void DevicePluginAnel::refreshStates()
|
||||
{
|
||||
foreach (Device *device, myDevices()) {
|
||||
if (device->deviceClassId() != netPwrCtlDeviceClassId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QUrl url(QUrl("http://" + device->paramValue(netPwrCtlDeviceIpAddressParamTypeId).toString() + ":" + device->paramValue(netPwrCtlDevicePortParamTypeId).toString() + "/strg.cfg"));
|
||||
// qCDebug(dcAnelElektronik()) << "Fetching state from:" << url.toString();
|
||||
|
||||
QNetworkRequest request;
|
||||
request.setUrl(url);
|
||||
QNetworkReply *reply = m_nam->get(request);
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
connect(reply, &QNetworkReply::finished, device, [this, device, reply](){
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcAnelElektronik()) << "Error fetching state for" << device->name();
|
||||
setConnectedState(device, false);
|
||||
return;
|
||||
}
|
||||
QByteArray data = reply->readAll();
|
||||
// qCDebug(dcAnelElektronik()) << "States reply:" << data;
|
||||
|
||||
QStringList parts = QString(data).split(';');
|
||||
int startIndex = parts.indexOf("end") - 58;
|
||||
if (startIndex < 0 || !parts.at(startIndex + 1).startsWith("NET-CONTROL")) {
|
||||
qCWarning(dcAnelElektronik()) << "Bad data from Panel" << device->name() << data;
|
||||
// This happens sometimes as the panel replies with packets we didn't request... Just ignore it...
|
||||
return;
|
||||
}
|
||||
setConnectedState(device, true);
|
||||
|
||||
foreach (Device *child, myDevices()) {
|
||||
if (child->parentId() == device->id()) {
|
||||
int number = child->paramValue(socketDeviceNumberParamTypeId).toInt();
|
||||
child->setStateValue(socketPowerStateTypeId, parts.value(startIndex + 20 + number).toInt() == 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DevicePluginAnel::setConnectedState(Device *device, bool connected)
|
||||
{
|
||||
device->setStateValue(m_connectedStateTypeIdMap.value(device->deviceClassId()), connected);
|
||||
foreach (Device *child, myDevices()) {
|
||||
if (child->parentId() == device->id()) {
|
||||
child->setStateValue(m_connectedStateTypeIdMap.value(child->deviceClassId()), connected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* *
|
||||
* Copyright (C) 2018 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||
* *
|
||||
* This file is part of nymea. *
|
||||
* *
|
||||
* nymea 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. *
|
||||
* *
|
||||
* nymea 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 nymea. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef DEVICEPLUGINANEL_H
|
||||
#define DEVICEPLUGINANEL_H
|
||||
|
||||
#include "plugin/deviceplugin.h"
|
||||
#include "devicemanager.h"
|
||||
|
||||
#include <QUdpSocket>
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
class PluginTimer;
|
||||
|
||||
class DevicePluginAnel: public DevicePlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "devicepluginanel.json")
|
||||
Q_INTERFACES(DevicePlugin)
|
||||
|
||||
public:
|
||||
explicit DevicePluginAnel();
|
||||
~DevicePluginAnel();
|
||||
|
||||
void init() override;
|
||||
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList ¶ms) override;
|
||||
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
|
||||
void deviceRemoved(Device *device) override;
|
||||
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
|
||||
|
||||
private slots:
|
||||
void refreshStates();
|
||||
|
||||
private:
|
||||
void setConnectedState(Device *device, bool connected);
|
||||
|
||||
private:
|
||||
QNetworkAccessManager *m_nam = nullptr;
|
||||
PluginTimer *m_pollTimer = nullptr;
|
||||
|
||||
QHash<DeviceClassId, StateTypeId> m_connectedStateTypeIdMap;
|
||||
};
|
||||
|
||||
#endif // DEVICEPLUGINANEL_H
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"name": "anelElektronik",
|
||||
"displayName": "ANEL-Elektronik AG",
|
||||
"id": "7a3e5b64-20e4-42bd-b86b-989b84afc22a",
|
||||
"vendors": [
|
||||
{
|
||||
"name": "anelElektronik",
|
||||
"displayName": "ANEL-Elektronik AG",
|
||||
"id": "0e0a7d31-9f6b-402f-8029-8f1b2a77f994",
|
||||
"deviceClasses": [
|
||||
{
|
||||
"id": "d70433ac-9738-49ca-932f-6d3e20bcc6d4",
|
||||
"name": "netPwrCtl",
|
||||
"displayName": "NET-PwrCtl",
|
||||
"createMethods": ["user", "discovery"],
|
||||
"interfaces": [ "gateway" ],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "1e273e10-3ea0-4337-a221-3b8e26c6e7dc",
|
||||
"name":"ipAddress",
|
||||
"displayName": "IP address",
|
||||
"type": "QString"
|
||||
},
|
||||
{
|
||||
"id": "81704e09-d283-49d1-9e3f-9c06f8b98d84",
|
||||
"name": "port",
|
||||
"displayName": "Web control Port",
|
||||
"type": "int",
|
||||
"defaultValue": 80
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "9cde6321-2abf-4a58-a1d6-c7418edb9747",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "9d8da004-a8a1-457f-a8ee-b86133828a49",
|
||||
"name": "socket",
|
||||
"displayName": "NET-PwrCtrl Socket",
|
||||
"createMethods": ["auto"],
|
||||
"interfaces": ["powersocket", "connectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "7d18f8b1-4eb8-433f-b833-14059dd190e9",
|
||||
"name": "number",
|
||||
"displayName": "Socket number",
|
||||
"type": "int"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "e7e868a0-2de4-46ba-8ce7-87eaa4fc8e06",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "47329958-c33f-478f-b2a0-910abd150da8",
|
||||
"name": "power",
|
||||
"displayName": "Power",
|
||||
"displayNameEvent": "Power changed",
|
||||
"displayNameAction": "Set power",
|
||||
"writable": true,
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
</TS>
|
||||
|
|
@ -13,6 +13,24 @@ Build-depends: libboblight-dev,
|
|||
Standards-Version: 3.9.3
|
||||
|
||||
|
||||
Package: nymea-plugin-anel
|
||||
Architecture: any
|
||||
Section: libs
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
nymea-plugins-translations,
|
||||
Replaces: guh-plugin-anel
|
||||
Description: nymea.io plugin for ANEL Elektronik NET-PwrCtrl power sockets
|
||||
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 ANEL Elektronik NET-PwrCtrl
|
||||
network controlled power sockets.
|
||||
|
||||
|
||||
Package: nymea-plugin-avahimonitor
|
||||
Architecture: any
|
||||
Section: libs
|
||||
|
|
@ -742,6 +760,7 @@ Depends: nymea-plugin-boblight,
|
|||
nymea-plugin-httpcommander,
|
||||
nymea-plugin-genericelements,
|
||||
nymea-plugin-avahimonitor,
|
||||
nymea-plugin-anel,
|
||||
nymea-plugin-gpio,
|
||||
nymea-plugin-mqttclient,
|
||||
nymea-plugin-remotessh,
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_devicepluginanel.so
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
TEMPLATE = subdirs
|
||||
|
||||
PLUGIN_DIRS = \
|
||||
anel \
|
||||
avahimonitor \
|
||||
awattar \
|
||||
boblight \
|
||||
|
|
|
|||
Loading…
Reference in New Issue