diff --git a/schrack/cion-registers.json b/schrack/cion-registers.json index 33d53a6..8ad26f0 100644 --- a/schrack/cion-registers.json +++ b/schrack/cion-registers.json @@ -72,7 +72,7 @@ "defaultValue": 0, "access": "R" } - ] + ] } ], "registers": [ @@ -106,6 +106,17 @@ "type": "uint16", "registerType": "holdingRegister", "readSchedule": "update", + "description": "Mode3-State A, B, C, D, U", + "defaultValue": 85, + "access": "R" + }, + { + "id": "cpSignalState", + "address": 139, + "size": 1, + "type": "uint16", + "registerType": "holdingRegister", + "readSchedule": "update", "description": "Status bits", "defaultValue": 0, "access": "R" diff --git a/schrack/cionmodbusrtuconnection.cpp b/schrack/cionmodbusrtuconnection.cpp index a9be7ae..0c94528 100644 --- a/schrack/cionmodbusrtuconnection.cpp +++ b/schrack/cionmodbusrtuconnection.cpp @@ -30,9 +30,7 @@ #include "cionmodbusrtuconnection.h" #include "loggingcategories.h" - -#include - +#include NYMEA_LOGGING_CATEGORY(dcCionModbusRtuConnection, "CionModbusRtuConnection") CionModbusRtuConnection::CionModbusRtuConnection(ModbusRtuMaster *modbusRtuMaster, quint16 slaveId, QObject *parent) : @@ -80,6 +78,11 @@ quint16 CionModbusRtuConnection::statusBits() const return m_statusBits; } +quint16 CionModbusRtuConnection::cpSignalState() const +{ + return m_cpSignalState; +} + float CionModbusRtuConnection::u1Voltage() const { return m_u1Voltage; @@ -131,6 +134,7 @@ void CionModbusRtuConnection::update() updateChargingEnabled(); updateChargingCurrentSetpoint(); updateStatusBits(); + updateCpSignalState(); updateU1Voltage(); updateGridVoltage(); updateMinChargingCurrent(); @@ -198,15 +202,15 @@ void CionModbusRtuConnection::updateChargingCurrentSetpoint() void CionModbusRtuConnection::updateStatusBits() { - // Update registers from Status bits - qCDebug(dcCionModbusRtuConnection()) << "--> Read \"Status bits\" register:" << 121 << "size:" << 1; + // Update registers from Mode3-State A, B, C, D, U + qCDebug(dcCionModbusRtuConnection()) << "--> Read \"Mode3-State A, B, C, D, U\" register:" << 121 << "size:" << 1; ModbusRtuReply *reply = readStatusBits(); if (reply) { if (!reply->isFinished()) { connect(reply, &ModbusRtuReply::finished, this, [this, reply](){ if (reply->error() == ModbusRtuReply::NoError) { QVector values = reply->result(); - qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"Status bits\" register" << 121 << "size:" << 1 << values; + qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"Mode3-State A, B, C, D, U\" register" << 121 << "size:" << 1 << values; quint16 receivedStatusBits = ModbusDataUtils::convertToUInt16(values); if (m_statusBits != receivedStatusBits) { m_statusBits = receivedStatusBits; @@ -215,6 +219,35 @@ void CionModbusRtuConnection::updateStatusBits() } }); + connect(reply, &ModbusRtuReply::errorOccurred, this, [reply] (ModbusRtuReply::Error error){ + qCWarning(dcCionModbusRtuConnection()) << "ModbusRtu reply error occurred while updating \"Mode3-State A, B, C, D, U\" registers" << error << reply->errorString(); + emit reply->finished(); + }); + } + } else { + qCWarning(dcCionModbusRtuConnection()) << "Error occurred while reading \"Mode3-State A, B, C, D, U\" registers"; + } +} + +void CionModbusRtuConnection::updateCpSignalState() +{ + // Update registers from Status bits + qCDebug(dcCionModbusRtuConnection()) << "--> Read \"Status bits\" register:" << 139 << "size:" << 1; + ModbusRtuReply *reply = readCpSignalState(); + if (reply) { + if (!reply->isFinished()) { + connect(reply, &ModbusRtuReply::finished, this, [this, reply](){ + if (reply->error() == ModbusRtuReply::NoError) { + QVector values = reply->result(); + qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"Status bits\" register" << 139 << "size:" << 1 << values; + quint16 receivedCpSignalState = ModbusDataUtils::convertToUInt16(values); + if (m_cpSignalState != receivedCpSignalState) { + m_cpSignalState = receivedCpSignalState; + emit cpSignalStateChanged(m_cpSignalState); + } + } + }); + connect(reply, &ModbusRtuReply::errorOccurred, this, [reply] (ModbusRtuReply::Error error){ qCWarning(dcCionModbusRtuConnection()) << "ModbusRtu reply error occurred while updating \"Status bits\" registers" << error << reply->errorString(); emit reply->finished(); @@ -236,7 +269,7 @@ void CionModbusRtuConnection::updateU1Voltage() if (reply->error() == ModbusRtuReply::NoError) { QVector values = reply->result(); qCDebug(dcCionModbusRtuConnection()) << "<-- Response from \"U1 voltage\" register" << 167 << "size:" << 1 << values; - float receivedU1Voltage = ModbusDataUtils::convertToUInt16(values) * 1.0 * qPow(10, -2); + float receivedU1Voltage = ModbusDataUtils::convertToUInt16(values) * 1.0 * pow(10, -2); if (m_u1Voltage != receivedU1Voltage) { m_u1Voltage = receivedU1Voltage; emit u1VoltageChanged(m_u1Voltage); @@ -412,6 +445,11 @@ ModbusRtuReply *CionModbusRtuConnection::readStatusBits() return m_modbusRtuMaster->readHoldingRegister(m_slaveId, 121, 1); } +ModbusRtuReply *CionModbusRtuConnection::readCpSignalState() +{ + return m_modbusRtuMaster->readHoldingRegister(m_slaveId, 139, 1); +} + ModbusRtuReply *CionModbusRtuConnection::readU1Voltage() { return m_modbusRtuMaster->readHoldingRegister(m_slaveId, 167, 1); @@ -440,7 +478,8 @@ QDebug operator<<(QDebug debug, CionModbusRtuConnection *cionModbusRtuConnection debug.nospace().noquote() << "CionModbusRtuConnection(" << cionModbusRtuConnection->modbusRtuMaster()->modbusUuid().toString() << ", " << cionModbusRtuConnection->modbusRtuMaster()->serialPort() << ", slave ID:" << cionModbusRtuConnection->slaveId() << ")" << "\n"; debug.nospace().noquote() << " - Charging enabled:" << cionModbusRtuConnection->chargingEnabled() << "\n"; debug.nospace().noquote() << " - Charging current setpoint:" << cionModbusRtuConnection->chargingCurrentSetpoint() << " [A]" << "\n"; - debug.nospace().noquote() << " - Status bits:" << cionModbusRtuConnection->statusBits() << "\n"; + debug.nospace().noquote() << " - Mode3-State A, B, C, D, U:" << cionModbusRtuConnection->statusBits() << "\n"; + debug.nospace().noquote() << " - Status bits:" << cionModbusRtuConnection->cpSignalState() << "\n"; debug.nospace().noquote() << " - U1 voltage:" << cionModbusRtuConnection->u1Voltage() << " [V]" << "\n"; debug.nospace().noquote() << " - Voltage of the power supply grid:" << cionModbusRtuConnection->gridVoltage() << " [V]" << "\n"; debug.nospace().noquote() << " - Minimum charging current:" << cionModbusRtuConnection->minChargingCurrent() << " [A]" << "\n"; diff --git a/schrack/cionmodbusrtuconnection.h b/schrack/cionmodbusrtuconnection.h index 9e77d6b..a9ab8db 100644 --- a/schrack/cionmodbusrtuconnection.h +++ b/schrack/cionmodbusrtuconnection.h @@ -47,6 +47,7 @@ public: RegisterCurrentChargingCurrentE3 = 126, RegisterMaxChargingCurrentE3 = 127, RegisterMaxChargingCurrentCableE3 = 128, + RegisterCpSignalState = 139, RegisterChargingDuration = 151, RegisterPluggedInDuration = 153, RegisterU1Voltage = 167, @@ -69,9 +70,12 @@ public: quint16 chargingCurrentSetpoint() const; ModbusRtuReply *setChargingCurrentSetpoint(quint16 chargingCurrentSetpoint); - /* Status bits - Address: 121, Size: 1 */ + /* Mode3-State A, B, C, D, U - Address: 121, Size: 1 */ quint16 statusBits() const; + /* Status bits - Address: 139, Size: 1 */ + quint16 cpSignalState() const; + /* U1 voltage [V] - Address: 167, Size: 1 */ float u1Voltage() const; @@ -111,6 +115,7 @@ public: void updateChargingEnabled(); void updateChargingCurrentSetpoint(); void updateStatusBits(); + void updateCpSignalState(); void updateU1Voltage(); void updateGridVoltage(); void updateMinChargingCurrent(); @@ -124,6 +129,7 @@ signals: void chargingEnabledChanged(quint16 chargingEnabled); void chargingCurrentSetpointChanged(quint16 chargingCurrentSetpoint); void statusBitsChanged(quint16 statusBits); + void cpSignalStateChanged(quint16 cpSignalState); void u1VoltageChanged(float u1Voltage); void gridVoltageChanged(float gridVoltage); void minChargingCurrentChanged(quint16 minChargingCurrent); @@ -137,13 +143,15 @@ protected: ModbusRtuReply *readChargingEnabled(); ModbusRtuReply *readChargingCurrentSetpoint(); ModbusRtuReply *readStatusBits(); + ModbusRtuReply *readCpSignalState(); ModbusRtuReply *readU1Voltage(); ModbusRtuReply *readGridVoltage(); ModbusRtuReply *readMinChargingCurrent(); quint16 m_chargingEnabled = 0; quint16 m_chargingCurrentSetpoint = 6; - quint16 m_statusBits = 0; + quint16 m_statusBits = 85; + quint16 m_cpSignalState = 0; float m_u1Voltage = 32; float m_gridVoltage = 0; quint16 m_minChargingCurrent = 13; diff --git a/schrack/integrationpluginschrack.cpp b/schrack/integrationpluginschrack.cpp index 222956d..d58755c 100644 --- a/schrack/integrationpluginschrack.cpp +++ b/schrack/integrationpluginschrack.cpp @@ -122,6 +122,14 @@ void IntegrationPluginSchrack::setupThing(ThingSetupInfo *info) // finishAction(cionMaxChargingCurrentStateTypeId); }); + connect(cionConnection, &CionModbusRtuConnection::cpSignalStateChanged, thing, [=](quint16 cpSignalState){ + qCDebug(dcSchrack()) << "CP Signal state changed:" << cpSignalState; + thing->setStateValue(cionPluggedInStateTypeId, cpSignalState >= 66); +// thing->setStateValue(cionMaxChargingCurrentStateTypeId, chargingCurrentSetpoint); +// thing->setStateValue(cionConnectedStateTypeId, true); +// finishAction(cionMaxChargingCurrentStateTypeId); + }); + // connect(cionConnection, &CionModbusRtuConnection::currentChargingCurrentE3Changed, thing, [=](quint16 currentChargingCurrentE3){ qCDebug(dcSchrack()) << "Current charging current E3 current changed:" << currentChargingCurrentE3; @@ -139,6 +147,7 @@ void IntegrationPluginSchrack::setupThing(ThingSetupInfo *info) }); connect(cionConnection, &CionModbusRtuConnection::statusBitsChanged, thing, [=](quint16 statusBits){ + thing->setStateValue(cionConnectedStateTypeId, true); qCDebug(dcSchrack()) << "Status bits changed:" << statusBits; }); @@ -155,11 +164,13 @@ void IntegrationPluginSchrack::setupThing(ThingSetupInfo *info) connect(cionConnection, &CionModbusRtuConnection::u1VoltageChanged, thing, [=](float u1Voltage){ qCDebug(dcSchrack()) << "U1 voltage changed:" << u1Voltage; updateCurrentPower(thing); + qCDebug(dcSchrack()) << "******** Charging duration:" << cionConnection->chargingDuration(); }); connect(cionConnection, &CionModbusRtuConnection::pluggedInDurationChanged, thing, [=](quint32 pluggedInDuration){ qCDebug(dcSchrack()) << "Plugged in duration changed:" << pluggedInDuration; - thing->setStateValue(cionPluggedInStateTypeId, pluggedInDuration > 0); + // Not reliable to determine if plugged in! +// thing->setStateValue(cionPluggedInStateTypeId, pluggedInDuration > 0); }); connect(cionConnection, &CionModbusRtuConnection::chargingDurationChanged, thing, [=](quint32 chargingDuration){ @@ -187,6 +198,8 @@ void IntegrationPluginSchrack::postSetupThing(Thing *thing) foreach (Thing *thing, myThings()) { m_cionConnections.value(thing)->update(); + thing->setStateValue(cionChargingStateTypeId, m_cionConnections.value(thing)->chargingDuration() != m_lastChargingDuration); + m_lastChargingDuration = m_cionConnections.value(thing)->chargingDuration(); } }); @@ -213,6 +226,7 @@ void IntegrationPluginSchrack::executeAction(ThingActionInfo *info) { CionModbusRtuConnection *cionConnection = m_cionConnections.value(info->thing()); if (info->action().actionTypeId() == cionPowerActionTypeId) { + qCDebug(dcSchrack()) << "Setting charging enabled:" << (info->action().paramValue(cionPowerActionPowerParamTypeId).toBool() ? 1 : 0); ModbusRtuReply *reply = cionConnection->setChargingEnabled(info->action().paramValue(cionPowerActionPowerParamTypeId).toBool() ? 1 : 0); waitForActionFinish(info, reply, cionPowerStateTypeId); } else if (info->action().actionTypeId() == cionMaxChargingCurrentActionTypeId) { @@ -233,6 +247,7 @@ void IntegrationPluginSchrack::waitForActionFinish(ThingActionInfo *info, Modbus connect(reply, &ModbusRtuReply::finished, info, [=](){ if (reply->error() != ModbusRtuReply::NoError) { + m_pendingActions.remove(info); info->finish(Thing::ThingErrorHardwareFailure); } }); @@ -262,7 +277,7 @@ void IntegrationPluginSchrack::updateCurrentPower(Thing *thing) thing->setProperty("lastUpdate", now); if (cionConnection->chargingDuration() > 0) { - thing->setStateValue(cionCurrentPowerStateTypeId, 1.0 * cionConnection->u1Voltage() / 100 * cionConnection->currentChargingCurrentE3()); + thing->setStateValue(cionCurrentPowerStateTypeId, 1.0 * cionConnection->u1Voltage() * cionConnection->currentChargingCurrentE3()); } else { thing->setStateValue(cionCurrentPowerStateTypeId, 0); } diff --git a/schrack/integrationpluginschrack.h b/schrack/integrationpluginschrack.h index 75ace86..9143985 100644 --- a/schrack/integrationpluginschrack.h +++ b/schrack/integrationpluginschrack.h @@ -68,6 +68,8 @@ private: QHash m_cionConnections; QHash m_pendingActions; + + qulonglong m_lastChargingDuration = 0; }; #endif // INTEGRATIONPLUGINSCHRACK_H