diff --git a/keba/integrationpluginkeba.cpp b/keba/integrationpluginkeba.cpp index 19fda8c1..09efb12c 100644 --- a/keba/integrationpluginkeba.cpp +++ b/keba/integrationpluginkeba.cpp @@ -120,9 +120,11 @@ void IntegrationPluginKeba::setupThing(ThingSetupInfo *info) if(!m_kebaData){ qCDebug(dcKebaKeContact()) << "Creating new Keba data layer"; - m_kebaData = new KeContactDataLayer; + m_kebaData = new KeContactDataLayer(this); if (!m_kebaData->init()) { m_kebaData->deleteLater(); + m_kebaData = nullptr; + connect(info, &ThingSetupInfo::aborted, m_kebaData, &KeContactDataLayer::deleteLater); // Clean up if the setup fails return info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("Error opening network port.")); } } @@ -142,19 +144,21 @@ void IntegrationPluginKeba::setupThing(ThingSetupInfo *info) qCDebug(dcKebaKeContact()) << "Report one received for" << thing->name(); qCDebug(dcKebaKeContact()) << " - Firmware" << report.firmware; + qCDebug(dcKebaKeContact()) << " - Serial" << report.serialNumber; qCDebug(dcKebaKeContact()) << " - Product" << report.product; qCDebug(dcKebaKeContact()) << " - Uptime" << report.seconds/60 << "[min]"; qCDebug(dcKebaKeContact()) << " - Com Module" << report.comModule; thing->setStateValue(wallboxConnectedStateTypeId, true); thing->setStateValue(wallboxFirmwareStateTypeId, report.firmware); + thing->setStateValue(wallboxSerialnumberStateTypeId, report.serialNumber); thing->setStateValue(wallboxModelStateTypeId, report.product); thing->setStateValue(wallboxUptimeStateTypeId, report.seconds/60); - m_kebaDevices.insert(thing->id(), keba); + m_kebaDevices.insert(thing->id(), keba); info->finish(Thing::ThingErrorNoError); }); - connect(info, &ThingSetupInfo::aborted, keba, &KeContact::deleteLater); + connect(info, &ThingSetupInfo::aborted, keba, &KeContact::deleteLater); // Clean up if the setup fails connect(keba, &KeContact::destroyed, this, [thing, this]{ m_kebaDevices.remove(thing->id()); }); @@ -351,7 +355,7 @@ void IntegrationPluginKeba::onReportTwoReceived(const KeContact::ReportTwo &repo thing->setStateValue(wallboxError2StateTypeId, reportTwo.error2); thing->setStateValue(wallboxSystemEnabledStateTypeId, reportTwo.enableSys); - thing->setStateValue(wallboxMaxChargingCurrentStateTypeId, reportTwo.maxCurrent); + thing->setStateValue(wallboxMaxChargingCurrentStateTypeId, reportTwo.currentUser); thing->setStateValue(wallboxMaxChargingCurrentPercentStateTypeId, reportTwo.maxCurrentPercentage); thing->setStateValue(wallboxMaxPossibleChargingCurrentStateTypeId, reportTwo.currentHardwareLimitation); @@ -481,10 +485,10 @@ void IntegrationPluginKeba::onBroadcastReceived(KeContact::BroadcastType type, c setDeviceState(thing, KeContact::State(content.toInt())); break; case KeContact::BroadcastTypeMaxCurr: - thing->setStateValue(wallboxMaxChargingCurrentStateTypeId, content.toInt()/1000.00); + //Current preset value via Control pilot in milliampere break; case KeContact::BroadcastTypeEnableSys: - qCDebug(dcKebaKeContact()) << "Broadcast enable sys not implemented"; + thing->setStateValue(wallboxSystemEnabledStateTypeId, (content.toInt() != 0)); break; } } @@ -503,7 +507,7 @@ void IntegrationPluginKeba::executeAction(ThingActionInfo *info) QUuid requestId; if(action.actionTypeId() == wallboxMaxChargingCurrentActionTypeId){ - int milliAmpere = action.param(wallboxMaxChargingCurrentActionMaxChargingCurrentParamTypeId).value().toInt(); + int milliAmpere = action.param(wallboxMaxChargingCurrentActionMaxChargingCurrentParamTypeId).value().toDouble()*1000; requestId = keba->setMaxAmpere(milliAmpere); } else if(action.actionTypeId() == wallboxPowerActionTypeId){ @@ -516,7 +520,11 @@ void IntegrationPluginKeba::executeAction(ThingActionInfo *info) requestId = keba->setOutputX2(action.param(wallboxOutputX2ActionOutputX2ParamTypeId).value().toBool()); } else if(action.actionTypeId() == wallboxFailsafeModeActionTypeId){ - requestId = keba->setFailsafe(60, 0, false); + int timeout = 0; + if (action.param(wallboxFailsafeModeActionFailsafeModeParamTypeId).value().toBool()) { + timeout = 60; + } + requestId = keba->setFailsafe(timeout, 0, false); } else { qCWarning(dcKebaKeContact()) << "Unhandled ActionTypeId:" << action.actionTypeId(); return info->finish(Thing::ThingErrorActionTypeNotFound); diff --git a/keba/kecontact.cpp b/keba/kecontact.cpp index 8e940424..ec02fac0 100644 --- a/keba/kecontact.cpp +++ b/keba/kecontact.cpp @@ -158,6 +158,10 @@ QUuid KeContact::enableOutput(bool state) QUuid KeContact::setMaxAmpere(int milliAmpere) { + if (milliAmpere < 6000 || milliAmpere > 63000) { + qCWarning(dcKebaKeContact()) << "KeContact: Set max ampere, mA out of range [6000, 63000]" << milliAmpere; + return ""; + } QUuid requestId = QUuid::createUuid(); m_pendingRequests.append(requestId); // Print information that we are executing now the update action @@ -307,7 +311,7 @@ void KeContact::onReceivedDatagram(const QHostAddress &address, const QByteArray m_requestTimeoutTimer->stop(); handleNextCommandInQueue(); - qCDebug(dcKebaKeContact()) << "Firmware information reveiced"; + qCDebug(dcKebaKeContact()) << "Firmware information received"; QByteArrayList firmware = datagram.split(':'); if (firmware.length() >= 2) { emit deviceInformationReceived(firmware[1]); @@ -382,7 +386,7 @@ void KeContact::onReceivedDatagram(const QHostAddress &address, const QByteArray } else if (id == 3) { ReportThree reportThree; - qCDebug(dcKebaKeContact()) << "Report 3 reveiced"; + qCDebug(dcKebaKeContact()) << "Report 3 received"; reportThree.currentPhase1 = data.value("I1").toInt()/1000.00; reportThree.currentPhase2 = data.value("I2").toInt()/1000.00; reportThree.currentPhase3 = data.value("I3").toInt()/1000.00; @@ -399,6 +403,7 @@ void KeContact::onReceivedDatagram(const QHostAddress &address, const QByteArray } else if (id >= 100) { Report1XX report; + qCDebug(dcKebaKeContact()) << "Report" << id << "received"; report.sessionId = data.value("Session ID").toInt(); report.currHW = data.value("Curr HW").toInt(); report.startTime = data.value("E Start ").toInt()/10000.00; diff --git a/keba/kecontactdatalayer.cpp b/keba/kecontactdatalayer.cpp index 4d794e04..2633631c 100644 --- a/keba/kecontactdatalayer.cpp +++ b/keba/kecontactdatalayer.cpp @@ -3,14 +3,22 @@ KeContactDataLayer::KeContactDataLayer(QObject *parent) : QObject(parent) { + qCDebug(dcKebaKeContact()) << "KeContactDataLayer: Creating UDP socket"; m_udpSocket = new QUdpSocket(this); connect(m_udpSocket, &QUdpSocket::readyRead, this, &KeContactDataLayer::readPendingDatagrams); + connect(m_udpSocket, &QUdpSocket::stateChanged, this, &KeContactDataLayer::onSocketStateChanged); + connect(m_udpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(onSocketError(QAbstractSocket::SocketError))); +} + +KeContactDataLayer::~KeContactDataLayer() +{ + qCDebug(dcKebaKeContact()) << "KeContactDataLayer: Deleting UDP socket"; } bool KeContactDataLayer::init() { if (!m_udpSocket->bind(QHostAddress::AnyIPv4, m_port, QAbstractSocket::ShareAddress)) { - qCWarning(dcKebaKeContact()) << "Cannot bind to port" << m_port; + qCWarning(dcKebaKeContact()) << "KeContactDataLayer: Cannot bind to port" << m_port; return false; } return true; @@ -33,7 +41,17 @@ void KeContactDataLayer::readPendingDatagrams() datagram.resize(socket->pendingDatagramSize()); socket->readDatagram(datagram.data(), datagram.size(), &senderAddress, &senderPort); - qCDebug(dcKebaKeContact()) << "Data received" << datagram << senderAddress; + qCDebug(dcKebaKeContact()) << "KeContactDataLayer: Data received" << datagram << senderAddress; emit datagramReceived(senderAddress, datagram); } } + +void KeContactDataLayer::onSocketError(QAbstractSocket::SocketError error) +{ + qCDebug(dcKebaKeContact()) << "KeContactDataLayer: Socket error" << error; +} + +void KeContactDataLayer::onSocketStateChanged(QAbstractSocket::SocketState socketState) +{ + qCDebug(dcKebaKeContact()) << "KeContactDataLayer: Socket state changed" << socketState; +} diff --git a/keba/kecontactdatalayer.h b/keba/kecontactdatalayer.h index 469a9dfd..ae343ac8 100644 --- a/keba/kecontactdatalayer.h +++ b/keba/kecontactdatalayer.h @@ -9,6 +9,7 @@ class KeContactDataLayer : public QObject Q_OBJECT public: explicit KeContactDataLayer(QObject *parent = nullptr); + ~KeContactDataLayer(); bool init(); void write(const QHostAddress &address, const QByteArray &data); @@ -22,6 +23,8 @@ signals: private slots: void readPendingDatagrams(); + void onSocketError(QAbstractSocket::SocketError error); + void onSocketStateChanged(QAbstractSocket::SocketState socketState); }; #endif // KECONTACTDATALAYER_H