Added SG Ready Support

pull/52/head
l.heizinger 2022-02-17 15:10:38 +01:00 committed by Simon Stürz
parent eac316e6f8
commit 374b107c10
4 changed files with 176 additions and 170 deletions

View File

@ -303,8 +303,8 @@ void IntegrationPluginStiebelEltron::setupThing(ThingSetupInfo *info) {
connect(
connection, &StiebelEltronModbusConnection::sgReadyStateChanged,
this,
[thing](StiebelEltronModbusConnection::SmartGridState
smartGridState) {
[thing](
StiebelEltronModbusConnection::SmartGridState smartGridState) {
qCDebug(dcStiebelEltron())
<< thing << "SG Ready activation changed" << smartGridState;
switch (smartGridState) {
@ -379,52 +379,130 @@ void IntegrationPluginStiebelEltron::executeAction(ThingActionInfo *info) {
Thing *thing = info->thing();
StiebelEltronModbusConnection *connection = m_connections.value(thing);
if (!connection->connected()) {
qCWarning(dcStiebelEltron()) << "Could not execute action. The modbus connection is currently not available.";
qCWarning(dcStiebelEltron())
<< "Could not execute action. The modbus connection is currently "
"not available.";
info->finish(Thing::ThingErrorHardwareNotAvailable);
return;
}
// Got this from StiebelEltron plugin, not sure if necessary
if (thing->thingClassId() != stiebelEltronThingClassId) {
if (thing->thingClassId() != stiebelEltronThingClassId) {
info->finish(Thing::ThingErrorNoError);
}
if (info->action().actionTypeId() == stiebelEltronSgReadyActiveActionTypeId) {
bool sgReadyActiveBool = info->action().paramValue(stiebelEltronSgReadyActiveActionSgReadyActiveParamTypeId).toBool();
qCDebug(dcStiebelEltron()) << "Execute action" << info->action().actionTypeId().toString() << info->action().params();
qCDebug(dcStiebelEltron()) << "Value: " << sgReadyActiveBool;
QModbusReply *reply = connection->setSgReadyActive(sgReadyActiveBool);
if (!reply) {
qCWarning(dcStiebelEltron()) << "Execute action failed because the reply could not be created.";
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
if (info->action().actionTypeId() ==
stiebelEltronSgReadyActiveActionTypeId) {
bool sgReadyActiveBool =
info->action()
.paramValue(
stiebelEltronSgReadyActiveActionSgReadyActiveParamTypeId)
.toBool();
qCDebug(dcStiebelEltron())
<< "Execute action" << info->action().actionTypeId().toString()
<< info->action().params();
qCDebug(dcStiebelEltron()) << "Value: " << sgReadyActiveBool;
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
connect(reply, &QModbusReply::finished, info, [info, reply, sgReadyActiveBool]{
if (reply->error() != QModbusDevice::NoError) {
qCWarning(dcStiebelEltron()) << "Set SG ready activation finished with error" << reply->errorString();
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
QModbusReply *reply = connection->setSgReadyActive(sgReadyActiveBool);
if (!reply) {
qCWarning(dcStiebelEltron()) << "Execute action failed because the "
"reply could not be created.";
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
connect(reply, &QModbusReply::finished, reply,
&QModbusReply::deleteLater);
connect(reply, &QModbusReply::finished, info,
[info, reply, sgReadyActiveBool] {
if (reply->error() != QModbusDevice::NoError) {
qCWarning(dcStiebelEltron())
<< "Set SG ready activation finished with error"
<< reply->errorString();
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
qCDebug(dcStiebelEltron()) << "Execute action finished successfully" << info->action().actionTypeId().toString() << info->action().params();
info->thing()->setStateValue(stiebelEltronSgReadyActiveStateTypeId, sgReadyActiveBool);
info->finish(Thing::ThingErrorNoError);
});
qCDebug(dcStiebelEltron())
<< "Execute action finished successfully"
<< info->action().actionTypeId().toString()
<< info->action().params();
info->thing()->setStateValue(
stiebelEltronSgReadyActiveStateTypeId,
sgReadyActiveBool);
info->finish(Thing::ThingErrorNoError);
});
connect(reply, &QModbusReply::errorOccurred, this, [reply] (QModbusDevice::Error error){
qCWarning(dcStiebelEltron()) << "Modbus reply error occurred while execute action" << error << reply->errorString();
emit reply->finished(); // To make sure it will be deleted
});
connect(reply, &QModbusReply::errorOccurred, this,
[reply](QModbusDevice::Error error) {
qCWarning(dcStiebelEltron())
<< "Modbus reply error occurred while execute action"
<< error << reply->errorString();
emit reply->finished(); // To make sure it will be deleted
});
} else if (info->action().actionTypeId() ==
stiebelEltronSgReadyModeActionTypeId) {
QString sgReadyModeString =
info->action()
.paramValue(
stiebelEltronSgReadyModeActionSgReadyModeParamTypeId)
.toString();
qCDebug(dcStiebelEltron())
<< "Execute action" << info->action().actionTypeId().toString()
<< info->action().params();
StiebelEltronModbusConnection::SmartGridState sgReadyState;
if (sgReadyModeString == "Mode 1") {
sgReadyState =
StiebelEltronModbusConnection::SmartGridStateModeOne;
} else if (sgReadyModeString == "Mode 2") {
sgReadyState =
StiebelEltronModbusConnection::SmartGridStateModeTwo;
} else if (sgReadyModeString == "Mode 3") {
sgReadyState =
StiebelEltronModbusConnection::SmartGridStateModeThree;
} else {
sgReadyState =
StiebelEltronModbusConnection::SmartGridStateModeFour;
}
QModbusReply *reply = connection->setSgReadyState(sgReadyState);
if (!reply) {
qCWarning(dcStiebelEltron()) << "Execute action failed because the "
"reply could not be created.";
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
connect(reply, &QModbusReply::finished, reply,
&QModbusReply::deleteLater);
connect(reply, &QModbusReply::finished, info,
[info, reply, sgReadyModeString] {
if (reply->error() != QModbusDevice::NoError) {
qCWarning(dcStiebelEltron())
<< "Set SG ready mode finished with error"
<< reply->errorString();
info->finish(Thing::ThingErrorHardwareFailure);
return;
}
qCDebug(dcStiebelEltron())
<< "Execute action finished successfully"
<< info->action().actionTypeId().toString()
<< info->action().params();
info->thing()->setStateValue(
stiebelEltronSgReadyModeStateTypeId, sgReadyModeString);
info->finish(Thing::ThingErrorNoError);
});
connect(reply, &QModbusReply::errorOccurred, this,
[reply](QModbusDevice::Error error) {
qCWarning(dcStiebelEltron())
<< "Modbus reply error occurred while execute action"
<< error << reply->errorString();
emit reply->finished(); // To make sure it will be deleted
});
}
info->finish(Thing::ThingErrorNoError);
}

View File

@ -36,19 +36,23 @@
"values": [
{
"key": "ModeOne",
"value": 1
"value": 1,
"comment": "0x00000001"
},
{
"key": "ModeTwo",
"value": 2
"value": 0,
"comment": "0x00000000"
},
{
"key": "ModeThree",
"value": 3
"value": 65536,
"comment": "0x00010000"
},
{
"key": "ModeFour",
"value": 4
"value": 65537,
"comment": "0x00010001"
}
]
}
@ -282,15 +286,14 @@
"access": "RO"
},
{
"id": "sgReadyState",
"id": "sgReadyStateRO",
"address": 5000,
"size": 1,
"type": "uint16",
"enum": "SmartGridState",
"registerType": "inputRegister",
"readSchedule": "update",
"description": "Smart grid status",
"defaultValue": "SmartGridStateModeTwo",
"defaultValue": 3,
"access": "RO"
},
{
@ -305,27 +308,16 @@
"access": "RW"
},
{
"id": "sgReadyInputOne",
"id": "sgReadyState",
"address": 4001,
"size": 1,
"type": "uint16",
"size": 2,
"type": "uint32",
"registerType": "holdingRegister",
"enum": "SmartGridState",
"readSchedule": "update",
"description": "SG Ready Input 1",
"defaultValue": 0,
"access": "RW"
},
{
"id": "sgReadyInputTwo",
"address": 4002,
"size": 1,
"type": "uint16",
"registerType": "holdingRegister",
"readSchedule": "update",
"description": "SG Read Input 2",
"defaultValue": 0,
"description": "SG Ready mode",
"defaultValue": "SmartGridStateModeThree",
"access": "RW"
}
]
}

View File

@ -131,9 +131,9 @@ quint16 StiebelEltronModbusConnection::systemStatus() const
return m_systemStatus;
}
StiebelEltronModbusConnection::SmartGridState StiebelEltronModbusConnection::sgReadyState() const
quint16 StiebelEltronModbusConnection::sgReadyStateRO() const
{
return m_sgReadyState;
return m_sgReadyStateRO;
}
quint16 StiebelEltronModbusConnection::sgReadyActive() const
@ -150,34 +150,20 @@ QModbusReply *StiebelEltronModbusConnection::setSgReadyActive(quint16 sgReadyAct
return sendWriteRequest(request, m_slaveId);
}
quint16 StiebelEltronModbusConnection::sgReadyInputOne() const
StiebelEltronModbusConnection::SmartGridState StiebelEltronModbusConnection::sgReadyState() const
{
return m_sgReadyInputOne;
return m_sgReadyState;
}
QModbusReply *StiebelEltronModbusConnection::setSgReadyInputOne(quint16 sgReadyInputOne)
QModbusReply *StiebelEltronModbusConnection::setSgReadyState(SmartGridState sgReadyState)
{
QVector<quint16> values = ModbusDataUtils::convertFromUInt16(sgReadyInputOne);
qCDebug(dcStiebelEltronModbusConnection()) << "--> Write \"SG Ready Input 1\" register:" << 4001 << "size:" << 1 << values;
QVector<quint16> values = ModbusDataUtils::convertFromUInt32(static_cast<quint32>(sgReadyState), ModbusDataUtils::ByteOrderBigEndian);
qCDebug(dcStiebelEltronModbusConnection()) << "--> Write \"SG Ready mode\" register:" << 4001 << "size:" << 2 << values;
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 4001, values.count());
request.setValues(values);
return sendWriteRequest(request, m_slaveId);
}
quint16 StiebelEltronModbusConnection::sgReadyInputTwo() const
{
return m_sgReadyInputTwo;
}
QModbusReply *StiebelEltronModbusConnection::setSgReadyInputTwo(quint16 sgReadyInputTwo)
{
QVector<quint16> values = ModbusDataUtils::convertFromUInt16(sgReadyInputTwo);
qCDebug(dcStiebelEltronModbusConnection()) << "--> Write \"SG Read Input 2\" register:" << 4002 << "size:" << 1 << values;
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 4002, values.count());
request.setValues(values);
return sendWriteRequest(request, m_slaveId);
}
void StiebelEltronModbusConnection::initialize()
{
// No init registers defined. Nothing to be done and we are finished.
@ -204,10 +190,9 @@ void StiebelEltronModbusConnection::update()
updateConsumedEnergyHotWater();
updateOperatingMode();
updateSystemStatus();
updateSgReadyState();
updateSgReadyStateRO();
updateSgReadyActive();
updateSgReadyInputOne();
updateSgReadyInputTwo();
updateSgReadyState();
}
void StiebelEltronModbusConnection::updateOutdoorTemperature()
@ -804,11 +789,11 @@ void StiebelEltronModbusConnection::updateSystemStatus()
}
}
void StiebelEltronModbusConnection::updateSgReadyState()
void StiebelEltronModbusConnection::updateSgReadyStateRO()
{
// Update registers from Smart grid status
qCDebug(dcStiebelEltronModbusConnection()) << "--> Read \"Smart grid status\" register:" << 5000 << "size:" << 1;
QModbusReply *reply = readSgReadyState();
QModbusReply *reply = readSgReadyStateRO();
if (reply) {
if (!reply->isFinished()) {
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
@ -817,10 +802,10 @@ void StiebelEltronModbusConnection::updateSgReadyState()
const QModbusDataUnit unit = reply->result();
const QVector<quint16> values = unit.values();
qCDebug(dcStiebelEltronModbusConnection()) << "<-- Response from \"Smart grid status\" register" << 5000 << "size:" << 1 << values;
SmartGridState receivedSgReadyState = static_cast<SmartGridState>(ModbusDataUtils::convertToUInt16(values));
if (m_sgReadyState != receivedSgReadyState) {
m_sgReadyState = receivedSgReadyState;
emit sgReadyStateChanged(m_sgReadyState);
quint16 receivedSgReadyStateRO = ModbusDataUtils::convertToUInt16(values);
if (m_sgReadyStateRO != receivedSgReadyStateRO) {
m_sgReadyStateRO = receivedSgReadyStateRO;
emit sgReadyStateROChanged(m_sgReadyStateRO);
}
}
});
@ -870,11 +855,11 @@ void StiebelEltronModbusConnection::updateSgReadyActive()
}
}
void StiebelEltronModbusConnection::updateSgReadyInputOne()
void StiebelEltronModbusConnection::updateSgReadyState()
{
// Update registers from SG Ready Input 1
qCDebug(dcStiebelEltronModbusConnection()) << "--> Read \"SG Ready Input 1\" register:" << 4001 << "size:" << 1;
QModbusReply *reply = readSgReadyInputOne();
// Update registers from SG Ready mode
qCDebug(dcStiebelEltronModbusConnection()) << "--> Read \"SG Ready mode\" register:" << 4001 << "size:" << 2;
QModbusReply *reply = readSgReadyState();
if (reply) {
if (!reply->isFinished()) {
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
@ -882,57 +867,24 @@ void StiebelEltronModbusConnection::updateSgReadyInputOne()
if (reply->error() == QModbusDevice::NoError) {
const QModbusDataUnit unit = reply->result();
const QVector<quint16> values = unit.values();
qCDebug(dcStiebelEltronModbusConnection()) << "<-- Response from \"SG Ready Input 1\" register" << 4001 << "size:" << 1 << values;
quint16 receivedSgReadyInputOne = ModbusDataUtils::convertToUInt16(values);
if (m_sgReadyInputOne != receivedSgReadyInputOne) {
m_sgReadyInputOne = receivedSgReadyInputOne;
emit sgReadyInputOneChanged(m_sgReadyInputOne);
qCDebug(dcStiebelEltronModbusConnection()) << "<-- Response from \"SG Ready mode\" register" << 4001 << "size:" << 2 << values;
SmartGridState receivedSgReadyState = static_cast<SmartGridState>(ModbusDataUtils::convertToUInt32(values, ModbusDataUtils::ByteOrderBigEndian));
if (m_sgReadyState != receivedSgReadyState) {
m_sgReadyState = receivedSgReadyState;
emit sgReadyStateChanged(m_sgReadyState);
}
}
});
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
qCWarning(dcStiebelEltronModbusConnection()) << "Modbus reply error occurred while updating \"SG Ready Input 1\" registers from" << hostAddress().toString() << error << reply->errorString();
qCWarning(dcStiebelEltronModbusConnection()) << "Modbus reply error occurred while updating \"SG Ready mode\" registers from" << hostAddress().toString() << error << reply->errorString();
emit reply->finished(); // To make sure it will be deleted
});
} else {
delete reply; // Broadcast reply returns immediatly
}
} else {
qCWarning(dcStiebelEltronModbusConnection()) << "Error occurred while reading \"SG Ready Input 1\" registers from" << hostAddress().toString() << errorString();
}
}
void StiebelEltronModbusConnection::updateSgReadyInputTwo()
{
// Update registers from SG Read Input 2
qCDebug(dcStiebelEltronModbusConnection()) << "--> Read \"SG Read Input 2\" register:" << 4002 << "size:" << 1;
QModbusReply *reply = readSgReadyInputTwo();
if (reply) {
if (!reply->isFinished()) {
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
connect(reply, &QModbusReply::finished, this, [this, reply](){
if (reply->error() == QModbusDevice::NoError) {
const QModbusDataUnit unit = reply->result();
const QVector<quint16> values = unit.values();
qCDebug(dcStiebelEltronModbusConnection()) << "<-- Response from \"SG Read Input 2\" register" << 4002 << "size:" << 1 << values;
quint16 receivedSgReadyInputTwo = ModbusDataUtils::convertToUInt16(values);
if (m_sgReadyInputTwo != receivedSgReadyInputTwo) {
m_sgReadyInputTwo = receivedSgReadyInputTwo;
emit sgReadyInputTwoChanged(m_sgReadyInputTwo);
}
}
});
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
qCWarning(dcStiebelEltronModbusConnection()) << "Modbus reply error occurred while updating \"SG Read Input 2\" registers from" << hostAddress().toString() << error << reply->errorString();
emit reply->finished(); // To make sure it will be deleted
});
} else {
delete reply; // Broadcast reply returns immediatly
}
} else {
qCWarning(dcStiebelEltronModbusConnection()) << "Error occurred while reading \"SG Read Input 2\" registers from" << hostAddress().toString() << errorString();
qCWarning(dcStiebelEltronModbusConnection()) << "Error occurred while reading \"SG Ready mode\" registers from" << hostAddress().toString() << errorString();
}
}
@ -1044,7 +996,7 @@ QModbusReply *StiebelEltronModbusConnection::readSystemStatus()
return sendReadRequest(request, m_slaveId);
}
QModbusReply *StiebelEltronModbusConnection::readSgReadyState()
QModbusReply *StiebelEltronModbusConnection::readSgReadyStateRO()
{
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::InputRegisters, 5000, 1);
return sendReadRequest(request, m_slaveId);
@ -1056,15 +1008,9 @@ QModbusReply *StiebelEltronModbusConnection::readSgReadyActive()
return sendReadRequest(request, m_slaveId);
}
QModbusReply *StiebelEltronModbusConnection::readSgReadyInputOne()
QModbusReply *StiebelEltronModbusConnection::readSgReadyState()
{
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 4001, 1);
return sendReadRequest(request, m_slaveId);
}
QModbusReply *StiebelEltronModbusConnection::readSgReadyInputTwo()
{
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 4002, 1);
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 4001, 2);
return sendReadRequest(request, m_slaveId);
}
@ -1097,10 +1043,9 @@ QDebug operator<<(QDebug debug, StiebelEltronModbusConnection *stiebelEltronModb
debug.nospace().noquote() << " - Consumed energy hot water:" << stiebelEltronModbusConnection->consumedEnergyHotWater() << " [kWh]" << "\n";
debug.nospace().noquote() << " - Operating mode:" << stiebelEltronModbusConnection->operatingMode() << "\n";
debug.nospace().noquote() << " - System status:" << stiebelEltronModbusConnection->systemStatus() << "\n";
debug.nospace().noquote() << " - Smart grid status:" << stiebelEltronModbusConnection->sgReadyState() << "\n";
debug.nospace().noquote() << " - Smart grid status:" << stiebelEltronModbusConnection->sgReadyStateRO() << "\n";
debug.nospace().noquote() << " - SG ready active:" << stiebelEltronModbusConnection->sgReadyActive() << "\n";
debug.nospace().noquote() << " - SG Ready Input 1:" << stiebelEltronModbusConnection->sgReadyInputOne() << "\n";
debug.nospace().noquote() << " - SG Read Input 2:" << stiebelEltronModbusConnection->sgReadyInputTwo() << "\n";
debug.nospace().noquote() << " - SG Ready mode:" << stiebelEltronModbusConnection->sgReadyState() << "\n";
return debug.quote().space();
}

