PcElectric: Improve modbus execution order handling
Signed-off-by: Simon Stürz <simon.stuerz@nymea.io>master
parent
b6cdaeffa0
commit
de9ed002b1
|
|
@ -45,8 +45,7 @@ PceWallbox::PceWallbox(const QHostAddress &hostAddress, uint port, quint16 slave
|
||||||
if (!reachable) {
|
if (!reachable) {
|
||||||
m_timer.stop();
|
m_timer.stop();
|
||||||
|
|
||||||
qDeleteAll(m_queue);
|
cleanupQueues();
|
||||||
m_queue.clear();
|
|
||||||
|
|
||||||
if (m_currentReply) {
|
if (m_currentReply) {
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
@ -80,7 +79,7 @@ bool PceWallbox::update()
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Make sure we only have one update call in the queue
|
// Make sure we only have one update call in the queue
|
||||||
foreach (QueuedModbusReply *r, m_queue) {
|
foreach (QueuedModbusReply *r, m_readQueue) {
|
||||||
if (r->dataUnit().startAddress() == readBlockInitInfosDataUnit().startAddress()) {
|
if (r->dataUnit().startAddress() == readBlockInitInfosDataUnit().startAddress()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +111,7 @@ bool PceWallbox::update()
|
||||||
// - chargingcurrent (if power is true)
|
// - chargingcurrent (if power is true)
|
||||||
// - phases (if power is true)
|
// - phases (if power is true)
|
||||||
bool chargingCurrentQueued = false;
|
bool chargingCurrentQueued = false;
|
||||||
foreach (QueuedModbusReply *r, m_queue) {
|
foreach (QueuedModbusReply *r, m_readQueue) {
|
||||||
if (r->dataUnit().startAddress() == chargingCurrentDataUnit().startAddress()) {
|
if (r->dataUnit().startAddress() == chargingCurrentDataUnit().startAddress()) {
|
||||||
chargingCurrentQueued = true;
|
chargingCurrentQueued = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -144,7 +143,7 @@ bool PceWallbox::update()
|
||||||
|
|
||||||
// Digital input
|
// Digital input
|
||||||
bool digitalInputAlreadyQueued = false;
|
bool digitalInputAlreadyQueued = false;
|
||||||
foreach (QueuedModbusReply *r, m_queue) {
|
foreach (QueuedModbusReply *r, m_readQueue) {
|
||||||
if (r->dataUnit().startAddress() == digitalInputModeDataUnit().startAddress()) {
|
if (r->dataUnit().startAddress() == digitalInputModeDataUnit().startAddress()) {
|
||||||
digitalInputAlreadyQueued = true;
|
digitalInputAlreadyQueued = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -177,7 +176,7 @@ bool PceWallbox::update()
|
||||||
|
|
||||||
// Led brightness
|
// Led brightness
|
||||||
bool ledBrightnessAlreadyQueued = false;
|
bool ledBrightnessAlreadyQueued = false;
|
||||||
foreach (QueuedModbusReply *r, m_queue) {
|
foreach (QueuedModbusReply *r, m_readQueue) {
|
||||||
if (r->dataUnit().startAddress() == ledBrightnessDataUnit().startAddress()) {
|
if (r->dataUnit().startAddress() == ledBrightnessDataUnit().startAddress()) {
|
||||||
ledBrightnessAlreadyQueued = true;
|
ledBrightnessAlreadyQueued = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -226,7 +225,7 @@ QueuedModbusReply *PceWallbox::setChargingCurrent(quint16 chargingCurrent)
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
enqueueRequest(reply, true);
|
enqueueRequest(reply);
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,7 +245,7 @@ QueuedModbusReply *PceWallbox::setLedBrightness(quint16 percentage)
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
enqueueRequest(reply, true);
|
enqueueRequest(reply);
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,7 +265,7 @@ QueuedModbusReply *PceWallbox::setDigitalInputMode(DigitalInputMode digitalInput
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
enqueueRequest(reply, true);
|
enqueueRequest(reply);
|
||||||
return reply;
|
return reply;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +274,7 @@ void PceWallbox::gracefullDeleteLater()
|
||||||
{
|
{
|
||||||
// Clean up the queue
|
// Clean up the queue
|
||||||
m_aboutToDelete = true;
|
m_aboutToDelete = true;
|
||||||
cleanupQueue();
|
cleanupQueues();
|
||||||
|
|
||||||
m_timer.stop();
|
m_timer.stop();
|
||||||
|
|
||||||
|
|
@ -344,12 +343,12 @@ void PceWallbox::sendHeartbeat()
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
enqueueRequest(reply, true);
|
enqueueRequest(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PceWallbox::sendNextRequest()
|
void PceWallbox::sendNextRequest()
|
||||||
{
|
{
|
||||||
if (m_queue.isEmpty())
|
if (m_writeQueue.isEmpty() && m_readQueue.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_currentReply)
|
if (m_currentReply)
|
||||||
|
|
@ -362,7 +361,20 @@ void PceWallbox::sendNextRequest()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentReply = m_queue.dequeue();
|
// Note: due to the fact that we have one register which controls 3 states,
|
||||||
|
// the order of the execution is critical at this point. We have to make sure
|
||||||
|
// the register gets written in the same order as they where requested by the action
|
||||||
|
// execution (and the dedicated ChargingCurrentState buffer)
|
||||||
|
|
||||||
|
if (!m_writeQueue.isEmpty()) {
|
||||||
|
// Prioritize write requests
|
||||||
|
m_currentReply = m_writeQueue.dequeue();
|
||||||
|
qCDebug(dcPcElectric()) << "Dequeued write request. Queue count: W" << m_writeQueue.count() << "| R:" << m_readQueue.count();
|
||||||
|
} else {
|
||||||
|
m_currentReply = m_readQueue.dequeue();
|
||||||
|
qCDebug(dcPcElectric()) << "Dequeued read request. Queue count: W" << m_writeQueue.count() << "| R:" << m_readQueue.count();
|
||||||
|
}
|
||||||
|
|
||||||
switch(m_currentReply->requestType()) {
|
switch(m_currentReply->requestType()) {
|
||||||
case QueuedModbusReply::RequestTypeRead:
|
case QueuedModbusReply::RequestTypeRead:
|
||||||
qCDebug(dcPcElectric()) << "--> Reading" << ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType())
|
qCDebug(dcPcElectric()) << "--> Reading" << ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType())
|
||||||
|
|
@ -400,21 +412,27 @@ void PceWallbox::sendNextRequest()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PceWallbox::enqueueRequest(QueuedModbusReply *reply, bool prepend)
|
void PceWallbox::enqueueRequest(QueuedModbusReply *reply)
|
||||||
{
|
{
|
||||||
if (prepend) {
|
switch (reply->requestType()) {
|
||||||
m_queue.prepend(reply);
|
case QueuedModbusReply::RequestTypeRead:
|
||||||
} else {
|
m_readQueue.enqueue(reply);
|
||||||
m_queue.enqueue(reply);
|
break;
|
||||||
|
case QueuedModbusReply::RequestTypeWrite:
|
||||||
|
m_writeQueue.enqueue(reply);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTimer::singleShot(0, this, &PceWallbox::sendNextRequest);
|
QTimer::singleShot(0, this, &PceWallbox::sendNextRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PceWallbox::cleanupQueue()
|
void PceWallbox::cleanupQueues()
|
||||||
{
|
{
|
||||||
qDeleteAll(m_queue);
|
qDeleteAll(m_readQueue);
|
||||||
m_queue.clear();
|
m_readQueue.clear();
|
||||||
|
|
||||||
|
qDeleteAll(m_writeQueue);
|
||||||
|
m_writeQueue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const PceWallbox::ChargingCurrentState &chargingCurrentState)
|
QDebug operator<<(QDebug debug, const PceWallbox::ChargingCurrentState &chargingCurrentState)
|
||||||
|
|
|
||||||
|
|
@ -79,12 +79,13 @@ private:
|
||||||
QTimer m_timer;
|
QTimer m_timer;
|
||||||
quint16 m_heartbeat = 1;
|
quint16 m_heartbeat = 1;
|
||||||
QueuedModbusReply *m_currentReply = nullptr;
|
QueuedModbusReply *m_currentReply = nullptr;
|
||||||
QQueue<QueuedModbusReply *> m_queue;
|
QQueue<QueuedModbusReply *> m_writeQueue;
|
||||||
|
QQueue<QueuedModbusReply *> m_readQueue;
|
||||||
bool m_aboutToDelete = false;
|
bool m_aboutToDelete = false;
|
||||||
|
|
||||||
void enqueueRequest(QueuedModbusReply *reply, bool prepend = false);
|
void enqueueRequest(QueuedModbusReply *reply);
|
||||||
|
|
||||||
void cleanupQueue();
|
void cleanupQueues();
|
||||||
};
|
};
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const PceWallbox::ChargingCurrentState &chargingCurrentState);
|
QDebug operator<<(QDebug debug, const PceWallbox::ChargingCurrentState &chargingCurrentState);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue