Readout working

master
Hermann Detz 2020-10-16 11:28:31 +02:00 committed by Michael Zanetti
parent bd5f3be35d
commit 9b346848a2
6 changed files with 179 additions and 44 deletions

View File

@ -29,16 +29,21 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "idm.h"
#include "../modbus/modbushelpers.h"
#include <cstring>
Idm::Idm(const QHostAddress &address, QObject *parent) :
QObject(parent),
m_hostAddress(address)
{
/* qCDebug(dcIdm()) << "Creating Idm with addr: " << address; */
m_modbusMaster = new ModbusTCPMaster(address, 502, this);
connect(m_modbusMaster, &ModbusTCPMaster::receivedHoldingRegister, this, &Idm::onReceivedHoldingRegister);
if (m_modbusMaster) {
m_modbusMaster->connectDevice();
connect(m_modbusMaster, &ModbusTCPMaster::receivedHoldingRegister, this, &Idm::onReceivedHoldingRegister);
}
}
Idm::~Idm()
@ -48,31 +53,104 @@ Idm::~Idm()
}
}
double Idm::getOutsideTemperature()
{
//m_modbusMaster->
return 0.0;
}
void Idm::onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const QVector<quint16> &value)
{
/* qCDebug(dcIdm()) << "Idm::onReceivedHoldingRegister"; */
Q_UNUSED(slaveAddress);
Q_UNUSED(modbusRegister);
Q_UNUSED(value);
IdmInfo *info = new IdmInfo;
info->m_outsideTemperature = 24.3;
switch (modbusRegister) {
case Idm::OutsideTemperature:
if (value.length() == 2) {
m_info->m_roomTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::OutsideTemperature - modbusRegister]);
}
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::CurrentFaultNumber, 1);
break;
case Idm::CurrentFaultNumber:
if (value.length() == 1) {
if (value[0] > 0) {
m_info->m_error = true;
} else {
m_info->m_error = false;
}
}
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::TargetHotWaterTemperature, 2);
break;
case Idm::TargetHotWaterTemperature:
if (value.length() == 2) {
m_info->m_targetWaterTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::TargetHotWaterTemperature - modbusRegister]);
}
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::HeatPumpOperatingMode, 1);
break;
case Idm::HeatPumpOperatingMode:
if (value.length() == 1) {
printf("read heat pump operation mode: %d\n", value[0]);
m_info->m_mode = heatPumpOperationModeToString((Idm::IdmHeatPumpMode)value[RegisterList::HeatPumpOperatingMode-modbusRegister]);
}
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::ExternalOutsideTemperature, 2);
break;
case Idm::ExternalOutsideTemperature:
if (value.length() == 2) {
m_info->m_outsideTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::ExternalOutsideTemperature - modbusRegister]);
}
emit statusUpdated(info);
emit statusUpdated(m_info);
break;
}
}
void Idm::onRequestStatus()
{
/* Reading a total of 16 bytes, starting from address 1000.
* This covers the following parameters:
* */
m_modbusMaster->readHoldingRegister(0xff, RegisterList::OutsideTemperature, 16);
m_info = new IdmInfo;
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::OutsideTemperature, 2);
}
QString Idm::systemOperationModeToString(IdmSysMode mode) {
QString result{};
/* Operation modes according to table of manual p. 13 */
switch (mode) {
case IdmSysModeStandby:
result = "Standby";
break;
case IdmSysModeAutomatic:
result = "Automatik";
break;
case IdmSysModeAway:
result = "Abwesend";
break;
case IdmSysModeOnlyHotwater:
result = "Nur Warmwasser";
break;
case IdmSysModeOnlyRoomHeating:
result = "Nur Heizung/Kühlung";
break;
}
return result;
}
QString Idm::heatPumpOperationModeToString(IdmHeatPumpMode mode) {
QString result{};
/* Operation modes according to table of manual p. 14 */
switch (mode) {
case IdmHeatPumpModeOff:
result = "Off";
break;
case IdmHeatPumpModeHeating:
result = "Heating";
break;
case IdmHeatPumpModeCooling:
result = "Cooling";
break;
case IdmHeatPumpModeHotWater:
result = "Hot water";
break;
case IdmHeatPumpModeDefrost:
result = "Defrost";
break;
}
return result;
}

