etm-powersync-plugins-modbus/eastron/integrationplugineastron.cpp
2026-05-31 11:50:55 +02:00

709 lines
36 KiB
C++

// SPDX-License-Identifier: GPL-3.0-or-later
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright (C) 2013 - 2024, nymea GmbH
* Copyright (C) 2025, ETM-Schurig SARL
*
* This file is part of nymea-plugins-modbus.
*
* nymea-plugins-modbus 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, either version 3 of the License, or
* (at your option) any later version.
*
* nymea-plugins-modbus 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-plugins-modbus. If not, see <https://www.gnu.org/licenses/>.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "integrationplugineastron.h"
#include "plugininfo.h"
IntegrationPluginEastron::IntegrationPluginEastron()
{
}
void IntegrationPluginEastron::init()
{
connect(hardwareManager()->modbusRtuResource(), &ModbusRtuHardwareResource::modbusRtuMasterRemoved,
this, [=](const QUuid &modbusUuid) {
qCDebug(dcEastron()) << "Modbus RTU master removed:" << modbusUuid.toString();
foreach (Thing *thing, myThings()) {
ThingClassId classId = thing->thingClassId();
if (classId == sdm630ThingClassId || classId == sdm630ConsumerThingClassId || classId == sdm630ProducerThingClassId) {
if (thing->paramValue(sdm630ThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm630ConnectedStateTypeId, false);
delete m_sdm630Connections.take(thing);
}
} else if (classId == sdm630ConsumerThingClassId) {
if (thing->paramValue(sdm630ConsumerThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm630ConsumerConnectedStateTypeId, false);
delete m_sdm630Connections.take(thing);
}
} else if (classId == sdm630ProducerThingClassId) {
if (thing->paramValue(sdm630ProducerThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm630ProducerConnectedStateTypeId, false);
delete m_sdm630Connections.take(thing);
}
} else if (classId == sdm72ThingClassId) {
if (thing->paramValue(sdm72ThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm72ConnectedStateTypeId, false);
delete m_sdm72Connections.take(thing);
}
} else if (classId == sdm72ConsumerThingClassId) {
if (thing->paramValue(sdm72ConsumerThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm72ConsumerConnectedStateTypeId, false);
delete m_sdm72Connections.take(thing);
}
} else if (classId == sdm72ProducerThingClassId) {
if (thing->paramValue(sdm72ProducerThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm72ProducerConnectedStateTypeId, false);
delete m_sdm72Connections.take(thing);
}
} else if (classId == sdm120ThingClassId) {
if (thing->paramValue(sdm120ThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm120ConnectedStateTypeId, false);
delete m_sdm120Connections.take(thing);
}
} else if (classId == sdm120ConsumerThingClassId) {
if (thing->paramValue(sdm120ConsumerThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm120ConsumerConnectedStateTypeId, false);
delete m_sdm120Connections.take(thing);
}
} else if (classId == sdm120ProducerThingClassId) {
if (thing->paramValue(sdm120ProducerThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm120ProducerConnectedStateTypeId, false);
delete m_sdm120Connections.take(thing);
}
} else if (classId == sdm220ThingClassId) {
if (thing->paramValue(sdm220ThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm220ConnectedStateTypeId, false);
delete m_sdm120Connections.take(thing);
}
} else if (classId == sdm220ConsumerThingClassId) {
if (thing->paramValue(sdm220ConsumerThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm220ConsumerConnectedStateTypeId, false);
delete m_sdm120Connections.take(thing);
}
} else if (classId == sdm220ProducerThingClassId) {
if (thing->paramValue(sdm220ProducerThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm220ProducerConnectedStateTypeId, false);
delete m_sdm120Connections.take(thing);
}
} else if (classId == sdm230ThingClassId) {
if (thing->paramValue(sdm230ThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm230ConnectedStateTypeId, false);
delete m_sdm120Connections.take(thing);
}
} else if (classId == sdm230ConsumerThingClassId) {
if (thing->paramValue(sdm230ConsumerThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm230ConsumerConnectedStateTypeId, false);
delete m_sdm120Connections.take(thing);
}
} else if (classId == sdm230ProducerThingClassId) {
if (thing->paramValue(sdm230ProducerThingModbusMasterUuidParamTypeId) == modbusUuid) {
thing->setStateValue(sdm230ProducerConnectedStateTypeId, false);
delete m_sdm120Connections.take(thing);
}
}
}
});
}
void IntegrationPluginEastron::discoverThings(ThingDiscoveryInfo *info)
{
ThingClassId classId = info->thingClassId();
QString modelName;
ParamTypeId discoverySlaveParamTypeId;
ParamTypeId thingSlaveParamTypeId;
ParamTypeId thingMasterUuidParamTypeId;
if (classId == sdm630ThingClassId) {
modelName = "SDM630";
discoverySlaveParamTypeId = sdm630DiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm630ThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm630ThingModbusMasterUuidParamTypeId;
} else if (classId == sdm630ConsumerThingClassId) {
modelName = "SDM630";
discoverySlaveParamTypeId = sdm630ConsumerDiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm630ConsumerThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm630ConsumerThingModbusMasterUuidParamTypeId;
} else if (classId == sdm630ProducerThingClassId) {
modelName = "SDM630";
discoverySlaveParamTypeId = sdm630ProducerDiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm630ProducerThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm630ProducerThingModbusMasterUuidParamTypeId;
} else if (classId == sdm72ThingClassId) {
modelName = "SDM72";
discoverySlaveParamTypeId = sdm72DiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm72ThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm72ThingModbusMasterUuidParamTypeId;
} else if (classId == sdm72ConsumerThingClassId) {
modelName = "SDM72";
discoverySlaveParamTypeId = sdm72ConsumerDiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm72ConsumerThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm72ConsumerThingModbusMasterUuidParamTypeId;
} else if (classId == sdm72ProducerThingClassId) {
modelName = "SDM72";
discoverySlaveParamTypeId = sdm72ProducerDiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm72ProducerThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm72ProducerThingModbusMasterUuidParamTypeId;
} else if (classId == sdm120ThingClassId) {
modelName = "SDM120";
discoverySlaveParamTypeId = sdm120DiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm120ThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm120ThingModbusMasterUuidParamTypeId;
} else if (classId == sdm120ConsumerThingClassId) {
modelName = "SDM120";
discoverySlaveParamTypeId = sdm120ConsumerDiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm120ConsumerThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm120ConsumerThingModbusMasterUuidParamTypeId;
} else if (classId == sdm120ProducerThingClassId) {
modelName = "SDM120";
discoverySlaveParamTypeId = sdm120ProducerDiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm120ProducerThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm120ProducerThingModbusMasterUuidParamTypeId;
} else if (classId == sdm220ThingClassId) {
modelName = "SDM220";
discoverySlaveParamTypeId = sdm220DiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm220ThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm220ThingModbusMasterUuidParamTypeId;
} else if (classId == sdm220ConsumerThingClassId) {
modelName = "SDM220";
discoverySlaveParamTypeId = sdm220ConsumerDiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm220ConsumerThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm220ConsumerThingModbusMasterUuidParamTypeId;
} else if (classId == sdm220ProducerThingClassId) {
modelName = "SDM220";
discoverySlaveParamTypeId = sdm220ProducerDiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm220ProducerThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm220ProducerThingModbusMasterUuidParamTypeId;
} else if (classId == sdm230ThingClassId) {
modelName = "SDM230";
discoverySlaveParamTypeId = sdm230DiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm230ThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm230ThingModbusMasterUuidParamTypeId;
} else if (classId == sdm230ConsumerThingClassId) {
modelName = "SDM230";
discoverySlaveParamTypeId = sdm230ConsumerDiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm230ConsumerThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm230ConsumerThingModbusMasterUuidParamTypeId;
} else if (classId == sdm230ProducerThingClassId) {
modelName = "SDM230";
discoverySlaveParamTypeId = sdm230ProducerDiscoverySlaveAddressParamTypeId;
thingSlaveParamTypeId = sdm230ProducerThingSlaveAddressParamTypeId;
thingMasterUuidParamTypeId = sdm230ProducerThingModbusMasterUuidParamTypeId;
} else {
info->finish(Thing::ThingErrorThingClassNotFound);
return;
}
discoverRtuDevices(info, modelName, discoverySlaveParamTypeId, thingSlaveParamTypeId, thingMasterUuidParamTypeId);
}
void IntegrationPluginEastron::discoverRtuDevices(ThingDiscoveryInfo *info, const QString &modelName,
const ParamTypeId &discoverySlaveParamTypeId,
const ParamTypeId &thingSlaveParamTypeId,
const ParamTypeId &thingMasterUuidParamTypeId)
{
if (hardwareManager()->modbusRtuResource()->modbusRtuMasters().isEmpty()) {
info->finish(Thing::ThingErrorHardwareNotAvailable,
QT_TR_NOOP("No Modbus RTU interface available. Please set up the Modbus RTU interface first."));
return;
}
uint slaveAddress = info->params().paramValue(discoverySlaveParamTypeId).toUInt();
if (slaveAddress == 0 || slaveAddress > 254) {
info->finish(Thing::ThingErrorInvalidParameter,
QT_TR_NOOP("The Modbus slave address must be a value between 1 and 254."));
return;
}
foreach (ModbusRtuMaster *modbusMaster, hardwareManager()->modbusRtuResource()->modbusRtuMasters()) {
qCDebug(dcEastron()) << "Found RTU master" << modbusMaster << "connected:" << modbusMaster->connected();
if (!modbusMaster->connected())
continue;
ThingDescriptor descriptor(info->thingClassId(), modelName,
QString::number(slaveAddress) + " " + modbusMaster->serialPort());
ParamList params;
params << Param(thingSlaveParamTypeId, slaveAddress);
params << Param(thingMasterUuidParamTypeId, modbusMaster->modbusUuid());
descriptor.setParams(params);
info->addThingDescriptor(descriptor);
}
info->finish(Thing::ThingErrorNoError);
}
void IntegrationPluginEastron::setupThing(ThingSetupInfo *info)
{
ThingClassId classId = info->thing()->thingClassId();
if (classId == sdm630ThingClassId || classId == sdm630ConsumerThingClassId || classId == sdm630ProducerThingClassId) {
setupSdm630(info);
} else if (classId == sdm72ThingClassId || classId == sdm72ConsumerThingClassId || classId == sdm72ProducerThingClassId) {
setupSdm72(info);
} else if (classId == sdm120ThingClassId || classId == sdm120ConsumerThingClassId || classId == sdm120ProducerThingClassId
|| classId == sdm220ThingClassId || classId == sdm220ConsumerThingClassId || classId == sdm220ProducerThingClassId
|| classId == sdm230ThingClassId || classId == sdm230ConsumerThingClassId || classId == sdm230ProducerThingClassId) {
setupSdm120(info);
} else {
info->finish(Thing::ThingErrorThingClassNotFound);
}
}
void IntegrationPluginEastron::setupSdm630(ThingSetupInfo *info)
{
Thing *thing = info->thing();
ThingClassId classId = thing->thingClassId();
ParamTypeId slaveParamTypeId;
ParamTypeId masterUuidParamTypeId;
StateTypeId connectedStateTypeId;
if (classId == sdm630ThingClassId) {
slaveParamTypeId = sdm630ThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm630ThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm630ConnectedStateTypeId;
} else if (classId == sdm630ConsumerThingClassId) {
slaveParamTypeId = sdm630ConsumerThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm630ConsumerThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm630ConsumerConnectedStateTypeId;
} else {
slaveParamTypeId = sdm630ProducerThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm630ProducerThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm630ProducerConnectedStateTypeId;
}
uint address = thing->paramValue(slaveParamTypeId).toUInt();
if (address == 0 || address > 254) {
qCWarning(dcEastron()) << "Setup failed, invalid slave address" << address;
info->finish(Thing::ThingErrorSetupFailed,
QT_TR_NOOP("The Modbus address not valid. It must be a value between 1 and 254."));
return;
}
QUuid uuid = thing->paramValue(masterUuidParamTypeId).toUuid();
if (!hardwareManager()->modbusRtuResource()->hasModbusRtuMaster(uuid)) {
qCWarning(dcEastron()) << "Setup failed, Modbus RTU master not available";
info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("The Modbus RTU interface not available."));
return;
}
if (m_sdm630Connections.contains(thing))
m_sdm630Connections.take(thing)->deleteLater();
Sdm630ModbusRtuConnection *connection = new Sdm630ModbusRtuConnection(
hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), address, this);
connect(connection, &Sdm630ModbusRtuConnection::reachableChanged, this, [=](bool reachable) {
thing->setStateValue(connectedStateTypeId, reachable);
});
if (classId == sdm630ThingClassId) {
connect(connection, &Sdm630ModbusRtuConnection::voltagePhaseAChanged, this, [=](float v) {
thing->setStateValue(sdm630VoltagePhaseAStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::voltagePhaseBChanged, this, [=](float v) {
thing->setStateValue(sdm630VoltagePhaseBStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::voltagePhaseCChanged, this, [=](float v) {
thing->setStateValue(sdm630VoltagePhaseCStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::currentPhaseAChanged, this, [=](float v) {
thing->setStateValue(sdm630CurrentPhaseAStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::currentPhaseBChanged, this, [=](float v) {
thing->setStateValue(sdm630CurrentPhaseBStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::currentPhaseCChanged, this, [=](float v) {
thing->setStateValue(sdm630CurrentPhaseCStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::totalCurrentPowerChanged, this, [=](float v) {
thing->setStateValue(sdm630CurrentPowerStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::powerPhaseAChanged, this, [=](float v) {
thing->setStateValue(sdm630CurrentPowerPhaseAStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::powerPhaseBChanged, this, [=](float v) {
thing->setStateValue(sdm630CurrentPowerPhaseBStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::powerPhaseCChanged, this, [=](float v) {
thing->setStateValue(sdm630CurrentPowerPhaseCStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::frequencyChanged, this, [=](float v) {
thing->setStateValue(sdm630FrequencyStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::totalEnergyConsumedChanged, this, [=](float v) {
thing->setStateValue(sdm630TotalEnergyConsumedStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::totalEnergyProducedChanged, this, [=](float v) {
thing->setStateValue(sdm630TotalEnergyProducedStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::energyConsumedPhaseAChanged, this, [=](float v) {
thing->setStateValue(sdm630EnergyConsumedPhaseAStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::energyConsumedPhaseBChanged, this, [=](float v) {
thing->setStateValue(sdm630EnergyConsumedPhaseBStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::energyConsumedPhaseCChanged, this, [=](float v) {
thing->setStateValue(sdm630EnergyConsumedPhaseCStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::energyProducedPhaseAChanged, this, [=](float v) {
thing->setStateValue(sdm630EnergyProducedPhaseAStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::energyProducedPhaseBChanged, this, [=](float v) {
thing->setStateValue(sdm630EnergyProducedPhaseBStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::energyProducedPhaseCChanged, this, [=](float v) {
thing->setStateValue(sdm630EnergyProducedPhaseCStateTypeId, v);
});
} else if (classId == sdm630ConsumerThingClassId) {
connect(connection, &Sdm630ModbusRtuConnection::totalCurrentPowerChanged, this, [=](float v) {
thing->setStateValue(sdm630ConsumerCurrentPowerStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::totalEnergyConsumedChanged, this, [=](float v) {
thing->setStateValue(sdm630ConsumerTotalEnergyConsumedStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::frequencyChanged, this, [=](float v) {
thing->setStateValue(sdm630ConsumerFrequencyStateTypeId, v);
});
} else { // sdm630Producer
connect(connection, &Sdm630ModbusRtuConnection::totalCurrentPowerChanged, this, [=](float v) {
thing->setStateValue(sdm630ProducerCurrentPowerStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::totalEnergyProducedChanged, this, [=](float v) {
thing->setStateValue(sdm630ProducerTotalEnergyProducedStateTypeId, v);
});
connect(connection, &Sdm630ModbusRtuConnection::frequencyChanged, this, [=](float v) {
thing->setStateValue(sdm630ProducerFrequencyStateTypeId, v);
});
}
m_sdm630Connections.insert(thing, connection);
info->finish(Thing::ThingErrorNoError);
}
void IntegrationPluginEastron::setupSdm72(ThingSetupInfo *info)
{
Thing *thing = info->thing();
ThingClassId classId = thing->thingClassId();
ParamTypeId slaveParamTypeId;
ParamTypeId masterUuidParamTypeId;
StateTypeId connectedStateTypeId;
if (classId == sdm72ThingClassId) {
slaveParamTypeId = sdm72ThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm72ThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm72ConnectedStateTypeId;
} else if (classId == sdm72ConsumerThingClassId) {
slaveParamTypeId = sdm72ConsumerThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm72ConsumerThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm72ConsumerConnectedStateTypeId;
} else {
slaveParamTypeId = sdm72ProducerThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm72ProducerThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm72ProducerConnectedStateTypeId;
}
uint address = thing->paramValue(slaveParamTypeId).toUInt();
if (address == 0 || address > 254) {
qCWarning(dcEastron()) << "Setup failed, invalid slave address" << address;
info->finish(Thing::ThingErrorSetupFailed,
QT_TR_NOOP("The Modbus address not valid. It must be a value between 1 and 254."));
return;
}
QUuid uuid = thing->paramValue(masterUuidParamTypeId).toUuid();
if (!hardwareManager()->modbusRtuResource()->hasModbusRtuMaster(uuid)) {
qCWarning(dcEastron()) << "Setup failed, Modbus RTU master not available";
info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("The Modbus RTU interface not available."));
return;
}
if (m_sdm72Connections.contains(thing))
m_sdm72Connections.take(thing)->deleteLater();
Sdm72ModbusRtuConnection *connection = new Sdm72ModbusRtuConnection(
hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), address, this);
connect(connection, &Sdm72ModbusRtuConnection::reachableChanged, this, [=](bool reachable) {
thing->setStateValue(connectedStateTypeId, reachable);
});
if (classId == sdm72ThingClassId) {
connect(connection, &Sdm72ModbusRtuConnection::voltagePhaseAChanged, this, [=](float v) {
thing->setStateValue(sdm72VoltagePhaseAStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::voltagePhaseBChanged, this, [=](float v) {
thing->setStateValue(sdm72VoltagePhaseBStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::voltagePhaseCChanged, this, [=](float v) {
thing->setStateValue(sdm72VoltagePhaseCStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::currentPhaseAChanged, this, [=](float v) {
thing->setStateValue(sdm72CurrentPhaseAStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::currentPhaseBChanged, this, [=](float v) {
thing->setStateValue(sdm72CurrentPhaseBStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::currentPhaseCChanged, this, [=](float v) {
thing->setStateValue(sdm72CurrentPhaseCStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::totalCurrentPowerChanged, this, [=](float v) {
thing->setStateValue(sdm72CurrentPowerStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::powerPhaseAChanged, this, [=](float v) {
thing->setStateValue(sdm72CurrentPowerPhaseAStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::powerPhaseBChanged, this, [=](float v) {
thing->setStateValue(sdm72CurrentPowerPhaseBStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::powerPhaseCChanged, this, [=](float v) {
thing->setStateValue(sdm72CurrentPowerPhaseCStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::frequencyChanged, this, [=](float v) {
thing->setStateValue(sdm72FrequencyStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::totalEnergyConsumedChanged, this, [=](float v) {
thing->setStateValue(sdm72TotalEnergyConsumedStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::totalEnergyProducedChanged, this, [=](float v) {
thing->setStateValue(sdm72TotalEnergyProducedStateTypeId, v);
});
} else if (classId == sdm72ConsumerThingClassId) {
connect(connection, &Sdm72ModbusRtuConnection::totalCurrentPowerChanged, this, [=](float v) {
thing->setStateValue(sdm72ConsumerCurrentPowerStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::totalEnergyConsumedChanged, this, [=](float v) {
thing->setStateValue(sdm72ConsumerTotalEnergyConsumedStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::frequencyChanged, this, [=](float v) {
thing->setStateValue(sdm72ConsumerFrequencyStateTypeId, v);
});
} else { // sdm72Producer
connect(connection, &Sdm72ModbusRtuConnection::totalCurrentPowerChanged, this, [=](float v) {
thing->setStateValue(sdm72ProducerCurrentPowerStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::totalEnergyProducedChanged, this, [=](float v) {
thing->setStateValue(sdm72ProducerTotalEnergyProducedStateTypeId, v);
});
connect(connection, &Sdm72ModbusRtuConnection::frequencyChanged, this, [=](float v) {
thing->setStateValue(sdm72ProducerFrequencyStateTypeId, v);
});
}
m_sdm72Connections.insert(thing, connection);
info->finish(Thing::ThingErrorNoError);
}
void IntegrationPluginEastron::setupSdm120(ThingSetupInfo *info)
{
Thing *thing = info->thing();
ThingClassId classId = thing->thingClassId();
ParamTypeId slaveParamTypeId;
ParamTypeId masterUuidParamTypeId;
StateTypeId connectedStateTypeId;
StateTypeId voltageStateTypeId;
StateTypeId currentStateTypeId;
StateTypeId powerStateTypeId;
StateTypeId frequencyStateTypeId;
StateTypeId totalEnergyConsumedStateTypeId;
StateTypeId totalEnergyProducedStateTypeId;
bool isEnergyMeter = false;
if (classId == sdm120ThingClassId) {
slaveParamTypeId = sdm120ThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm120ThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm120ConnectedStateTypeId;
voltageStateTypeId = sdm120VoltagePhaseAStateTypeId;
currentStateTypeId = sdm120CurrentPhaseAStateTypeId;
powerStateTypeId = sdm120CurrentPowerStateTypeId;
frequencyStateTypeId = sdm120FrequencyStateTypeId;
totalEnergyConsumedStateTypeId = sdm120TotalEnergyConsumedStateTypeId;
totalEnergyProducedStateTypeId = sdm120TotalEnergyProducedStateTypeId;
isEnergyMeter = true;
} else if (classId == sdm120ConsumerThingClassId) {
slaveParamTypeId = sdm120ConsumerThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm120ConsumerThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm120ConsumerConnectedStateTypeId;
powerStateTypeId = sdm120ConsumerCurrentPowerStateTypeId;
frequencyStateTypeId = sdm120ConsumerFrequencyStateTypeId;
totalEnergyConsumedStateTypeId = sdm120ConsumerTotalEnergyConsumedStateTypeId;
} else if (classId == sdm120ProducerThingClassId) {
slaveParamTypeId = sdm120ProducerThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm120ProducerThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm120ProducerConnectedStateTypeId;
powerStateTypeId = sdm120ProducerCurrentPowerStateTypeId;
frequencyStateTypeId = sdm120ProducerFrequencyStateTypeId;
totalEnergyProducedStateTypeId = sdm120ProducerTotalEnergyProducedStateTypeId;
} else if (classId == sdm220ThingClassId) {
slaveParamTypeId = sdm220ThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm220ThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm220ConnectedStateTypeId;
voltageStateTypeId = sdm220VoltagePhaseAStateTypeId;
currentStateTypeId = sdm220CurrentPhaseAStateTypeId;
powerStateTypeId = sdm220CurrentPowerStateTypeId;
frequencyStateTypeId = sdm220FrequencyStateTypeId;
totalEnergyConsumedStateTypeId = sdm220TotalEnergyConsumedStateTypeId;
totalEnergyProducedStateTypeId = sdm220TotalEnergyProducedStateTypeId;
isEnergyMeter = true;
} else if (classId == sdm220ConsumerThingClassId) {
slaveParamTypeId = sdm220ConsumerThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm220ConsumerThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm220ConsumerConnectedStateTypeId;
powerStateTypeId = sdm220ConsumerCurrentPowerStateTypeId;
frequencyStateTypeId = sdm220ConsumerFrequencyStateTypeId;
totalEnergyConsumedStateTypeId = sdm220ConsumerTotalEnergyConsumedStateTypeId;
} else if (classId == sdm220ProducerThingClassId) {
slaveParamTypeId = sdm220ProducerThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm220ProducerThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm220ProducerConnectedStateTypeId;
powerStateTypeId = sdm220ProducerCurrentPowerStateTypeId;
frequencyStateTypeId = sdm220ProducerFrequencyStateTypeId;
totalEnergyProducedStateTypeId = sdm220ProducerTotalEnergyProducedStateTypeId;
} else if (classId == sdm230ThingClassId) {
slaveParamTypeId = sdm230ThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm230ThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm230ConnectedStateTypeId;
voltageStateTypeId = sdm230VoltagePhaseAStateTypeId;
currentStateTypeId = sdm230CurrentPhaseAStateTypeId;
powerStateTypeId = sdm230CurrentPowerStateTypeId;
frequencyStateTypeId = sdm230FrequencyStateTypeId;
totalEnergyConsumedStateTypeId = sdm230TotalEnergyConsumedStateTypeId;
totalEnergyProducedStateTypeId = sdm230TotalEnergyProducedStateTypeId;
isEnergyMeter = true;
} else if (classId == sdm230ConsumerThingClassId) {
slaveParamTypeId = sdm230ConsumerThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm230ConsumerThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm230ConsumerConnectedStateTypeId;
powerStateTypeId = sdm230ConsumerCurrentPowerStateTypeId;
frequencyStateTypeId = sdm230ConsumerFrequencyStateTypeId;
totalEnergyConsumedStateTypeId = sdm230ConsumerTotalEnergyConsumedStateTypeId;
} else { // sdm230Producer
slaveParamTypeId = sdm230ProducerThingSlaveAddressParamTypeId;
masterUuidParamTypeId = sdm230ProducerThingModbusMasterUuidParamTypeId;
connectedStateTypeId = sdm230ProducerConnectedStateTypeId;
powerStateTypeId = sdm230ProducerCurrentPowerStateTypeId;
frequencyStateTypeId = sdm230ProducerFrequencyStateTypeId;
totalEnergyProducedStateTypeId = sdm230ProducerTotalEnergyProducedStateTypeId;
}
uint address = thing->paramValue(slaveParamTypeId).toUInt();
if (address == 0 || address > 254) {
qCWarning(dcEastron()) << "Setup failed, invalid slave address" << address;
info->finish(Thing::ThingErrorSetupFailed,
QT_TR_NOOP("The Modbus address not valid. It must be a value between 1 and 254."));
return;
}
QUuid uuid = thing->paramValue(masterUuidParamTypeId).toUuid();
if (!hardwareManager()->modbusRtuResource()->hasModbusRtuMaster(uuid)) {
qCWarning(dcEastron()) << "Setup failed, Modbus RTU master not available";
info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("The Modbus RTU interface not available."));
return;
}
if (m_sdm120Connections.contains(thing))
m_sdm120Connections.take(thing)->deleteLater();
Sdm120ModbusRtuConnection *connection = new Sdm120ModbusRtuConnection(
hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), address, this);
connect(connection, &Sdm120ModbusRtuConnection::reachableChanged, this, [=](bool reachable) {
thing->setStateValue(connectedStateTypeId, reachable);
});
connect(connection, &Sdm120ModbusRtuConnection::activePowerChanged, this, [=](float v) {
thing->setStateValue(powerStateTypeId, v);
});
connect(connection, &Sdm120ModbusRtuConnection::frequencyChanged, this, [=](float v) {
thing->setStateValue(frequencyStateTypeId, v);
});
if (isEnergyMeter) {
connect(connection, &Sdm120ModbusRtuConnection::voltageChanged, this, [=](float v) {
thing->setStateValue(voltageStateTypeId, v);
});
connect(connection, &Sdm120ModbusRtuConnection::currentChanged, this, [=](float v) {
thing->setStateValue(currentStateTypeId, v);
});
connect(connection, &Sdm120ModbusRtuConnection::totalEnergyConsumedChanged, this, [=](float v) {
thing->setStateValue(totalEnergyConsumedStateTypeId, v);
});
connect(connection, &Sdm120ModbusRtuConnection::totalEnergyProducedChanged, this, [=](float v) {
thing->setStateValue(totalEnergyProducedStateTypeId, v);
});
} else {
// Consumer or producer: connect only the relevant energy direction
bool isProducer = (classId == sdm120ProducerThingClassId
|| classId == sdm220ProducerThingClassId
|| classId == sdm230ProducerThingClassId);
if (isProducer) {
connect(connection, &Sdm120ModbusRtuConnection::totalEnergyProducedChanged, this, [=](float v) {
thing->setStateValue(totalEnergyProducedStateTypeId, v);
});
} else {
connect(connection, &Sdm120ModbusRtuConnection::totalEnergyConsumedChanged, this, [=](float v) {
thing->setStateValue(totalEnergyConsumedStateTypeId, v);
});
}
}
m_sdm120Connections.insert(thing, connection);
info->finish(Thing::ThingErrorNoError);
}
void IntegrationPluginEastron::postSetupThing(Thing *thing)
{
qCDebug(dcEastron()) << "Post setup thing" << thing->name();
if (!m_refreshTimer) {
m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(2);
connect(m_refreshTimer, &PluginTimer::timeout, this, [this] {
foreach (Thing *thing, myThings()) {
if (m_sdm630Connections.contains(thing))
m_sdm630Connections.value(thing)->update();
else if (m_sdm72Connections.contains(thing))
m_sdm72Connections.value(thing)->update();
else if (m_sdm120Connections.contains(thing))
m_sdm120Connections.value(thing)->update();
}
});
qCDebug(dcEastron()) << "Refresh timer started";
m_refreshTimer->start();
}
}
void IntegrationPluginEastron::thingRemoved(Thing *thing)
{
qCDebug(dcEastron()) << "Thing removed" << thing->name();
if (m_sdm630Connections.contains(thing))
m_sdm630Connections.take(thing)->deleteLater();
else if (m_sdm72Connections.contains(thing))
m_sdm72Connections.take(thing)->deleteLater();
else if (m_sdm120Connections.contains(thing))
m_sdm120Connections.take(thing)->deleteLater();
if (myThings().isEmpty() && m_refreshTimer) {
hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer);
m_refreshTimer = nullptr;
qCDebug(dcEastron()) << "Refresh timer stopped";
}
}