View File

@ -60,9 +60,8 @@ public:
RegisterConsumedEnergyHeating = 3511,
RegisterConsumedEnergyHotWater = 3514,
RegisterSgReadyActive = 4000,
RegisterSgReadyInputOne = 4001,
RegisterSgReadyInputTwo = 4002,
RegisterSgReadyState = 5000
RegisterSgReadyState = 4001,
RegisterSgReadyStateRO = 5000
};
Q_ENUM(Registers)
@ -78,9 +77,9 @@ public:
enum SmartGridState {
SmartGridStateModeOne = 1,
SmartGridStateModeTwo = 2,
SmartGridStateModeThree = 3,
SmartGridStateModeFour = 4
SmartGridStateModeTwo = 0,
SmartGridStateModeThree = 65536,
SmartGridStateModeFour = 65537
};
Q_ENUM(SmartGridState)
@ -142,19 +141,15 @@ public:
quint16 systemStatus() const;
/* Smart grid status - Address: 5000, Size: 1 */
SmartGridState sgReadyState() const;
quint16 sgReadyStateRO() const;
/* SG ready active - Address: 4000, Size: 1 */
quint16 sgReadyActive() const;
QModbusReply *setSgReadyActive(quint16 sgReadyActive);
/* SG Ready Input 1 - Address: 4001, Size: 1 */
quint16 sgReadyInputOne() const;
QModbusReply *setSgReadyInputOne(quint16 sgReadyInputOne);
/* SG Read Input 2 - Address: 4002, Size: 1 */
quint16 sgReadyInputTwo() const;
QModbusReply *setSgReadyInputTwo(quint16 sgReadyInputTwo);
/* SG Ready mode - Address: 4001, Size: 2 */
SmartGridState sgReadyState() const;
QModbusReply *setSgReadyState(SmartGridState sgReadyState);
virtual void initialize();
virtual void update();
@ -177,10 +172,9 @@ public:
void updateConsumedEnergyHotWater();
void updateOperatingMode();
void updateSystemStatus();
void updateSgReadyState();
void updateSgReadyStateRO();
void updateSgReadyActive();
void updateSgReadyInputOne();
void updateSgReadyInputTwo();
void updateSgReadyState();
signals:
void initializationFinished();
@ -203,10 +197,9 @@ signals:
void consumedEnergyHotWaterChanged(quint32 consumedEnergyHotWater);
void operatingModeChanged(OperatingMode operatingMode);
void systemStatusChanged(quint16 systemStatus);
void sgReadyStateChanged(SmartGridState sgReadyState);
void sgReadyStateROChanged(quint16 sgReadyStateRO);
void sgReadyActiveChanged(quint16 sgReadyActive);
void sgReadyInputOneChanged(quint16 sgReadyInputOne);
void sgReadyInputTwoChanged(quint16 sgReadyInputTwo);
void sgReadyStateChanged(SmartGridState sgReadyState);
protected:
QModbusReply *readOutdoorTemperature();
@ -227,10 +220,9 @@ protected:
QModbusReply *readConsumedEnergyHotWater();
QModbusReply *readOperatingMode();
QModbusReply *readSystemStatus();
QModbusReply *readSgReadyState();
QModbusReply *readSgReadyStateRO();
QModbusReply *readSgReadyActive();
QModbusReply *readSgReadyInputOne();
QModbusReply *readSgReadyInputTwo();
QModbusReply *readSgReadyState();
float m_outdoorTemperature = 0;
float m_flowTemperature = 0;
@ -250,10 +242,9 @@ protected:
quint32 m_consumedEnergyHotWater = 0;
OperatingMode m_operatingMode = OperatingModeStandby;
quint16 m_systemStatus = 0;
SmartGridState m_sgReadyState = SmartGridStateModeTwo;
quint16 m_sgReadyStateRO = 3;
quint16 m_sgReadyActive = 0;
quint16 m_sgReadyInputOne = 0;
quint16 m_sgReadyInputTwo = 0;
SmartGridState m_sgReadyState = SmartGridStateModeThree;
private:
quint16 m_slaveId = 1;