diff --git a/energymeters/bg-etechmodbusregister.h b/energymeters/bg-etechmodbusregister.h index 368c5eb..deffe6b 100644 --- a/energymeters/bg-etechmodbusregister.h +++ b/energymeters/bg-etechmodbusregister.h @@ -33,27 +33,14 @@ #include "registerdescriptor.h" -class BgEtechModbusRegisers -{ - -private: - BgEtechModbusRegisers() {} - static void init () { - m_registerMap.insert(ModbusRegisterType::Voltage, ModbusRegisterDescriptor(1, 3, 2, "V", "float")); - /* m_registerMap.insert(ModbusRegisterType::Current, ModbusRegisterDescriptor(1, 3, 2, "V", "float")); - m_registerMap.insert(ModbusRegisterType::ActivePower, ModbusRegisterDescriptor(1, 3, 2, "V", "float")); - m_registerMap.insert(ModbusRegisterType::Frequency, ModbusRegisterDescriptor(1, 3, 2, "V", "float")); - m_registerMap.insert(ModbusRegisterType::PowerFactor, ModbusRegisterDescriptor(1, 3, 2, "V", "float")); - m_registerMap.insert(ModbusRegisterType::EnergyConsumed, ModbusRegisterDescriptor(1, 3, 2, "V", "float")); - m_registerMap.insert(ModbusRegisterType::EnergyProduced, ModbusRegisterDescriptor(1, 3, 2, "V", "float"));*/ - } -protected: - static QHash m_registerMap; -public: - static QHash map() - { BgEtechModbusRegisers(); - init(); - return m_registerMap;} +static const QHash sdm630RegisterMap { + {ModbusRegisterType::Voltage, ModbusRegisterDescriptor(30043, 4, 2, "V", "float")}, //Average line to neutral volts + {ModbusRegisterType::Current, ModbusRegisterDescriptor(30047, 4, 2, "A", "float")}, //Average line current + {ModbusRegisterType::ActivePower, ModbusRegisterDescriptor(30053, 4, 2, "W", "float")}, //Total system power + {ModbusRegisterType::Frequency, ModbusRegisterDescriptor(30071, 4, 2, "Hz", "float")}, + {ModbusRegisterType::PowerFactor, ModbusRegisterDescriptor(30067, 4, 2, "Degree", "float")}, //Total system phase angle + {ModbusRegisterType::EnergyConsumed, ModbusRegisterDescriptor(30073, 4, 2, "kWh", "float")}, //Total Import kWh + {ModbusRegisterType::EnergyProduced, ModbusRegisterDescriptor(30075, 4, 2, "kWh", "float")} //Total Export kWh }; #endif // BGETECHMODBUSREGISTER_H diff --git a/energymeters/energymeter.cpp b/energymeters/energymeter.cpp index 65c6f63..8083f49 100644 --- a/energymeters/energymeter.cpp +++ b/energymeters/energymeter.cpp @@ -31,6 +31,8 @@ #include "energymeter.h" #include "hardware/modbus/modbusrtureply.h" +#include "extern-plugininfo.h" + EnergyMeter::EnergyMeter(ModbusRtuMaster *modbusMaster, int slaveAddress, const QHash &modbusRegisters, QObject *parent) : QObject(parent), m_modbusRtuMaster(modbusMaster), @@ -123,26 +125,60 @@ bool EnergyMeter::getEnergyConsumed() void EnergyMeter::getRegister(ModbusRegisterType type, ModbusRegisterDescriptor descriptor) { - ModbusRtuReply *reply; - if (descriptor.functionCode() == 1){ - - } else if (descriptor.functionCode() == 2){ - - } else if (descriptor.functionCode() == 3){ + ModbusRtuReply *reply = nullptr; + if (descriptor.functionCode() == 3){ reply = m_modbusRtuMaster->readHoldingRegister(m_slaveAddress, descriptor.address(), descriptor.length()); } else if (descriptor.functionCode() == 4){ + reply = m_modbusRtuMaster->readInputRegister(m_slaveAddress, descriptor.address(), descriptor.length()); } connect(reply, &ModbusRtuReply::finished, reply, &ModbusRtuReply::deleteLater); - connect(reply, &ModbusRtuReply::finished, this, [reply, type, this] { + connect(reply, &ModbusRtuReply::finished, this, [reply, type, descriptor, this] { if (reply->error() != ModbusRtuReply::NoError) { return; } double value = 0; - if (reply->result().length() == 2) { + if (reply->result().length() == 1) { + value = static_cast(reply->result().at(0)); + } else if (reply->result().length() == 2) { + if (descriptor.dataType() == "float") { value = static_cast(reply->result().at(0) << 16 | reply->result().at(1)); + } else { + qCWarning(dcEnergyMeters()) << "Data type not supported" << descriptor.dataType(); + } } - emit valueReceived(type, value); + if (type == ModbusRegisterType::Voltage) { + if (descriptor.unit() == "mV") + value /= 1000; + + emit voltageReceived(value); + } else if (type == ModbusRegisterType::Current) { + if (descriptor.unit() == "mA") + value /= 1000; + + emit currentReceived(value); + } else if (type == ModbusRegisterType::ActivePower) { + if (descriptor.unit() == "kW") { + value *= 1000; + } else if (descriptor.unit() == "mW") { + value /= 1000; + } + emit activePowerReceived(value); + } else if (type == ModbusRegisterType::PowerFactor) { + emit powerFactorReceived(value); + } else if (type == ModbusRegisterType::Frequency) { + emit frequencyReceived(value); + } else if (type == ModbusRegisterType::EnergyConsumed) { + if (descriptor.unit() == "Wh") { + value /= 1000; + } + emit consumedEnergyReceived(value); + } else if (type == ModbusRegisterType::EnergyProduced) { + if (descriptor.unit() == "Wh") { + value /= 1000; + } + emit producedEnergyReceived(value); + } }); } diff --git a/energymeters/energymeter.h b/energymeters/energymeter.h index d5e4fe9..1773d5d 100644 --- a/energymeters/energymeter.h +++ b/energymeters/energymeter.h @@ -64,7 +64,6 @@ private: signals: void connectedChanged(bool connected); - void valueReceived(ModbusRegisterType type, double value); void voltageReceived(double voltage); void currentReceived(double current); diff --git a/energymeters/inepromodbusregister.h b/energymeters/inepromodbusregister.h index 370a4ed..b4e23eb 100644 --- a/energymeters/inepromodbusregister.h +++ b/energymeters/inepromodbusregister.h @@ -1,45 +1,45 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2020, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + #ifndef INEPROMODBUSREGISTER_H #define INEPROMODBUSREGISTER_H +#include "registerdescriptor.h" -enum InputRegisters { - Phase1ToNeutralVolts = 1, - Phase2ToNeutralVolts = 3, - Phase3ToNeutralVolts = 5, - Phase1Current = 7, - Phase2Current = 9, - Phase3Current = 11, - Phase1Power = 13, - Phase2Power = 15, - Phase3Power = 17, - Phase1ApparentPower = 19, - Phase2ApparentPower = 21, - Phase3ApparentPower = 23, - Phase1ReactivePower = 25, - Phase2ReactivePower = 27, - Phase3ReactivePower = 29, - Phase1PowerFactor = 31, - Phase2PowerFactor = 33, - Phase3PowerFactor = 35, - Phase1Angle = 37, - Phase2Angle = 39, - Phase3Angle = 41, - Frequency = 71, - ImportActiveEnergy = 73, - ExportActiveEnergy = 75, - ImportReactiveEnergy = 77, - ExportReactiveEnergy = 79, - TotalActiveEnergy = 343, - TotalReactiveEnergy = 345 +static const QHash pro380RegisterMap { + {ModbusRegisterType::Voltage, ModbusRegisterDescriptor(20482, 3, 2, "V", "float")}, //L1 Voltage + {ModbusRegisterType::Current, ModbusRegisterDescriptor(20492, 3, 2, "A", "float")}, //L1 Current + {ModbusRegisterType::ActivePower, ModbusRegisterDescriptor(20498, 3, 2, "kW", "float")}, //Total active power + {ModbusRegisterType::Frequency, ModbusRegisterDescriptor(20488, 3, 2, "Hz", "float")}, + {ModbusRegisterType::PowerFactor, ModbusRegisterDescriptor(20522, 3, 2, "Degree", "float")}, + {ModbusRegisterType::EnergyConsumed, ModbusRegisterDescriptor(24588, 3, 2, "kWh", "float")}, //Forward active energy + {ModbusRegisterType::EnergyProduced, ModbusRegisterDescriptor(24600, 3, 2, "kWh", "float")} //Reverse active energy }; -enum HoldingRegisters { - RelayPulseWidth = 13, - NetworkParityStop = 19, - NetworkPortNode = 21, - NetworkBaudRate = 29, - Pulse1Output = 87, - Pulse1Constant = 63761, - MeasurementMode = 63776 -}; - -#endif // BGETECHMODBUSREGISTER_H +#endif //INEPROMODBUSREGISTER_H diff --git a/energymeters/integrationpluginenergymeters.cpp b/energymeters/integrationpluginenergymeters.cpp index e7b5743..2dd79a4 100644 --- a/energymeters/integrationpluginenergymeters.cpp +++ b/energymeters/integrationpluginenergymeters.cpp @@ -32,6 +32,7 @@ #include "plugininfo.h" #include "bg-etechmodbusregister.h" +#include "inepromodbusregister.h" IntegrationPluginEnergyMeters::IntegrationPluginEnergyMeters() { @@ -67,6 +68,9 @@ IntegrationPluginEnergyMeters::IntegrationPluginEnergyMeters() m_discoverySlaveAddressParamTypeIds.insert(pro380ThingClassId, pro380DiscoverySlaveAddressParamTypeId); m_discoverySlaveAddressParamTypeIds.insert(sdm630ThingClassId, sdm630DiscoverySlaveAddressParamTypeId); + m_registerMaps.insert(pro380ThingClassId, &pro380RegisterMap); + m_registerMaps.insert(sdm630ThingClassId, &sdm630RegisterMap); + // Modbus RTU hardware resource connect(hardwareManager()->modbusRtuResource(), &ModbusRtuHardwareResource::modbusRtuMasterRemoved, this, [=](const QUuid &modbusUuid){ qCDebug(dcEnergyMeters()) << "Modbus RTU master has been removed" << modbusUuid.toString(); @@ -148,7 +152,7 @@ void IntegrationPluginEnergyMeters::setupThing(ThingSetupInfo *info) return; } - EnergyMeter *meter = new EnergyMeter(hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), address, BgEtechModbusRegisers::map(), this); + 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"; diff --git a/energymeters/integrationpluginenergymeters.h b/energymeters/integrationpluginenergymeters.h index 9dfbf10..8f9dc91 100644 --- a/energymeters/integrationpluginenergymeters.h +++ b/energymeters/integrationpluginenergymeters.h @@ -70,6 +70,8 @@ private: QHash m_slaveIdParamTypeIds; QHash m_modbusUuidParamTypeIds; + QHash *> m_registerMaps; + QHash m_energyMeters; QHash m_modbusRtuMasters; PluginTimer *m_pluginTimer = nullptr;