improved async action handling
This commit is contained in:
parent
4b0b83d941
commit
1cbbeb2045
@ -214,42 +214,43 @@ void DevicePluginKeba::onReportTwoReceived(const KeContact::ReportTwo &reportTwo
|
||||
return;
|
||||
|
||||
device->setStateValue(wallboxPowerStateTypeId, reportTwo.enableUser);
|
||||
device->setStateValue(wallboxMaxChargingCurrentPercentStateTypeId, reportTwo.MaxCurrentPercentage);
|
||||
|
||||
switch (reportTwo.state) {
|
||||
case KeContact::State::Starting:
|
||||
case KeContact::StateStarting:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Starting"));
|
||||
break;
|
||||
case KeContact::State::NotReady:
|
||||
case KeContact::StateNotReady:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Not ready for charging"));
|
||||
break;
|
||||
case KeContact::State::Ready:
|
||||
case KeContact::StateReady:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Ready for charging"));
|
||||
break;
|
||||
case KeContact::State::Charging:
|
||||
case KeContact::StateCharging:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Charging"));
|
||||
break;
|
||||
case KeContact::State::Error:
|
||||
case KeContact::StateError:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Erro"));
|
||||
break;
|
||||
case KeContact::State::AuthorizationRejected:
|
||||
case KeContact::StateAuthorizationRejected:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Authorization rejected"));
|
||||
break;
|
||||
}
|
||||
|
||||
switch (reportTwo.plugState) {
|
||||
case KeContact::PlugState::Unplugged:
|
||||
case KeContact::PlugStateUnplugged:
|
||||
device->setStateValue(wallboxPlugStateStateTypeId, QT_TR_NOOP("Unplugged"));
|
||||
break;
|
||||
case KeContact::PlugState::PluggedOnChargingStation:
|
||||
case KeContact::PlugStatePluggedOnChargingStation:
|
||||
device->setStateValue(wallboxPlugStateStateTypeId, QT_TR_NOOP("Plugged in charging station"));
|
||||
break;
|
||||
case KeContact::PlugState::PluggedOnChargingStationAndPluggedOnEV:
|
||||
case KeContact::PlugStatePluggedOnChargingStationAndPluggedOnEV:
|
||||
device->setStateValue(wallboxPlugStateStateTypeId, QT_TR_NOOP("Plugged in on EV"));
|
||||
break;
|
||||
case KeContact::PlugState::PluggedOnChargingStationAndPlugLocked:
|
||||
case KeContact::PlugStatePluggedOnChargingStationAndPlugLocked:
|
||||
device->setStateValue(wallboxPlugStateStateTypeId, QT_TR_NOOP("Plugged in and locked"));
|
||||
break;
|
||||
case KeContact::PlugState::PluggedOnChargingStationAndPlugLockedAndPluggedOnEV:
|
||||
case KeContact::PlugStatePluggedOnChargingStationAndPlugLockedAndPluggedOnEV:
|
||||
device->setStateValue(wallboxPlugStateStateTypeId, QT_TR_NOOP("Plugged in on EV and locked"));
|
||||
break;
|
||||
}
|
||||
@ -273,17 +274,74 @@ void DevicePluginKeba::onReportThreeReceived(const KeContact::ReportThree &repor
|
||||
device->setStateValue(wallboxTotalEnergyConsumedStateTypeId, reportThree.EnergyTotal);
|
||||
}
|
||||
|
||||
void DevicePluginKeba::onBroadcastReceived(KeContact::BroadcastType type, const QVariant &content)
|
||||
{
|
||||
KeContact *keba = static_cast<KeContact *>(sender());
|
||||
Device *device = myDevices().findById(m_kebaDevices.key(keba));
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
switch (type) {
|
||||
case KeContact::BroadcastTypePlug:
|
||||
switch (KeContact::PlugState(content.toInt())) {
|
||||
case KeContact::PlugStateUnplugged:
|
||||
device->setStateValue(wallboxPlugStateStateTypeId, QT_TR_NOOP("Unplugged"));
|
||||
break;
|
||||
case KeContact::PlugStatePluggedOnChargingStation:
|
||||
device->setStateValue(wallboxPlugStateStateTypeId, QT_TR_NOOP("Plugged in charging station"));
|
||||
break;
|
||||
case KeContact::PlugStatePluggedOnChargingStationAndPluggedOnEV:
|
||||
device->setStateValue(wallboxPlugStateStateTypeId, QT_TR_NOOP("Plugged in on EV"));
|
||||
break;
|
||||
case KeContact::PlugStatePluggedOnChargingStationAndPlugLocked:
|
||||
device->setStateValue(wallboxPlugStateStateTypeId, QT_TR_NOOP("Plugged in and locked"));
|
||||
break;
|
||||
case KeContact::PlugStatePluggedOnChargingStationAndPlugLockedAndPluggedOnEV:
|
||||
device->setStateValue(wallboxPlugStateStateTypeId, QT_TR_NOOP("Plugged in on EV and locked"));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KeContact::BroadcastTypeInput:
|
||||
break;
|
||||
case KeContact::BroadcastTypeEPres:
|
||||
device->setStateValue(wallboxEPStateTypeId, content.toInt());
|
||||
break;
|
||||
case KeContact::BroadcastTypeState:
|
||||
switch (KeContact::State(content.toInt())) {
|
||||
case KeContact::StateStarting:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Starting"));
|
||||
break;
|
||||
case KeContact::StateNotReady:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Not ready for charging"));
|
||||
break;
|
||||
case KeContact::StateReady:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Ready for charging"));
|
||||
break;
|
||||
case KeContact::StateCharging:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Charging"));
|
||||
break;
|
||||
case KeContact::StateError:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Erro"));
|
||||
break;
|
||||
case KeContact::StateAuthorizationRejected:
|
||||
device->setStateValue(wallboxActivityStateTypeId, QT_TR_NOOP("Authorization rejected"));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KeContact::BroadcastTypeMaxCurr:
|
||||
device->setStateValue(wallboxMaxChargingCurrentStateTypeId, content.toInt());
|
||||
break;
|
||||
case KeContact::BroadcastTypeEnableSys:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DevicePluginKeba::executeAction(DeviceActionInfo *info)
|
||||
{
|
||||
Device *device = info->device();
|
||||
Action action = info->action();
|
||||
|
||||
qCDebug(dcKebaKeContact()) << "Execute action" << device->name() << action.actionTypeId().toString();
|
||||
|
||||
if (device->deviceClassId() == wallboxDeviceClassId) {
|
||||
|
||||
// Print information that we are executing now the update action
|
||||
qCDebug(dcKebaKeContact()) << "Execute update action" << action.id();
|
||||
KeContact *keba = m_kebaDevices.value(device->id());
|
||||
if (!keba) {
|
||||
qCWarning(dcKebaKeContact()) << "Device not properly initialized, Keba object missing";
|
||||
@ -291,8 +349,8 @@ void DevicePluginKeba::executeAction(DeviceActionInfo *info)
|
||||
}
|
||||
|
||||
if(action.actionTypeId() == wallboxMaxChargingCurrentActionTypeId){
|
||||
int ampere = action.param(wallboxMaxChargingCurrentActionMaxChargingCurrentParamTypeId).value().toInt()*1000;
|
||||
QUuid requestId = keba->setMaxAmpere(ampere);
|
||||
int milliAmpere = action.param(wallboxMaxChargingCurrentActionMaxChargingCurrentParamTypeId).value().toInt();
|
||||
QUuid requestId = keba->setMaxAmpere(milliAmpere);
|
||||
m_asyncActions.insert(requestId, info);
|
||||
connect(info, &DeviceActionInfo::aborted, this, [requestId, this]{m_asyncActions.remove(requestId);});
|
||||
|
||||
|
||||
@ -75,6 +75,7 @@ private slots:
|
||||
void onReportOneReceived(const KeContact::ReportOne &reportOne);
|
||||
void onReportTwoReceived(const KeContact::ReportTwo &reportTwo);
|
||||
void onReportThreeReceived(const KeContact::ReportThree &reportThree);
|
||||
void onBroadcastReceived(KeContact::BroadcastType type, const QVariant &content);
|
||||
};
|
||||
|
||||
#endif // INTEGRATIONPLUGINKEBA_H
|
||||
|
||||
@ -39,7 +39,8 @@
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connection changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
"defaultValue": false,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "83ed0774-2a91-434d-b03c-d920d02f2981",
|
||||
|
||||
@ -45,6 +45,7 @@ KeContact::KeContact(QHostAddress address, QObject *parent) :
|
||||
emit connectionChanged(false);
|
||||
//Try to send the next command
|
||||
handleNextCommandInQueue();
|
||||
m_deviceBlocked = false;
|
||||
});
|
||||
}
|
||||
|
||||
@ -88,13 +89,14 @@ void KeContact::sendCommand(const QByteArray &command)
|
||||
emit connectionChanged(false);
|
||||
return;
|
||||
}
|
||||
if(!m_commandList.isEmpty()) {
|
||||
if(m_deviceBlocked) {
|
||||
//add command to queue
|
||||
m_commandList.append(command);
|
||||
} else {
|
||||
//send command
|
||||
m_udpSocket->writeDatagram(command, m_address, 7090);
|
||||
m_requestTimeoutTimer->start(5000);
|
||||
m_deviceBlocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,7 +109,7 @@ void KeContact::handleNextCommandInQueue()
|
||||
}
|
||||
qCDebug(dcKebaKeContact()) << "Handle Command Queue- Pending commands" << m_commandList.length() << "Pending requestIds" << m_pendingRequests.length();
|
||||
if (!m_commandList.isEmpty()) {
|
||||
QByteArray command = m_commandList.first();
|
||||
QByteArray command = m_commandList.takeFirst();
|
||||
m_udpSocket->writeDatagram(command, m_address, 7090);
|
||||
m_requestTimeoutTimer->start(5000);
|
||||
} else {
|
||||
@ -244,83 +246,119 @@ void KeContact::readPendingDatagrams()
|
||||
|
||||
qCDebug(dcKebaKeContact()) << "Data received" << datagram;
|
||||
if(datagram.contains("TCH-OK")){
|
||||
if (datagram.contains("done")) {
|
||||
emit commandExecuted(m_pendingRequests.takeFirst(), true);
|
||||
|
||||
//Command response has been received, now send the next command
|
||||
m_deviceBlocked = false;
|
||||
m_requestTimeoutTimer->stop();
|
||||
handleNextCommandInQueue();
|
||||
|
||||
if (!m_pendingRequests.isEmpty()) {
|
||||
QUuid requestId = m_pendingRequests.takeFirst();
|
||||
if (datagram.contains("done")) {
|
||||
emit commandExecuted(requestId, true);
|
||||
} else {
|
||||
emit commandExecuted(requestId, false);
|
||||
}
|
||||
} else {
|
||||
emit commandExecuted(m_pendingRequests.takeFirst(), false);
|
||||
//Probably the response has taken too long and the requestId has been already removed
|
||||
}
|
||||
}
|
||||
} else if(datagram.left(8).contains("Firmware")){
|
||||
|
||||
//Command response has been received, now send the next command
|
||||
m_requestTimeoutTimer->stop();
|
||||
handleNextCommandInQueue();
|
||||
//Command response has been received, now send the next command
|
||||
m_deviceBlocked = false;
|
||||
m_requestTimeoutTimer->stop();
|
||||
handleNextCommandInQueue();
|
||||
|
||||
if(datagram.left(8).contains("Firmware")){
|
||||
qCDebug(dcKebaKeContact()) << "Firmware information reveiced";
|
||||
QByteArrayList firmware = datagram.split(':');
|
||||
if (firmware.length() >= 2) {
|
||||
emit deviceInformationReceived(firmware[1]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Convert the rawdata to a json document
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(datagram, &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcKebaKeContact()) << "Failed to parse JSON data" << datagram << ":" << error.errorString();
|
||||
}
|
||||
//Command response has been received, now send the next command
|
||||
m_deviceBlocked = false;
|
||||
m_requestTimeoutTimer->stop();
|
||||
handleNextCommandInQueue();
|
||||
|
||||
QVariantMap data = jsonDoc.toVariant().toMap();
|
||||
// Convert the rawdata to a json document
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(datagram, &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcKebaKeContact()) << "Failed to parse JSON data" << datagram << ":" << error.errorString();
|
||||
}
|
||||
|
||||
if(data.contains("ID")){
|
||||
QVariantMap data = jsonDoc.toVariant().toMap();
|
||||
|
||||
if (data.value("ID").toString() == "1") {
|
||||
ReportOne reportOne;
|
||||
qCDebug(dcKebaKeContact()) << "Report 1 received";
|
||||
reportOne.product = data.value("Product").toString();
|
||||
reportOne.firmware = data.value("Firmware").toString();
|
||||
reportOne.serialNumber = data.value("Serial").toString();;
|
||||
emit reportOneReceived(reportOne);
|
||||
if(data.contains("ID")) {
|
||||
|
||||
} else if(data.value("ID").toString() == "2"){
|
||||
if (data.value("ID").toString() == "1") {
|
||||
ReportOne reportOne;
|
||||
qCDebug(dcKebaKeContact()) << "Report 1 received";
|
||||
reportOne.product = data.value("Product").toString();
|
||||
reportOne.firmware = data.value("Firmware").toString();
|
||||
reportOne.serialNumber = data.value("Serial").toString();;
|
||||
emit reportOneReceived(reportOne);
|
||||
|
||||
ReportTwo reportTwo;
|
||||
qCDebug(dcKebaKeContact()) << "Report 2 reveiced";
|
||||
int state = data.value("State").toInt();
|
||||
reportTwo.state = State(state);
|
||||
reportTwo.error1 = data.value("Error1").toInt();
|
||||
reportTwo.error2 = data.value("Error2").toInt();
|
||||
reportTwo.plugState = PlugState(data.value("Plug").toInt());
|
||||
reportTwo.enableUser = data.value("Enable user").toBool();
|
||||
reportTwo.enableSys = data.value("Enable sys").toBool();
|
||||
reportTwo.MaxCurrent = data.value("Max curr").toInt()/1000;
|
||||
reportTwo.MaxCurrentPercentage = data.value("Max curr %").toInt()/10;
|
||||
reportTwo.CurrentHardwareLimitation = data.value("Curr HW").toInt()/1000;
|
||||
reportTwo.CurrentUser = data.value("Curr user").toInt();
|
||||
reportTwo.CurrFS = data.value("Curr FS").toInt();
|
||||
reportTwo.TmoFS = data.value("Tmo FS").toInt();
|
||||
reportTwo.output = data.value("Output").toInt();
|
||||
reportTwo.input= data.value("Input").toInt();
|
||||
reportTwo.serialNumber = data.value("Serial").toString();
|
||||
reportTwo.seconds = data.value("Sec").toInt();
|
||||
emit reportTwoReceived(reportTwo);
|
||||
} else if(data.value("ID").toString() == "2"){
|
||||
|
||||
} else if(data.value("ID").toString() == "3"){
|
||||
ReportTwo reportTwo;
|
||||
qCDebug(dcKebaKeContact()) << "Report 2 reveiced";
|
||||
int state = data.value("State").toInt();
|
||||
reportTwo.state = State(state);
|
||||
reportTwo.error1 = data.value("Error1").toInt();
|
||||
reportTwo.error2 = data.value("Error2").toInt();
|
||||
reportTwo.plugState = PlugState(data.value("Plug").toInt());
|
||||
reportTwo.enableUser = data.value("Enable user").toBool();
|
||||
reportTwo.enableSys = data.value("Enable sys").toBool();
|
||||
reportTwo.MaxCurrent = data.value("Max curr").toInt()/1000;
|
||||
reportTwo.MaxCurrentPercentage = data.value("Max curr %").toInt()/10;
|
||||
reportTwo.CurrentHardwareLimitation = data.value("Curr HW").toInt()/1000;
|
||||
reportTwo.CurrentUser = data.value("Curr user").toInt();
|
||||
reportTwo.CurrFS = data.value("Curr FS").toInt();
|
||||
reportTwo.TmoFS = data.value("Tmo FS").toInt();
|
||||
reportTwo.output = data.value("Output").toInt();
|
||||
reportTwo.input= data.value("Input").toInt();
|
||||
reportTwo.serialNumber = data.value("Serial").toString();
|
||||
reportTwo.seconds = data.value("Sec").toInt();
|
||||
emit reportTwoReceived(reportTwo);
|
||||
|
||||
ReportThree reportThree;
|
||||
qCDebug(dcKebaKeContact()) << "Report 3 reveiced";
|
||||
reportThree.CurrentPhase1 = data.value("I1").toInt();
|
||||
reportThree.CurrentPhase2 = data.value("I2").toInt();
|
||||
reportThree.CurrentPhase3 = data.value("I3").toInt();
|
||||
reportThree.VoltagePhase1 = data.value("U1").toInt();
|
||||
reportThree.VoltagePhase2 = data.value("U2").toInt();
|
||||
reportThree.VoltagePhase3 = data.value("U3").toInt();
|
||||
reportThree.Power = data.value("P").toInt();
|
||||
reportThree.PowerFactor = data.value("PF").toInt()/10;
|
||||
reportThree.EnergySession = data.value("E pres").toInt()/10000.00;
|
||||
reportThree.EnergyTotal = data.value("E total").toInt()/10000.00;
|
||||
reportThree.SerialNumber = data.value("Serial").toString();
|
||||
emit reportThreeReceived(reportThree);
|
||||
} else if(data.value("ID").toString() == "3"){
|
||||
|
||||
ReportThree reportThree;
|
||||
qCDebug(dcKebaKeContact()) << "Report 3 reveiced";
|
||||
reportThree.CurrentPhase1 = data.value("I1").toInt();
|
||||
reportThree.CurrentPhase2 = data.value("I2").toInt();
|
||||
reportThree.CurrentPhase3 = data.value("I3").toInt();
|
||||
reportThree.VoltagePhase1 = data.value("U1").toInt();
|
||||
reportThree.VoltagePhase2 = data.value("U2").toInt();
|
||||
reportThree.VoltagePhase3 = data.value("U3").toInt();
|
||||
reportThree.Power = data.value("P").toInt();
|
||||
reportThree.PowerFactor = data.value("PF").toInt()/10;
|
||||
reportThree.EnergySession = data.value("E pres").toInt()/10000.00;
|
||||
reportThree.EnergyTotal = data.value("E total").toInt()/10000.00;
|
||||
reportThree.SerialNumber = data.value("Serial").toString();
|
||||
emit reportThreeReceived(reportThree);
|
||||
}
|
||||
} else {
|
||||
if (data.contains("State")) {
|
||||
emit broadcastReceived(BroadcastType::BroadcastTypeState, data.value("State"));
|
||||
}
|
||||
if (data.contains("Plug")) {
|
||||
emit broadcastReceived(BroadcastType::BroadcastTypePlug, data.value("Plug"));
|
||||
}
|
||||
if (data.contains("Input")) {
|
||||
emit broadcastReceived(BroadcastType::BroadcastTypeInput, data.value("Input"));
|
||||
}
|
||||
if (data.contains("Enable sys")) {
|
||||
emit broadcastReceived(BroadcastType::BroadcastTypeEnableSys, data.value("Enable sys"));
|
||||
}
|
||||
if (data.contains("Max curr")) {
|
||||
emit broadcastReceived(BroadcastType::BroadcastTypeMaxCurr, data.value("Max curr"));
|
||||
}
|
||||
if (data.contains("E pres")) {
|
||||
emit broadcastReceived(BroadcastType::BroadcastTypeEPres, data.value("E pres"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,20 +47,29 @@ public:
|
||||
bool init();
|
||||
|
||||
enum State {
|
||||
Starting = 0,
|
||||
NotReady,
|
||||
Ready,
|
||||
Charging,
|
||||
Error,
|
||||
AuthorizationRejected
|
||||
StateStarting = 0,
|
||||
StateNotReady,
|
||||
StateReady,
|
||||
StateCharging,
|
||||
StateError,
|
||||
StateAuthorizationRejected
|
||||
};
|
||||
|
||||
enum PlugState {
|
||||
Unplugged = 0,
|
||||
PluggedOnChargingStation = 1,
|
||||
PluggedOnChargingStationAndPlugLocked = 3,
|
||||
PluggedOnChargingStationAndPluggedOnEV = 5,
|
||||
PluggedOnChargingStationAndPlugLockedAndPluggedOnEV = 7
|
||||
PlugStateUnplugged = 0,
|
||||
PlugStatePluggedOnChargingStation = 1,
|
||||
PlugStatePluggedOnChargingStationAndPlugLocked = 3,
|
||||
PlugStatePluggedOnChargingStationAndPluggedOnEV = 5,
|
||||
PlugStatePluggedOnChargingStationAndPlugLockedAndPluggedOnEV = 7
|
||||
};
|
||||
|
||||
enum BroadcastType {
|
||||
BroadcastTypeState = 0,
|
||||
BroadcastTypePlug,
|
||||
BroadcastTypeInput,
|
||||
BroadcastTypeEnableSys,
|
||||
BroadcastTypeMaxCurr,
|
||||
BroadcastTypeEPres
|
||||
};
|
||||
|
||||
struct ReportOne {
|
||||
@ -139,6 +148,7 @@ signals:
|
||||
void reportOneReceived(const ReportOne &reportOne);
|
||||
void reportTwoReceived(const ReportTwo &reportTwo);
|
||||
void reportThreeReceived(const ReportThree &reportThree);
|
||||
void broadcastReceived(BroadcastType type, const QVariant &content);
|
||||
|
||||
private slots:
|
||||
void readPendingDatagrams();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user