diff --git a/keba/integrationpluginkeba.cpp b/keba/integrationpluginkeba.cpp index 80209bb8..d484d02e 100644 --- a/keba/integrationpluginkeba.cpp +++ b/keba/integrationpluginkeba.cpp @@ -30,7 +30,6 @@ #include "plugininfo.h" #include "integrationpluginkeba.h" -#include "network/networkdevicediscovery.h" #include #include @@ -48,49 +47,56 @@ void IntegrationPluginKeba::init() void IntegrationPluginKeba::discoverThings(ThingDiscoveryInfo *info) { + + // Init data layer if not already created + if (!m_kebaDataLayer){ + qCDebug(dcKeba()) << "Creating new Keba data layer..."; + m_kebaDataLayer= new KeContactDataLayer(this); + if (!m_kebaDataLayer->init()) { + m_kebaDataLayer->deleteLater(); + m_kebaDataLayer = nullptr; + qCWarning(dcKeba()) << "Failed to create Keba data layer..."; + info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("The communication could not be established.")); + return; + } + } + + if (!hardwareManager()->networkDeviceDiscovery()->available()) { + qCWarning(dcKeba()) << "The network discovery does not seem to be available."; + info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("The network discovery is not available. Please enter the IP address manually.")); + return; + } + if (info->thingClassId() == wallboxThingClassId) { - qCDebug(dcKeba()) << "Discovering Keba Wallbox..."; - NetworkDeviceDiscoveryReply *discoveryReply = hardwareManager()->networkDeviceDiscovery()->discover(); - connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){ - ThingDescriptors descriptors; - qCDebug(dcKeba()) << "Discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "devices"; - foreach (const NetworkDeviceInfo &networkDeviceInfo, discoveryReply->networkDeviceInfos()) { - if (!networkDeviceInfo.macAddressManufacturer().contains("keba", Qt::CaseSensitivity::CaseInsensitive)) - continue; + // Create a discovery with the info as parent for auto deleting the object once the discovery info is done + KebaDiscovery *discovery = new KebaDiscovery(m_kebaDataLayer, hardwareManager()->networkDeviceDiscovery(), info); + connect(discovery, &KebaDiscovery::discoveryFinished, info, [=](){ + foreach (const KebaDiscovery::KebaDiscoveryResult &result, discovery->discoveryResults()) { - qCDebug(dcKeba()) << " - Keba Wallbox" << networkDeviceInfo; - QString title = "Keba Wallbox "; - if (networkDeviceInfo.hostName().isEmpty()) { - title += "(" + networkDeviceInfo.address().toString() + ")"; - } else { - title += networkDeviceInfo.hostName() + " (" + networkDeviceInfo.address().toString() + ")"; - } - - QString description; - if (networkDeviceInfo.macAddressManufacturer().isEmpty()) { - description = networkDeviceInfo.macAddress(); - } else { - description = networkDeviceInfo.macAddress() + " (" + networkDeviceInfo.macAddressManufacturer() + ")"; - } - - ThingDescriptor descriptor(wallboxThingClassId, title, description); + ThingDescriptor descriptor(wallboxThingClassId, "Keba " + result.product, "Serial: " + result.serialNumber + " - " + result.networkDeviceInfo.address().toString()); // Check if we already have set up this device - Things existingThings = myThings().filterByParam(wallboxThingMacAddressParamTypeId, networkDeviceInfo.macAddress()); + Things existingThings = myThings().filterByParam(wallboxThingMacAddressParamTypeId, result.networkDeviceInfo.macAddress()); if (existingThings.count() == 1) { - qCDebug(dcKeba()) << "This wallbox already exists in the system!" << networkDeviceInfo; + qCDebug(dcKeba()) << "This wallbox already exists in the system!" << result.networkDeviceInfo; descriptor.setThingId(existingThings.first()->id()); } ParamList params; - params << Param(wallboxThingMacAddressParamTypeId, networkDeviceInfo.macAddress()); - params << Param(wallboxThingIpAddressParamTypeId, networkDeviceInfo.address().toString()); + params << Param(wallboxThingMacAddressParamTypeId, result.networkDeviceInfo.macAddress()); + params << Param(wallboxThingIpAddressParamTypeId, result.networkDeviceInfo.address().toString()); + params << Param(wallboxThingModelParamTypeId, result.product); + params << Param(wallboxThingSerialNumberParamTypeId, result.serialNumber); descriptor.setParams(params); info->addThingDescriptor(descriptor); } info->finish(Thing::ThingErrorNoError); }); + + // Start the discovery process + discovery->startDiscovery(); + } else { qCWarning(dcKeba()) << "Could not discover things because of unhandled thing class id" << info->thingClassId().toString(); info->finish(Thing::ThingErrorThingClassNotFound); @@ -130,8 +136,9 @@ void IntegrationPluginKeba::setupThing(ThingSetupInfo *info) // Check if we have a keba with this ip, if reconfigure the object would already been removed from the hash foreach (KeContact *kebaConnect, m_kebaDevices.values()) { if (kebaConnect->address() == address) { - qCWarning(dcKeba()) << "Failed to set up keba for host address" << address.toString() << "because there has already been configured a keba for this ip."; - return info->finish(Thing::ThingErrorThingInUse, QT_TR_NOOP("Already configured for this IP address.")); + qCWarning(dcKeba()) << "Failed to set up keba for host address" << address.toString() << "because there has already been configured a keba for this IP."; + info->finish(Thing::ThingErrorThingInUse, QT_TR_NOOP("Already configured for this IP address.")); + return; } } @@ -143,24 +150,45 @@ void IntegrationPluginKeba::setupThing(ThingSetupInfo *info) connect(keba, &KeContact::report1XXReceived, this, &IntegrationPluginKeba::onReport1XXReceived); connect(keba, &KeContact::broadcastReceived, this, &IntegrationPluginKeba::onBroadcastReceived); + // Make sure we receive data from the keba and the DIP switches are configured correctly connect(keba, &KeContact::reportOneReceived, info, [info, this, keba] (const KeContact::ReportOne &report) { Thing *thing = info->thing(); - qCDebug(dcKeba()) << "Report one received for" << thing->name(); qCDebug(dcKeba()) << " - Firmware" << report.firmware; qCDebug(dcKeba()) << " - Serial" << report.serialNumber; qCDebug(dcKeba()) << " - Product" << report.product; - qCDebug(dcKeba()) << " - Uptime" << report.seconds/60 << "[min]"; + qCDebug(dcKeba()) << " - Uptime" << report.seconds / 60 << "[min]"; qCDebug(dcKeba()) << " - Com Module" << report.comModule; + qCDebug(dcKeba()) << " - DIP switch 1" << report.dipSw1; + qCDebug(dcKeba()) << " - DIP switch 2" << report.dipSw2; - 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); + if (thing->paramValue(wallboxThingSerialNumberParamTypeId).toString().isEmpty()) { + qCDebug(dcKeba()) << "Update serial number parameter for" << thing << "to" << report.serialNumber; + thing->setParamValue(wallboxThingSerialNumberParamTypeId, report.serialNumber); + } + + if (thing->paramValue(wallboxThingModelParamTypeId).toString().isEmpty()) { + qCDebug(dcKeba()) << "Update model parameter for" << thing << "to" << report.product; + thing->setParamValue(wallboxThingModelParamTypeId, report.product); + } + + // Verify the DIP switches and warn the user in case if wrong configuration + // For having UPD controll on the wallbox we need DIP Switch 1.3 enabled + KeContact::DipSwitchOneFlag dipSwOne(report.dipSw1); + qCDebug(dcKeba()) << dipSwOne; + if (!dipSwOne.testFlag(KeContact::DipSwitchOneSmartHomeInterface)) { + qCWarning(dcKeba()) << "Connected successfully to Keba but the DIP Switch for controlling it is not enabled."; + info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("The required communication interface is not enabled on this wallbox. Please make sure the DIP switch 1.3 is switched on and try again.")); + return; + } m_kebaDevices.insert(thing->id(), keba); info->finish(Thing::ThingErrorNoError); + qCDebug(dcKeba()) << "Setup finsihed successfully for" << thing << thing->params(); + + thing->setStateValue(wallboxConnectedStateTypeId, true); + thing->setStateValue(wallboxFirmwareStateTypeId, report.firmware); + thing->setStateValue(wallboxUptimeStateTypeId, report.seconds / 60); }); keba->getReport1(); @@ -168,8 +196,9 @@ void IntegrationPluginKeba::setupThing(ThingSetupInfo *info) 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()); + // Setup failed, lets search the network, maybe the IP has changed... + searchNetworkDevices(); }); - } else { qCWarning(dcKeba()) << "Could not setup thing: unhandled device class" << thing->thingClass(); info->finish(Thing::ThingErrorThingClassNotFound); @@ -194,12 +223,13 @@ void IntegrationPluginKeba::postSetupThing(Thing *thing) } // Try to find the mac address in case the user added the ip manually - if (thing->paramValue(wallboxThingMacAddressParamTypeId).toString().isEmpty() || thing->paramValue(wallboxThingMacAddressParamTypeId).toString() == "00:00:00:00:00:00") { + if (thing->paramValue(wallboxThingMacAddressParamTypeId).toString().isEmpty() + || thing->paramValue(wallboxThingMacAddressParamTypeId).toString() == "00:00:00:00:00:00") { searchNetworkDevices(); } if (!m_updateTimer) { - m_updateTimer = hardwareManager()->pluginTimerManager()->registerTimer(60); + m_updateTimer = hardwareManager()->pluginTimerManager()->registerTimer(10); connect(m_updateTimer, &PluginTimer::timeout, this, [this]() { foreach (Thing *thing, myThings().filterByThingClassId(wallboxThingClassId)) { KeContact *keba = m_kebaDevices.value(thing->id()); @@ -219,21 +249,26 @@ void IntegrationPluginKeba::postSetupThing(Thing *thing) } if (!m_reconnectTimer) { - m_reconnectTimer = hardwareManager()->pluginTimerManager()->registerTimer(60*5); + m_reconnectTimer = hardwareManager()->pluginTimerManager()->registerTimer(60 * 5); connect(m_reconnectTimer, &PluginTimer::timeout, this, [this] { + bool startDiscoveryRequired = false; // Only search for new network devices if there is one keba which is not connected foreach (Thing *thing, myThings().filterByThingClassId(wallboxThingClassId)) { KeContact *keba = m_kebaDevices.value(thing->id()); if (!keba) { qCWarning(dcKeba()) << "No Keba connection found for" << thing->name(); + startDiscoveryRequired = true; continue; } if (!keba->reachable()) { - searchNetworkDevices(); + startDiscoveryRequired = true; return; } } + + if (startDiscoveryRequired) + searchNetworkDevices(); }); m_reconnectTimer->start(); @@ -243,7 +278,7 @@ void IntegrationPluginKeba::postSetupThing(Thing *thing) void IntegrationPluginKeba::thingRemoved(Thing *thing) { qCDebug(dcKeba()) << "Deleting" << thing->name(); - if (thing->thingClassId() == wallboxThingClassId) { + if (thing->thingClassId() == wallboxThingClassId && m_kebaDevices.contains(thing->id())) { KeContact *keba = m_kebaDevices.take(thing->id()); keba->deleteLater(); } @@ -266,6 +301,89 @@ void IntegrationPluginKeba::thingRemoved(Thing *thing) } } +void IntegrationPluginKeba::executeAction(ThingActionInfo *info) +{ + Thing *thing = info->thing(); + Action action = info->action(); + + if (thing->thingClassId() == wallboxThingClassId) { + KeContact *keba = m_kebaDevices.value(thing->id()); + if (!keba) { + qCWarning(dcKeba()) << "Device not properly initialized, Keba object missing"; + return info->finish(Thing::ThingErrorHardwareNotAvailable); + } + + // Make sure wallbox is reachable + if (!keba->reachable()) { + qCWarning(dcKeba()) << "Failed to execute action. The wallbox seems not to be reachable" << thing; + info->finish(Thing::ThingErrorHardwareNotAvailable); + return; + } + + QUuid requestId; + if (action.actionTypeId() == wallboxMaxChargingCurrentActionTypeId) { + int milliAmpere = action.paramValue(wallboxMaxChargingCurrentActionMaxChargingCurrentParamTypeId).toUInt() * 1000; + requestId = keba->setMaxAmpereGeneral(milliAmpere); + } else if (action.actionTypeId() == wallboxPowerActionTypeId) { + requestId = keba->enableOutput(action.param(wallboxPowerActionTypeId).value().toBool()); + } else if (action.actionTypeId() == wallboxDisplayActionTypeId) { + requestId = keba->displayMessage(action.param(wallboxDisplayActionMessageParamTypeId).value().toByteArray()); + } else if (action.actionTypeId() == wallboxOutputX2ActionTypeId) { + requestId = keba->setOutputX2(action.param(wallboxOutputX2ActionOutputX2ParamTypeId).value().toBool()); + } else if (action.actionTypeId() == wallboxFailsafeModeActionTypeId) { + int timeout = 0; + if (action.param(wallboxFailsafeModeActionFailsafeModeParamTypeId).value().toBool()) { + timeout = 60; + } + requestId = keba->setFailsafe(timeout, 0, false); + } else { + qCWarning(dcKeba()) << "Unhandled ActionTypeId:" << action.actionTypeId(); + return info->finish(Thing::ThingErrorActionTypeNotFound); + } + + // If the keba returns an invalid uuid, something went wrong + if (requestId.isNull()) { + info->finish(Thing::ThingErrorHardwareFailure); + return; + } + + m_asyncActions.insert(requestId, info); + connect(info, &ThingActionInfo::aborted, this, [requestId, this]{ m_asyncActions.remove(requestId); }); + } else { + qCWarning(dcKeba()) << "Execute action, unhandled device class" << thing->thingClass(); + info->finish(Thing::ThingErrorThingClassNotFound); + } +} + +void IntegrationPluginKeba::onCommandExecuted(QUuid requestId, bool success) +{ + if (m_asyncActions.contains(requestId)) { + KeContact *keba = static_cast(sender()); + Thing *thing = myThings().findById(m_kebaDevices.key(keba)); + if (!thing) { + qCWarning(dcKeba()) << "On command executed: missing device object"; + return; + } + + ThingActionInfo *info = m_asyncActions.take(requestId); + if (success) { + qCDebug(dcKeba()) << "Action execution finished successfully. Request ID:" << requestId.toString(); + info->finish(Thing::ThingErrorNoError); + + // Set the value to the state so we don't have to wait for the report 2 response + if (info->action().actionTypeId() == wallboxMaxChargingCurrentActionTypeId) { + uint value = info->action().paramValue(wallboxMaxChargingCurrentActionMaxChargingCurrentParamTypeId).toUInt(); + info->thing()->setStateValue(wallboxMaxChargingCurrentStateTypeId, value); + } else if (info->action().actionTypeId() == wallboxPowerActionTypeId) { + info->thing()->setStateValue(wallboxPowerStateTypeId, info->action().paramValue(wallboxPowerActionTypeId).toBool()); + } + } else { + qCWarning(dcKeba()) << "Action execution finished with error. Request ID:" << requestId.toString(); + info->finish(Thing::ThingErrorHardwareFailure); + } + } +} + void IntegrationPluginKeba::setDeviceState(Thing *thing, KeContact::State state) { switch (state) { @@ -321,40 +439,57 @@ void IntegrationPluginKeba::setDevicePlugState(Thing *thing, KeContact::PlugStat void IntegrationPluginKeba::searchNetworkDevices() { - qCDebug(dcKeba()) << "Start searching for things..."; - NetworkDeviceDiscoveryReply *discoveryReply = hardwareManager()->networkDeviceDiscovery()->discover(); - connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){ - ThingDescriptors descriptors; - qCDebug(dcKeba()) << "Discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "devices"; - foreach (const NetworkDeviceInfo &networkDeviceInfo, discoveryReply->networkDeviceInfos()) { - if (!networkDeviceInfo.hostName().contains("keba", Qt::CaseSensitivity::CaseInsensitive)) - continue; + if (m_runningDiscovery) { + qCDebug(dcKeba()) << "Keba discovery already running."; + return; + } + if (!m_kebaDataLayer) { + qCDebug(dcKeba()) << "Could not search wallboxes in the network. The data layer seems not to be available"; + return; + } + + qCDebug(dcKeba()) << "Start searching for wallboxes in the network..."; + m_runningDiscovery = new KebaDiscovery(m_kebaDataLayer, hardwareManager()->networkDeviceDiscovery(), this); + connect(m_runningDiscovery, &KebaDiscovery::discoveryFinished, this, [=](){ + foreach (const KebaDiscovery::KebaDiscoveryResult &result, m_runningDiscovery->discoveryResults()) { foreach (Thing *existingThing, myThings().filterByThingClassId(wallboxThingClassId)) { if (existingThing->paramValue(wallboxThingMacAddressParamTypeId).toString().isEmpty()) { //This device got probably manually setup, to enable auto rediscovery the MAC address needs to setup - if (existingThing->paramValue(wallboxThingIpAddressParamTypeId).toString() == networkDeviceInfo.address().toString()) { - qCDebug(dcKeba()) << "Keba Wallbox MAC Address has been discovered" << existingThing->name() << networkDeviceInfo.macAddress(); - existingThing->setParamValue(wallboxThingMacAddressParamTypeId, networkDeviceInfo.macAddress()); + if (existingThing->paramValue(wallboxThingIpAddressParamTypeId).toString() == result.networkDeviceInfo.address().toString()) { + qCDebug(dcKeba()) << "Wallbox MAC address has been discovered" << existingThing->name() << result.networkDeviceInfo.macAddress(); + existingThing->setParamValue(wallboxThingMacAddressParamTypeId, result.networkDeviceInfo.macAddress()); } - } else if (existingThing->paramValue(wallboxThingMacAddressParamTypeId).toString() == networkDeviceInfo.macAddress()) { + } else if (existingThing->paramValue(wallboxThingMacAddressParamTypeId).toString() == result.networkDeviceInfo.macAddress()) { // We found the existing keba thing, lets check if the ip has changed - if (existingThing->paramValue(wallboxThingIpAddressParamTypeId).toString() != networkDeviceInfo.address().toString()) { - qCDebug(dcKeba()) << "Keba Wallbox IP Address has changed, from" << existingThing->paramValue(wallboxThingIpAddressParamTypeId).toString() << "to" << networkDeviceInfo.address().toString(); - existingThing->setParamValue(wallboxThingIpAddressParamTypeId, networkDeviceInfo.address().toString()); + if (existingThing->paramValue(wallboxThingIpAddressParamTypeId).toString() != result.networkDeviceInfo.address().toString()) { + // Update the ip address of the thing. + // FIXME: as of now the thing manager does not store the changed param + qCDebug(dcKeba()) << "Wallbox IP Address has changed, from" << existingThing->paramValue(wallboxThingIpAddressParamTypeId).toString() << "to" << result.networkDeviceInfo.address().toString(); + existingThing->setParamValue(wallboxThingIpAddressParamTypeId, result.networkDeviceInfo.address().toString()); + + // Make sure the setup has already run for this thing, if not, the thingmanager will retry with the new ip every 15 seconds KeContact *keba = m_kebaDevices.value(existingThing->id()); if (keba) { - keba->setAddress(QHostAddress(networkDeviceInfo.address())); + keba->setAddress(QHostAddress(result.networkDeviceInfo.address())); + + // Refresh + keba->getReport2(); + keba->getReport3(); } else { - qCWarning(dcKeba()) << "Could not update IP address, for" << existingThing; + qCWarning(dcKeba()) << "Could not update IP address since the keba connection has not been set up yet for" << existingThing; } } else { - qCDebug(dcKeba()) << "Keba Wallbox" << existingThing->name() << "IP address has not changed" << networkDeviceInfo.address().toString(); + qCDebug(dcKeba()) << "Wallbox" << existingThing->name() << "IP address has not changed" << result.networkDeviceInfo.address().toString(); } break; } } } + + // Clean up + m_runningDiscovery->deleteLater(); + m_runningDiscovery = nullptr; }); } @@ -373,28 +508,6 @@ void IntegrationPluginKeba::onConnectionChanged(bool status) } } -void IntegrationPluginKeba::onCommandExecuted(QUuid requestId, bool success) -{ - if (m_asyncActions.contains(requestId)) { - KeContact *keba = static_cast(sender()); - - keba->getReport2(); //Check if the state was actually set - - Thing *thing = myThings().findById(m_kebaDevices.key(keba)); - if (!thing) { - qCWarning(dcKeba()) << "On command executed: missing device object"; - return; - } - - ThingActionInfo *info = m_asyncActions.take(requestId); - if (success) { - info->finish(Thing::ThingErrorNoError); - } else { - info->finish(Thing::ThingErrorHardwareFailure); - } - } -} - void IntegrationPluginKeba::onReportTwoReceived(const KeContact::ReportTwo &reportTwo) { KeContact *keba = static_cast(sender()); @@ -402,7 +515,7 @@ void IntegrationPluginKeba::onReportTwoReceived(const KeContact::ReportTwo &repo if (!thing) return; - qCDebug(dcKeba()) << "Report 2 received for" << thing->name() << "Serial number:" << thing->stateValue(wallboxSerialnumberStateTypeId).toString(); + qCDebug(dcKeba()) << "Report 2 received for" << thing->name() << "Serial number:" << thing->paramValue(wallboxThingSerialNumberParamTypeId).toString(); qCDebug(dcKeba()) << " - State:" << reportTwo.state; qCDebug(dcKeba()) << " - Error 1:" << reportTwo.error1; qCDebug(dcKeba()) << " - Error 2:" << reportTwo.error2; @@ -422,7 +535,7 @@ void IntegrationPluginKeba::onReportTwoReceived(const KeContact::ReportTwo &repo qCDebug(dcKeba()) << " - Serial number:" << reportTwo.serialNumber; qCDebug(dcKeba()) << " - Uptime:" << reportTwo.seconds/60 << "[min]"; - if (reportTwo.serialNumber == thing->stateValue(wallboxSerialnumberStateTypeId).toString()) { + if (reportTwo.serialNumber == thing->paramValue(wallboxThingSerialNumberParamTypeId).toString()) { setDeviceState(thing, reportTwo.state); setDevicePlugState(thing, reportTwo.plugState); @@ -458,7 +571,7 @@ void IntegrationPluginKeba::onReportThreeReceived(const KeContact::ReportThree & if (!thing) return; - qCDebug(dcKeba()) << "Report 3 received for" << thing->name() << "Serial number:" << thing->stateValue(wallboxSerialnumberStateTypeId).toString(); + qCDebug(dcKeba()) << "Report 3 received for" << thing->name() << "Serial number:" << thing->paramValue(wallboxThingSerialNumberParamTypeId).toString(); qCDebug(dcKeba()) << " - Current phase 1:" << reportThree.currentPhase1 << "[A]"; qCDebug(dcKeba()) << " - Current phase 2:" << reportThree.currentPhase2 << "[A]"; qCDebug(dcKeba()) << " - Current phase 3:" << reportThree.currentPhase3 << "[A]"; @@ -471,7 +584,7 @@ void IntegrationPluginKeba::onReportThreeReceived(const KeContact::ReportThree & qCDebug(dcKeba()) << " - Serial number" << reportThree.serialNumber; qCDebug(dcKeba()) << " - Uptime" << reportThree.seconds / 60 << "[min]"; - if (reportThree.serialNumber == thing->stateValue(wallboxSerialnumberStateTypeId).toString()) { + if (reportThree.serialNumber == thing->paramValue(wallboxThingSerialNumberParamTypeId).toString()) { thing->setStateValue(wallboxCurrentPhaseAEventTypeId, reportThree.currentPhase1); thing->setStateValue(wallboxCurrentPhaseBEventTypeId, reportThree.currentPhase2); thing->setStateValue(wallboxCurrentPhaseCEventTypeId, reportThree.currentPhase3); @@ -509,7 +622,7 @@ void IntegrationPluginKeba::onReport1XXReceived(int reportNumber, const KeContac if (!thing) return; - qCDebug(dcKeba()) << "Report" << reportNumber << "received for" << thing->name() << "Serial number:" << thing->stateValue(wallboxSerialnumberStateTypeId).toString(); + qCDebug(dcKeba()) << "Report" << reportNumber << "received for" << thing->name() << "Serial number:" << thing->paramValue(wallboxThingSerialNumberParamTypeId).toString(); qCDebug(dcKeba()) << " - Session Id" << report.sessionId; qCDebug(dcKeba()) << " - Curr HW" << report.currHW; qCDebug(dcKeba()) << " - Energy start" << report.startEnergy; @@ -534,7 +647,7 @@ void IntegrationPluginKeba::onReport1XXReceived(int reportNumber, const KeContac } else if (reportNumber == 101) { // Report 101 is the lastest finished session - if (report.serialNumber == thing->stateValue(wallboxSerialnumberStateTypeId).toString()) { + if (report.serialNumber == thing->paramValue(wallboxThingSerialNumberParamTypeId).toString()) { if (!m_lastSessionId.contains(thing->id())) { // This happens after reboot m_lastSessionId.insert(thing->id(), report.sessionId); @@ -590,50 +703,3 @@ void IntegrationPluginKeba::onBroadcastReceived(KeContact::BroadcastType type, c break; } } - -void IntegrationPluginKeba::executeAction(ThingActionInfo *info) -{ - Thing *thing = info->thing(); - Action action = info->action(); - - if (thing->thingClassId() == wallboxThingClassId) { - KeContact *keba = m_kebaDevices.value(thing->id()); - if (!keba) { - qCWarning(dcKeba()) << "Device not properly initialized, Keba object missing"; - return info->finish(Thing::ThingErrorHardwareNotAvailable); - } - - QUuid requestId; - if (action.actionTypeId() == wallboxMaxChargingCurrentActionTypeId) { - int milliAmpere = action.param(wallboxMaxChargingCurrentActionMaxChargingCurrentParamTypeId).value().toUInt() * 1000; - requestId = keba->setMaxAmpereGeneral(milliAmpere); - } else if(action.actionTypeId() == wallboxPowerActionTypeId) { - requestId = keba->enableOutput(action.param(wallboxPowerActionTypeId).value().toBool()); - } else if(action.actionTypeId() == wallboxDisplayActionTypeId) { - requestId = keba->displayMessage(action.param(wallboxDisplayActionMessageParamTypeId).value().toByteArray()); - } else if(action.actionTypeId() == wallboxOutputX2ActionTypeId) { - requestId = keba->setOutputX2(action.param(wallboxOutputX2ActionOutputX2ParamTypeId).value().toBool()); - } else if(action.actionTypeId() == wallboxFailsafeModeActionTypeId) { - int timeout = 0; - if (action.param(wallboxFailsafeModeActionFailsafeModeParamTypeId).value().toBool()) { - timeout = 60; - } - requestId = keba->setFailsafe(timeout, 0, false); - } else { - qCWarning(dcKeba()) << "Unhandled ActionTypeId:" << action.actionTypeId(); - return info->finish(Thing::ThingErrorActionTypeNotFound); - } - - // If the keba returns an invalid uuid, something went wrong - if (requestId.isNull()) { - info->finish(Thing::ThingErrorHardwareFailure); - return; - } - - m_asyncActions.insert(requestId, info); - connect(info, &ThingActionInfo::aborted, this, [requestId, this]{ m_asyncActions.remove(requestId); }); - } else { - qCWarning(dcKeba()) << "Execute action, unhandled device class" << thing->thingClass(); - info->finish(Thing::ThingErrorThingClassNotFound); - } -} diff --git a/keba/integrationpluginkeba.h b/keba/integrationpluginkeba.h index 03abbcc6..324865e9 100644 --- a/keba/integrationpluginkeba.h +++ b/keba/integrationpluginkeba.h @@ -31,9 +31,12 @@ #ifndef INTEGRATIONPLUGINKEBA_H #define INTEGRATIONPLUGINKEBA_H -#include "integrations/integrationplugin.h" -#include "plugintimer.h" +#include +#include +#include + #include "kecontact.h" +#include "kebadiscovery.h" #include "kecontactdatalayer.h" #include @@ -41,6 +44,7 @@ #include #include + class IntegrationPluginKeba : public IntegrationPlugin { Q_OBJECT @@ -64,13 +68,12 @@ public: private: PluginTimer *m_updateTimer = nullptr; PluginTimer *m_reconnectTimer = nullptr; - KeContactDataLayer *m_kebaDataLayer = nullptr; QHash m_kebaDevices; QHash m_lastSessionId; - QHash m_asyncActions; + KebaDiscovery *m_runningDiscovery = nullptr; void setDeviceState(Thing *device, KeContact::State state); void setDevicePlugState(Thing *device, KeContact::PlugState plugState); diff --git a/keba/integrationpluginkeba.json b/keba/integrationpluginkeba.json index 9cf84009..ab3c8c10 100644 --- a/keba/integrationpluginkeba.json +++ b/keba/integrationpluginkeba.json @@ -31,6 +31,24 @@ "inputType": "TextLine", "defaultValue":"", "readOnly": true + }, + { + "id": "45255155-318b-4204-8ce6-2c106a56286d", + "name": "serialNumber", + "displayName": "Serial number", + "type": "QString", + "inputType": "TextLine", + "defaultValue":"", + "readOnly": true + }, + { + "id": "a996c698-4831-4977-8979-f76f78ac7da8", + "name": "model", + "displayName": "Product name", + "type": "QString", + "inputType": "TextLine", + "defaultValue":"", + "readOnly": true } ], "stateTypes": [ @@ -43,30 +61,6 @@ "defaultValue": false, "cached": false }, - { - "id": "c3fca233-95b9-4948-88c6-4c0f13cf53b1", - "name": "model", - "displayName": "Model", - "displayNameEvent": "Model changed", - "type": "QString", - "defaultValue": "Unknown" - }, - { - "id": "e941ace5-fb7f-4dc2-b3f2-188233f4e934", - "name": "firmware", - "displayName": "Firmware", - "displayNameEvent": "Firmware changed", - "type": "QString", - "defaultValue": "" - }, - { - "id": "9a1b4316-ce01-4cd3-890f-a8c94b8b5029", - "name": "serialnumber", - "displayName": "Serial number", - "displayNameEvent": "Serial number changed", - "type": "QString", - "defaultValue": "" - }, { "id": "83ed0774-2a91-434d-b03c-d920d02f2981", "name": "power", @@ -328,6 +322,14 @@ "writable": true, "type": "bool", "defaultValue": false + }, + { + "id": "e941ace5-fb7f-4dc2-b3f2-188233f4e934", + "name": "firmware", + "displayName": "Firmware", + "displayNameEvent": "Firmware changed", + "type": "QString", + "defaultValue": "" } ], "actionTypes": [ diff --git a/keba/keba.pro b/keba/keba.pro index ea4239f2..e8bc1164 100644 --- a/keba/keba.pro +++ b/keba/keba.pro @@ -6,10 +6,12 @@ TARGET = $$qtLibraryTarget(nymea_integrationpluginkeba) SOURCES += \ integrationpluginkeba.cpp \ + kebadiscovery.cpp \ kecontact.cpp \ kecontactdatalayer.cpp HEADERS += \ integrationpluginkeba.h \ + kebadiscovery.h \ kecontact.h \ kecontactdatalayer.h diff --git a/keba/kebadiscovery.cpp b/keba/kebadiscovery.cpp new file mode 100644 index 00000000..d5f2937f --- /dev/null +++ b/keba/kebadiscovery.cpp @@ -0,0 +1,136 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2021, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project is distributed in the hope that +* it will be useful, but WITHOUT ANY WARRANTY; without even the implied +* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "kebadiscovery.h" +#include "kecontactdatalayer.h" +#include "extern-plugininfo.h" + +#include +#include + +KebaDiscovery::KebaDiscovery(KeContactDataLayer *kebaDataLayer, NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent) : + QObject(parent), + m_kebaDataLayer(kebaDataLayer), + m_networkDeviceDiscovery(networkDeviceDiscovery) +{ + // Timer for waiting if network devices responded to the "report 1 request" + m_responseTimer.setInterval(5000); + m_responseTimer.setSingleShot(true); + connect(&m_responseTimer, &QTimer::timeout, this, [=](){ + qCDebug(dcKeba()) << "Discovery: Report response timeout. Found" << m_results.count() << "Keba Wallbox"; + emit discoveryFinished(); + }); + + // Read data from the keba data layer and verify if it is a keba report + connect (m_kebaDataLayer, &KeContactDataLayer::datagramReceived, this, [=](const QHostAddress &address, const QByteArray &datagram){ + + // Just continue if this is a new address we have no result for + if (alreadyDiscovered(address)) { + qCDebug(dcKeba()) << "Discovery: Skipping datagram from already discovered Keba on" << address.toString(); + return; + } + + // Try to convert the received data to a json document + QJsonParseError error; + QJsonDocument jsonDoc = QJsonDocument::fromJson(datagram, &error); + if (error.error != QJsonParseError::NoError) { + qCWarning(dcKeba()) << "Discovery: Received data from the keba data link but failed to parse the data as JSON:" << datagram << ":" << error.errorString(); + return; + } + + // Verify JSON data + QVariantMap dataMap = jsonDoc.toVariant().toMap(); + if (!dataMap.contains("ID") || !dataMap.contains("Serial") || !dataMap.contains("Product") || !dataMap.contains("Firmware")) { + qCDebug(dcKeba()) << "Discovery: Received valid JSON data on data layer but they don't seem to be what we are listening for:" << qUtf8Printable(jsonDoc.toJson()); + return; + } + + if (dataMap.value("ID").toInt() != 1) { + qCDebug(dcKeba()) << "Discovery: Received valid Keba JSON data on data layer but this is not a report 1 message:" << qUtf8Printable(jsonDoc.toJson()); + return; + } + + // We have received a report 1 datagram, let's add it to the result + foreach (const NetworkDeviceInfo &networkDeviceInfo, m_networkDeviceInfos) { + if (networkDeviceInfo.address() == address) { + KebaDiscoveryResult result; + result.networkDeviceInfo = networkDeviceInfo; + result.product = dataMap.value("Product").toString(); + result.serialNumber = dataMap.value("Serial").toString(); + result.firmwareVersion = dataMap.value("Firmware").toString(); + m_results.append(result); + qCDebug(dcKeba()) << "Discovery: -->" << networkDeviceInfo << networkDeviceInfo.macAddress() << result.product << result.serialNumber << result.firmwareVersion; + } + } + }); + +} + +KebaDiscovery::~KebaDiscovery() +{ + qCDebug(dcKeba()) << "Discovery: Destroying object."; +} + +void KebaDiscovery::startDiscovery() +{ + // Clean up + m_networkDeviceInfos.clear(); + m_results.clear(); + + qCDebug(dcKeba()) << "Discovery: Start discovering Keba Wallboxs..."; + NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover(); + connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){ + qCDebug(dcKeba()) << "Discovery: Network discovery finished. Found" << discoveryReply->networkDeviceInfos().count() << "network devices"; + m_networkDeviceInfos = discoveryReply->networkDeviceInfos(); + + // Send a report 1 request to all discovered network devices and see which one responds + qCDebug(dcKeba()) << "Discovery: Start sending \"report 1\" request to all discovered network devices"; + foreach (const NetworkDeviceInfo &networkDeviceInfo, m_networkDeviceInfos) + m_kebaDataLayer->write(networkDeviceInfo.address(), QByteArray("report 1\n")); + + m_responseTimer.start(); + }); +} + +QList KebaDiscovery::discoveryResults() const +{ + return m_results; +} + +bool KebaDiscovery::alreadyDiscovered(const QHostAddress &address) +{ + foreach (const KebaDiscoveryResult &result, m_results) { + if (result.networkDeviceInfo.address() == address) { + return true; + } + } + + return false; +} diff --git a/keba/kebadiscovery.h b/keba/kebadiscovery.h new file mode 100644 index 00000000..d7556944 --- /dev/null +++ b/keba/kebadiscovery.h @@ -0,0 +1,73 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2021, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project is distributed in the hope that +* it will be useful, but WITHOUT ANY WARRANTY; without even the implied +* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef KEBADISCOVERY_H +#define KEBADISCOVERY_H + +#include +#include + +#include + +class KeContactDataLayer; +class NetworkDeviceDiscovery; + +class KebaDiscovery : public QObject +{ + Q_OBJECT +public: + typedef struct KebaDiscoveryResult { + QString product; + QString serialNumber; + QString firmwareVersion; + NetworkDeviceInfo networkDeviceInfo; + } KebaDiscoveryResult; + + explicit KebaDiscovery(KeContactDataLayer *kebaDataLayer, NetworkDeviceDiscovery *networkDeviceDiscovery, QObject *parent = nullptr); + ~KebaDiscovery(); + + void startDiscovery(); + + QList discoveryResults() const; + +signals: + void discoveryFinished(); + +private: + KeContactDataLayer *m_kebaDataLayer = nullptr; + NetworkDeviceDiscovery *m_networkDeviceDiscovery = nullptr; + QTimer m_responseTimer; + NetworkDeviceInfos m_networkDeviceInfos; + QList m_results; + + bool alreadyDiscovered(const QHostAddress &address); +}; + +#endif // KEBADISCOVERY_H diff --git a/keba/kecontact.cpp b/keba/kecontact.cpp index 1f3ca12b..ef182775 100644 --- a/keba/kecontact.cpp +++ b/keba/kecontact.cpp @@ -129,7 +129,6 @@ void KeContact::sendCommand(const QByteArray &command) return; } - qCDebug(dcKeba()) << "--> Writing datagram to" << m_address.toString() << command; m_dataLayer->write(m_address, command); m_requestTimeoutTimer->start(5000); } @@ -157,6 +156,8 @@ void KeContact::setReachable(bool reachable) qCDebug(dcKeba()) << "The keba wallbox on" << m_address.toString() << "is now reachable again."; } else { qCWarning(dcKeba()) << "The keba wallbox on" << m_address.toString() << "is not reachable any more."; + m_requestQueue.clear(); + m_currentRequest = KeContactRequest(); } m_reachable = reachable; @@ -231,7 +232,6 @@ QUuid KeContact::setMaxAmpereGeneral(int milliAmpere) QByteArray datagram = commandLine.toUtf8(); KeContactRequest request(QUuid::createUuid(), datagram); request.setDelayUntilNextCommand(1200); - qCDebug(dcKeba()) << "Set max general charging amps: Datagram:" << datagram; m_requestQueue.enqueue(request); sendNextCommand(); return request.requestId(); @@ -390,11 +390,8 @@ QUuid KeContact::unlockCharger() void KeContact::onReceivedDatagram(const QHostAddress &address, const QByteArray &datagram) { // Make sure the datagram is for this keba - if (address != m_address) { + if (address != m_address) return; - } - - qCDebug(dcKeba()) << "<--" << qUtf8Printable(datagram); if (datagram.contains("TCH-OK")){ // We received valid data from the address over the data link, so the wallbox must be reachable @@ -462,7 +459,7 @@ void KeContact::onReceivedDatagram(const QHostAddress &address, const QByteArray setReachable(true); ReportOne reportOne; - qCDebug(dcKeba()) << "Report 1 received"; + //qCDebug(dcKeba()) << "Report 1 received"; reportOne.product = data.value("Product").toString(); reportOne.firmware = data.value("Firmware").toString(); reportOne.serialNumber = data.value("Serial").toString(); @@ -470,6 +467,9 @@ void KeContact::onReceivedDatagram(const QHostAddress &address, const QByteArray //"timeQ": 3 //"DIP-Sw1": "0x22" //"DIP-Sw2": + reportOne.dipSw1 = data.value("DIP-Sw1").toString().remove("0x").toUInt(nullptr, 16); + reportOne.dipSw2 = data.value("DIP-Sw2").toString().remove("0x").toUInt(nullptr, 16); + if (data.contains("COM-module")) { reportOne.comModule = (data.value("COM-module").toInt() == 1); } else { @@ -487,7 +487,7 @@ void KeContact::onReceivedDatagram(const QHostAddress &address, const QByteArray setReachable(true); ReportTwo reportTwo; - qCDebug(dcKeba()) << "Report 2 received"; + //qCDebug(dcKeba()) << "Report 2 received"; int state = data.value("State").toInt(); reportTwo.state = State(state); reportTwo.error1 = data.value("Error1").toInt(); @@ -518,17 +518,17 @@ void KeContact::onReceivedDatagram(const QHostAddress &address, const QByteArray setReachable(true); ReportThree reportThree; - qCDebug(dcKeba()) << "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; + //qCDebug(dcKeba()) << "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; reportThree.voltagePhase1 = data.value("U1").toInt(); reportThree.voltagePhase2 = data.value("U2").toInt(); reportThree.voltagePhase3 = data.value("U3").toInt(); - reportThree.power = data.value("P").toInt()/1000.00; - reportThree.powerFactor = data.value("PF").toInt()/10.00; - reportThree.energySession = data.value("E pres").toInt()/10000.00; - reportThree.energyTotal = data.value("E total").toInt()/10000.00; + reportThree.power = data.value("P").toInt() / 1000.00; + reportThree.powerFactor = data.value("PF").toInt() / 10.00; + reportThree.energySession = data.value("E pres").toInt() / 10000.00; + reportThree.energyTotal = data.value("E total").toInt() / 10000.00; reportThree.serialNumber = data.value("Serial").toString(); reportThree.seconds = data.value("Sec").toInt(); emit reportThreeReceived(reportThree); @@ -537,7 +537,7 @@ void KeContact::onReceivedDatagram(const QHostAddress &address, const QByteArray setReachable(true); Report1XX report; - qCDebug(dcKeba()) << "Report" << id << "received"; + //qCDebug(dcKeba()) << "Report" << id << "received"; report.sessionId = data.value("Session ID").toInt(); report.currHW = data.value("Curr HW").toInt(); report.startEnergy = data.value("E start").toInt() / 10000.00; @@ -552,6 +552,8 @@ void KeContact::onReceivedDatagram(const QHostAddress &address, const QByteArray emit report1XXReceived(id, report); } } else { + // Broadcast message, lets see what we recognize + if (data.contains("State")) { // We received valid data from the address over the data link, so the wallbox must be reachable setReachable(true); diff --git a/keba/kecontact.h b/keba/kecontact.h index 70c3748b..3df318d1 100644 --- a/keba/kecontact.h +++ b/keba/kecontact.h @@ -62,11 +62,31 @@ private: }; - class KeContact : public QObject { Q_OBJECT public: + enum DipSwitchOne { + // Power settings + // DIP 6 7 8 (Bit 2, 1, 0) + // 0 0 0 : 10A + // 1 0 0 : 13A + // 0 1 0 : 16A + // 1 1 0 : 20A + // 0 0 1 : 25A + // 1 0 1 : 32A + DipSwitchOnePin8 = 0x01, + DipSwitchOnePin7 = 0x02, + DipSwitchOnePin6 = 0x04, + DipSwitchOnePin5 = 0x08, + DipSwitchOnePin4 = 0x10, + DipSwitchOneSmartHomeInterface = 0x20, // 3 + DipSwitchOneExternalInputX2 = 0x40, // 2 + DipSwitchOneExternalInputX1 = 0x80 // 1 + }; + Q_ENUM(DipSwitchOne) + Q_DECLARE_FLAGS(DipSwitchOneFlag, DipSwitchOne) + enum State { StateStarting = 0, StateNotReady, @@ -102,6 +122,8 @@ public: QString firmware; // Firmware version bool comModule; // Communication module is installed (only P30) int seconds; // Current system clock since restart of the charging station.(only P30) + quint8 dipSw1; // Dip Switch 1 flag + quint8 dipSw2; // Dip Switch 2 flag }; struct ReportTwo { @@ -216,5 +238,8 @@ private slots: void onReceivedDatagram(const QHostAddress &address, const QByteArray &datagram); }; + +Q_DECLARE_OPERATORS_FOR_FLAGS(KeContact::DipSwitchOneFlag); + #endif // KECONTACT_H diff --git a/keba/kecontactdatalayer.cpp b/keba/kecontactdatalayer.cpp index c0772647..806c1a60 100644 --- a/keba/kecontactdatalayer.cpp +++ b/keba/kecontactdatalayer.cpp @@ -66,6 +66,7 @@ bool KeContactDataLayer::initialized() const void KeContactDataLayer::write(const QHostAddress &address, const QByteArray &data) { + qCDebug(dcKeba()) << "KeContactDataLayer: -->" << address.toString() << data; m_udpSocket->writeDatagram(data, address, m_port); } @@ -80,14 +81,14 @@ void KeContactDataLayer::readPendingDatagrams() while (socket->hasPendingDatagrams()) { datagram.resize(socket->pendingDatagramSize()); socket->readDatagram(datagram.data(), datagram.size(), &senderAddress, &senderPort); - qCDebug(dcKeba()) << "KeContactDataLayer: Data received from" << senderAddress.toString() << datagram ; + qCDebug(dcKeba()) << "KeContactDataLayer: <--" << senderAddress.toString() << datagram; emit datagramReceived(senderAddress, datagram); } } void KeContactDataLayer::onSocketError(QAbstractSocket::SocketError error) { - qCDebug(dcKeba()) << "KeContactDataLayer: Socket error" << error; + qCWarning(dcKeba()) << "KeContactDataLayer: Socket error" << error; } void KeContactDataLayer::onSocketStateChanged(QAbstractSocket::SocketState socketState) diff --git a/keba/translations/9142b09f-30a9-43d0-9ede-2f8debe075ac-de.ts b/keba/translations/9142b09f-30a9-43d0-9ede-2f8debe075ac-de.ts index 14ec0e16..4f7f0726 100644 --- a/keba/translations/9142b09f-30a9-43d0-9ede-2f8debe075ac-de.ts +++ b/keba/translations/9142b09f-30a9-43d0-9ede-2f8debe075ac-de.ts @@ -4,16 +4,36 @@ IntegrationPluginKeba - + + The communication could not be established. + + + + + The network discovery is not available. Please enter the IP address manually. + + + + Error opening network port. Fehler beim Öffnen des Netzwerkports. + + + Already configured for this IP address. + + + + + The required communication interface is not enabled on this wallbox. Please make sure the DIP switch 1.3 is switched on and try again. + + Keba - - + + Activity The name of the ParamType (ThingClass: wallbox, EventType: activity, ID: {539e5602-6dd9-465d-9705-3bb59bcf8982}) ---------- @@ -21,14 +41,14 @@ The name of the StateType ({539e5602-6dd9-465d-9705-3bb59bcf8982}) of ThingClass Aktivität - + Activity changed The name of the EventType ({539e5602-6dd9-465d-9705-3bb59bcf8982}) of ThingClass wallbox Aktivität geändert - - + + Car plugged in The name of the ParamType (ThingClass: wallbox, EventType: pluggedIn, ID: {6c227717-f420-4dcd-bd52-49973715603b}) ---------- @@ -36,15 +56,30 @@ The name of the StateType ({6c227717-f420-4dcd-bd52-49973715603b}) of ThingClass - + Car plugged in changed The name of the EventType ({6c227717-f420-4dcd-bd52-49973715603b}) of ThingClass wallbox - - - + + + Charging + The name of the ParamType (ThingClass: wallbox, EventType: charging, ID: {c9785626-2501-478d-8c18-c42ad5d9a269}) +---------- +The name of the StateType ({c9785626-2501-478d-8c18-c42ad5d9a269}) of ThingClass wallbox + + + + + Charging changed + The name of the EventType ({c9785626-2501-478d-8c18-c42ad5d9a269}) of ThingClass wallbox + + + + + + Charging enabled The name of the ParamType (ThingClass: wallbox, ActionType: power, ID: {83ed0774-2a91-434d-b03c-d920d02f2981}) ---------- @@ -54,20 +89,20 @@ The name of the StateType ({83ed0774-2a91-434d-b03c-d920d02f2981}) of ThingClass Laden ermöglicht - + Charging enabled changed The name of the EventType ({83ed0774-2a91-434d-b03c-d920d02f2981}) of ThingClass wallbox Laden ermäglicht geändert - + Charging session finished The name of the EventType ({dac02c37-f051-481a-ae99-1de0885ef37a}) of ThingClass wallbox Ladesession beendet - - + + Connected The name of the ParamType (ThingClass: wallbox, EventType: connected, ID: {ce813458-d7d8-4f40-9648-dba4c41e92f0}) ---------- @@ -75,98 +110,83 @@ The name of the StateType ({ce813458-d7d8-4f40-9648-dba4c41e92f0}) of ThingClass Verbunden - + Connected changed The name of the EventType ({ce813458-d7d8-4f40-9648-dba4c41e92f0}) of ThingClass wallbox Verbunden geändert - - - Current - The name of the ParamType (ThingClass: wallbox, EventType: current, ID: {a29c1748-fe97-4830-a56e-e1cc4e618385}) ----------- -The name of the StateType ({a29c1748-fe97-4830-a56e-e1cc4e618385}) of ThingClass wallbox - Stromstärke - - - - Current changed - The name of the EventType ({a29c1748-fe97-4830-a56e-e1cc4e618385}) of ThingClass wallbox - Stromstärke geändert - - - - - Current phase 1 - The name of the ParamType (ThingClass: wallbox, EventType: currentPhase1, ID: {31ec17b0-11e3-4332-92b0-fea821cf024f}) + + + Current phase A + The name of the ParamType (ThingClass: wallbox, EventType: currentPhaseA, ID: {31ec17b0-11e3-4332-92b0-fea821cf024f}) ---------- The name of the StateType ({31ec17b0-11e3-4332-92b0-fea821cf024f}) of ThingClass wallbox - Stromstärke Phase 1 + - - Current phase 1 changed + + Current phase A changed The name of the EventType ({31ec17b0-11e3-4332-92b0-fea821cf024f}) of ThingClass wallbox - Stromstärke Phase 1 geändert + - - - Current phase 2 - The name of the ParamType (ThingClass: wallbox, EventType: currentPhase2, ID: {cdc7e10a-0d0a-4e93-ad2c-d34ffca45c97}) + + + Current phase B + The name of the ParamType (ThingClass: wallbox, EventType: currentPhaseB, ID: {cdc7e10a-0d0a-4e93-ad2c-d34ffca45c97}) ---------- The name of the StateType ({cdc7e10a-0d0a-4e93-ad2c-d34ffca45c97}) of ThingClass wallbox - Stromstärke Phase 2 + - - Current phase 2 changed + + Current phase B changed The name of the EventType ({cdc7e10a-0d0a-4e93-ad2c-d34ffca45c97}) of ThingClass wallbox - Stromstärke Phase 2 geändert + - - - Current phase 3 - The name of the ParamType (ThingClass: wallbox, EventType: currentPhase3, ID: {da838dc8-85f0-4e55-b4b5-cb93a43b373d}) + + + Current phase C + The name of the ParamType (ThingClass: wallbox, EventType: currentPhaseC, ID: {da838dc8-85f0-4e55-b4b5-cb93a43b373d}) ---------- The name of the StateType ({da838dc8-85f0-4e55-b4b5-cb93a43b373d}) of ThingClass wallbox - Stromstärke Phase 3 + - - Current phase 3 changed + + Current phase C changed The name of the EventType ({da838dc8-85f0-4e55-b4b5-cb93a43b373d}) of ThingClass wallbox - Stromstärke Phase 3 geändert + - + Display The name of the ActionType ({158b1a8f-fde9-4191-bf42-4ece5fe582e6}) of ThingClass wallbox Anzeige - + Display message The name of the ParamType (ThingClass: wallbox, ActionType: display, ID: {4e69a761-f4f1-42d0-83db-380894a86ebc}) Nachricht - + Duration The name of the ParamType (ThingClass: wallbox, EventType: chargingSessionFinished, ID: {60494d6f-853b-42b8-894e-108a52ed6feb}) Dauer - + Energy The name of the ParamType (ThingClass: wallbox, EventType: chargingSessionFinished, ID: {c8de58b6-b671-4fee-b552-d2c14a37a769}) Energie - - + + Error 1 The name of the ParamType (ThingClass: wallbox, EventType: error1, ID: {b44bc948-1234-4f87-9a22-bfb6de09df4d}) ---------- @@ -174,14 +194,14 @@ The name of the StateType ({b44bc948-1234-4f87-9a22-bfb6de09df4d}) of ThingClass Error 1 - + Error 1 changed The name of the EventType ({b44bc948-1234-4f87-9a22-bfb6de09df4d}) of ThingClass wallbox Error 1 geändert - - + + Error 2 The name of the ParamType (ThingClass: wallbox, EventType: error2, ID: {afca201a-5213-43fe-bfec-cae6ce7509d2}) ---------- @@ -189,15 +209,15 @@ The name of the StateType ({afca201a-5213-43fe-bfec-cae6ce7509d2}) of ThingClass Error 2 - + Error 2 changed The name of the EventType ({afca201a-5213-43fe-bfec-cae6ce7509d2}) of ThingClass wallbox Error 2 geändert - - - + + + Failsafe mode The name of the ParamType (ThingClass: wallbox, ActionType: failsafeMode, ID: {f1758c5c-2c02-41cb-93ec-b778a3c78d28}) ---------- @@ -207,14 +227,14 @@ The name of the StateType ({f1758c5c-2c02-41cb-93ec-b778a3c78d28}) of ThingClass Failsafe Module - + Failsafe mode changed The name of the EventType ({f1758c5c-2c02-41cb-93ec-b778a3c78d28}) of ThingClass wallbox Failsafe Modus geändert - - + + Firmware The name of the ParamType (ThingClass: wallbox, EventType: firmware, ID: {e941ace5-fb7f-4dc2-b3f2-188233f4e934}) ---------- @@ -222,26 +242,26 @@ The name of the StateType ({e941ace5-fb7f-4dc2-b3f2-188233f4e934}) of ThingClass Firmware - + Firmware changed The name of the EventType ({e941ace5-fb7f-4dc2-b3f2-188233f4e934}) of ThingClass wallbox Firmware geändert - + ID The name of the ParamType (ThingClass: wallbox, EventType: chargingSessionFinished, ID: {33446eae-f2cc-4cf2-af29-b3a45e4b91c0}) ID - + IP address The name of the ParamType (ThingClass: wallbox, Type: thing, ID: {730cd3d3-5f0e-4028-a8c2-ced7574f13f3}) IP Adresse - - + + Input The name of the ParamType (ThingClass: wallbox, EventType: input, ID: {ba600276-8b36-4404-b8ec-415245e5bc15}) ---------- @@ -249,20 +269,20 @@ The name of the StateType ({ba600276-8b36-4404-b8ec-415245e5bc15}) of ThingClass Eingang - + Input changed The name of the EventType ({ba600276-8b36-4404-b8ec-415245e5bc15}) of ThingClass wallbox Eingang geändert - + Keba The name of the vendor ({f7cda40b-829a-4675-abaa-485697430f5f}) Keba - - + + Keba KeContact The name of the ThingClass ({900dacec-cae7-4a37-95ba-501846368ea2}) ---------- @@ -270,15 +290,15 @@ The name of the plugin Keba ({9142b09f-30a9-43d0-9ede-2f8debe075ac})Keba KeContact - + MAC address The name of the ParamType (ThingClass: wallbox, Type: thing, ID: {c2df921d-ff8b-411c-9b1d-04a437d7dfa6}) MAC Adresse - - - + + + Maximal charging current The name of the ParamType (ThingClass: wallbox, ActionType: maxChargingCurrent, ID: {593656f0-babf-4308-8767-68f34e10fb15}) ---------- @@ -288,14 +308,14 @@ The name of the StateType ({593656f0-babf-4308-8767-68f34e10fb15}) of ThingClass Maximaler Ladestrom - + Maximal charging current changed The name of the EventType ({593656f0-babf-4308-8767-68f34e10fb15}) of ThingClass wallbox Maximaler Ladestrom geändert - - + + Maximal charging current in percent The name of the ParamType (ThingClass: wallbox, EventType: maxChargingCurrentPercent, ID: {3c7b83a0-0e42-47bf-9788-dde6aab5ceea}) ---------- @@ -303,45 +323,90 @@ The name of the StateType ({3c7b83a0-0e42-47bf-9788-dde6aab5ceea}) of ThingClass Maximaler Ladestrom in Prozent - + Maximal charging current percentage changed The name of the EventType ({3c7b83a0-0e42-47bf-9788-dde6aab5ceea}) of ThingClass wallbox Maximaler Ladestrom in Prozent geändert - - - Maximum possible charging current - The name of the ParamType (ThingClass: wallbox, EventType: maxPossibleChargingCurrent, ID: {08bb9872-8d63-49b0-a8ce-7a449341f13b}) + + + Maximal hardware charging current + The name of the ParamType (ThingClass: wallbox, EventType: maxChargingCurrentHardware, ID: {33e2ed95-f01e-44db-8156-34d124a8ecc8}) ---------- -The name of the StateType ({08bb9872-8d63-49b0-a8ce-7a449341f13b}) of ThingClass wallbox +The name of the StateType ({33e2ed95-f01e-44db-8156-34d124a8ecc8}) of ThingClass wallbox - - Maximum possible charging current changed - The name of the EventType ({08bb9872-8d63-49b0-a8ce-7a449341f13b}) of ThingClass wallbox + + Maximal hardware charging current changed + The name of the EventType ({33e2ed95-f01e-44db-8156-34d124a8ecc8}) of ThingClass wallbox - - - Model - The name of the ParamType (ThingClass: wallbox, EventType: model, ID: {c3fca233-95b9-4948-88c6-4c0f13cf53b1}) + + + Number of connected phases + The name of the ParamType (ThingClass: wallbox, EventType: phaseCount, ID: {6713b2e7-41b3-4596-a304-3065726bdbe4}) ---------- -The name of the StateType ({c3fca233-95b9-4948-88c6-4c0f13cf53b1}) of ThingClass wallbox - Modell +The name of the StateType ({6713b2e7-41b3-4596-a304-3065726bdbe4}) of ThingClass wallbox + - - Model changed - The name of the EventType ({c3fca233-95b9-4948-88c6-4c0f13cf53b1}) of ThingClass wallbox - Modell geändert + + Number of connected phases changed + The name of the EventType ({6713b2e7-41b3-4596-a304-3065726bdbe4}) of ThingClass wallbox + - - - + + + Voltage phase A + The name of the ParamType (ThingClass: wallbox, EventType: voltagePhaseA, ID: {4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) +---------- +The name of the StateType ({4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) of ThingClass wallbox + + + + + Voltage phase A changed + The name of the EventType ({4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) of ThingClass wallbox + + + + + + Voltage phase B + The name of the ParamType (ThingClass: wallbox, EventType: voltagePhaseB, ID: {c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) +---------- +The name of the StateType ({c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) of ThingClass wallbox + + + + + Voltage phase B changed + The name of the EventType ({c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) of ThingClass wallbox + + + + + + Voltage phase C + The name of the ParamType (ThingClass: wallbox, EventType: voltagePhaseC, ID: {5f01e86c-0943-4849-a01a-db441916ebd5}) +---------- +The name of the StateType ({5f01e86c-0943-4849-a01a-db441916ebd5}) of ThingClass wallbox + + + + + Voltage phase C changed + The name of the EventType ({5f01e86c-0943-4849-a01a-db441916ebd5}) of ThingClass wallbox + + + + + + Output X2 The name of the ParamType (ThingClass: wallbox, ActionType: outputX2, ID: {96b2d176-6460-4109-8824-3af4679c6573}) ---------- @@ -351,14 +416,14 @@ The name of the StateType ({96b2d176-6460-4109-8824-3af4679c6573}) of ThingClass Ausgang X2 - + Output X2 changed The name of the EventType ({96b2d176-6460-4109-8824-3af4679c6573}) of ThingClass wallbox Ausgang X2 geändert - - + + Plug state The name of the ParamType (ThingClass: wallbox, EventType: plugState, ID: {3b4d29f3-3101-47ad-90fd-269b6348783b}) ---------- @@ -366,14 +431,14 @@ The name of the StateType ({3b4d29f3-3101-47ad-90fd-269b6348783b}) of ThingClass Stecker-Status - + Plug state changed The name of the EventType ({3b4d29f3-3101-47ad-90fd-269b6348783b}) of ThingClass wallbox Stecker-Status geändert - - + + Power consumption The name of the ParamType (ThingClass: wallbox, EventType: currentPower, ID: {7af9e93b-099d-4d9d-a480-9c0f66aecd8b}) ---------- @@ -381,14 +446,14 @@ The name of the StateType ({7af9e93b-099d-4d9d-a480-9c0f66aecd8b}) of ThingClass Leistungsaufnahme - + Power consumtion changed The name of the EventType ({7af9e93b-099d-4d9d-a480-9c0f66aecd8b}) of ThingClass wallbox Leistungsaufnahme geändert - - + + Power factor The name of the ParamType (ThingClass: wallbox, EventType: powerFactor, ID: {889c3c9a-96b4-4408-bd9a-d79e36ed9296}) ---------- @@ -396,29 +461,26 @@ The name of the StateType ({889c3c9a-96b4-4408-bd9a-d79e36ed9296}) of ThingClass Leistungsfaktor - + Power factor changed The name of the EventType ({889c3c9a-96b4-4408-bd9a-d79e36ed9296}) of ThingClass wallbox Leistungsfaktor - - + + Product name + The name of the ParamType (ThingClass: wallbox, Type: thing, ID: {a996c698-4831-4977-8979-f76f78ac7da8}) + + + + Serial number - The name of the ParamType (ThingClass: wallbox, EventType: serialnumber, ID: {9a1b4316-ce01-4cd3-890f-a8c94b8b5029}) ----------- -The name of the StateType ({9a1b4316-ce01-4cd3-890f-a8c94b8b5029}) of ThingClass wallbox + The name of the ParamType (ThingClass: wallbox, Type: thing, ID: {45255155-318b-4204-8ce6-2c106a56286d}) Seriennummer - - Serial number changed - The name of the EventType ({9a1b4316-ce01-4cd3-890f-a8c94b8b5029}) of ThingClass wallbox - Seriennnummer geändert - - - - + + Session ID The name of the ParamType (ThingClass: wallbox, EventType: sessionId, ID: {1d30ce60-2ea0-450f-817e-5c88f59ebfbf}) ---------- @@ -426,14 +488,14 @@ The name of the StateType ({1d30ce60-2ea0-450f-817e-5c88f59ebfbf}) of ThingClass Session ID - + Session ID changed The name of the EventType ({1d30ce60-2ea0-450f-817e-5c88f59ebfbf}) of ThingClass wallbox Session ID geändert - - + + Session energy The name of the ParamType (ThingClass: wallbox, EventType: sessionEnergy, ID: {8e277efe-21ef-4536-bfc0-901b32d44d7c}) ---------- @@ -441,14 +503,14 @@ The name of the StateType ({8e277efe-21ef-4536-bfc0-901b32d44d7c}) of ThingClass Session Energie - + Session energy changed The name of the EventType ({8e277efe-21ef-4536-bfc0-901b32d44d7c}) of ThingClass wallbox Session Energie geändert - - + + Session time The name of the ParamType (ThingClass: wallbox, EventType: sessionTime, ID: {a6f35ea0-aaea-438b-b818-6d161762611e}) ---------- @@ -456,38 +518,38 @@ The name of the StateType ({a6f35ea0-aaea-438b-b818-6d161762611e}) of ThingClass Sessiondauer - + Session time changed The name of the EventType ({a6f35ea0-aaea-438b-b818-6d161762611e}) of ThingClass wallbox Sessiondauer geändert - + Set charging enabled The name of the ActionType ({83ed0774-2a91-434d-b03c-d920d02f2981}) of ThingClass wallbox Setze Laden ermöglicht - + Set failsafe mode The name of the ActionType ({f1758c5c-2c02-41cb-93ec-b778a3c78d28}) of ThingClass wallbox Setze Failsafe Modus - + Set maximal charging current The name of the ActionType ({593656f0-babf-4308-8767-68f34e10fb15}) of ThingClass wallbox Setze maximaler Ladestrom - + Set output X2 The name of the ActionType ({96b2d176-6460-4109-8824-3af4679c6573}) of ThingClass wallbox Setze Ausgang X2 - - + + System enabled The name of the ParamType (ThingClass: wallbox, EventType: systemEnabled, ID: {e5631593-f486-47cb-9951-b7597d0b769b}) ---------- @@ -495,14 +557,14 @@ The name of the StateType ({e5631593-f486-47cb-9951-b7597d0b769b}) of ThingClass System ermöglicht - + System enabled changed The name of the EventType ({e5631593-f486-47cb-9951-b7597d0b769b}) of ThingClass wallbox System ermöglicht geändert - - + + Total energy consumed The name of the ParamType (ThingClass: wallbox, EventType: totalEnergyConsumed, ID: {41e179b3-29a2-43ec-b537-023a527081e8}) ---------- @@ -510,14 +572,14 @@ The name of the StateType ({41e179b3-29a2-43ec-b537-023a527081e8}) of ThingClass Gesamter Energieverbrauch - + Total energy consumption changed The name of the EventType ({41e179b3-29a2-43ec-b537-023a527081e8}) of ThingClass wallbox Gesamter Energieverbrauch geändert - - + + Uptime The name of the ParamType (ThingClass: wallbox, EventType: uptime, ID: {3421ecf9-c95f-4dc1-ad0c-144e9b6ae056}) ---------- @@ -525,55 +587,10 @@ The name of the StateType ({3421ecf9-c95f-4dc1-ad0c-144e9b6ae056}) of ThingClass Betriebszeit - + Uptime changed The name of the EventType ({3421ecf9-c95f-4dc1-ad0c-144e9b6ae056}) of ThingClass wallbox Betriebszeit geändert - - - - Voltage phase 1 - The name of the ParamType (ThingClass: wallbox, EventType: voltagePhase1, ID: {4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) ----------- -The name of the StateType ({4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) of ThingClass wallbox - Spannung Phase 1 - - - - Voltage phase 1 changed - The name of the EventType ({4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) of ThingClass wallbox - Spannung Phase 1 geändert - - - - - Voltage phase 2 - The name of the ParamType (ThingClass: wallbox, EventType: voltagePhase2, ID: {c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) ----------- -The name of the StateType ({c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) of ThingClass wallbox - Spannung Phase 2 - - - - Voltage phase 2 changed - The name of the EventType ({c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) of ThingClass wallbox - Spannung Phase 2 geändert - - - - - Voltage phase 3 - The name of the ParamType (ThingClass: wallbox, EventType: voltagePhase3, ID: {5f01e86c-0943-4849-a01a-db441916ebd5}) ----------- -The name of the StateType ({5f01e86c-0943-4849-a01a-db441916ebd5}) of ThingClass wallbox - Spannung Phase 3 - - - - Voltage phase 3 changed - The name of the EventType ({5f01e86c-0943-4849-a01a-db441916ebd5}) of ThingClass wallbox - Spannung Phase 3 geändert - diff --git a/keba/translations/9142b09f-30a9-43d0-9ede-2f8debe075ac-en_US.ts b/keba/translations/9142b09f-30a9-43d0-9ede-2f8debe075ac-en_US.ts index 23c4bbf3..3e9da0f0 100644 --- a/keba/translations/9142b09f-30a9-43d0-9ede-2f8debe075ac-en_US.ts +++ b/keba/translations/9142b09f-30a9-43d0-9ede-2f8debe075ac-en_US.ts @@ -4,16 +4,36 @@ IntegrationPluginKeba - + + The communication could not be established. + + + + + The network discovery is not available. Please enter the IP address manually. + + + + Error opening network port. + + + Already configured for this IP address. + + + + + The required communication interface is not enabled on this wallbox. Please make sure the DIP switch 1.3 is switched on and try again. + + Keba - - + + Activity The name of the ParamType (ThingClass: wallbox, EventType: activity, ID: {539e5602-6dd9-465d-9705-3bb59bcf8982}) ---------- @@ -21,14 +41,14 @@ The name of the StateType ({539e5602-6dd9-465d-9705-3bb59bcf8982}) of ThingClass - + Activity changed The name of the EventType ({539e5602-6dd9-465d-9705-3bb59bcf8982}) of ThingClass wallbox - - + + Car plugged in The name of the ParamType (ThingClass: wallbox, EventType: pluggedIn, ID: {6c227717-f420-4dcd-bd52-49973715603b}) ---------- @@ -36,15 +56,30 @@ The name of the StateType ({6c227717-f420-4dcd-bd52-49973715603b}) of ThingClass - + Car plugged in changed The name of the EventType ({6c227717-f420-4dcd-bd52-49973715603b}) of ThingClass wallbox - - - + + + Charging + The name of the ParamType (ThingClass: wallbox, EventType: charging, ID: {c9785626-2501-478d-8c18-c42ad5d9a269}) +---------- +The name of the StateType ({c9785626-2501-478d-8c18-c42ad5d9a269}) of ThingClass wallbox + + + + + Charging changed + The name of the EventType ({c9785626-2501-478d-8c18-c42ad5d9a269}) of ThingClass wallbox + + + + + + Charging enabled The name of the ParamType (ThingClass: wallbox, ActionType: power, ID: {83ed0774-2a91-434d-b03c-d920d02f2981}) ---------- @@ -54,20 +89,20 @@ The name of the StateType ({83ed0774-2a91-434d-b03c-d920d02f2981}) of ThingClass - + Charging enabled changed The name of the EventType ({83ed0774-2a91-434d-b03c-d920d02f2981}) of ThingClass wallbox - + Charging session finished The name of the EventType ({dac02c37-f051-481a-ae99-1de0885ef37a}) of ThingClass wallbox - - + + Connected The name of the ParamType (ThingClass: wallbox, EventType: connected, ID: {ce813458-d7d8-4f40-9648-dba4c41e92f0}) ---------- @@ -75,98 +110,83 @@ The name of the StateType ({ce813458-d7d8-4f40-9648-dba4c41e92f0}) of ThingClass - + Connected changed The name of the EventType ({ce813458-d7d8-4f40-9648-dba4c41e92f0}) of ThingClass wallbox - - - Current - The name of the ParamType (ThingClass: wallbox, EventType: current, ID: {a29c1748-fe97-4830-a56e-e1cc4e618385}) ----------- -The name of the StateType ({a29c1748-fe97-4830-a56e-e1cc4e618385}) of ThingClass wallbox - - - - - Current changed - The name of the EventType ({a29c1748-fe97-4830-a56e-e1cc4e618385}) of ThingClass wallbox - - - - - - Current phase 1 - The name of the ParamType (ThingClass: wallbox, EventType: currentPhase1, ID: {31ec17b0-11e3-4332-92b0-fea821cf024f}) + + + Current phase A + The name of the ParamType (ThingClass: wallbox, EventType: currentPhaseA, ID: {31ec17b0-11e3-4332-92b0-fea821cf024f}) ---------- The name of the StateType ({31ec17b0-11e3-4332-92b0-fea821cf024f}) of ThingClass wallbox - - Current phase 1 changed + + Current phase A changed The name of the EventType ({31ec17b0-11e3-4332-92b0-fea821cf024f}) of ThingClass wallbox - - - Current phase 2 - The name of the ParamType (ThingClass: wallbox, EventType: currentPhase2, ID: {cdc7e10a-0d0a-4e93-ad2c-d34ffca45c97}) + + + Current phase B + The name of the ParamType (ThingClass: wallbox, EventType: currentPhaseB, ID: {cdc7e10a-0d0a-4e93-ad2c-d34ffca45c97}) ---------- The name of the StateType ({cdc7e10a-0d0a-4e93-ad2c-d34ffca45c97}) of ThingClass wallbox - - Current phase 2 changed + + Current phase B changed The name of the EventType ({cdc7e10a-0d0a-4e93-ad2c-d34ffca45c97}) of ThingClass wallbox - - - Current phase 3 - The name of the ParamType (ThingClass: wallbox, EventType: currentPhase3, ID: {da838dc8-85f0-4e55-b4b5-cb93a43b373d}) + + + Current phase C + The name of the ParamType (ThingClass: wallbox, EventType: currentPhaseC, ID: {da838dc8-85f0-4e55-b4b5-cb93a43b373d}) ---------- The name of the StateType ({da838dc8-85f0-4e55-b4b5-cb93a43b373d}) of ThingClass wallbox - - Current phase 3 changed + + Current phase C changed The name of the EventType ({da838dc8-85f0-4e55-b4b5-cb93a43b373d}) of ThingClass wallbox - + Display The name of the ActionType ({158b1a8f-fde9-4191-bf42-4ece5fe582e6}) of ThingClass wallbox - + Display message The name of the ParamType (ThingClass: wallbox, ActionType: display, ID: {4e69a761-f4f1-42d0-83db-380894a86ebc}) - + Duration The name of the ParamType (ThingClass: wallbox, EventType: chargingSessionFinished, ID: {60494d6f-853b-42b8-894e-108a52ed6feb}) - + Energy The name of the ParamType (ThingClass: wallbox, EventType: chargingSessionFinished, ID: {c8de58b6-b671-4fee-b552-d2c14a37a769}) - - + + Error 1 The name of the ParamType (ThingClass: wallbox, EventType: error1, ID: {b44bc948-1234-4f87-9a22-bfb6de09df4d}) ---------- @@ -174,14 +194,14 @@ The name of the StateType ({b44bc948-1234-4f87-9a22-bfb6de09df4d}) of ThingClass - + Error 1 changed The name of the EventType ({b44bc948-1234-4f87-9a22-bfb6de09df4d}) of ThingClass wallbox - - + + Error 2 The name of the ParamType (ThingClass: wallbox, EventType: error2, ID: {afca201a-5213-43fe-bfec-cae6ce7509d2}) ---------- @@ -189,15 +209,15 @@ The name of the StateType ({afca201a-5213-43fe-bfec-cae6ce7509d2}) of ThingClass - + Error 2 changed The name of the EventType ({afca201a-5213-43fe-bfec-cae6ce7509d2}) of ThingClass wallbox - - - + + + Failsafe mode The name of the ParamType (ThingClass: wallbox, ActionType: failsafeMode, ID: {f1758c5c-2c02-41cb-93ec-b778a3c78d28}) ---------- @@ -207,14 +227,14 @@ The name of the StateType ({f1758c5c-2c02-41cb-93ec-b778a3c78d28}) of ThingClass - + Failsafe mode changed The name of the EventType ({f1758c5c-2c02-41cb-93ec-b778a3c78d28}) of ThingClass wallbox - - + + Firmware The name of the ParamType (ThingClass: wallbox, EventType: firmware, ID: {e941ace5-fb7f-4dc2-b3f2-188233f4e934}) ---------- @@ -222,26 +242,26 @@ The name of the StateType ({e941ace5-fb7f-4dc2-b3f2-188233f4e934}) of ThingClass - + Firmware changed The name of the EventType ({e941ace5-fb7f-4dc2-b3f2-188233f4e934}) of ThingClass wallbox - + ID The name of the ParamType (ThingClass: wallbox, EventType: chargingSessionFinished, ID: {33446eae-f2cc-4cf2-af29-b3a45e4b91c0}) - + IP address The name of the ParamType (ThingClass: wallbox, Type: thing, ID: {730cd3d3-5f0e-4028-a8c2-ced7574f13f3}) - - + + Input The name of the ParamType (ThingClass: wallbox, EventType: input, ID: {ba600276-8b36-4404-b8ec-415245e5bc15}) ---------- @@ -249,20 +269,20 @@ The name of the StateType ({ba600276-8b36-4404-b8ec-415245e5bc15}) of ThingClass - + Input changed The name of the EventType ({ba600276-8b36-4404-b8ec-415245e5bc15}) of ThingClass wallbox - + Keba The name of the vendor ({f7cda40b-829a-4675-abaa-485697430f5f}) - - + + Keba KeContact The name of the ThingClass ({900dacec-cae7-4a37-95ba-501846368ea2}) ---------- @@ -270,15 +290,15 @@ The name of the plugin Keba ({9142b09f-30a9-43d0-9ede-2f8debe075ac}) - + MAC address The name of the ParamType (ThingClass: wallbox, Type: thing, ID: {c2df921d-ff8b-411c-9b1d-04a437d7dfa6}) - - - + + + Maximal charging current The name of the ParamType (ThingClass: wallbox, ActionType: maxChargingCurrent, ID: {593656f0-babf-4308-8767-68f34e10fb15}) ---------- @@ -288,14 +308,14 @@ The name of the StateType ({593656f0-babf-4308-8767-68f34e10fb15}) of ThingClass - + Maximal charging current changed The name of the EventType ({593656f0-babf-4308-8767-68f34e10fb15}) of ThingClass wallbox - - + + Maximal charging current in percent The name of the ParamType (ThingClass: wallbox, EventType: maxChargingCurrentPercent, ID: {3c7b83a0-0e42-47bf-9788-dde6aab5ceea}) ---------- @@ -303,45 +323,90 @@ The name of the StateType ({3c7b83a0-0e42-47bf-9788-dde6aab5ceea}) of ThingClass - + Maximal charging current percentage changed The name of the EventType ({3c7b83a0-0e42-47bf-9788-dde6aab5ceea}) of ThingClass wallbox - - - Maximum possible charging current - The name of the ParamType (ThingClass: wallbox, EventType: maxPossibleChargingCurrent, ID: {08bb9872-8d63-49b0-a8ce-7a449341f13b}) + + + Maximal hardware charging current + The name of the ParamType (ThingClass: wallbox, EventType: maxChargingCurrentHardware, ID: {33e2ed95-f01e-44db-8156-34d124a8ecc8}) ---------- -The name of the StateType ({08bb9872-8d63-49b0-a8ce-7a449341f13b}) of ThingClass wallbox +The name of the StateType ({33e2ed95-f01e-44db-8156-34d124a8ecc8}) of ThingClass wallbox - - Maximum possible charging current changed - The name of the EventType ({08bb9872-8d63-49b0-a8ce-7a449341f13b}) of ThingClass wallbox + + Maximal hardware charging current changed + The name of the EventType ({33e2ed95-f01e-44db-8156-34d124a8ecc8}) of ThingClass wallbox - - - Model - The name of the ParamType (ThingClass: wallbox, EventType: model, ID: {c3fca233-95b9-4948-88c6-4c0f13cf53b1}) + + + Number of connected phases + The name of the ParamType (ThingClass: wallbox, EventType: phaseCount, ID: {6713b2e7-41b3-4596-a304-3065726bdbe4}) ---------- -The name of the StateType ({c3fca233-95b9-4948-88c6-4c0f13cf53b1}) of ThingClass wallbox +The name of the StateType ({6713b2e7-41b3-4596-a304-3065726bdbe4}) of ThingClass wallbox - - Model changed - The name of the EventType ({c3fca233-95b9-4948-88c6-4c0f13cf53b1}) of ThingClass wallbox + + Number of connected phases changed + The name of the EventType ({6713b2e7-41b3-4596-a304-3065726bdbe4}) of ThingClass wallbox - - - + + + Voltage phase A + The name of the ParamType (ThingClass: wallbox, EventType: voltagePhaseA, ID: {4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) +---------- +The name of the StateType ({4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) of ThingClass wallbox + + + + + Voltage phase A changed + The name of the EventType ({4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) of ThingClass wallbox + + + + + + Voltage phase B + The name of the ParamType (ThingClass: wallbox, EventType: voltagePhaseB, ID: {c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) +---------- +The name of the StateType ({c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) of ThingClass wallbox + + + + + Voltage phase B changed + The name of the EventType ({c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) of ThingClass wallbox + + + + + + Voltage phase C + The name of the ParamType (ThingClass: wallbox, EventType: voltagePhaseC, ID: {5f01e86c-0943-4849-a01a-db441916ebd5}) +---------- +The name of the StateType ({5f01e86c-0943-4849-a01a-db441916ebd5}) of ThingClass wallbox + + + + + Voltage phase C changed + The name of the EventType ({5f01e86c-0943-4849-a01a-db441916ebd5}) of ThingClass wallbox + + + + + + Output X2 The name of the ParamType (ThingClass: wallbox, ActionType: outputX2, ID: {96b2d176-6460-4109-8824-3af4679c6573}) ---------- @@ -351,14 +416,14 @@ The name of the StateType ({96b2d176-6460-4109-8824-3af4679c6573}) of ThingClass - + Output X2 changed The name of the EventType ({96b2d176-6460-4109-8824-3af4679c6573}) of ThingClass wallbox - - + + Plug state The name of the ParamType (ThingClass: wallbox, EventType: plugState, ID: {3b4d29f3-3101-47ad-90fd-269b6348783b}) ---------- @@ -366,14 +431,14 @@ The name of the StateType ({3b4d29f3-3101-47ad-90fd-269b6348783b}) of ThingClass - + Plug state changed The name of the EventType ({3b4d29f3-3101-47ad-90fd-269b6348783b}) of ThingClass wallbox - - + + Power consumption The name of the ParamType (ThingClass: wallbox, EventType: currentPower, ID: {7af9e93b-099d-4d9d-a480-9c0f66aecd8b}) ---------- @@ -381,14 +446,14 @@ The name of the StateType ({7af9e93b-099d-4d9d-a480-9c0f66aecd8b}) of ThingClass - + Power consumtion changed The name of the EventType ({7af9e93b-099d-4d9d-a480-9c0f66aecd8b}) of ThingClass wallbox - - + + Power factor The name of the ParamType (ThingClass: wallbox, EventType: powerFactor, ID: {889c3c9a-96b4-4408-bd9a-d79e36ed9296}) ---------- @@ -396,29 +461,26 @@ The name of the StateType ({889c3c9a-96b4-4408-bd9a-d79e36ed9296}) of ThingClass - + Power factor changed The name of the EventType ({889c3c9a-96b4-4408-bd9a-d79e36ed9296}) of ThingClass wallbox - - + + Product name + The name of the ParamType (ThingClass: wallbox, Type: thing, ID: {a996c698-4831-4977-8979-f76f78ac7da8}) + + + + Serial number - The name of the ParamType (ThingClass: wallbox, EventType: serialnumber, ID: {9a1b4316-ce01-4cd3-890f-a8c94b8b5029}) ----------- -The name of the StateType ({9a1b4316-ce01-4cd3-890f-a8c94b8b5029}) of ThingClass wallbox + The name of the ParamType (ThingClass: wallbox, Type: thing, ID: {45255155-318b-4204-8ce6-2c106a56286d}) - - Serial number changed - The name of the EventType ({9a1b4316-ce01-4cd3-890f-a8c94b8b5029}) of ThingClass wallbox - - - - - + + Session ID The name of the ParamType (ThingClass: wallbox, EventType: sessionId, ID: {1d30ce60-2ea0-450f-817e-5c88f59ebfbf}) ---------- @@ -426,14 +488,14 @@ The name of the StateType ({1d30ce60-2ea0-450f-817e-5c88f59ebfbf}) of ThingClass - + Session ID changed The name of the EventType ({1d30ce60-2ea0-450f-817e-5c88f59ebfbf}) of ThingClass wallbox - - + + Session energy The name of the ParamType (ThingClass: wallbox, EventType: sessionEnergy, ID: {8e277efe-21ef-4536-bfc0-901b32d44d7c}) ---------- @@ -441,14 +503,14 @@ The name of the StateType ({8e277efe-21ef-4536-bfc0-901b32d44d7c}) of ThingClass - + Session energy changed The name of the EventType ({8e277efe-21ef-4536-bfc0-901b32d44d7c}) of ThingClass wallbox - - + + Session time The name of the ParamType (ThingClass: wallbox, EventType: sessionTime, ID: {a6f35ea0-aaea-438b-b818-6d161762611e}) ---------- @@ -456,38 +518,38 @@ The name of the StateType ({a6f35ea0-aaea-438b-b818-6d161762611e}) of ThingClass - + Session time changed The name of the EventType ({a6f35ea0-aaea-438b-b818-6d161762611e}) of ThingClass wallbox - + Set charging enabled The name of the ActionType ({83ed0774-2a91-434d-b03c-d920d02f2981}) of ThingClass wallbox - + Set failsafe mode The name of the ActionType ({f1758c5c-2c02-41cb-93ec-b778a3c78d28}) of ThingClass wallbox - + Set maximal charging current The name of the ActionType ({593656f0-babf-4308-8767-68f34e10fb15}) of ThingClass wallbox - + Set output X2 The name of the ActionType ({96b2d176-6460-4109-8824-3af4679c6573}) of ThingClass wallbox - - + + System enabled The name of the ParamType (ThingClass: wallbox, EventType: systemEnabled, ID: {e5631593-f486-47cb-9951-b7597d0b769b}) ---------- @@ -495,14 +557,14 @@ The name of the StateType ({e5631593-f486-47cb-9951-b7597d0b769b}) of ThingClass - + System enabled changed The name of the EventType ({e5631593-f486-47cb-9951-b7597d0b769b}) of ThingClass wallbox - - + + Total energy consumed The name of the ParamType (ThingClass: wallbox, EventType: totalEnergyConsumed, ID: {41e179b3-29a2-43ec-b537-023a527081e8}) ---------- @@ -510,14 +572,14 @@ The name of the StateType ({41e179b3-29a2-43ec-b537-023a527081e8}) of ThingClass - + Total energy consumption changed The name of the EventType ({41e179b3-29a2-43ec-b537-023a527081e8}) of ThingClass wallbox - - + + Uptime The name of the ParamType (ThingClass: wallbox, EventType: uptime, ID: {3421ecf9-c95f-4dc1-ad0c-144e9b6ae056}) ---------- @@ -525,55 +587,10 @@ The name of the StateType ({3421ecf9-c95f-4dc1-ad0c-144e9b6ae056}) of ThingClass - + Uptime changed The name of the EventType ({3421ecf9-c95f-4dc1-ad0c-144e9b6ae056}) of ThingClass wallbox - - - - Voltage phase 1 - The name of the ParamType (ThingClass: wallbox, EventType: voltagePhase1, ID: {4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) ----------- -The name of the StateType ({4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) of ThingClass wallbox - - - - - Voltage phase 1 changed - The name of the EventType ({4a2d75d8-a3a0-4b40-9ca7-e8b6f11d0ef9}) of ThingClass wallbox - - - - - - Voltage phase 2 - The name of the ParamType (ThingClass: wallbox, EventType: voltagePhase2, ID: {c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) ----------- -The name of the StateType ({c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) of ThingClass wallbox - - - - - Voltage phase 2 changed - The name of the EventType ({c8344ca5-21ac-4cd1-8f4b-e5ed202c5862}) of ThingClass wallbox - - - - - - Voltage phase 3 - The name of the ParamType (ThingClass: wallbox, EventType: voltagePhase3, ID: {5f01e86c-0943-4849-a01a-db441916ebd5}) ----------- -The name of the StateType ({5f01e86c-0943-4849-a01a-db441916ebd5}) of ThingClass wallbox - - - - - Voltage phase 3 changed - The name of the EventType ({5f01e86c-0943-4849-a01a-db441916ebd5}) of ThingClass wallbox - -