Readout working
parent
bd5f3be35d
commit
9b346848a2
118
idm/idm.cpp
118
idm/idm.cpp
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
62
idm/idm.h
62
idm/idm.h
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue