PcElectric: Update action handling based on single register
Signed-off-by: Simon Stürz <simon.stuerz@nymea.io>
This commit is contained in:
parent
8d85307f46
commit
b6cdaeffa0
@ -306,7 +306,7 @@
|
|||||||
"registerType": "holdingRegister",
|
"registerType": "holdingRegister",
|
||||||
"description": "Write charging current",
|
"description": "Write charging current",
|
||||||
"unit": "mA",
|
"unit": "mA",
|
||||||
"access": "WO"
|
"access": "RW"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "chargingCurrentOffline",
|
"id": "chargingCurrentOffline",
|
||||||
|
|||||||
@ -139,6 +139,7 @@ void IntegrationPluginPcElectric::setupThing(ThingSetupInfo *info)
|
|||||||
void IntegrationPluginPcElectric::postSetupThing(Thing *thing)
|
void IntegrationPluginPcElectric::postSetupThing(Thing *thing)
|
||||||
{
|
{
|
||||||
qCDebug(dcPcElectric()) << "Post setup thing" << thing->name();
|
qCDebug(dcPcElectric()) << "Post setup thing" << thing->name();
|
||||||
|
|
||||||
if (!m_refreshTimer) {
|
if (!m_refreshTimer) {
|
||||||
m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(1);
|
m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(1);
|
||||||
connect(m_refreshTimer, &PluginTimer::timeout, this, [this] {
|
connect(m_refreshTimer, &PluginTimer::timeout, this, [this] {
|
||||||
@ -152,6 +153,14 @@ void IntegrationPluginPcElectric::postSetupThing(Thing *thing)
|
|||||||
qCDebug(dcPcElectric()) << "Starting refresh timer...";
|
qCDebug(dcPcElectric()) << "Starting refresh timer...";
|
||||||
m_refreshTimer->start();
|
m_refreshTimer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PceWallbox::ChargingCurrentState chargingCurrentState;
|
||||||
|
chargingCurrentState.power = thing->stateValue(ev11PowerStateTypeId).toBool();
|
||||||
|
chargingCurrentState.maxChargingCurrent = thing->stateValue(ev11MaxChargingCurrentStateTypeId).toDouble();
|
||||||
|
chargingCurrentState.desiredPhaseCount = thing->stateValue(ev11DesiredPhaseCountStateTypeId).toDouble();
|
||||||
|
qCDebug(dcPcElectric()) << "Initialize charging current state with cached values" << chargingCurrentState;
|
||||||
|
m_chargingCurrentStateBuffer[thing] = chargingCurrentState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntegrationPluginPcElectric::thingRemoved(Thing *thing)
|
void IntegrationPluginPcElectric::thingRemoved(Thing *thing)
|
||||||
@ -167,6 +176,9 @@ void IntegrationPluginPcElectric::thingRemoved(Thing *thing)
|
|||||||
if (m_initialUpdate.contains(thing))
|
if (m_initialUpdate.contains(thing))
|
||||||
m_initialUpdate.remove(thing);
|
m_initialUpdate.remove(thing);
|
||||||
|
|
||||||
|
if (m_chargingCurrentStateBuffer.contains(thing))
|
||||||
|
m_chargingCurrentStateBuffer.remove(thing);
|
||||||
|
|
||||||
// Unregister related hardware resources
|
// Unregister related hardware resources
|
||||||
if (m_monitors.contains(thing))
|
if (m_monitors.contains(thing))
|
||||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
||||||
@ -190,91 +202,81 @@ void IntegrationPluginPcElectric::executeAction(ThingActionInfo *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (info->action().actionTypeId() == ev11PowerActionTypeId) {
|
if (info->action().actionTypeId() == ev11PowerActionTypeId) {
|
||||||
bool power = info->action().paramValue(ev11PowerActionPowerParamTypeId).toBool();
|
|
||||||
quint16 chargingCurrent = 0;
|
|
||||||
if (power) {
|
|
||||||
chargingCurrent = thing->stateValue(ev11MaxChargingCurrentStateTypeId).toUInt() * 1000;
|
|
||||||
if (thing->stateValue(ev11DesiredPhaseCountStateTypeId).toUInt() == 3) {
|
|
||||||
// If 3 phase charging is enabled, we set the first bit
|
|
||||||
chargingCurrent |= static_cast<quint16>(1) << 15;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Writing charging current register" << chargingCurrent << "mA";
|
bool power = info->action().paramValue(ev11PowerActionPowerParamTypeId).toBool();
|
||||||
QueuedModbusReply *reply = connection->setChargingCurrent(chargingCurrent);
|
qCDebug(dcPcElectric()) << "Set charging enabled to" << power;
|
||||||
connect(reply, &QueuedModbusReply::finished, info, [reply, info, thing, power, chargingCurrent](){
|
|
||||||
|
// Update buffer
|
||||||
|
m_chargingCurrentStateBuffer[thing].power = power;
|
||||||
|
|
||||||
|
quint16 registerValue = PceWallbox::deriveRegisterFromStates(m_chargingCurrentStateBuffer.value(thing));
|
||||||
|
qCDebug(dcPcElectric()) << "Writing charging current register" << registerValue;
|
||||||
|
QueuedModbusReply *reply = connection->setChargingCurrent(registerValue);
|
||||||
|
connect(reply, &QueuedModbusReply::finished, info, [reply, info, thing, power, registerValue](){
|
||||||
if (reply->error() != QModbusDevice::NoError) {
|
if (reply->error() != QModbusDevice::NoError) {
|
||||||
qCWarning(dcPcElectric()) << "Could not set power state to" << power << "(" << chargingCurrent << "mA)" << reply->errorString();
|
qCWarning(dcPcElectric()) << "Could not set power state to" << power << "(" << registerValue << ")" << reply->errorString();
|
||||||
info->finish(Thing::ThingErrorHardwareFailure);
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Successfully set power state to" << power << "(" << chargingCurrent << "mA)";
|
qCDebug(dcPcElectric()) << "Successfully set power state to" << power << "(" << registerValue << ")";
|
||||||
thing->setStateValue(ev11PowerStateTypeId, power);
|
thing->setStateValue(ev11PowerStateTypeId, power);
|
||||||
info->finish(Thing::ThingErrorNoError);
|
info->finish(Thing::ThingErrorNoError);
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else if (info->action().actionTypeId() == ev11MaxChargingCurrentActionTypeId) {
|
} else if (info->action().actionTypeId() == ev11MaxChargingCurrentActionTypeId) {
|
||||||
|
|
||||||
uint desiredChargingCurrent = info->action().paramValue(ev11MaxChargingCurrentActionMaxChargingCurrentParamTypeId).toUInt();
|
uint desiredChargingCurrent = info->action().paramValue(ev11MaxChargingCurrentActionMaxChargingCurrentParamTypeId).toUInt();
|
||||||
qCDebug(dcPcElectric()) << "Set max charging current to" << desiredChargingCurrent << "A";
|
qCDebug(dcPcElectric()) << "Set max charging current to" << desiredChargingCurrent << "A";
|
||||||
if (thing->stateValue(ev11PowerStateTypeId).toBool()) {
|
|
||||||
// The charging is enabled, let's write the value to the wallbox
|
// Update buffer
|
||||||
quint16 finalChargingCurrent = static_cast<quint16>(desiredChargingCurrent * 1000);
|
m_chargingCurrentStateBuffer[thing].maxChargingCurrent = desiredChargingCurrent;
|
||||||
if (thing->stateValue(ev11DesiredPhaseCountStateTypeId).toUInt() == 3) {
|
|
||||||
// If 3 phase charging is enabled, we set the first bit
|
quint16 registerValue = PceWallbox::deriveRegisterFromStates(m_chargingCurrentStateBuffer.value(thing));
|
||||||
finalChargingCurrent |= static_cast<quint16>(1) << 15;
|
qCDebug(dcPcElectric()) << "Writing charging current register" << registerValue;
|
||||||
|
QueuedModbusReply *reply = connection->setChargingCurrent(registerValue);
|
||||||
|
connect(reply, &QueuedModbusReply::finished, info, [reply, info, thing, desiredChargingCurrent](){
|
||||||
|
if (reply->error() != QModbusDevice::NoError) {
|
||||||
|
qCWarning(dcPcElectric()) << "Could not set charging current to" << desiredChargingCurrent << reply->errorString();
|
||||||
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Writing charging current register" << finalChargingCurrent << "mA";
|
qCDebug(dcPcElectric()) << "Successfully set charging current (" << desiredChargingCurrent << ")";
|
||||||
QueuedModbusReply *reply = connection->setChargingCurrent(finalChargingCurrent);
|
|
||||||
connect(reply, &QueuedModbusReply::finished, info, [reply, info, thing, desiredChargingCurrent](){
|
|
||||||
if (reply->error() != QModbusDevice::NoError) {
|
|
||||||
qCWarning(dcPcElectric()) << "Could not set charging current to" << desiredChargingCurrent << "mA" << reply->errorString();
|
|
||||||
info->finish(Thing::ThingErrorHardwareFailure);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Successfully set charging current to" << desiredChargingCurrent << "mA";
|
|
||||||
thing->setStateValue(ev11MaxChargingCurrentStateTypeId, desiredChargingCurrent);
|
|
||||||
info->finish(Thing::ThingErrorNoError);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Save the value in the state, but do not send the value to the wallbox since the power state is reflected using the charging current...
|
|
||||||
qCDebug(dcPcElectric()) << "Setting charging current to" << desiredChargingCurrent << "without synching to wallbox since the power state is false";
|
|
||||||
thing->setStateValue(ev11MaxChargingCurrentStateTypeId, desiredChargingCurrent);
|
thing->setStateValue(ev11MaxChargingCurrentStateTypeId, desiredChargingCurrent);
|
||||||
info->finish(Thing::ThingErrorNoError);
|
info->finish(Thing::ThingErrorNoError);
|
||||||
}
|
});
|
||||||
return;
|
|
||||||
} else if (info->action().actionTypeId() == ev11DesiredPhaseCountActionTypeId) {
|
|
||||||
uint desiredPhaseCount = info->action().paramValue(ev11DesiredPhaseCountActionDesiredPhaseCountParamTypeId).toUInt();
|
|
||||||
qCDebug(dcPcElectric()) << "Desried phase count changed" << desiredPhaseCount;
|
|
||||||
thing->setStateValue(ev11DesiredPhaseCountStateTypeId, desiredPhaseCount);
|
|
||||||
info->finish(Thing::ThingErrorNoError);
|
|
||||||
|
|
||||||
// Update the max charging current according to the new desired phase count
|
return;
|
||||||
if (thing->stateValue(ev11PowerStateTypeId).toBool()) {
|
|
||||||
uint chargingCurrent = thing->stateValue(ev11MaxChargingCurrentStateTypeId).toUInt();
|
} else if (info->action().actionTypeId() == ev11DesiredPhaseCountActionTypeId) {
|
||||||
quint16 finalChargingCurrent = static_cast<quint16>(chargingCurrent * 1000);
|
|
||||||
if (thing->stateValue(ev11DesiredPhaseCountStateTypeId).toUInt() == 3) {
|
uint desiredPhaseCount = info->action().paramValue(ev11DesiredPhaseCountActionDesiredPhaseCountParamTypeId).toUInt();
|
||||||
// If 3 phase charging is enabled, we set the first bit
|
qCDebug(dcPcElectric()) << "Set desried phase count to" << desiredPhaseCount;
|
||||||
finalChargingCurrent |= static_cast<quint16>(1) << 15;
|
|
||||||
|
// Update buffer
|
||||||
|
m_chargingCurrentStateBuffer[thing].desiredPhaseCount = desiredPhaseCount;
|
||||||
|
|
||||||
|
quint16 registerValue = PceWallbox::deriveRegisterFromStates(m_chargingCurrentStateBuffer.value(thing));
|
||||||
|
qCDebug(dcPcElectric()) << "Writing charging current register" << registerValue;
|
||||||
|
QueuedModbusReply *reply = connection->setChargingCurrent(registerValue);
|
||||||
|
connect(reply, &QueuedModbusReply::finished, info, [reply, info, thing, desiredPhaseCount](){
|
||||||
|
if (reply->error() != QModbusDevice::NoError) {
|
||||||
|
qCWarning(dcPcElectric()) << "Could not set desired phase count to" << desiredPhaseCount << reply->errorString();
|
||||||
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Writing charging current register" << finalChargingCurrent << "mA";
|
qCDebug(dcPcElectric()) << "Successfully set phase count (" << desiredPhaseCount << ")";
|
||||||
QueuedModbusReply *reply = connection->setChargingCurrent(finalChargingCurrent);
|
thing->setStateValue(ev11DesiredPhaseCountStateTypeId, desiredPhaseCount);
|
||||||
connect(reply, &QueuedModbusReply::finished, info, [reply, finalChargingCurrent](){
|
info->finish(Thing::ThingErrorNoError);
|
||||||
if (reply->error() != QModbusDevice::NoError) {
|
});
|
||||||
qCWarning(dcPcElectric()) << "Could not set charging current to" << finalChargingCurrent << "mA" << reply->errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Successfully set charging current to" << finalChargingCurrent << "mA";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Q_ASSERT_X(false, "IntegrationPluginPcElectric::executeAction", QString("Unhandled action: %1").arg(info->action().actionTypeId().toString()).toLocal8Bit());
|
Q_ASSERT_X(false, "IntegrationPluginPcElectric::executeAction", QString("Unhandled action: %1").arg(info->action().actionTypeId().toString()).toLocal8Bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +338,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
|
|
||||||
thing->setStateMaxValue(ev11MaxChargingCurrentStateTypeId, connection->maxChargingCurrentDip() / 1000);
|
thing->setStateMaxValue(ev11MaxChargingCurrentStateTypeId, connection->maxChargingCurrentDip() / 1000);
|
||||||
thing->setStateValue(ev11PluggedInStateTypeId, connection->chargingState() >= PceWallbox::ChargingStateB1 &&
|
thing->setStateValue(ev11PluggedInStateTypeId, connection->chargingState() >= PceWallbox::ChargingStateB1 &&
|
||||||
connection->chargingState() < PceWallbox::ChargingStateError);
|
connection->chargingState() < PceWallbox::ChargingStateError);
|
||||||
|
|
||||||
thing->setStateValue(ev11ChargingStateTypeId, connection->chargingState() == PceWallbox::ChargingStateC2);
|
thing->setStateValue(ev11ChargingStateTypeId, connection->chargingState() == PceWallbox::ChargingStateC2);
|
||||||
if (connection->chargingRelayState() != EV11ModbusTcpConnection::ChargingRelayStateNoCharging) {
|
if (connection->chargingRelayState() != EV11ModbusTcpConnection::ChargingRelayStateNoCharging) {
|
||||||
@ -383,6 +385,19 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
if (m_initialUpdate.value(thing)) {
|
if (m_initialUpdate.value(thing)) {
|
||||||
|
|
||||||
m_initialUpdate[thing] = false;
|
m_initialUpdate[thing] = false;
|
||||||
|
|
||||||
|
qCDebug(dcPcElectric()) << "Update initial charger states from charging current register...";
|
||||||
|
|
||||||
|
PceWallbox::ChargingCurrentState chargingCurrentState = PceWallbox::deriveStatesFromRegister(connection->chargingCurrent());
|
||||||
|
qCDebug(dcPcElectric()) << chargingCurrentState;
|
||||||
|
thing->setStateValue(ev11PowerStateTypeId, chargingCurrentState.power);
|
||||||
|
thing->setStateValue(ev11DesiredPhaseCountStateTypeId, chargingCurrentState.desiredPhaseCount);
|
||||||
|
if (chargingCurrentState.power) {
|
||||||
|
thing->setStateValue(ev11MaxChargingCurrentStateTypeId, chargingCurrentState.maxChargingCurrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_chargingCurrentStateBuffer[thing] = chargingCurrentState;
|
||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Updating initial settings after connecting...";
|
qCDebug(dcPcElectric()) << "Updating initial settings after connecting...";
|
||||||
|
|
||||||
thing->setSettingValue(ev11SettingsLedBrightnessParamTypeId, connection->ledBrightness());
|
thing->setSettingValue(ev11SettingsLedBrightnessParamTypeId, connection->ledBrightness());
|
||||||
@ -451,3 +466,4 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
if (monitor->reachable())
|
if (monitor->reachable())
|
||||||
connection->connectDevice();
|
connection->connectDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,7 @@
|
|||||||
#define INTEGRATIONPLUGINPCELECTRIC_H
|
#define INTEGRATIONPLUGINPCELECTRIC_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include <integrations/integrationplugin.h>
|
#include <integrations/integrationplugin.h>
|
||||||
#include <network/networkdevicediscovery.h>
|
#include <network/networkdevicediscovery.h>
|
||||||
@ -59,12 +60,22 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
PluginTimer *m_refreshTimer = nullptr;
|
PluginTimer *m_refreshTimer = nullptr;
|
||||||
|
|
||||||
QHash<Thing *, PceWallbox *> m_connections;
|
QHash<Thing *, PceWallbox *> m_connections;
|
||||||
QHash<Thing *, NetworkDeviceMonitor *> m_monitors;
|
QHash<Thing *, NetworkDeviceMonitor *> m_monitors;
|
||||||
QHash<Thing *, bool> m_initialUpdate;
|
QHash<Thing *, bool> m_initialUpdate;
|
||||||
|
|
||||||
|
// We need to buffer the desired power / current / phase count states because all 3 states
|
||||||
|
// will be represented by one register (200 - chaegingCurrent). If all 3 actions get executed, they might
|
||||||
|
// overwrite each other, since the action gets started right the way, but the request gets queued.
|
||||||
|
// If the actions would be queued, there would be still the issue with the order of the actions
|
||||||
|
// (set power to false and then set charging current would always enable charging in the end).
|
||||||
|
QHash<Thing *, PceWallbox::ChargingCurrentState> m_chargingCurrentStateBuffer;
|
||||||
|
|
||||||
void setupConnection(ThingSetupInfo *info);
|
void setupConnection(ThingSetupInfo *info);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // INTEGRATIONPLUGINPCELECTRIC_H
|
#endif // INTEGRATIONPLUGINPCELECTRIC_H
|
||||||
|
|||||||
@ -107,6 +107,41 @@ bool PceWallbox::update()
|
|||||||
|
|
||||||
enqueueRequest(reply);
|
enqueueRequest(reply);
|
||||||
|
|
||||||
|
// charging current register. Contains
|
||||||
|
// - power state
|
||||||
|
// - chargingcurrent (if power is true)
|
||||||
|
// - phases (if power is true)
|
||||||
|
bool chargingCurrentQueued = false;
|
||||||
|
foreach (QueuedModbusReply *r, m_queue) {
|
||||||
|
if (r->dataUnit().startAddress() == chargingCurrentDataUnit().startAddress()) {
|
||||||
|
chargingCurrentQueued = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chargingCurrentQueued) {
|
||||||
|
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, chargingCurrentDataUnit(), 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) {
|
||||||
|
QTimer::singleShot(0, this, &PceWallbox::sendNextRequest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QModbusDataUnit unit = reply->reply()->result();
|
||||||
|
const QVector<quint16> values = unit.values();
|
||||||
|
processChargingCurrentRegisterValues(values);
|
||||||
|
|
||||||
|
QTimer::singleShot(0, this, &PceWallbox::sendNextRequest);
|
||||||
|
});
|
||||||
|
|
||||||
|
enqueueRequest(reply);
|
||||||
|
}
|
||||||
|
|
||||||
// Digital input
|
// Digital input
|
||||||
bool digitalInputAlreadyQueued = false;
|
bool digitalInputAlreadyQueued = false;
|
||||||
foreach (QueuedModbusReply *r, m_queue) {
|
foreach (QueuedModbusReply *r, m_queue) {
|
||||||
@ -255,6 +290,38 @@ void PceWallbox::gracefullDeleteLater()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quint16 PceWallbox::deriveRegisterFromStates(PceWallbox::ChargingCurrentState state)
|
||||||
|
{
|
||||||
|
quint16 registerValue = 0;
|
||||||
|
if (!state.power)
|
||||||
|
return registerValue; // 0
|
||||||
|
|
||||||
|
registerValue = state.maxChargingCurrent * 1000; // convert to mA
|
||||||
|
if (state.desiredPhaseCount > 1) {
|
||||||
|
registerValue |= static_cast<quint16>(1) << 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
return registerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PceWallbox::ChargingCurrentState PceWallbox::deriveStatesFromRegister(quint16 registerValue)
|
||||||
|
{
|
||||||
|
PceWallbox::ChargingCurrentState chargingCurrentState;
|
||||||
|
chargingCurrentState.power = (registerValue != 0);
|
||||||
|
|
||||||
|
// Only set max charging current if power, otherwise we use default 6A
|
||||||
|
if (chargingCurrentState.power) {
|
||||||
|
|
||||||
|
bool threePhaseCharging = (registerValue & (1 << 15));
|
||||||
|
chargingCurrentState.desiredPhaseCount = (threePhaseCharging ? 3 : 1);
|
||||||
|
|
||||||
|
chargingCurrentState.maxChargingCurrent = (registerValue & 0x7FFF) / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chargingCurrentState;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PceWallbox::sendHeartbeat()
|
void PceWallbox::sendHeartbeat()
|
||||||
{
|
{
|
||||||
if (m_aboutToDelete)
|
if (m_aboutToDelete)
|
||||||
@ -349,3 +416,10 @@ void PceWallbox::cleanupQueue()
|
|||||||
qDeleteAll(m_queue);
|
qDeleteAll(m_queue);
|
||||||
m_queue.clear();
|
m_queue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const PceWallbox::ChargingCurrentState &chargingCurrentState)
|
||||||
|
{
|
||||||
|
QDebugStateSaver saver(debug);
|
||||||
|
debug.nospace() << "ChargingCurrentState(" << chargingCurrentState.power << ", " << chargingCurrentState.maxChargingCurrent << " [A], " << chargingCurrentState.desiredPhaseCount << ')';
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
|
#include <QDebug>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include <queuedmodbusreply.h>
|
#include <queuedmodbusreply.h>
|
||||||
@ -43,6 +44,12 @@ class PceWallbox : public EV11ModbusTcpConnection
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
typedef struct ChargingCurrentState {
|
||||||
|
bool power = false;
|
||||||
|
double maxChargingCurrent = 6;
|
||||||
|
uint desiredPhaseCount = 3;
|
||||||
|
} ChargingCurrentState;
|
||||||
|
|
||||||
explicit PceWallbox(const QHostAddress &hostAddress, uint port, quint16 slaveId, QObject *parent = nullptr);
|
explicit PceWallbox(const QHostAddress &hostAddress, uint port, quint16 slaveId, QObject *parent = nullptr);
|
||||||
|
|
||||||
bool update() override;
|
bool update() override;
|
||||||
@ -54,7 +61,6 @@ public:
|
|||||||
QueuedModbusReply *setDigitalInputMode(DigitalInputMode digitalInputMode);
|
QueuedModbusReply *setDigitalInputMode(DigitalInputMode digitalInputMode);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Note: the modbus implementation of the wallbox gets stuck if a Modbus request has been sent
|
// 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
|
// 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
|
// fixes the broken communication afterwards. This method waits for the current request before closing the
|
||||||
@ -62,6 +68,9 @@ public:
|
|||||||
// IMPORTNAT: do not use the object after this call, this is a temporary workaround
|
// IMPORTNAT: do not use the object after this call, this is a temporary workaround
|
||||||
void gracefullDeleteLater();
|
void gracefullDeleteLater();
|
||||||
|
|
||||||
|
static quint16 deriveRegisterFromStates(PceWallbox::ChargingCurrentState state);
|
||||||
|
static PceWallbox::ChargingCurrentState deriveStatesFromRegister(quint16 registerValue);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void sendHeartbeat();
|
void sendHeartbeat();
|
||||||
void sendNextRequest();
|
void sendNextRequest();
|
||||||
@ -78,4 +87,7 @@ private:
|
|||||||
void cleanupQueue();
|
void cleanupQueue();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const PceWallbox::ChargingCurrentState &chargingCurrentState);
|
||||||
|
|
||||||
|
|
||||||
#endif // PCEWALLBOX_H
|
#endif // PCEWALLBOX_H
|
||||||
|
|||||||
Reference in New Issue
Block a user