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();
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::readRequestError, this, &Idm::onModbusError);
connect(m_modbusMaster, &ModbusTCPMaster::writeRequestError, this, &Idm::onModbusError);
connect(m_modbusMaster, &ModbusTCPMaster::writeRequestExecuted, this, &Idm::writeRequestExecuted);
}
connect(m_modbusMaster, &ModbusTCPMaster::receivedHoldingRegister, this, &Idm::onReceivedHoldingRegister);
connect(m_modbusMaster, &ModbusTCPMaster::readRequestError, this, &Idm::onModbusError);
connect(m_modbusMaster, &ModbusTCPMaster::writeRequestError, this, &Idm::onModbusError);
connect(m_modbusMaster, &ModbusTCPMaster::writeRequestExecuted, this, &Idm::writeRequestExecuted);
}
Idm::~Idm()
@ -61,21 +57,21 @@ bool Idm::connectDevice()
return m_modbusMaster->connectDevice();
}
QHostAddress Idm::getIdmAddress() const
QHostAddress Idm::address() const
{
return m_hostAddress;
}
void Idm::getStatus()
{
//this request starts an update cycle
// This request starts an update cycle
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::OutsideTemperature, 2);
}
QUuid Idm::setTargetTemperature(double targetTemperature)
{
QVector<uint16_t> value = ModbusHelpers::convertFloatToRegister(targetTemperature);
return m_modbusMaster->writeHoldingRegisters(Idm::modbusUnitID, Idm::RegisterList::RoomTemperatureTargetHeatingEcoHKA, value);
QVector<uint16_t> value = ModbusHelpers::convertFloatToRegister(targetTemperature);
return m_modbusMaster->writeHoldingRegisters(Idm::modbusUnitID, Idm::RegisterList::RoomTemperatureTargetHeatingEcoHKA, value);
}
void Idm::onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const QVector<quint16> &value)

View File

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

View File

@ -28,6 +28,7 @@
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "network/networkdevicediscovery.h"
#include "integrationpluginidm.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)
{
Thing *thing = info->thing();
@ -57,8 +100,8 @@ void IntegrationPluginIdm::setupThing(ThingSetupInfo *info)
qCDebug(dcIdm()) << "User entered address: " << hostAddress.toString();
/* Check, if address is already in use for another device */
Q_FOREACH (Idm *idm, m_idmConnections) {
if (hostAddress.isEqual(idm->getIdmAddress())) {
foreach (Idm *idm, m_idmConnections) {
if (hostAddress.isEqual(idm->address())) {
qCWarning(dcIdm()) << "Address already in use";
info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("IP address already in use"));
return;
@ -144,8 +187,7 @@ void IntegrationPluginIdm::executeAction(ThingActionInfo *info)
double targetTemperature = thing->stateValue(navigator2TargetTemperatureStateTypeId).toDouble();
QUuid requestId = idm->setTargetTemperature(targetTemperature);
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 {
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) {
qCDebug(dcIdm()) << "Updating thing" << thing->name();
Idm *idm = m_idmConnections.value(thing);
if (!idm) {
return;
}
if (!idm) { return; };
idm->getStatus();
}
}
@ -170,7 +209,6 @@ void IntegrationPluginIdm::update(Thing *thing)
void IntegrationPluginIdm::onStatusUpdated(const IdmInfo &info)
{
qCDebug(dcIdm()) << "Received status from heat pump";
Idm *idm = qobject_cast<Idm *>(sender());
Thing *thing = m_idmConnections.key(idm);
@ -205,8 +243,6 @@ void IntegrationPluginIdm::onWriteRequestExecuted(const QUuid &requestId, bool s
void IntegrationPluginIdm::onRefreshTimer()
{
qCDebug(dcIdm()) << "onRefreshTimer called";
foreach (Thing *thing, myThings().filterByThingClassId(navigator2ThingClassId)) {
update(thing);
}

View File

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

View File

@ -1,5 +1,5 @@
{
"name": "Idm",
"name": "idm",
"displayName": "iDM",
"id": "3968d86d-d51a-4ad1-a185-91faa017e38f",
"vendors": [
@ -12,14 +12,23 @@
"name": "navigator2",
"displayName": "Navigator 2.0",
"id": "1c95ac91-4eca-4cbf-b0f4-d60d35d069ed",
"createMethods": ["user"],
"createMethods": ["user", "discovery"],
"interfaces": ["thermostat", "connectable"],
"paramTypes": [
{
"id": "05714e5c-d66a-4095-bbff-a0eb96fb035b",
"name":"ipAddress",
"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":[