diff --git a/anel/devicepluginanel.cpp b/anel/devicepluginanel.cpp
index 5fb28523..4be20b4c 100644
--- a/anel/devicepluginanel.cpp
+++ b/anel/devicepluginanel.cpp
@@ -39,6 +39,109 @@
\quotefile plugins/deviceplugins/tasmota/devicepluginanel.json
*/
+/*
+Example reply for HOME and PRO:
+
+ HOME: GET /daten.cfg: Length 13
+ 0: NET-CONTROL ;
+ 1: Mo, 07.01.19 02:24:54;
+ 2: 18;
+ 3: ;
+ 4: 12;
+ 5: 1;
+ 6: Login: user7 10.10.10.128;
+ 7: 4.5 DE;
+ 8: 7648;
+ 9: 0;
+ 10: H;
+ 11: end;
+ 12: NET - Power Control
+
+ ADV: GET /daten.cfg: Length 11
+ 0: 1546827738;
+ 1: 64;
+ 2: 0;
+ 3: 37;
+ 4: 1;
+ 5: 19789;
+ 6: 5;
+ 7: 24.7;
+ 8: 9;
+ 9: 2;
+ 10: end
+
+ HUT: GET /daten.cfg: Length 18
+ 0: 1546830796;
+ 1: 93;
+ 2: 41;
+ 3: 194;
+ 4: 1;
+ 5: 12587;
+ 6: 14;
+ 7: 24.7;
+ 8: 9;
+ 9: 2;
+ 10: end;
+ 11: s;
+ 12: 1;
+ 13: 22.90;
+ 14: 44.4;
+ 15: 851;
+ 16: 1;
+ 17: 0.00;
+
+
+
+ HOME/PRO GET strg.cfg: Length 60
+ 0: NET-PWRCTRL_04.5; // device name
+ 1: NET-CONTROL ; // hostname
+ 2: 10.10.10.132; // IP
+ 3: 255.255.255.0; // Netmask
+ 4: 10.10.10.1; // Gateway
+ 5: 00:04:A3:0B:0C:3A; // MAC
+ 6: 80; // Webcontrol port
+ 7: ; // Temp
+ 8: H; // Type
+ 9: ; // ?? (Skipped by upstream code)
+ Following fields are repeated 8 times each, one for each socket
+ 10: Nr. 1; // Name 1
+ 11: 1; // Stand
+ 12: 0; // Dis
+ 13: Anfangsstatus; // Info
+ 14: ; // TK
+
+ end;
+ NET - Power Control"
+
+ ADV: GET /strg.cfg: Length 58
+ 0: Nr.1;0;0;28;K;
+ 5: Nr.2;0;0;28;;
+ 10: Nr.3;1;0;27;;
+ 15: Nr.4;0;0;28;;
+ 20: Nr.5;0;0;28;;
+ 25: Nr.6;0;0;28;;
+ 30: Nr.7;0;0;0;;
+ 35: Nr.8;0;0;28;;
+ 40: end;
+ 41: 0;
+ 42: 0;
+ 43: 0;
+ 44: 1;
+ 45: 0;
+ 46: 0;
+ 47: 0;
+ 48: 1;
+ 49: 10122;
+ 50: 10123;
+ 51: 10124;
+ 52: 8657;
+ 53: 10126;
+ 54: 10127;
+ 55: 10128;
+ 56: 8659;
+
+*/
+
#include "devicepluginanel.h"
#include "plugininfo.h"
#include "plugintimer.h"
@@ -46,11 +149,35 @@
#include
#include
#include
+#include
DevicePluginAnel::DevicePluginAnel()
{
- m_connectedStateTypeIdMap.insert(netPwrCtlDeviceClassId, netPwrCtlConnectedStateTypeId);
+ m_connectedStateTypeIdMap.insert(netPwrCtlHomeDeviceClassId, netPwrCtlHomeConnectedStateTypeId);
+ m_connectedStateTypeIdMap.insert(netPwrCtlProDeviceClassId, netPwrCtlProConnectedStateTypeId);
+ m_connectedStateTypeIdMap.insert(netPwrCtlAdvDeviceClassId, netPwrCtlAdvConnectedStateTypeId);
+ m_connectedStateTypeIdMap.insert(netPwrCtlHutDeviceClassId, netPwrCtlHutConnectedStateTypeId);
m_connectedStateTypeIdMap.insert(socketDeviceClassId, socketConnectedStateTypeId);
+
+ m_ipAddressParamTypeIdMap.insert(netPwrCtlHomeDeviceClassId, netPwrCtlHomeDeviceIpAddressParamTypeId);
+ m_ipAddressParamTypeIdMap.insert(netPwrCtlProDeviceClassId, netPwrCtlProDeviceIpAddressParamTypeId);
+ m_ipAddressParamTypeIdMap.insert(netPwrCtlAdvDeviceClassId, netPwrCtlAdvDeviceIpAddressParamTypeId);
+ m_ipAddressParamTypeIdMap.insert(netPwrCtlHutDeviceClassId, netPwrCtlHutDeviceIpAddressParamTypeId);
+
+ m_portParamTypeIdMap.insert(netPwrCtlHomeDeviceClassId, netPwrCtlHomeDevicePortParamTypeId);
+ m_portParamTypeIdMap.insert(netPwrCtlProDeviceClassId, netPwrCtlProDevicePortParamTypeId);
+ m_portParamTypeIdMap.insert(netPwrCtlAdvDeviceClassId, netPwrCtlAdvDevicePortParamTypeId);
+ m_portParamTypeIdMap.insert(netPwrCtlHutDeviceClassId, netPwrCtlHutDevicePortParamTypeId);
+
+ m_userParamTypeIdMap.insert(netPwrCtlHomeDeviceClassId, netPwrCtlHomeDeviceUsernameParamTypeId);
+ m_userParamTypeIdMap.insert(netPwrCtlProDeviceClassId, netPwrCtlProDeviceUsernameParamTypeId);
+ m_userParamTypeIdMap.insert(netPwrCtlAdvDeviceClassId, netPwrCtlAdvDeviceUsernameParamTypeId);
+ m_userParamTypeIdMap.insert(netPwrCtlHutDeviceClassId, netPwrCtlHutDeviceUsernameParamTypeId);
+
+ m_passParamTypeIdMap.insert(netPwrCtlHomeDeviceClassId, netPwrCtlHomeDevicePasswordParamTypeId);
+ m_passParamTypeIdMap.insert(netPwrCtlProDeviceClassId, netPwrCtlProDevicePasswordParamTypeId);
+ m_passParamTypeIdMap.insert(netPwrCtlAdvDeviceClassId, netPwrCtlAdvDevicePasswordParamTypeId);
+ m_passParamTypeIdMap.insert(netPwrCtlHutDeviceClassId, netPwrCtlHutDevicePasswordParamTypeId);
}
DevicePluginAnel::~DevicePluginAnel()
@@ -79,7 +206,7 @@ DeviceManager::DeviceError DevicePluginAnel::discoverDevices(const DeviceClassId
return DeviceManager::DeviceErrorHardwareFailure;
}
- QTimer::singleShot(2000, this, [this, searchSocket](){
+ QTimer::singleShot(2000, this, [this, searchSocket, deviceClassId](){
QList descriptorList;
while(searchSocket->hasPendingDatagrams()) {
char buffer[1024];
@@ -97,9 +224,15 @@ DeviceManager::DeviceError DevicePluginAnel::discoverDevices(const DeviceClassId
continue;
}
qCDebug(dcAnelElektronik()) << "Found NET-CONTROL:" << senderAddress << parts.at(2) << parts.at(3) << senderAddress.protocol();
+
+ ParamTypeId ipAddressParamTypeId = m_ipAddressParamTypeIdMap.value(deviceClassId);
+ ParamTypeId portParamTypeId = m_portParamTypeIdMap.value(deviceClassId);
+ ParamTypeId userParamTypeId = m_userParamTypeIdMap.value(deviceClassId);
+ ParamTypeId passParamTypeId = m_passParamTypeIdMap.value(deviceClassId);
+
bool existing = false;
foreach (Device *existingDev, myDevices()) {
- if (existingDev->deviceClassId() == netPwrCtlDeviceClassId && existingDev->paramValue(netPwrCtlDeviceIpAddressParamTypeId).toString() == senderAddress.toString()) {
+ if (existingDev->deviceClassId() == deviceClassId && existingDev->paramValue(ipAddressParamTypeId).toString() == senderAddress.toString()) {
existing = true;
}
}
@@ -107,16 +240,16 @@ DeviceManager::DeviceError DevicePluginAnel::discoverDevices(const DeviceClassId
qCDebug(dcAnelElektronik()) << "Already have device" << senderAddress << "in configured devices. Skipping...";
continue;
}
- DeviceDescriptor d(netPwrCtlDeviceClassId, parts.at(2), senderAddress.toString());
+ DeviceDescriptor d(deviceClassId, parts.at(2), senderAddress.toString());
ParamList params;
- params << Param(netPwrCtlDeviceIpAddressParamTypeId, senderAddress.toString());
- params << Param(netPwrCtlDevicePortParamTypeId, parts.at(3).toInt());
- params << Param(netPwrCtlDeviceUsernameParamTypeId, "user7");
- params << Param(netPwrCtlDevicePasswordParamTypeId, "anel");
+ params << Param(ipAddressParamTypeId, senderAddress.toString());
+ params << Param(portParamTypeId, parts.at(3).toInt());
+ params << Param(userParamTypeId, "user7");
+ params << Param(passParamTypeId, "anel");
d.setParams(params);
descriptorList << d;
}
- emit devicesDiscovered(netPwrCtlDeviceClassId, descriptorList);
+ emit devicesDiscovered(deviceClassId, descriptorList);
searchSocket->deleteLater();
});
return DeviceManager::DeviceErrorAsync;
@@ -124,95 +257,13 @@ DeviceManager::DeviceError DevicePluginAnel::discoverDevices(const DeviceClassId
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"));
- QString username = device->paramValue(netPwrCtlDeviceUsernameParamTypeId).toString();
- QString password = device->paramValue(netPwrCtlDevicePasswordParamTypeId).toString();
- request.setRawHeader("Authorization", "Basic " + QString("%1:%2").arg(username, password).toUtf8().toBase64());
- qCDebug(dcAnelElektronik()) << "SetupDevice fetching:" << request.url() << request.rawHeader("Authorization") << username << password;
- QNetworkReply *reply = hardwareManager()->networkManager()->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() << reply->error() << reply->errorString();
- 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 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() == netPwrCtlHomeDeviceClassId
+ || device->deviceClassId() == netPwrCtlProDeviceClassId) {
+ return setupHomeProDevice(device);
+ }
+ if (device->deviceClassId() == netPwrCtlAdvDeviceClassId
+ || device->deviceClassId() == netPwrCtlHutDeviceClassId) {
+ return setupAdvDevice(device);
}
if (device->deviceClassId() == socketDeviceClassId) {
@@ -240,14 +291,17 @@ void DevicePluginAnel::deviceRemoved(Device *device)
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");
+
+ Device *parentDevice = myDevices().findById(device->parentId());
+
+ QString ipAddress = parentDevice->paramValue(m_ipAddressParamTypeIdMap.value(parentDevice->deviceClassId())).toString();
+ int port = parentDevice->paramValue(m_portParamTypeIdMap.value(parentDevice->deviceClassId())).toInt();
+ QString username = parentDevice->paramValue(m_userParamTypeIdMap.value(parentDevice->deviceClassId())).toString();
+ QString password = parentDevice->paramValue(m_passParamTypeIdMap.value(parentDevice->deviceClassId())).toString();
+
+ QUrl url(QString("http://%1:%2/ctrl.htm").arg(ipAddress).arg(port));
QNetworkRequest request(url);
- QString username = parentDevice->paramValue(netPwrCtlDeviceUsernameParamTypeId).toString();
- QString password = parentDevice->paramValue(netPwrCtlDevicePasswordParamTypeId).toString();
request.setRawHeader("Authorization", "Basic " + QString("%1:%2").arg(username, password).toUtf8().toBase64());
request.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");
QByteArray data = QString("F%1=%2").arg(device->paramValue(socketDeviceNumberParamTypeId).toString(), action.param(socketPowerActionPowerParamTypeId).value().toBool() == true ? "1" : "0").toUtf8();
@@ -270,47 +324,15 @@ DeviceManager::DeviceError DevicePluginAnel::executeAction(Device *device, const
void DevicePluginAnel::refreshStates()
{
foreach (Device *device, myDevices()) {
- if (device->deviceClassId() != netPwrCtlDeviceClassId) {
- continue;
+ if (device->deviceClassId() == netPwrCtlHomeDeviceClassId
+ || device->deviceClassId() == netPwrCtlProDeviceClassId) {
+ refreshHomePro(device);
+ }
+ if (device->deviceClassId() == netPwrCtlAdvDeviceClassId
+ || device->deviceClassId() == netPwrCtlHutDeviceClassId) {
+ refreshAdv(device);
}
-
- 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);
- QString username = device->paramValue(netPwrCtlDeviceUsernameParamTypeId).toString();
- QString password = device->paramValue(netPwrCtlDevicePasswordParamTypeId).toString();
- request.setRawHeader("Authorization", "Basic " + QString("%1:%2").arg(username, password).toUtf8().toBase64());
- QNetworkReply *reply = hardwareManager()->networkManager()->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)
@@ -322,3 +344,299 @@ void DevicePluginAnel::setConnectedState(Device *device, bool connected)
}
}
}
+
+DeviceManager::DeviceSetupStatus DevicePluginAnel::setupHomeProDevice(Device *device)
+{
+ QString ipAddress = device->paramValue(m_ipAddressParamTypeIdMap.value(device->deviceClassId())).toString();
+ int port = device->paramValue(m_portParamTypeIdMap.value(device->deviceClassId())).toInt();
+ QString username = device->paramValue(m_userParamTypeIdMap.value(device->deviceClassId())).toString();
+ QString password = device->paramValue(m_passParamTypeIdMap.value(device->deviceClassId())).toString();
+
+ QNetworkRequest request;
+ request.setUrl(QUrl(QString("http://%1:%2/strg.cfg").arg(ipAddress).arg(port)));
+ request.setRawHeader("Authorization", "Basic " + QString("%1:%2").arg(username).arg(password).toUtf8().toBase64());
+ qCDebug(dcAnelElektronik()) << "SetupDevice fetching:" << request.url() << request.rawHeader("Authorization") << username << password;
+ QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
+ connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
+ connect(reply, &QNetworkReply::finished, device, [this, device, reply](){
+ StateTypeId connectedStateTypeId = m_connectedStateTypeIdMap.value(device->deviceClassId());
+ if (reply->error() != QNetworkReply::NoError) {
+ qCWarning(dcAnelElektronik()) << "Error fetching state for" << device->name() << reply->error() << reply->errorString();
+ device->setStateValue(connectedStateTypeId, false);
+ emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
+ return;
+ }
+ device->setStateValue(connectedStateTypeId, true);
+
+ QByteArray data = reply->readAll();
+
+ QStringList parts = QString(data).split(';');
+
+ int startIndex = parts.indexOf("end") - 58;
+ if (startIndex < 0 || !parts.at(startIndex).startsWith("NET-PWRCTRL") || parts.length() < 60) {
+ 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;
+ }
+ }
+
+ // Lets add the child devices now
+ int childs = -1;
+ QString type = parts.at(startIndex + 8);
+ if (type == "H") {
+ childs = 3;
+ } else {
+ childs = 8;
+ }
+
+ QList 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;
+}
+
+DeviceManager::DeviceSetupStatus DevicePluginAnel::setupAdvDevice(Device *device)
+{
+ QString ipAddress = device->paramValue(m_ipAddressParamTypeIdMap.value(device->deviceClassId())).toString();
+ int port = device->paramValue(m_portParamTypeIdMap.value(device->deviceClassId())).toInt();
+ QString username = device->paramValue(m_userParamTypeIdMap.value(device->deviceClassId())).toString();
+ QString password = device->paramValue(m_passParamTypeIdMap.value(device->deviceClassId())).toString();
+
+ QNetworkRequest request;
+ request.setUrl(QUrl(QString("http://%1:%2/strg.cfg").arg(ipAddress).arg(port)));
+ request.setRawHeader("Authorization", "Basic " + QString("%1:%2").arg(username).arg(password).toUtf8().toBase64());
+ qCDebug(dcAnelElektronik()) << "SetupDevice fetching:" << request.url() << request.rawHeader("Authorization") << username << password;
+ QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
+ connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
+ connect(reply, &QNetworkReply::finished, device, [this, device, reply](){
+ StateTypeId connectedStateTypeId = m_connectedStateTypeIdMap.value(device->deviceClassId());
+ if (reply->error() != QNetworkReply::NoError) {
+ qCWarning(dcAnelElektronik()) << "Error fetching state for" << device->name() << reply->error() << reply->errorString();
+ device->setStateValue(connectedStateTypeId, false);
+ emit deviceSetupFinished(device, DeviceManager::DeviceSetupStatusFailure);
+ return;
+ }
+ device->setStateValue(connectedStateTypeId, true);
+
+ QByteArray data = reply->readAll();
+
+ QStringList parts = QString(data).split(';');
+
+ int startIndex = parts.indexOf("end") - 40;
+ if (startIndex < 0 || parts.length() < 58) {
+ 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;
+ }
+ }
+
+ QList descriptorList;
+ for (int i = 0; i < 8; i++) {
+ QString deviceName = parts.at(startIndex + (i * 5));
+ DeviceDescriptor d(socketDeviceClassId, deviceName, device->name(), device->id());
+ d.setParams(ParamList() << Param(socketDeviceNumberParamTypeId, i));
+ descriptorList << d;
+ }
+ emit autoDevicesAppeared(socketDeviceClassId, descriptorList);
+ });
+
+ return DeviceManager::DeviceSetupStatusAsync;
+}
+
+void DevicePluginAnel::refreshHomePro(Device *device)
+{
+ QString ipAddress = device->paramValue(m_ipAddressParamTypeIdMap.value(device->deviceClassId())).toString();
+ int port = device->paramValue(m_portParamTypeIdMap.value(device->deviceClassId())).toInt();
+ QString username = device->paramValue(m_userParamTypeIdMap.value(device->deviceClassId())).toString();
+ QString password = device->paramValue(m_passParamTypeIdMap.value(device->deviceClassId())).toString();
+
+ QUrl url(QString("http://%1:%2/strg.cfg").arg(ipAddress).arg(port));
+
+ QNetworkRequest request;
+ request.setUrl(url);
+ request.setRawHeader("Authorization", "Basic " + QString("%1:%2").arg(username, password).toUtf8().toBase64());
+ QNetworkReply *reply = hardwareManager()->networkManager()->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).startsWith("NET-PWRCTRL")) {
+ qCWarning(dcAnelElektronik()) << "Bad data from Panel" << device->name() << data;
+ // This happens sometimes when multiple clients are talking to the panel... Just ignore it...
+ return;
+ }
+ setConnectedState(device, true);
+
+ // The temp sensor seems to have a bit of jitter. Reduce sample rate to avoid spamming the log
+ quint32 samples = device->property("tempSamples").toUInt();
+ if (samples % 15 == 0 && device->deviceClassId() == netPwrCtlProDeviceClassId) {
+ bool ok;
+ double tempValue = parts.at(startIndex + 7).toDouble(&ok);
+ if (ok) {
+ device->setStateValue(netPwrCtlProTemperatureStateTypeId, tempValue);
+ } else {
+ qCWarning(dcAnelElektronik()) << "Error reading temperature value from data:" << parts.at(startIndex + 7);
+ }
+ }
+ device->setProperty("tempSamples", ++samples);
+
+ 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::refreshAdv(Device *device)
+{
+ QString ipAddress = device->paramValue(m_ipAddressParamTypeIdMap.value(device->deviceClassId())).toString();
+ int port = device->paramValue(m_portParamTypeIdMap.value(device->deviceClassId())).toInt();
+ QString username = device->paramValue(m_userParamTypeIdMap.value(device->deviceClassId())).toString();
+ QString password = device->paramValue(m_passParamTypeIdMap.value(device->deviceClassId())).toString();
+
+ QUrl url(QString("http://%1:%2/strg.cfg").arg(ipAddress).arg(port));
+
+ QNetworkRequest request;
+ request.setUrl(url);
+ request.setRawHeader("Authorization", "Basic " + QString("%1:%2").arg(username, password).toUtf8().toBase64());
+ QNetworkReply *reply = hardwareManager()->networkManager()->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") - 40;
+ if (startIndex < 0 || parts.count() < 58) {
+ qCWarning(dcAnelElektronik()) << "Bad data from Panel" << device->name() << data << "Length:" << parts.length();
+ // This happens sometimes when multiple clients are talking to the panel... 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 + (number * 5) + 1).toInt() == 1);
+ }
+ }
+
+ // The temp sensor seems to have a bit of jitter. Reduce sample rate to avoid spamming the log
+ quint32 samples = device->property("tempSamples").toUInt();
+ if (samples % 15 == 0) {
+ refreshAdvTemp(device);
+ }
+ device->setProperty("tempSamples", ++samples);
+
+ });
+}
+
+void DevicePluginAnel::refreshAdvTemp(Device *device)
+{
+ QString ipAddress = device->paramValue(m_ipAddressParamTypeIdMap.value(device->deviceClassId())).toString();
+ int port = device->paramValue(m_portParamTypeIdMap.value(device->deviceClassId())).toInt();
+ QString username = device->paramValue(m_userParamTypeIdMap.value(device->deviceClassId())).toString();
+ QString password = device->paramValue(m_passParamTypeIdMap.value(device->deviceClassId())).toString();
+
+ QUrl url(QString("http://%1:%2/daten.cfg").arg(ipAddress).arg(port));
+
+ QNetworkRequest request;
+ request.setUrl(url);
+ request.setRawHeader("Authorization", "Basic " + QString("%1:%2").arg(username, password).toUtf8().toBase64());
+ QNetworkReply *reply = hardwareManager()->networkManager()->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 temp for" << device->name();
+ setConnectedState(device, false);
+ return;
+ }
+ QByteArray data = reply->readAll();
+ qCDebug(dcAnelElektronik()) << "Temp reply:" << data;
+
+ QStringList parts = QString(data).split(';');
+ int startIndex = parts.indexOf("end") - 10;
+ if (startIndex < 0) {
+ qCWarning(dcAnelElektronik()) << "Bad data from Panel" << device->name() << data << "Length:" << parts.length();
+ // This happens sometimes when multiple clients are talking to the panel... Just ignore it...
+ return;
+ }
+
+ if (device->deviceClassId() == netPwrCtlAdvDeviceClassId) {
+ bool ok;
+ double temp = parts.at(7).toDouble(&ok);
+ if (ok) {
+ device->setStateValue(netPwrCtlAdvTemperatureStateTypeId, temp);
+ } else {
+ qCWarning(dcAnelElektronik()) << "Error fetching temperature value:" << data;
+ }
+ } else { // HUT
+ if (parts.length() < 18) {
+ qCWarning(dcAnelElektronik()) << "Data too short for HUT device" << data;
+ return;
+ }
+ bool ok;
+ double temp = parts.at(13).toDouble(&ok);
+ if (ok) {
+ device->setStateValue(netPwrCtlHutTemperatureStateTypeId, temp);
+ } else {
+ qCWarning(dcAnelElektronik()) << "Error fetching temperature value:" << data;
+ }
+ double humidity = parts.at(14).toDouble(&ok);
+ if (ok) {
+ device->setStateValue(netPwrCtlHutHumidityStateTypeId, humidity);
+ } else {
+ qCWarning(dcAnelElektronik()) << "Error fetching humidity value:" << data;
+ }
+ int lux = parts.at(15).toInt(&ok);
+ if (ok) {
+ device->setStateValue(netPwrCtlHutLightIntensityStateTypeId, lux);
+ } else {
+ qCWarning(dcAnelElektronik()) << "Error fetching light intensity value:" << data;
+ }
+ }
+
+ });
+}
diff --git a/anel/devicepluginanel.h b/anel/devicepluginanel.h
index 0a8c9b49..7a3c1917 100644
--- a/anel/devicepluginanel.h
+++ b/anel/devicepluginanel.h
@@ -53,10 +53,21 @@ private slots:
private:
void setConnectedState(Device *device, bool connected);
+ DeviceManager::DeviceSetupStatus setupHomeProDevice(Device *device);
+ DeviceManager::DeviceSetupStatus setupAdvDevice(Device *device);
+
+ void refreshHomePro(Device *device);
+ void refreshAdv(Device *device);
+ void refreshAdvTemp(Device *device);
+
private:
PluginTimer *m_pollTimer = nullptr;
QHash m_connectedStateTypeIdMap;
+ QHash m_ipAddressParamTypeIdMap;
+ QHash m_portParamTypeIdMap;
+ QHash m_userParamTypeIdMap;
+ QHash m_passParamTypeIdMap;
};
#endif // DEVICEPLUGINANEL_H
diff --git a/anel/devicepluginanel.json b/anel/devicepluginanel.json
index daa1701d..1537c38e 100644
--- a/anel/devicepluginanel.json
+++ b/anel/devicepluginanel.json
@@ -10,8 +10,8 @@
"deviceClasses": [
{
"id": "d70433ac-9738-49ca-932f-6d3e20bcc6d4",
- "name": "netPwrCtl",
- "displayName": "NET-PwrCtl",
+ "name": "netPwrCtlHome",
+ "displayName": "NET-PwrCtl HOME",
"createMethods": ["user", "discovery"],
"interfaces": [ "gateway" ],
"paramTypes": [
@@ -53,6 +53,188 @@
}
]
},
+ {
+ "id": "1492f911-1c09-42ce-b920-084548a689ea",
+ "name": "netPwrCtlPro",
+ "displayName": "NET-PwrCtl PRO",
+ "createMethods": ["user", "discovery"],
+ "interfaces": [ "gateway", "temperaturesensor" ],
+ "paramTypes": [
+ {
+ "id": "b1cf9a4f-9c2a-4ab4-a920-46f0b8a8b988",
+ "name":"ipAddress",
+ "displayName": "IP address",
+ "type": "QString"
+ },
+ {
+ "id": "31540acc-949f-454f-9987-982e97ce7d21",
+ "name": "port",
+ "displayName": "Web control Port",
+ "type": "int",
+ "defaultValue": 80
+ },
+ {
+ "id": "f9cae7eb-a534-404f-b041-6e5a6720494e",
+ "name": "username",
+ "displayName": "Username",
+ "type": "QString"
+ },
+ {
+ "id": "dac97153-074a-481a-8057-1936bfb63b6e",
+ "name": "password",
+ "displayName": "Password",
+ "type": "QString"
+ }
+ ],
+ "stateTypes": [
+ {
+ "id": "820c54bd-0d4f-4e13-8160-a8efa77c9db5",
+ "name": "connected",
+ "displayName": "Connected",
+ "displayNameEvent": "Connected changed",
+ "type": "bool",
+ "defaultValue": false,
+ "cached": false
+ },
+ {
+ "id": "2973ec1e-9c26-45ad-a97b-dd5eccbf650a",
+ "name": "temperature",
+ "displayName": "Temperature",
+ "displayNameEvent": "Temperature changed",
+ "type": "double",
+ "defaultValue": 0,
+ "unit": "DegreeCelsius"
+ }
+ ]
+ },
+ {
+ "id": "99987919-d32d-4d8f-938c-bcf9683003b6",
+ "name": "netPwrCtlAdv",
+ "displayName": "NET-PwrCtl ADV",
+ "createMethods": ["user", "discovery"],
+ "interfaces": [ "gateway", "temperaturesensor" ],
+ "paramTypes": [
+ {
+ "id": "5d98ead0-e445-492c-821c-ae169af648e4",
+ "name":"ipAddress",
+ "displayName": "IP address",
+ "type": "QString"
+ },
+ {
+ "id": "1913912f-2579-4e8a-9e23-af1de4a2ef72",
+ "name": "port",
+ "displayName": "Web control Port",
+ "type": "int",
+ "defaultValue": 80
+ },
+ {
+ "id": "0eeaa6f0-7232-4d6e-8637-6e21f58a2018",
+ "name": "username",
+ "displayName": "Username",
+ "type": "QString"
+ },
+ {
+ "id": "14a8c3bd-27a6-440c-a2ba-139fabc870a1",
+ "name": "password",
+ "displayName": "Password",
+ "type": "QString"
+ }
+ ],
+ "stateTypes": [
+ {
+ "id": "d143b775-e004-4119-a317-6c508686d473",
+ "name": "connected",
+ "displayName": "Connected",
+ "displayNameEvent": "Connected changed",
+ "type": "bool",
+ "defaultValue": false,
+ "cached": false
+ },
+ {
+ "id": "aed7464a-6c36-4858-adb7-776d97c5498e",
+ "name": "temperature",
+ "displayName": "Temperature",
+ "displayNameEvent": "Temperature changed",
+ "type": "double",
+ "defaultValue": 0,
+ "unit": "DegreeCelsius"
+ }
+ ]
+ },
+ {
+ "id": "bc9a90e0-b320-46f1-8d7b-2d24f40af5ea",
+ "name": "netPwrCtlHut",
+ "displayName": "NET-PwrCtl HUT",
+ "createMethods": ["user", "discovery"],
+ "interfaces": [ "gateway", "temperaturesensor", "humiditysensor", "lightsensor" ],
+ "paramTypes": [
+ {
+ "id": "fb34919c-3ca0-47b3-a14a-7986b5ce24e2",
+ "name":"ipAddress",
+ "displayName": "IP address",
+ "type": "QString"
+ },
+ {
+ "id": "35010dff-dde9-4acf-a60b-cf92b7edc2a5",
+ "name": "port",
+ "displayName": "Web control Port",
+ "type": "int",
+ "defaultValue": 80
+ },
+ {
+ "id": "3bf3db56-4fe4-4c87-a5cd-7c1f1acb6408",
+ "name": "username",
+ "displayName": "Username",
+ "type": "QString"
+ },
+ {
+ "id": "d5f315b9-99ff-4e69-95c8-97cb81d1e8d7",
+ "name": "password",
+ "displayName": "Password",
+ "type": "QString"
+ }
+ ],
+ "stateTypes": [
+ {
+ "id": "3b30c586-4756-4903-8405-b00bc9d34685",
+ "name": "connected",
+ "displayName": "Connected",
+ "displayNameEvent": "Connected changed",
+ "type": "bool",
+ "defaultValue": false,
+ "cached": false
+ },
+ {
+ "id": "7689239c-e6c3-48cc-ae90-bd1cad44b631",
+ "name": "temperature",
+ "displayName": "Temperature",
+ "displayNameEvent": "Temperature changed",
+ "type": "double",
+ "defaultValue": 0,
+ "unit": "DegreeCelsius"
+ },
+ {
+ "id": "6e38c9f7-cdd7-4909-9312-2047812d1883",
+ "name": "humidity",
+ "displayName": "Humidity",
+ "displayNameEvent": "Humidity changed",
+ "type": "double",
+ "defaultValue": 0,
+ "minValue": 0,
+ "maxValue": 100,
+ "unit": "Percentage"
+ },
+ {
+ "id": "60792bc4-fc67-47f6-8c3f-45717a072d59",
+ "name": "lightIntensity",
+ "displayName": "Light intensity",
+ "displayNameEvent": "Light intensity changed",
+ "type": "double",
+ "defaultValue": 0,
+ "unit": "Lux"
+ }
+ ]
+ },
{
"id": "9d8da004-a8a1-457f-a8ee-b86133828a49",
"name": "socket",