added modbus maps and add value received signals

master
Boernsman 2021-04-21 18:41:35 +02:00 committed by Michael Zanetti
parent 9027579cda
commit 9b413b185a
6 changed files with 100 additions and 72 deletions

View File

@ -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<ModbusRegisterType, ModbusRegisterDescriptor> m_registerMap;
public:
static QHash<ModbusRegisterType, ModbusRegisterDescriptor> map()
{ BgEtechModbusRegisers();
init();
return m_registerMap;}
static const QHash<ModbusRegisterType, ModbusRegisterDescriptor> 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

View File

@ -31,6 +31,8 @@
#include "energymeter.h"
#include "hardware/modbus/modbusrtureply.h"
#include "extern-plugininfo.h"
EnergyMeter::EnergyMeter(ModbusRtuMaster *modbusMaster, int slaveAddress, const QHash<ModbusRegisterType, ModbusRegisterDescriptor> &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<float>(reply->result().at(0));
} else if (reply->result().length() == 2) {
if (descriptor.dataType() == "float") {
value = static_cast<float>(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);
}
});
}

View File

@ -64,7 +64,6 @@ private:
signals:
void connectedChanged(bool connected);
void valueReceived(ModbusRegisterType type, double value);
void voltageReceived(double voltage);
void currentReceived(double current);

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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<ModbusRegisterType, ModbusRegisterDescriptor> 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

View File

@ -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";

View File

@ -70,6 +70,8 @@ private:
QHash<ThingClassId, ParamTypeId> m_slaveIdParamTypeIds;
QHash<ThingClassId, ParamTypeId> m_modbusUuidParamTypeIds;
QHash<ThingClassId, const QHash<ModbusRegisterType, ModbusRegisterDescriptor> *> m_registerMaps;
QHash<Thing *, EnergyMeter *> m_energyMeters;
QHash<Thing *, ModbusRtuMaster *> m_modbusRtuMasters;
PluginTimer *m_pluginTimer = nullptr;