View File

@ -41,13 +41,23 @@ class Idm : public QObject
{
Q_OBJECT
public:
/** Constructor */
explicit Idm(const QHostAddress &address, QObject *parent = nullptr);
~Idm();
double getOutsideTemperature();
//void getCurrentFaultNumber();
/** Destructor */
~Idm();
private:
/* Note: It would be desirable to read the modbus registers
* of the Idm heat pump in groups to minimize the number
* of read requests. However, a maximum of 6 registers
* can be read simultaneously. With the given set of
* addresses it is not possible to reasonably group the
* registers, therefore they are read individually.
*/
/** Modbus Unit ID of Idm device */
static const quint16 ModbusUnitID = 1;
enum IscModus {
KeineAbwarme = 0,
@ -56,11 +66,29 @@ private:
Warmequelle = 8,
};
/** System operation modes according to manual p. 13 */
enum IdmSysMode {
IdmSysModeStandby = 0,
IdmSysModeAutomatic = 1,
IdmSysModeAway = 2,
IdmSysModeOnlyHotwater = 4,
IdmSysModeOnlyRoomHeating = 5
};
/** Heat pump operation modes according to manual p. 14 */
enum IdmHeatPumpMode {
IdmHeatPumpModeOff = 0,
IdmHeatPumpModeHeating = 1,
IdmHeatPumpModeCooling = 2,
IdmHeatPumpModeHotWater = 4,
IdmHeatPumpModeDefrost = 8
};
/** The following modbus addresses are according to the manual
* Modbus TCP Navigatorregelung 2.0 pages 13-31.
* Comments at the end of each line give their original name
* in the German manual. */
enum RegisterList {
/* The following modbus addresses are according to the manual
* Modbus TCP Navigatorregelung 2.0 pages 13-31.
* Comments at the end of each line give their original name
* in the German manual. */
OutsideTemperature = 1000, // Außentemperatur (B31)
MeanOutsideTemperature = 1002, // Gemittelte Außentemperature
CurrentFaultNumber = 1004, // Aktuelle Störungsnummer
@ -75,6 +103,7 @@ private:
HeatPumpOperatingMode = 1090, // Betriebsart Wärmepumpe
SummationFaultHeatPump = 1099, // Summenstörung Wärepumpe
Humiditysensor = 1392, // Feuchtesensor
RoomTemperatureTargetHeatingHKA = 1401, // Raumsolltemperatur Heizen Normal HK A
ExternalOutsideTemperature = 1690, // Externe Außentemperatur
ExternalHumidity = 1692, // Externe Feuchte
ExternalRequestTemperatureHeating = 1694, // Externe Anforderungstemperatur Heizen
@ -97,6 +126,7 @@ private:
SolarOperatingMode = 1856, // Betriebsart Solar
ISCMode = 1875, // ISCModus
AcknowledgeFaultMessages = 1999, // Störmeldungen quittieren
TargetRoomTemperatureZ1R1 = 2004, // Zonenmodul 1 Raumsolltemperatur Raum 1
CurrentPhotovoltaicsSurplus = 74, // Aktueller PV-Überschuss
CurrentPhotovoltaicsProduction = 78, // Aktueller PV Produktion
CurrentPowerConsumption = 4122, // Aktuelle Leistungsaufnahme Wärmepumpe
@ -106,18 +136,26 @@ private:
* TCP Modbus connection. Multiple devices are managed
* within the IntegrationPluginIdm class. */
QHostAddress m_hostAddress;
/** Pointer to ModbusTCPMaster object, responseible for low-level communicaiton */
ModbusTCPMaster *m_modbusMaster = nullptr;
/** This structure is allocated within onRequestStatus and filled
* by the receivedStatusGroupx functions */
IdmInfo *m_info = nullptr;
/** Converts a system operation mode code to a string (according to manual p. 13) */
QString systemOperationModeToString(IdmSysMode mode);
/** Converts a heat pump operation mode code to a string (according to manual p. 14) */
QString heatPumpOperationModeToString(IdmHeatPumpMode mode);
signals:
void statusUpdated(IdmInfo *info);
private slots:
void onRequestStatus();
// only public for debugging!
public slots:
void onRequestStatus();
void onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const QVector<quint16> &value);
};
#endif // IDM_H

