Add read write for digitalInputMode register

Signed-off-by: Martin Lukas <martin.lukas@chargebyte.com>
master
Martin Lukas 2024-09-02 09:31:42 +02:00
parent 3f3b9d0e01
commit 816c132c46
5 changed files with 120 additions and 1 deletions

View File

@ -103,6 +103,23 @@
"value": 9
}
]
},
{
"name": "DigitalInputMode",
"values": [
{
"key": "EnableCharging",
"value": 0
},
{
"key": "EnableChargingInverted",
"value": 1
},
{
"key": "PwmS0Enabled",
"value": 2
}
]
}
],
"blocks": [
@ -329,6 +346,16 @@
"description": "LED brightness",
"unit": "%",
"access": "WO"
},
{
"id": "digitalInputMode",
"address": 205,
"size": 1,
"type": "uint16",
"registerType": "holdingRegister",
"description": "Digital input mode",
"enum": "DigitalInputMode",
"access": "WR"
}
]
}

View File

@ -329,7 +329,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
thing->setStateMaxValue(ev11MaxChargingCurrentStateTypeId, connection->maxChargingCurrentDip() / 1000);
thing->setStateValue(ev11PluggedInStateTypeId, connection->chargingState() >= PceWallbox::ChargingStateB1 &&
connection->chargingState() < PceWallbox::ChargingStateError);
connection->chargingState() < PceWallbox::ChargingStateError);
thing->setStateValue(ev11ChargingStateTypeId, connection->chargingState() == PceWallbox::ChargingStateC2);
if (connection->chargingRelayState() != EV11ModbusTcpConnection::ChargingRelayStateNoCharging) {
@ -372,6 +372,18 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
thing->setStateValue(ev11ErrorStateTypeId, "DC Fehlerstromsensor, Fehler.");
break;
}
switch (connection->digitalInputMode()) {
case EV11ModbusTcpConnection::DigitalInputModeEnableCharging:
thing->setSettingValue(ev11SettingsDigitalInputModeParamTypeId, "Charging allowed");
break;
case EV11ModbusTcpConnection::DigitalInputModeEnableChargingInverted:
thing->setSettingValue(ev11SettingsDigitalInputModeParamTypeId, "Charging allowed inverted");
break;
case EV11ModbusTcpConnection::DigitalInputModePwmS0Enabled:
thing->setSettingValue(ev11SettingsDigitalInputModeParamTypeId, "PWM and S0 signaling");
break;
}
});
connect(thing, &Thing::settingChanged, connection, [thing, connection](const ParamTypeId &paramTypeId, const QVariant &value){
@ -387,6 +399,26 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
qCDebug(dcPcElectric()) << "Successfully set led brightness to" << percentage << "%";
});
} else if (paramTypeId == ev11SettingsDigitalInputModeParamTypeId) {
QString mode = value.toString();
qCDebug(dcPcElectric()) << "Set Digital input mode" << mode;
EV11ModbusTcpConnection::DigitalInputMode modeValue = EV11ModbusTcpConnection::DigitalInputModeEnableCharging;
if (mode == "Charging allowed inverted") {
modeValue = EV11ModbusTcpConnection::DigitalInputModeEnableChargingInverted;
} else if (mode == "PWM and S0 signaling") {
modeValue = EV11ModbusTcpConnection::DigitalInputModePwmS0Enabled;
}
QueuedModbusReply *reply = connection->setDigitalInputMode(modeValue);
connect(reply, &QueuedModbusReply::finished, thing, [reply, modeValue](){
if (reply->error() != QModbusDevice::NoError) {
qCWarning(dcPcElectric()) << "Could not set digital input mode to" << modeValue << reply->errorString();
return;
}
qCDebug(dcPcElectric()) << "Successfully set digital input mode to" << modeValue;
});
}
});

View File

@ -42,6 +42,14 @@
"maxValue": 100,
"unit": "Percentage",
"defaultValue": 50
},
{
"id": "930e0bf9-0038-436d-9eae-5c0f1cb28825",
"name": "digitalInputMode",
"displayName": "Digital input mode",
"type": "QString",
"defaultValue": "Charging allowed",
"allowedValues": ["Charging allowed", "Charging allowed inverted", "PWM and S0 signaling"]
}
],
"stateTypes": [

View File

@ -107,6 +107,35 @@ bool PceWallbox::update()
sendNextRequest();
});
enqueueRequest(reply);
foreach (QueuedModbusReply *r, m_queue) {
if (r->dataUnit().startAddress() == digitalInputModeDataUnit().startAddress()) {
return true;
}
}
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, digitalInputModeDataUnit(), this);
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
if (m_currentReply == reply)
m_currentReply = nullptr;
if (reply->error() != QModbusDevice::NoError) {
emit updateFinished();
sendNextRequest();
return;
}
const QModbusDataUnit unit = reply->reply()->result();
const QVector<quint16> values = unit.values();
processDigitalInputModeRegisterValues(values);
emit updateFinished();
sendNextRequest();
});
enqueueRequest(reply);
return true;
}
@ -151,6 +180,27 @@ QueuedModbusReply *PceWallbox::setLedBrightness(quint16 percentage)
return reply;
}
QueuedModbusReply *PceWallbox::setDigitalInputMode(DigitalInputMode digitalInputMode)
{
if (m_aboutToDelete)
return nullptr;
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setDigitalInputModeDataUnit(digitalInputMode), this);
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
if (m_currentReply == reply)
m_currentReply = nullptr;
sendNextRequest();
return;
});
enqueueRequest(reply, true);
return reply;
}
void PceWallbox::gracefullDeleteLater()
{
// Clean up the queue

View File

@ -51,6 +51,8 @@ public:
QueuedModbusReply *setLedBrightness(quint16 percentage);
QueuedModbusReply *setDigitalInputMode(DigitalInputMode digitalInputMode);
// Note: the modbus implementation of the wallbox gets stuck if a Modbus request has been sent
// and we disconnect the socket before the response has arrived. Only a reboot of the wallbox
// fixes the broken communication afterwards. This method waits for the current request before closing the