added set target temperature action
This commit is contained in:
parent
f004899127
commit
4c1ec41a15
58
idm/idm.cpp
58
idm/idm.cpp
@ -46,6 +46,7 @@ Idm::Idm(const QHostAddress &address, QObject *parent) :
|
||||
connect(m_modbusMaster, &ModbusTCPMaster::receivedHoldingRegister, this, &Idm::onReceivedHoldingRegister);
|
||||
connect(m_modbusMaster, &ModbusTCPMaster::readRequestError, this, &Idm::onModbusError);
|
||||
connect(m_modbusMaster, &ModbusTCPMaster::writeRequestError, this, &Idm::onModbusError);
|
||||
connect(m_modbusMaster, &ModbusTCPMaster::writeRequestExecuted, this, &Idm::writeRequestExecuted);
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,6 +66,18 @@ QHostAddress Idm::getIdmAddress() const
|
||||
return m_hostAddress;
|
||||
}
|
||||
|
||||
void Idm::getStatus()
|
||||
{
|
||||
//this request starts an update cycle
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::OutsideTemperature, 2);
|
||||
}
|
||||
|
||||
QUuid Idm::setTargetTemperature(double targetTemperature)
|
||||
{
|
||||
QVector<uint16_t> value = ModbusHelpers::convertFloatToRegister(targetTemperature);
|
||||
return m_modbusMaster->writeHoldingRegisters(Idm::modbusUnitID, Idm::RegisterList::RoomTemperatureTargetHeatingEcoHKA, value);
|
||||
}
|
||||
|
||||
void Idm::onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const QVector<quint16> &value)
|
||||
{
|
||||
Q_UNUSED(slaveAddress);
|
||||
@ -74,81 +87,81 @@ void Idm::onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const
|
||||
case Idm::OutsideTemperature:
|
||||
/* qCDebug(dcIdm()) << "received outside temperature"; */
|
||||
if (value.length() == 2) {
|
||||
m_info.outsideTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::OutsideTemperature - modbusRegister]);
|
||||
m_idmInfo.outsideTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::OutsideTemperature - modbusRegister]);
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::CurrentFaultNumber, 1);
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::CurrentFaultNumber, 1);
|
||||
});
|
||||
break;
|
||||
case Idm::CurrentFaultNumber:
|
||||
/* qCDebug(dcIdm()) << "current fault number"; */
|
||||
if (value.length() == 1) {
|
||||
if (value[0] > 0) {
|
||||
m_info.error = true;
|
||||
m_idmInfo.error = true;
|
||||
} else {
|
||||
m_info.error = false;
|
||||
m_idmInfo.error = false;
|
||||
}
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::HeatStorageTemperature, 2);
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::HeatStorageTemperature, 2);
|
||||
});
|
||||
break;
|
||||
case Idm::HeatStorageTemperature:
|
||||
/* qCDebug(dcIdm()) << "received storage temperature"; */
|
||||
if (value.length() == 2) {
|
||||
m_info.waterTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::HeatStorageTemperature - modbusRegister]);
|
||||
m_idmInfo.waterTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::HeatStorageTemperature - modbusRegister]);
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::TargetHotWaterTemperature, 1);
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::TargetHotWaterTemperature, 1);
|
||||
});
|
||||
break;
|
||||
case Idm::TargetHotWaterTemperature:
|
||||
/* qCDebug(dcIdm()) << "received target hot water temperature"; */
|
||||
if (value.length() == 1) {
|
||||
/* The hot water target temperature is stored as UCHAR (manual p. 13) */
|
||||
m_info.targetWaterTemperature = (double)value[RegisterList::TargetHotWaterTemperature - modbusRegister];
|
||||
m_idmInfo.targetWaterTemperature = (double)value[RegisterList::TargetHotWaterTemperature - modbusRegister];
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::HeatPumpOperatingMode, 1);
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::HeatPumpOperatingMode, 1);
|
||||
});
|
||||
break;
|
||||
case Idm::HeatPumpOperatingMode:
|
||||
/* qCDebug(dcIdm()) << "received heat pump operating mode"; */
|
||||
if (value.length() == 1) {
|
||||
m_info.mode = heatPumpOperationModeToString((Idm::IdmHeatPumpMode)value[RegisterList::HeatPumpOperatingMode-modbusRegister]);
|
||||
m_idmInfo.mode = heatPumpOperationModeToString((Idm::IdmHeatPumpMode)value[RegisterList::HeatPumpOperatingMode-modbusRegister]);
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::RoomTemperatureHKA, 2);
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::RoomTemperatureHKA, 2);
|
||||
});
|
||||
break;
|
||||
case Idm::RoomTemperatureHKA:
|
||||
/* qCDebug(dcIdm()) << "received room temperature hka"; */
|
||||
if (value.length() == 2) {
|
||||
m_info.roomTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::RoomTemperatureHKA - modbusRegister]);
|
||||
m_idmInfo.roomTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::RoomTemperatureHKA - modbusRegister]);
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::RoomTemperatureTargetHeatingEcoHKA, 2);
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::RoomTemperatureTargetHeatingEcoHKA, 2);
|
||||
});
|
||||
break;
|
||||
case Idm::RoomTemperatureTargetHeatingEcoHKA:
|
||||
/* qCDebug(dcIdm()) << "received room temprature hka eco"; */
|
||||
if (value.length() == 2) {
|
||||
m_info.targetRoomTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::RoomTemperatureTargetHeatingEcoHKA - modbusRegister]);
|
||||
m_idmInfo.targetRoomTemperature = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::RoomTemperatureTargetHeatingEcoHKA - modbusRegister]);
|
||||
}
|
||||
QTimer::singleShot(200, this, [this] {
|
||||
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::CurrentPowerConsumptionHeatPump, 2);
|
||||
m_modbusMaster->readHoldingRegister(Idm::modbusUnitID, Idm::CurrentPowerConsumptionHeatPump, 2);
|
||||
});
|
||||
break;
|
||||
case Idm::CurrentPowerConsumptionHeatPump:
|
||||
/* qCDebug(dcIdm()) << "received power consumption heat pump"; */
|
||||
if (value.length() == 2) {
|
||||
m_info.powerConsumptionHeatPump = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::CurrentPowerConsumptionHeatPump - modbusRegister]);
|
||||
m_idmInfo.powerConsumptionHeatPump = ModbusHelpers::convertRegisterToFloat(&value[RegisterList::CurrentPowerConsumptionHeatPump - modbusRegister]);
|
||||
}
|
||||
|
||||
/* Everything read without an error
|
||||
* -> set connected to true */
|
||||
m_info.connected = true;
|
||||
emit statusUpdated(m_info);
|
||||
m_idmInfo.connected = true;
|
||||
emit statusUpdated(m_idmInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -156,13 +169,8 @@ void Idm::onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const
|
||||
void Idm::onModbusError()
|
||||
{
|
||||
qCDebug(dcIdm()) << "iDM: Received modbus error";
|
||||
m_info.connected = false;
|
||||
emit statusUpdated(m_info);
|
||||
}
|
||||
|
||||
void Idm::onRequestStatus()
|
||||
{
|
||||
m_modbusMaster->readHoldingRegister(Idm::ModbusUnitID, Idm::OutsideTemperature, 2);
|
||||
m_idmInfo.connected = false;
|
||||
emit statusUpdated(m_idmInfo);
|
||||
}
|
||||
|
||||
QString Idm::systemOperationModeToString(IdmSysMode mode)
|
||||
|
||||
14
idm/idm.h
14
idm/idm.h
@ -73,12 +73,12 @@ public:
|
||||
|
||||
bool connectDevice();
|
||||
QHostAddress getIdmAddress() const;
|
||||
bool setTargetTemperature;
|
||||
QUuid setTargetTemperature(double targetTemperature);
|
||||
void getStatus();
|
||||
|
||||
private:
|
||||
|
||||
/** Modbus Unit ID of Idm device */
|
||||
static const quint16 ModbusUnitID = 1;
|
||||
static const quint16 modbusUnitID = 1;
|
||||
|
||||
enum IscModus {
|
||||
KeineAbwarme = 0,
|
||||
@ -160,12 +160,12 @@ private:
|
||||
* within the IntegrationPluginIdm class. */
|
||||
QHostAddress m_hostAddress;
|
||||
|
||||
/** Pointer to ModbusTCPMaster object, responseible for low-level communicaiton */
|
||||
/** Pointer to ModbusTCPMaster object, responsible for low-level communicaiton */
|
||||
ModbusTCPMaster *m_modbusMaster = nullptr;
|
||||
|
||||
/** This structure is allocated within onRequestStatus and filled
|
||||
* by the receivedStatusGroupx functions */
|
||||
IdmInfo m_info;
|
||||
IdmInfo m_idmInfo;
|
||||
|
||||
/** Converts a system operation mode code to a string (according to manual p. 13) */
|
||||
QString systemOperationModeToString(IdmSysMode mode);
|
||||
@ -176,10 +176,10 @@ private:
|
||||
signals:
|
||||
void statusUpdated(const IdmInfo &info);
|
||||
void targetRoomTemperatureChanged();
|
||||
void writeRequestExecuted(const QUuid &requestId, bool success);
|
||||
|
||||
public slots:
|
||||
private slots:
|
||||
void onModbusError();
|
||||
void onRequestStatus();
|
||||
void onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const QVector<quint16> &value);
|
||||
};
|
||||
|
||||
|
||||
@ -62,7 +62,7 @@ void IntegrationPluginIdm::setupThing(ThingSetupInfo *info)
|
||||
Q_FOREACH (Idm *idm, m_idmConnections) {
|
||||
if (hostAddress.isEqual(idm->getIdmAddress())) {
|
||||
qCWarning(dcIdm()) << "Address already in use";
|
||||
info->finish(Thing::ThingErrorSetupFailed, "IP address already in use");
|
||||
info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("IP address already in use"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -75,15 +75,18 @@ void IntegrationPluginIdm::setupThing(ThingSetupInfo *info)
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
m_idmConnections.insert(thing, idm);
|
||||
connect(idm, &Idm::statusUpdated, info, [info] (const IdmInfo &idmInfo) {
|
||||
|
||||
connect(idm, &Idm::statusUpdated, info, [info, thing, idm, this] (const IdmInfo &idmInfo) {
|
||||
if (idmInfo.connected) {
|
||||
m_idmConnections.insert(thing, idm);
|
||||
connect(idm, &Idm::statusUpdated, this, &IntegrationPluginIdm::onStatusUpdated);
|
||||
connect(idm, &Idm::writeRequestExecuted, this, &IntegrationPluginIdm::onWriteRequestExecuted);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
}
|
||||
});
|
||||
connect(idm, &Idm::destroyed, this, [thing, this] {m_idmConnections.remove(thing);});
|
||||
connect(info, &ThingSetupInfo::aborted, idm, &Idm::deleteLater);
|
||||
connect(idm, &Idm::statusUpdated, this, &IntegrationPluginIdm::onStatusUpdated);
|
||||
|
||||
|
||||
} else {
|
||||
Q_ASSERT_X(false, "setupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8());
|
||||
@ -101,16 +104,14 @@ void IntegrationPluginIdm::postSetupThing(Thing *thing)
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == navigator2ThingClassId) {
|
||||
qCDebug(dcIdm()) << "Thing id: " << thing->id();
|
||||
Idm *idm = m_idmConnections.value(thing);
|
||||
|
||||
if (idm != nullptr) {
|
||||
|
||||
qCDebug(dcIdm()) << "Thing set up, calling update";
|
||||
update(thing);
|
||||
|
||||
thing->setStateValue(navigator2ConnectedStateTypeId, true);
|
||||
if (!idm) {
|
||||
qCWarning(dcIdm()) << "Could not find any iDM connection for" << thing->name();
|
||||
return;
|
||||
}
|
||||
|
||||
thing->setStateValue(navigator2ConnectedStateTypeId, true);
|
||||
update(thing);
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,9 +138,14 @@ void IntegrationPluginIdm::executeAction(ThingActionInfo *info)
|
||||
Action action = info->action();
|
||||
|
||||
if (thing->thingClassId() == navigator2ThingClassId) {
|
||||
Idm *idm = m_idmConnections.value(thing);
|
||||
if (!idm) {
|
||||
return info->finish(Thing::ThingErrorHardwareFailure);
|
||||
}
|
||||
if (action.actionTypeId() == navigator2TargetTemperatureActionTypeId) {
|
||||
double targetTemperature = thing->stateValue(navigator2TargetTemperatureStateTypeId).toDouble();
|
||||
Q_UNUSED(targetTemperature);
|
||||
QUuid requestId = idm->setTargetTemperature(targetTemperature);
|
||||
m_asyncActions.insert(requestId, info);
|
||||
|
||||
} else {
|
||||
Q_ASSERT_X(false, "executeAction", QString("Unhandled action: %1").arg(action.actionTypeId().toString()).toUtf8());
|
||||
@ -152,13 +158,13 @@ void IntegrationPluginIdm::executeAction(ThingActionInfo *info)
|
||||
void IntegrationPluginIdm::update(Thing *thing)
|
||||
{
|
||||
if (thing->thingClassId() == navigator2ThingClassId) {
|
||||
qCDebug(dcIdm()) << "Updating thing";
|
||||
qCDebug(dcIdm()) << "Updating thing" << thing->name();
|
||||
|
||||
Idm *idm = m_idmConnections.value(thing);
|
||||
|
||||
if (idm != nullptr) {
|
||||
idm->onRequestStatus();
|
||||
if (!idm) {
|
||||
return;
|
||||
}
|
||||
idm->getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,6 +192,18 @@ void IntegrationPluginIdm::onStatusUpdated(const IdmInfo &info)
|
||||
thing->setStateValue(navigator2ErrorStateTypeId, info.error);
|
||||
}
|
||||
|
||||
void IntegrationPluginIdm::onWriteRequestExecuted(const QUuid &requestId, bool success)
|
||||
{
|
||||
if (m_asyncActions.contains(requestId)) {
|
||||
ThingActionInfo *info = m_asyncActions.value(requestId);
|
||||
if (success) {
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
} else {
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginIdm::onRefreshTimer()
|
||||
{
|
||||
qCDebug(dcIdm()) << "onRefreshTimer called";
|
||||
|
||||
@ -38,7 +38,6 @@
|
||||
|
||||
#include <QUuid>
|
||||
|
||||
|
||||
class IntegrationPluginIdm: public IntegrationPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -64,6 +63,8 @@ private:
|
||||
|
||||
private slots:
|
||||
void onStatusUpdated(const IdmInfo &info);
|
||||
void onWriteRequestExecuted(const QUuid &requestId, bool success);
|
||||
|
||||
};
|
||||
|
||||
#endif // INTEGRATIONPLUGINIDM_H
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include "modbushelpers.h"
|
||||
|
||||
float ModbusHelpers::convertRegisterToFloat(const quint16 *reg) {
|
||||
|
||||
float result = 0.0;
|
||||
|
||||
if (reg != nullptr) {
|
||||
@ -47,12 +48,14 @@ float ModbusHelpers::convertRegisterToFloat(const quint16 *reg) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void ModbusHelpers::convertFloatToRegister(QVector<quint16> ®, float value) {
|
||||
QVector<quint16> ModbusHelpers::convertFloatToRegister(float value)
|
||||
{
|
||||
quint32 tmp = 0;
|
||||
|
||||
memcpy((char *)&tmp, (char *)&value, sizeof(value));
|
||||
|
||||
QVector<quint16> reg;
|
||||
reg.append((quint16)(tmp));
|
||||
reg.append((quint16)((tmp & 0xFFFF0000) >> 16));
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
class ModbusHelpers {
|
||||
public:
|
||||
static float convertRegisterToFloat(const quint16 *reg);
|
||||
static void convertFloatToRegister(QVector<quint16> ®, float value);
|
||||
static QVector<quint16> convertFloatToRegister(float value);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
@ -63,7 +63,7 @@ ModbusTCPMaster::~ModbusTCPMaster()
|
||||
}
|
||||
|
||||
bool ModbusTCPMaster::connectDevice() {
|
||||
// TCP connction to target device
|
||||
// TCP connection to target device
|
||||
qCDebug(dcModbusTCP()) << "Setting up TCP connecion";
|
||||
|
||||
if (!m_modbusTcpClient)
|
||||
@ -87,6 +87,11 @@ void ModbusTCPMaster::setTimeout(int timeout)
|
||||
m_modbusTcpClient->setTimeout(timeout);
|
||||
}
|
||||
|
||||
QString ModbusTCPMaster::errorString() const
|
||||
{
|
||||
return m_modbusTcpClient->errorString();
|
||||
}
|
||||
|
||||
uint ModbusTCPMaster::port()
|
||||
{
|
||||
return m_modbusTcpClient->connectionParameter(QModbusDevice::NetworkPortParameter).toUInt();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Copyright 2013 - 2021, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
@ -37,7 +37,7 @@
|
||||
#include <QTimer>
|
||||
#include <QUuid>
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcModbus)
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcModbusTcp)
|
||||
|
||||
class ModbusTCPMaster : public QObject
|
||||
{
|
||||
@ -51,6 +51,8 @@ public:
|
||||
void setNumberOfRetries(int number);
|
||||
void setTimeout(int timeout);
|
||||
|
||||
QString errorString() const;
|
||||
|
||||
QUuid readCoil(uint slaveAddress, uint registerAddress, uint size = 1);
|
||||
QUuid readDiscreteInput(uint slaveAddress, uint registerAddress, uint size = 1);
|
||||
QUuid readInputRegister(uint slaveAddress, uint registerAddress, uint size = 1);
|
||||
|
||||
Reference in New Issue
Block a user