View File

@ -8,9 +8,12 @@ SOURCES += \
idm.cpp \
integrationpluginidm.cpp \
../modbus/modbustcpmaster.cpp \
../modbus/modbushelpers.cpp \
HEADERS += \
idm.h \
idminfo.h \
integrationpluginidm.h \
../modbus/modbustcpmaster.h \
../modbus/modbushelpers.h \

View File

@ -31,19 +31,40 @@
#ifndef IDMINFO_H
#define IDMINFO_H
#include <QMetaType>
#include <QString>
/** This struct holds the status information that is read from the IDM device
* and passed to the nymea framework within this plugin.
*/
struct IdmInfo {
bool m_connected;
bool m_power;
/** RegisterList::OutsideTemperature */
double m_roomTemperature;
/** RegisterList::ExternalOutsideTemperature */
double m_outsideTemperature;
/** RegisterList::HeatStorageTemperature */
double m_waterTemperature;
/** RegisterList::TargetRoomTemperatureZ1R1 (zone 1, room 1) */
double m_targetRoomTemperature;
/** RegisterList::TargetHotWaterTemperature */
double m_targetWaterTemperature;
/** RegisterList::OperationModeSystem */
QString m_mode;
/** True if there is an error code set
* (RegisterList::CurrentFaultNumber != 0) */
bool m_error;
};
Q_DECLARE_METATYPE(IdmInfo);
#endif

View File

@ -43,7 +43,7 @@ void IntegrationPluginIdm::discoverThings(ThingDiscoveryInfo *info)
// The plugin has a parameter for the IP address
QString description = "Navigator 2";
ThingDescriptor descriptor(info->thingClassId(), "", description);
ThingDescriptor descriptor(info->thingClassId(), "Idm", description);
info->addThingDescriptor(descriptor);
// Just report no error for now, until the above question
@ -58,8 +58,12 @@ void IntegrationPluginIdm::setupThing(ThingSetupInfo *info)
if (thing->thingClassId() == navigator2ThingClassId) {
QHostAddress hostAddress = QHostAddress(thing->paramValue(navigator2ThingIpAddressParamTypeId).toString());
/* Create new Idm object and store it in hash table */
Idm *idm = new Idm(hostAddress, this);
m_idmConnections.insert(thing, idm);
/* Store thing info in hash table */
m_idmInfos.insert(thing, info);
info->finish(Thing::ThingErrorNoError);
@ -119,10 +123,8 @@ void IntegrationPluginIdm::update(Thing *thing)
QVector<quint16> val{};
idm->onReceivedHoldingRegister(0, 1021, val);
//idm->onRequestStatus();
idm->onRequestStatus();
//idm->readHoldingRegister(0xff, RegisterList::OutsideTemperature);
if (m_idmInfos.contains(thing)) {
ThingSetupInfo *info = m_idmInfos.take(thing);
info->finish(Thing::ThingErrorNoError);

View File

@ -48,6 +48,7 @@ class IntegrationPluginIdm: public IntegrationPlugin
public:
/** Constructor */
explicit IntegrationPluginIdm();
void discoverThings(ThingDiscoveryInfo *info) override;
@ -59,14 +60,6 @@ public:
private:
enum IdmSysMode {
IdmSysModeStandby = 0,
IdmSysModeAutomatic,
IdmSysModeAway,
IdmSysModeOnlyWarmwater,
IdmSysModeOnlyRoomHeating
};
enum IdmSmartGridMode {
EVUSperreKeinPVErtrag,
EVUBezugKeinPVErtrag,