Update iDM plugin and add network discovery

pull/26/head
Simon Stürz 2021-06-07 15:57:42 +02:00 committed by Michael Zanetti
parent 6651121030
commit acb5dbe9a2
5 changed files with 69 additions and 28 deletions

View File

@ -40,14 +40,10 @@ Idm::Idm(const QHostAddress &address, QObject *parent) :
{ {
qCDebug(dcIdm()) << "iDM: Creating iDM connection" << m_hostAddress.toString(); qCDebug(dcIdm()) << "iDM: Creating iDM connection" << m_hostAddress.toString();
m_modbusMaster = new ModbusTCPMaster(address, 502, this); m_modbusMaster = new ModbusTCPMaster(address, 502, this);
if (m_modbusMaster) {
qCDebug(dcIdm()) << "iDM: Created ModbusTCPMaster";
connect(m_modbusMaster, &ModbusTCPMaster::receivedHoldingRegister, this, &Idm::onReceivedHoldingRegister); connect(m_modbusMaster, &ModbusTCPMaster::receivedHoldingRegister, this, &Idm::onReceivedHoldingRegister);
connect(m_modbusMaster, &ModbusTCPMaster::readRequestError, this, &Idm::onModbusError); connect(m_modbusMaster, &ModbusTCPMaster::readRequestError, this, &Idm::onModbusError);
connect(m_modbusMaster, &ModbusTCPMaster::writeRequestError, this, &Idm::onModbusError); connect(m_modbusMaster, &ModbusTCPMaster::writeRequestError, this, &Idm::onModbusError);
connect(m_modbusMaster, &ModbusTCPMaster::writeRequestExecuted, this, &Idm::writeRequestExecuted); connect(m_modbusMaster, &ModbusTCPMaster::writeRequestExecuted, this, &Idm::writeRequestExecuted);
}
} }
Idm::~Idm() Idm::~Idm()
@ -61,14 +57,14 @@ bool Idm::connectDevice()
return m_modbusMaster->connectDevice(); return m_modbusMaster->connectDevice();
} }
QHostAddress Idm::getIdmAddress() const QHostAddress Idm::address() const
{ {
return m_hostAddress; return m_hostAddress;
} }
void Idm::getStatus() void Idm::getStatus()
{ {
//this request starts an update cycle // This request starts an update cycle
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::OutsideTemperature, 2); m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::OutsideTemperature, 2);
} }

View File

@ -72,7 +72,7 @@ public:
~Idm(); ~Idm();
bool connectDevice(); bool connectDevice();
QHostAddress getIdmAddress() const; QHostAddress address() const;
QUuid setTargetTemperature(double targetTemperature); QUuid setTargetTemperature(double targetTemperature);
void getStatus(); void getStatus();

View File

