From c393bbcf192a055812ddb2bd8080d0a7ba8bd54c Mon Sep 17 00:00:00 2001 From: Boernsman Date: Thu, 29 Apr 2021 16:34:45 +0200 Subject: [PATCH] changes requested by reviewer --- energymeters/README.md | 2 +- energymeters/bg-etechmodbusregister.h | 2 +- energymeters/energymeter.cpp | 21 ++- energymeters/energymeter.h | 11 +- energymeters/inepromodbusregister.h | 2 +- .../integrationpluginenergymeters.cpp | 166 +++++++++--------- energymeters/integrationpluginenergymeters.h | 2 +- .../integrationpluginenergymeters.json | 4 +- energymeters/registerdescriptor.h | 2 +- 9 files changed, 112 insertions(+), 100 deletions(-) diff --git a/energymeters/README.md b/energymeters/README.md index eea6276..0c90177 100644 --- a/energymeters/README.md +++ b/energymeters/README.md @@ -11,5 +11,5 @@ Connect Modbus RTU based energy meters. ## Requirements -* The plugin 'nymea-plugin-energymeter' must be installed +* The plugin 'nymea-plugin-energymeter' must be installed. * At least one Modbus RTU interface must be setup. diff --git a/energymeters/bg-etechmodbusregister.h b/energymeters/bg-etechmodbusregister.h index a0dd0ed..34bd78f 100644 --- a/energymeters/bg-etechmodbusregister.h +++ b/energymeters/bg-etechmodbusregister.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2021, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/energymeters/energymeter.cpp b/energymeters/energymeter.cpp index ac6bdda..cfb94b5 100644 --- a/energymeters/energymeter.cpp +++ b/energymeters/energymeter.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2021, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -42,12 +42,17 @@ EnergyMeter::EnergyMeter(ModbusRtuMaster *modbusMaster, int slaveAddress, const } -QUuid EnergyMeter::modbusRtuMasterUuid() +ModbusRtuMaster *EnergyMeter::modbusMaster() { - return m_modbusRtuMaster->modbusUuid(); + return m_modbusRtuMaster; } -bool EnergyMeter::connected() +void EnergyMeter::setModbusMaster(ModbusRtuMaster *modbusMaster) +{ + m_modbusRtuMaster = modbusMaster; +} + +bool EnergyMeter::connected() const { return m_connected; } @@ -112,6 +117,12 @@ bool EnergyMeter::getRegister(ModbusRegisterType type) if (!m_modbusRegisters.contains(type)) return false; + if (!m_modbusRtuMaster) + return false; + + if (!m_modbusRtuMaster->connected()) + return false; + ModbusRegisterDescriptor descriptor = m_modbusRegisters.value(type); ModbusRtuReply *reply = nullptr; @@ -199,6 +210,8 @@ bool EnergyMeter::getRegister(ModbusRegisterType type) value.f /= 1000.00; } emit producedEnergyReceived(value.f); + } else { + qCWarning(dcEnergyMeters()) << "EnergyMeter: Modbus register type not handled" << type; } }); return true; diff --git a/energymeters/energymeter.h b/energymeters/energymeter.h index 46b3da2..208fb23 100644 --- a/energymeters/energymeter.h +++ b/energymeters/energymeter.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2021, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -43,8 +43,10 @@ class EnergyMeter : public QObject public: explicit EnergyMeter(ModbusRtuMaster *modbusMaster, int slaveAddress, const QHash &modbusRegisters, QObject *parent = nullptr); - QUuid modbusRtuMasterUuid(); - bool connected(); + ModbusRtuMaster *modbusMaster(); + void setModbusMaster(ModbusRtuMaster *modbusMaster); + + bool connected() const; bool getVoltageL1(); bool getVoltageL2(); bool getVoltageL3(); @@ -87,9 +89,6 @@ signals: void powerFactorReceived(double powerFactor); void producedEnergyReceived(double energy); void consumedEnergyReceived(double energy); - -//private slot: -// void onRegisterReceived(); }; #endif // ENERGYMETER_H diff --git a/energymeters/inepromodbusregister.h b/energymeters/inepromodbusregister.h index 2bf4f24..e419c9d 100644 --- a/energymeters/inepromodbusregister.h +++ b/energymeters/inepromodbusregister.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2021, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/energymeters/integrationpluginenergymeters.cpp b/energymeters/integrationpluginenergymeters.cpp index b0d85fc..8b68f1d 100644 --- a/energymeters/integrationpluginenergymeters.cpp +++ b/energymeters/integrationpluginenergymeters.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2021, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. @@ -95,15 +95,17 @@ void IntegrationPluginEnergyMeters::init() connect(hardwareManager()->modbusRtuResource(), &ModbusRtuHardwareResource::modbusRtuMasterRemoved, this, [=] (const QUuid &modbusUuid){ qCDebug(dcEnergyMeters()) << "Modbus RTU master has been removed" << modbusUuid.toString(); - // Check if there is any device using this resource - foreach (EnergyMeter * meter, m_energyMeters) { - if (meter->modbusRtuMasterUuid() == modbusUuid) { - Thing *thing = m_energyMeters.key(meter); - if (!thing) - return; + Q_FOREACH(Thing *thing, myThings()) { + if (m_modbusUuidParamTypeIds.contains(thing->thingClassId())) { + if (thing->paramValue(m_modbusUuidParamTypeIds.value(thing->thingClassId())) == modbusUuid) { + qCWarning(dcEnergyMeters()) << "Modbus RTU hardware resource removed for" << thing << ". The thing will not be functional any more until a new resource has been configured for it."; + thing->setStateValue(m_connectionStateTypeIds[thing->thingClassId()], false); - qCWarning(dcEnergyMeters()) << "Modbus RTU hardware resource removed for" << thing << ". The thing will not be functional any more until a new resource has been configured for it."; - thing->setStateValue(m_connectionStateTypeIds[thing->thingClassId()], false); + EnergyMeter *meter = m_energyMeters.value(thing); + if (!meter) + return; + meter->setModbusMaster(nullptr); + } } } }); @@ -119,29 +121,28 @@ void IntegrationPluginEnergyMeters::discoverThings(ThingDiscoveryInfo *info) return; } - if (m_connectionStateTypeIds.contains(info->thingClassId())) { - int slaveAddress = info->params().paramValue(m_discoverySlaveAddressParamTypeIds.value(info->thingClassId())).toInt(); - if (slaveAddress > 254 || slaveAddress == 0) { - info->finish(Thing::ThingErrorInvalidParameter, tr("Modbus slave address must be between 1 and 254")); - return; - } - Q_FOREACH(ModbusRtuMaster *modbusMaster, hardwareManager()->modbusRtuResource()->modbusRtuMasters()) { - qCDebug(dcEnergyMeters()) << "Found RTU master resource" << modbusMaster << "connected" << modbusMaster->connected(); - if (!modbusMaster->connected()) { - continue; - } - ThingDescriptor descriptor(info->thingClassId(), QT_TR_NOOP("Energy meter"), QT_TR_NOOP("Slave address ") +QString::number(slaveAddress)+" "+modbusMaster->serialPort()); - ParamList params; - params << Param(m_slaveIdParamTypeIds.value(info->thingClassId()), slaveAddress); - params << Param(m_modbusUuidParamTypeIds.value(info->thingClassId()), modbusMaster->modbusUuid()); - descriptor.setParams(params); - info->addThingDescriptor(descriptor); - } - info->finish(Thing::ThingErrorNoError); - return; - } else { + if (!m_connectionStateTypeIds.contains(info->thingClassId())) { Q_ASSERT_X(false, "discoverThings", QString("Unhandled thingClassId: %1").arg(info->thingClassId().toString()).toUtf8()); } + uint slaveAddress = info->params().paramValue(m_discoverySlaveAddressParamTypeIds.value(info->thingClassId())).toUInt(); + if (slaveAddress > 254 || slaveAddress == 0) { + info->finish(Thing::ThingErrorInvalidParameter, tr("Modbus slave address must be between 1 and 254")); + return; + } + Q_FOREACH(ModbusRtuMaster *modbusMaster, hardwareManager()->modbusRtuResource()->modbusRtuMasters()) { + qCDebug(dcEnergyMeters()) << "Found RTU master resource" << modbusMaster << "connected" << modbusMaster->connected(); + if (!modbusMaster->connected()) { + continue; + } + ThingDescriptor descriptor(info->thingClassId(), QT_TR_NOOP("Energy meter"), QT_TR_NOOP("Slave address ") +QString::number(slaveAddress)+" "+modbusMaster->serialPort()); + ParamList params; + params << Param(m_slaveIdParamTypeIds.value(info->thingClassId()), slaveAddress); + params << Param(m_modbusUuidParamTypeIds.value(info->thingClassId()), modbusMaster->modbusUuid()); + descriptor.setParams(params); + info->addThingDescriptor(descriptor); + } + info->finish(Thing::ThingErrorNoError); + return; } void IntegrationPluginEnergyMeters::setupThing(ThingSetupInfo *info) @@ -149,50 +150,49 @@ void IntegrationPluginEnergyMeters::setupThing(ThingSetupInfo *info) Thing *thing = info->thing(); qCDebug(dcEnergyMeters()) << "Setup thing" << thing->name(); - if (m_connectionStateTypeIds.contains(thing->thingClassId())) { - - if (m_energyMeters.contains(thing)) { - qCDebug(dcEnergyMeters()) << "Setup after rediscovery, cleaning up ..."; - m_energyMeters.take(thing)->deleteLater(); - } - int address = thing->paramValue(m_slaveIdParamTypeIds.value(thing->thingClassId())).toInt(); - if (address > 254 || address == 0) { - qCWarning(dcEnergyMeters()) << "Setup failed, slave address is not valid" << address; - info->finish(Thing::ThingErrorSetupFailed, tr("Slave address not valid, must be between 1 and 254")); - return; - } - QUuid uuid = thing->paramValue(m_modbusUuidParamTypeIds.value(thing->thingClassId())).toString(); - if (!hardwareManager()->modbusRtuResource()->hasModbusRtuMaster(uuid)) { - qCWarning(dcEnergyMeters()) << "Setup failed, hardware manager not available"; - info->finish(Thing::ThingErrorSetupFailed, tr("Modbus RTU resource not available.")); - return; - } - - EnergyMeter *meter = new EnergyMeter(hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), address, m_registerMaps.value(thing->thingClassId()), this); - connect(info, &ThingSetupInfo::aborted, meter, &EnergyMeter::deleteLater); - connect(meter, &EnergyMeter::consumedEnergyReceived, info, [this, info, meter] { - qCDebug(dcEnergyMeters()) << "Reply received, setup finished"; - connect(meter, &EnergyMeter::connectedChanged, this, &IntegrationPluginEnergyMeters::onConnectionStateChanged); - connect(meter, &EnergyMeter::voltageL1Received, this, &IntegrationPluginEnergyMeters::onVoltageL1Received); - connect(meter, &EnergyMeter::voltageL2Received, this, &IntegrationPluginEnergyMeters::onVoltageL2Received); - connect(meter, &EnergyMeter::voltageL3Received, this, &IntegrationPluginEnergyMeters::onVoltageL3Received); - connect(meter, &EnergyMeter::currentL1Received, this, &IntegrationPluginEnergyMeters::onCurrentL1Received); - connect(meter, &EnergyMeter::currentL2Received, this, &IntegrationPluginEnergyMeters::onCurrentL2Received); - connect(meter, &EnergyMeter::currentL3Received, this, &IntegrationPluginEnergyMeters::onCurrentL3Received); - connect(meter, &EnergyMeter::activePowerReceived, this, &IntegrationPluginEnergyMeters::onActivePowerReceived); - connect(meter, &EnergyMeter::powerFactorReceived, this, &IntegrationPluginEnergyMeters::onPowerFactorReceived); - connect(meter, &EnergyMeter::frequencyReceived, this, &IntegrationPluginEnergyMeters::onFrequencyReceived); - connect(meter, &EnergyMeter::producedEnergyReceived, this, &IntegrationPluginEnergyMeters::onProducedEnergyReceived); - connect(meter, &EnergyMeter::consumedEnergyReceived, this, &IntegrationPluginEnergyMeters::onConsumedEnergyReceived); - - m_energyMeters.insert(info->thing(), meter); - info->finish(Thing::ThingErrorNoError); - }); - meter->getEnergyConsumed(); - return; - } else { + if (!m_connectionStateTypeIds.contains(thing->thingClassId())) { Q_ASSERT_X(false, "setupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); } + + if (m_energyMeters.contains(thing)) { + qCDebug(dcEnergyMeters()) << "Setup after rediscovery, cleaning up ..."; + m_energyMeters.take(thing)->deleteLater(); + } + uint address = thing->paramValue(m_slaveIdParamTypeIds.value(thing->thingClassId())).toUInt(); + if (address > 254 || address == 0) { + qCWarning(dcEnergyMeters()) << "Setup failed, slave address is not valid" << address; + info->finish(Thing::ThingErrorSetupFailed, tr("Slave address not valid, must be between 1 and 254")); + return; + } + QUuid uuid = thing->paramValue(m_modbusUuidParamTypeIds.value(thing->thingClassId())).toUuid(); + if (!hardwareManager()->modbusRtuResource()->hasModbusRtuMaster(uuid)) { + qCWarning(dcEnergyMeters()) << "Setup failed, hardware manager not available"; + info->finish(Thing::ThingErrorSetupFailed, tr("Modbus RTU resource not available.")); + return; + } + + EnergyMeter *meter = new EnergyMeter(hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), address, m_registerMaps.value(thing->thingClassId()), this); + connect(info, &ThingSetupInfo::aborted, meter, &EnergyMeter::deleteLater); + connect(meter, &EnergyMeter::consumedEnergyReceived, info, [this, info, meter] { + qCDebug(dcEnergyMeters()) << "Reply received, setup finished"; + connect(meter, &EnergyMeter::connectedChanged, this, &IntegrationPluginEnergyMeters::onConnectionStateChanged); + connect(meter, &EnergyMeter::voltageL1Received, this, &IntegrationPluginEnergyMeters::onVoltageL1Received); + connect(meter, &EnergyMeter::voltageL2Received, this, &IntegrationPluginEnergyMeters::onVoltageL2Received); + connect(meter, &EnergyMeter::voltageL3Received, this, &IntegrationPluginEnergyMeters::onVoltageL3Received); + connect(meter, &EnergyMeter::currentL1Received, this, &IntegrationPluginEnergyMeters::onCurrentL1Received); + connect(meter, &EnergyMeter::currentL2Received, this, &IntegrationPluginEnergyMeters::onCurrentL2Received); + connect(meter, &EnergyMeter::currentL3Received, this, &IntegrationPluginEnergyMeters::onCurrentL3Received); + connect(meter, &EnergyMeter::activePowerReceived, this, &IntegrationPluginEnergyMeters::onActivePowerReceived); + connect(meter, &EnergyMeter::powerFactorReceived, this, &IntegrationPluginEnergyMeters::onPowerFactorReceived); + connect(meter, &EnergyMeter::frequencyReceived, this, &IntegrationPluginEnergyMeters::onFrequencyReceived); + connect(meter, &EnergyMeter::producedEnergyReceived, this, &IntegrationPluginEnergyMeters::onProducedEnergyReceived); + connect(meter, &EnergyMeter::consumedEnergyReceived, this, &IntegrationPluginEnergyMeters::onConsumedEnergyReceived); + + m_energyMeters.insert(info->thing(), meter); + info->finish(Thing::ThingErrorNoError); + }); + meter->getEnergyConsumed(); + return; } void IntegrationPluginEnergyMeters::postSetupThing(Thing *thing) @@ -277,7 +277,7 @@ void IntegrationPluginEnergyMeters::onConnectionStateChanged(bool status) void IntegrationPluginEnergyMeters::onVoltageL1Received(double voltage) { - EnergyMeter *meter = static_cast(sender()); + EnergyMeter *meter = qobject_cast(sender()); Thing *thing = m_energyMeters.key(meter); if (!thing) return; @@ -288,7 +288,7 @@ void IntegrationPluginEnergyMeters::onVoltageL1Received(double voltage) void IntegrationPluginEnergyMeters::onVoltageL2Received(double voltage) { - EnergyMeter *meter = static_cast(sender()); + EnergyMeter *meter = qobject_cast(sender()); Thing *thing = m_energyMeters.key(meter); if (!thing) return; @@ -299,7 +299,7 @@ void IntegrationPluginEnergyMeters::onVoltageL2Received(double voltage) void IntegrationPluginEnergyMeters::onVoltageL3Received(double voltage) { - EnergyMeter *meter = static_cast(sender()); + EnergyMeter *meter = qobject_cast(sender()); Thing *thing = m_energyMeters.key(meter); if (!thing) return; @@ -310,7 +310,7 @@ void IntegrationPluginEnergyMeters::onVoltageL3Received(double voltage) void IntegrationPluginEnergyMeters::onCurrentL1Received(double current) { - EnergyMeter *meter = static_cast(sender()); + EnergyMeter *meter = qobject_cast(sender()); Thing *thing = m_energyMeters.key(meter); if (!thing) return; @@ -321,7 +321,7 @@ void IntegrationPluginEnergyMeters::onCurrentL1Received(double current) void IntegrationPluginEnergyMeters::onCurrentL2Received(double current) { - EnergyMeter *meter = static_cast(sender()); + EnergyMeter *meter = qobject_cast(sender()); Thing *thing = m_energyMeters.key(meter); if (!thing) return; @@ -332,7 +332,7 @@ void IntegrationPluginEnergyMeters::onCurrentL2Received(double current) void IntegrationPluginEnergyMeters::onCurrentL3Received(double current) { - EnergyMeter *meter = static_cast(sender()); + EnergyMeter *meter = qobject_cast(sender()); Thing *thing = m_energyMeters.key(meter); if (!thing) return; @@ -343,7 +343,7 @@ void IntegrationPluginEnergyMeters::onCurrentL3Received(double current) void IntegrationPluginEnergyMeters::onActivePowerReceived(double power) { - EnergyMeter *meter = static_cast(sender()); + EnergyMeter *meter = qobject_cast(sender()); Thing *thing = m_energyMeters.key(meter); if (!thing) return; @@ -354,7 +354,7 @@ void IntegrationPluginEnergyMeters::onActivePowerReceived(double power) void IntegrationPluginEnergyMeters::onFrequencyReceived(double frequency) { - EnergyMeter *meter = static_cast(sender()); + EnergyMeter *meter = qobject_cast(sender()); Thing *thing = m_energyMeters.key(meter); if (!thing) return; @@ -365,7 +365,7 @@ void IntegrationPluginEnergyMeters::onFrequencyReceived(double frequency) void IntegrationPluginEnergyMeters::onPowerFactorReceived(double powerFactor) { - EnergyMeter *meter = static_cast(sender()); + EnergyMeter *meter = qobject_cast(sender()); Thing *thing = m_energyMeters.key(meter); if (!thing) return; @@ -376,7 +376,7 @@ void IntegrationPluginEnergyMeters::onPowerFactorReceived(double powerFactor) void IntegrationPluginEnergyMeters::onProducedEnergyReceived(double energy) { - EnergyMeter *meter = static_cast(sender()); + EnergyMeter *meter = qobject_cast(sender()); Thing *thing = m_energyMeters.key(meter); if (!thing) return; @@ -387,7 +387,7 @@ void IntegrationPluginEnergyMeters::onProducedEnergyReceived(double energy) void IntegrationPluginEnergyMeters::onConsumedEnergyReceived(double energy) { - EnergyMeter *meter = static_cast(sender()); + EnergyMeter *meter = qobject_cast(sender()); Thing *thing = m_energyMeters.key(meter); if (!thing) return; diff --git a/energymeters/integrationpluginenergymeters.h b/energymeters/integrationpluginenergymeters.h index 1764b44..dd9ae7c 100644 --- a/energymeters/integrationpluginenergymeters.h +++ b/energymeters/integrationpluginenergymeters.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2021, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea. diff --git a/energymeters/integrationpluginenergymeters.json b/energymeters/integrationpluginenergymeters.json index 7ad8198..8878bc5 100644 --- a/energymeters/integrationpluginenergymeters.json +++ b/energymeters/integrationpluginenergymeters.json @@ -39,7 +39,7 @@ "id": "c75b2c31-6ec3-49ab-8c8f-5231d0a7e941", "name": "slaveAddress", "displayName": "Modbus slave address", - "type": "int", + "type": "uint", "defaultValue": 1 }, { @@ -188,7 +188,7 @@ "id": "ac77ea98-b006-486e-a3e8-b30a483f26c1", "name": "slaveAddress", "displayName": "Modbus slave address", - "type": "int", + "type": "uint", "defaultValue": 1 }, { diff --git a/energymeters/registerdescriptor.h b/energymeters/registerdescriptor.h index 868a221..d330b3f 100644 --- a/energymeters/registerdescriptor.h +++ b/energymeters/registerdescriptor.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Copyright 2013 - 2020, nymea GmbH +* Copyright 2013 - 2021, nymea GmbH * Contact: contact@nymea.io * * This file is part of nymea.