@ -28,6 +28,7 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "network/networkdevicediscovery.h"
#include "integrationpluginidm.h" #include "integrationpluginidm.h"
#include "plugininfo.h" #include "plugininfo.h"
@ -36,6 +37,48 @@ IntegrationPluginIdm::IntegrationPluginIdm()
} }
void IntegrationPluginIdm::discoverThings(ThingDiscoveryInfo *info)
{
qCDebug(dcIdm()) << "Discovering network...";
NetworkDeviceDiscoveryReply *discoveryReply = hardwareManager()->networkDeviceDiscovery()->discover();
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
ThingDescriptors descriptors;
qCDebug(dcIdm()) << "Discovery finished. Found" << discoveryReply->networkDevices().count() << "devices";
foreach (const NetworkDevice &networkDevice, discoveryReply->networkDevices()) {
qCDebug(dcIdm()) << networkDevice;
QString title;
if (networkDevice.hostName().isEmpty()) {
title += networkDevice.address().toString();
} else {
title += networkDevice.address().toString() + " (" + networkDevice.hostName() + ")";
}
QString description;
if (networkDevice.macAddressManufacturer().isEmpty()) {
description = networkDevice.macAddress();
} else {
description = networkDevice.macAddress() + " (" + networkDevice.macAddressManufacturer() + ")";
}
ThingDescriptor descriptor(navigator2ThingClassId, title, description);
// Check if we already have set up this device
Things existingThings = myThings().filterByParam(navigator2ThingMacAddressParamTypeId, networkDevice.macAddress());
if (existingThings.count() == 1) {
qCDebug(dcIdm()) << "This thing already exists in the system." << existingThings.first() << networkDevice;
descriptor.setThingId(existingThings.first()->id());
}
ParamList params;
params << Param(navigator2ThingMacAddressParamTypeId, networkDevice.macAddress());
params << Param(navigator2ThingIpAddressParamTypeId, networkDevice.address().toString());
descriptor.setParams(params);
info->addThingDescriptor(descriptor);
}
info->finish(Thing::ThingErrorNoError);
});
}
void IntegrationPluginIdm::setupThing(ThingSetupInfo *info) void IntegrationPluginIdm::setupThing(ThingSetupInfo *info)
{ {
Thing *thing = info->thing(); Thing *thing = info->thing();
@ -57,8 +100,8 @@ void IntegrationPluginIdm::setupThing(ThingSetupInfo *info)
qCDebug(dcIdm()) << "User entered address: " << hostAddress.toString(); qCDebug(dcIdm()) << "User entered address: " << hostAddress.toString();
/* Check, if address is already in use for another device */ /* Check, if address is already in use for another device */
Q_FOREACH (Idm *idm, m_idmConnections) { foreach (Idm *idm, m_idmConnections) {
if (hostAddress.isEqual(idm->getIdmAddress())) { if (hostAddress.isEqual(idm->address())) {
qCWarning(dcIdm()) << "Address already in use"; qCWarning(dcIdm()) << "Address already in use";
info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("IP address already in use")); info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("IP address already in use"));
return; return;
@ -144,8 +187,7 @@ void IntegrationPluginIdm::executeAction(ThingActionInfo *info)
double targetTemperature = thing->stateValue(navigator2TargetTemperatureStateTypeId).toDouble(); double targetTemperature = thing->stateValue(navigator2TargetTemperatureStateTypeId).toDouble();
QUuid requestId = idm->setTargetTemperature(targetTemperature); QUuid requestId = idm->setTargetTemperature(targetTemperature);
m_asyncActions.insert(requestId, info); m_asyncActions.insert(requestId, info);
connect(info, &ThingActionInfo::aborted, [requestId, this] {m_asyncActions.remove(requestId);}); connect(info, &ThingActionInfo::aborted, [requestId, this] (){ m_asyncActions.remove(requestId); });
} else { } else {
Q_ASSERT_X(false, "executeAction", QString("Unhandled action: %1").arg(action.actionTypeId().toString()).toUtf8()); Q_ASSERT_X(false, "executeAction", QString("Unhandled action: %1").arg(action.actionTypeId().toString()).toUtf8());
} }
@ -158,11 +200,8 @@ void IntegrationPluginIdm::update(Thing *thing)
{ {
if (thing->thingClassId() == navigator2ThingClassId) { if (thing->thingClassId() == navigator2ThingClassId) {
qCDebug(dcIdm()) << "Updating thing" << thing->name(); qCDebug(dcIdm()) << "Updating thing" << thing->name();
Idm *idm = m_idmConnections.value(thing); Idm *idm = m_idmConnections.value(thing);
if (!idm) { if (!idm) { return; };
return;
}
idm->getStatus(); idm->getStatus();
} }
} }
@ -170,7 +209,6 @@ void IntegrationPluginIdm::update(Thing *thing)
void IntegrationPluginIdm::onStatusUpdated(const IdmInfo &info) void IntegrationPluginIdm::onStatusUpdated(const IdmInfo &info)
{ {
qCDebug(dcIdm()) << "Received status from heat pump"; qCDebug(dcIdm()) << "Received status from heat pump";
Idm *idm = qobject_cast<Idm *>(sender()); Idm *idm = qobject_cast<Idm *>(sender());
Thing *thing = m_idmConnections.key(idm); Thing *thing = m_idmConnections.key(idm);
@ -205,8 +243,6 @@ void IntegrationPluginIdm::onWriteRequestExecuted(const QUuid &requestId, bool s
void IntegrationPluginIdm::onRefreshTimer() void IntegrationPluginIdm::onRefreshTimer()
{ {
qCDebug(dcIdm()) << "onRefreshTimer called";
foreach (Thing *thing, myThings().filterByThingClassId(navigator2ThingClassId)) { foreach (Thing *thing, myThings().filterByThingClassId(navigator2ThingClassId)) {
update(thing); update(thing);
} }

View File

@ -33,7 +33,6 @@
#include "integrations/integrationplugin.h" #include "integrations/integrationplugin.h"
#include "plugintimer.h" #include "plugintimer.h"
#include "idm.h" #include "idm.h"
#include <QUuid> #include <QUuid>
@ -48,6 +47,7 @@ class IntegrationPluginIdm: public IntegrationPlugin
public: public:
explicit IntegrationPluginIdm(); explicit IntegrationPluginIdm();
void discoverThings(ThingDiscoveryInfo *info) override;
void setupThing(ThingSetupInfo *info) override; void setupThing(ThingSetupInfo *info) override;
void postSetupThing(Thing *thing) override; void postSetupThing(Thing *thing) override;
void thingRemoved(Thing *thing) override; void thingRemoved(Thing *thing) override;

View File

@ -1,5 +1,5 @@
{ {
"name": "Idm", "name": "idm",
"displayName": "iDM", "displayName": "iDM",
"id": "3968d86d-d51a-4ad1-a185-91faa017e38f", "id": "3968d86d-d51a-4ad1-a185-91faa017e38f",
"vendors": [ "vendors": [
@ -12,14 +12,23 @@
"name": "navigator2", "name": "navigator2",
"displayName": "Navigator 2.0", "displayName": "Navigator 2.0",
"id": "1c95ac91-4eca-4cbf-b0f4-d60d35d069ed", "id": "1c95ac91-4eca-4cbf-b0f4-d60d35d069ed",
"createMethods": ["user"], "createMethods": ["user", "discovery"],
"interfaces": ["thermostat", "connectable"], "interfaces": ["thermostat", "connectable"],
"paramTypes": [ "paramTypes": [
{ {
"id": "05714e5c-d66a-4095-bbff-a0eb96fb035b", "id": "05714e5c-d66a-4095-bbff-a0eb96fb035b",
"name":"ipAddress", "name":"ipAddress",
"displayName": "IP address", "displayName": "IP address",
"type": "QString" "inputType": "IPv4Address",
"type": "QString",
"defaultValue": "0.0.0.0"
},
{
"id": "d178ca29-41a1-4f56-82ec-76a833c1de50",
"name": "macAddress",
"displayName": "MAC address",
"type": "QString",
"defaultValue": ""
} }
], ],
"stateTypes":[ "stateTypes":[