From ef2a7b7b42474d8f3746b4f488d1b30e7a744491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 15 Oct 2026 15:51:14 +0200 Subject: [PATCH] EVerest: Add PCE EV11.4 charger --- everest/integrationplugineverest.cpp | 78 ++++-- everest/integrationplugineverest.json | 330 ++++++++++++++++++++++- everest/jsonrpc/everestevse.cpp | 6 +- everest/rfid/everestrfidutils.h | 5 + everest/tests/tst_everestconnection.cpp | 10 +- everest/tests/tst_rfidproviderclient.cpp | 20 ++ 6 files changed, 424 insertions(+), 25 deletions(-) diff --git a/everest/integrationplugineverest.cpp b/everest/integrationplugineverest.cpp index eb9331ca..494acd46 100644 --- a/everest/integrationplugineverest.cpp +++ b/everest/integrationplugineverest.cpp @@ -37,6 +37,16 @@ #include #include +static bool isRfidThingClass(const ThingClassId &thingClassId) +{ + return thingClassId == everestChargerAcRfidThingClassId || thingClassId == everestChargerPceThingClassId; +} + +static bool isAcThingClass(const ThingClassId &thingClassId) +{ + return thingClassId == everestChargerAcThingClassId || isRfidThingClass(thingClassId); +} + IntegrationPluginEverest::IntegrationPluginEverest() { @@ -50,8 +60,9 @@ void IntegrationPluginEverest::init() Thing *target = rfidTarget(); if (!target) return; - emit emitEvent(Event(everestChargerAcRfidTagDetectedEventTypeId, target->id(), - ParamList() << Param(everestChargerAcRfidTagDetectedEventCodeParamTypeId, code))); + const EventType eventType = target->thingClass().eventTypes().findByName("tagDetected"); + emit emitEvent(Event(eventType.id(), target->id(), + ParamList() << Param(eventType.paramTypes().findByName("code").id(), code))); }); m_rfidProvider->probe(); QFileInfo enableMqttFileInfo(NymeaSettings::settingsPath() + "/everest-mqtt"); @@ -424,6 +435,13 @@ void IntegrationPluginEverest::setupThing(ThingSetupInfo *info) if (available) { thing->setStateValue(everestConnectionApiVersionStateTypeId, connection->client()->apiVersion()); + const EverestJsonRpcClient::ChargerInfo chargerInfo = connection->client()->chargerInfo(); + foreach (Thing *child, myThings().filterByParentId(thing->id()).filterByThingClassId(everestChargerPceThingClassId)) { + child->setStateValue(everestChargerPceFirmwareVersionStateTypeId, chargerInfo.firmwareVersion); + if (child->paramValue(everestChargerPceThingSerialNumberParamTypeId).toString() != chargerInfo.serialNumber) + child->setParamValue(everestChargerPceThingSerialNumberParamTypeId, chargerInfo.serialNumber); + } + // Finish the bounded provider probe before choosing a new child's class. QPointer guardedThing(thing); QPointer guardedConnection(connection); @@ -479,6 +497,15 @@ void IntegrationPluginEverest::setupThing(ThingSetupInfo *info) ThingDescriptor descriptor(everestChargerDcThingClassId, evseInfo.id, evseInfo.description, thing->id()); descriptor.setParams(ParamList() << Param(everestChargerDcThingIndexParamTypeId, evseInfo.index)); descriptors.append(descriptor); + } else if (withRfid && everestIsPceVendor(connection->client()->chargerInfo().vendor)) { + const EverestJsonRpcClient::ChargerInfo chargerInfo = connection->client()->chargerInfo(); + const QString name = chargerInfo.model.isEmpty() ? evseInfo.id : chargerInfo.model; + qCDebug(dcEverest()) << "-> Adding new discovered PCE charger" << name << "on" << connection->client()->serverUrl(); + ThingDescriptor descriptor(everestChargerPceThingClassId, name, evseInfo.description, thing->id()); + descriptor.setParams(ParamList() + << Param(everestChargerPceThingIndexParamTypeId, evseInfo.index) + << Param(everestChargerPceThingSerialNumberParamTypeId, chargerInfo.serialNumber)); + descriptors.append(descriptor); } else { // If not a DC charger, default to AC qCDebug(dcEverest()) << "-> Adding new discovered AC charger on" << connection->client()->serverUrl(); @@ -511,7 +538,7 @@ void IntegrationPluginEverest::setupThing(ThingSetupInfo *info) connection->start(); return; - } else if (thing->thingClassId() == everestChargerAcThingClassId || thing->thingClassId() == everestChargerAcRfidThingClassId || thing->thingClassId() == everestChargerDcThingClassId) { + } else if (isAcThingClass(thing->thingClassId()) || thing->thingClassId() == everestChargerDcThingClassId) { Thing *parentThing = myThings().findById(thing->parentId()); EverestConnection *connection = m_everstConnections.value(parentThing); @@ -520,6 +547,9 @@ void IntegrationPluginEverest::setupThing(ThingSetupInfo *info) return; } + if (thing->thingClassId() == everestChargerPceThingClassId && connection->available()) + thing->setStateValue(everestChargerPceFirmwareVersionStateTypeId, connection->client()->chargerInfo().firmwareVersion); + info->finish(Thing::ThingErrorNoError); connection->addThing(thing); @@ -530,17 +560,18 @@ void IntegrationPluginEverest::setupThing(ThingSetupInfo *info) void IntegrationPluginEverest::executeAction(ThingActionInfo *info) { - if (info->thing()->thingClassId() == everestChargerAcRfidThingClassId) { - const auto actionId = info->action().actionTypeId(); - if (actionId == everestChargerAcRfidRfidEnrollmentActiveActionTypeId) { + if (isRfidThingClass(info->thing()->thingClassId())) { + ActionTypes actionTypes = info->thing()->thingClass().actionTypes(); + const ActionType actionType = actionTypes.findById(info->action().actionTypeId()); + if (actionType.name() == "rfidEnrollmentActive") { info->thing()->setStateValue("rfidEnrollmentActive", - info->action().paramValue(everestChargerAcRfidRfidEnrollmentActiveActionRfidEnrollmentActiveParamTypeId)); + info->action().paramValue(actionType.paramTypes().findByName("rfidEnrollmentActive").id())); info->finish(Thing::ThingErrorNoError); return; } - if (actionId == everestChargerAcRfidTagAcceptedActionTypeId || actionId == everestChargerAcRfidTagRejectedActionTypeId) { + if (actionType.name() == "tagAccepted" || actionType.name() == "tagRejected") { qCInfo(dcEverest()) << "RFID tag" - << (actionId == everestChargerAcRfidTagAcceptedActionTypeId ? "accepted" : "rejected") + << (actionType.name() == "tagAccepted" ? "accepted" : "rejected") << "for" << info->thing()->name() << "- charger feedback RPC is not yet available."; info->thing()->setStateValue("rfidEnrollmentActive", false); info->finish(Thing::ThingErrorNoError); @@ -598,7 +629,7 @@ void IntegrationPluginEverest::executeAction(ThingActionInfo *info) } return; - } else if (info->thing()->thingClassId() == everestChargerAcThingClassId || info->thing()->thingClassId() == everestChargerAcRfidThingClassId) { + } else if (isAcThingClass(info->thing()->thingClassId())) { Thing *thing = info->thing(); Thing *parentThing = myThings().findById(thing->parentId()); EverestConnection *connection = m_everstConnections.value(parentThing); @@ -618,8 +649,13 @@ void IntegrationPluginEverest::executeAction(ThingActionInfo *info) return; } - if (info->action().actionTypeId() == everestChargerAcPowerActionTypeId || info->action().actionTypeId() == everestChargerAcRfidPowerActionTypeId) { - bool power = info->action().paramValue(thing->thingClassId() == everestChargerAcRfidThingClassId ? everestChargerAcRfidPowerActionPowerParamTypeId : everestChargerAcPowerActionPowerParamTypeId).toBool(); + // Same action names across all AC thing classes, resolve by name + ActionTypes actionTypes = thing->thingClass().actionTypes(); + const ActionType actionType = actionTypes.findById(info->action().actionTypeId()); + const QVariant actionValue = info->action().paramValue(actionType.paramTypes().findByName(actionType.name()).id()); + + if (actionType.name() == "power") { + bool power = actionValue.toBool(); qCDebug(dcEverest()) << "Execute power action" << power; EverestJsonRpcReply *reply = evse->setChargingAllowed(power) ; connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater); @@ -641,8 +677,8 @@ void IntegrationPluginEverest::executeAction(ThingActionInfo *info) info->thing()->setStateValue(QStringLiteral("power"), power); info->finish(Thing::ThingErrorNoError); }); - } else if (info->action().actionTypeId() == everestChargerAcMaxChargingCurrentActionTypeId || info->action().actionTypeId() == everestChargerAcRfidMaxChargingCurrentActionTypeId) { - double current = info->action().paramValue(thing->thingClassId() == everestChargerAcRfidThingClassId ? everestChargerAcRfidMaxChargingCurrentActionMaxChargingCurrentParamTypeId : everestChargerAcMaxChargingCurrentActionMaxChargingCurrentParamTypeId).toDouble(); + } else if (actionType.name() == "maxChargingCurrent") { + double current = actionValue.toDouble(); qCDebug(dcEverest()) << "Execute action set max charging current" << current << "[A]"; EverestJsonRpcReply *reply = evse->setACChargingCurrent(current) ; connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater); @@ -664,8 +700,8 @@ void IntegrationPluginEverest::executeAction(ThingActionInfo *info) info->thing()->setStateValue(QStringLiteral("maxChargingCurrent"), current); info->finish(Thing::ThingErrorNoError); }); - } else if (info->action().actionTypeId() == everestChargerAcDesiredPhaseCountActionTypeId || info->action().actionTypeId() == everestChargerAcRfidDesiredPhaseCountActionTypeId) { - int phaseCount = info->action().paramValue(thing->thingClassId() == everestChargerAcRfidThingClassId ? everestChargerAcRfidDesiredPhaseCountActionDesiredPhaseCountParamTypeId : everestChargerAcDesiredPhaseCountActionDesiredPhaseCountParamTypeId).toInt(); + } else if (actionType.name() == "desiredPhaseCount") { + int phaseCount = actionValue.toInt(); qCDebug(dcEverest()) << "Execute action set phase count" << phaseCount; EverestJsonRpcReply *reply = evse->setACChargingPhaseCount(phaseCount); connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater); @@ -786,7 +822,7 @@ void IntegrationPluginEverest::thingRemoved(Thing *thing) } } else if (thing->thingClassId() == everestConnectionThingClassId) { m_everstConnections.take(thing)->deleteLater(); - } else if (thing->thingClassId() == everestChargerAcThingClassId || thing->thingClassId() == everestChargerAcRfidThingClassId || thing->thingClassId() == everestChargerDcThingClassId) { + } else if (isAcThingClass(thing->thingClassId()) || thing->thingClassId() == everestChargerDcThingClassId) { Thing *parentThing = myThings().findById(thing->parentId()); EverestConnection *connection = m_everstConnections.value(parentThing); if (!connection) @@ -811,7 +847,7 @@ Thing *IntegrationPluginEverest::rfidTarget() const if (!everestRfidEligible(connection->client()->serverUrl(), connection->client()->evseInfos())) continue; for (Thing *child : myThings().filterByParentId(it.key()->id())) { - if (child->thingClassId() != everestChargerAcRfidThingClassId + if (!isRfidThingClass(child->thingClassId()) || child->paramValue("index").toInt() != connection->client()->evseInfos().first().index) continue; if (target) @@ -825,6 +861,8 @@ Thing *IntegrationPluginEverest::rfidTarget() const void IntegrationPluginEverest::updateRfidAvailability() { Thing *target = rfidTarget(); - for (Thing *thing : myThings().filterByThingClassId(everestChargerAcRfidThingClassId)) - thing->setStateValue("rfidAvailable", thing == target && m_rfidProvider->ready()); + for (Thing *thing : myThings()) { + if (isRfidThingClass(thing->thingClassId())) + thing->setStateValue("rfidAvailable", thing == target && m_rfidProvider->ready()); + } } diff --git a/everest/integrationplugineverest.json b/everest/integrationplugineverest.json index 4a1d592d..acb778e7 100644 --- a/everest/integrationplugineverest.json +++ b/everest/integrationplugineverest.json @@ -1048,7 +1048,335 @@ } ] + }, + { + "name": "PcElectric", + "displayName": "PC Electric GmbH", + "id": "b365937b-f1d6-46bf-9ff1-e787373b8aa6", + "thingClasses": [ + { + "name": "everestChargerPce", + "displayName": "EV11.4 Wallbox R37 11kW", + "id": "75453003-9005-4b82-aaa9-41e05426c64c", + "setupMethod": "JustAdd", + "createMethods": [ + "auto" + ], + "interfaces": [ + "evchargerac", + "smartmeterconsumer", + "connectable", + "rfid" + ], + "paramTypes": [ + { + "id": "85db8ca5-b0cb-450d-89bd-4da9103da3f6", + "name": "index", + "displayName": "Index", + "type": "uint", + "defaultValue": 0 + }, + { + "id": "df601274-b5a9-4e4c-b390-601d51a64b75", + "name": "serialNumber", + "displayName": "Serial number", + "type": "QString", + "defaultValue": "", + "readOnly": true + } + ], + "settingsTypes": [], + "stateTypes": [ + { + "id": "7289ecfe-27e2-4e80-8b43-919226810b2e", + "name": "firmwareVersion", + "displayName": "Firmware version", + "type": "QString", + "defaultValue": "" + }, + { + "id": "247b7178-d208-4457-8725-675aa9710b05", + "name": "connected", + "displayName": "Connected", + "type": "bool", + "cached": false, + "defaultValue": false + }, + { + "id": "0cbf8be7-7937-4424-9628-7458f1684eec", + "name": "power", + "displayName": "Charging enabled", + "displayNameAction": "Enable or disable charging", + "type": "bool", + "defaultValue": false, + "writable": true + }, + { + "id": "ed1e72fd-2e2b-41d8-8135-1d72b44e8acd", + "name": "maxChargingCurrent", + "displayName": "Maximum charging current", + "displayNameAction": "Set maximum charging current", + "type": "double", + "unit": "Ampere", + "defaultValue": 6, + "minValue": 6, + "maxValue": 32, + "stepSize": 0.01, + "writable": true + }, + { + "id": "f71d4542-2d26-4ede-8dd1-4b1752f69dff", + "name": "pluggedIn", + "displayName": "Plugged in", + "type": "bool", + "defaultValue": false + }, + { + "id": "37cdab39-d18d-4905-8e8e-20e07aa9a1a9", + "name": "charging", + "displayName": "Charging", + "type": "bool", + "defaultValue": false + }, + { + "id": "db274123-6fbe-4a11-9db3-cbe9439a6dbe", + "name": "phaseCount", + "displayName": "Active phases", + "type": "uint", + "minValue": 1, + "maxValue": 3, + "defaultValue": 1 + }, + { + "id": "e1835179-1df1-480d-9d2a-528244f6bb0c", + "name": "desiredPhaseCount", + "displayName": "Desired phase count", + "displayNameAction": "Set desired phase count", + "type": "uint", + "minValue": 1, + "maxValue": 3, + "possibleValues": [ + 1, + 3 + ], + "writable": true, + "defaultValue": 3 + }, + { + "id": "9d4be811-cb50-4828-856d-3dea56e2a2a5", + "name": "state", + "displayName": "State", + "type": "QString", + "defaultValue": "", + "cached": false + }, + { + "id": "54c23843-03c2-4eb6-8374-bd383a2189e8", + "name": "totalEnergyConsumed", + "displayName": "Total energy", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0, + "cached": true + }, + { + "id": "11f62675-ce61-4e60-8104-5d0e20490982", + "name": "sessionEnergy", + "displayName": "Session energy", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 0, + "suggestLogging": true + }, + { + "id": "38f27852-0153-4f68-be73-765e18bb39df", + "name": "currentPower", + "displayName": "Current power", + "type": "double", + "unit": "Watt", + "defaultValue": 0, + "cached": false + }, + { + "id": "a77a5580-caa3-419d-ba2c-1035e85df0e4", + "name": "currentPowerPhaseA", + "displayName": "Current power phase A", + "displayNameEvent": "Current power phase A changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0, + "cached": false + }, + { + "id": "23876033-cf4d-48dc-8a99-4a8513f2808f", + "name": "currentPowerPhaseB", + "displayName": "Current power phase B", + "displayNameEvent": "Current power phase B changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0, + "cached": false + }, + { + "id": "7373304a-2d65-49b6-b551-9c047e823a2e", + "name": "currentPowerPhaseC", + "displayName": "Current power phase C", + "displayNameEvent": "Current power phase C changed", + "type": "double", + "unit": "Watt", + "defaultValue": 0, + "cached": false + }, + { + "id": "bf1ad69c-2b9c-4600-a7b0-a915230732d3", + "name": "currentPhaseA", + "displayName": "Phase A current", + "displayNameEvent": "Phase A current changed", + "type": "double", + "unit": "Ampere", + "defaultValue": 0, + "cached": false + }, + { + "id": "7d7ac0c9-5c75-4ba5-9b6b-417ea79c65d4", + "name": "currentPhaseB", + "displayName": "Phase B current", + "displayNameEvent": "Phase B current changed", + "type": "double", + "unit": "Ampere", + "defaultValue": 0, + "cached": false + }, + { + "id": "7ed089e8-9634-45d5-a627-69f7c32440a5", + "name": "currentPhaseC", + "displayName": "Phase C current", + "displayNameEvent": "Phase C current changed", + "type": "double", + "unit": "Ampere", + "defaultValue": 0, + "cached": false + }, + { + "id": "14d4c49f-3bc5-4e24-a4b9-219dc37cfe10", + "name": "voltagePhaseA", + "displayName": "Phase A voltage", + "displayNameEvent": "Phase A volatage changed", + "type": "double", + "unit": "Volt", + "defaultValue": 0, + "cached": false + }, + { + "id": "3da9556e-285b-494d-aafa-6189b2fa81a4", + "name": "voltagePhaseB", + "displayName": "Phase B voltage", + "displayNameEvent": "Phase B voltage changed", + "type": "double", + "unit": "Volt", + "defaultValue": 0, + "cached": false + }, + { + "id": "befca107-3f05-4fa2-9558-1ddcbd399844", + "name": "voltagePhaseC", + "displayName": "Phase C voltage", + "displayNameEvent": "Phase C voltage changed", + "type": "double", + "unit": "Volt", + "defaultValue": 0, + "cached": false + }, + { + "id": "78f2f4c6-e8f5-4805-8392-3713aac56e8e", + "name": "temperature", + "displayName": "Temperature", + "type": "double", + "unit": "DegreeCelsius", + "defaultValue": 0, + "cached": false + }, + { + "id": "50c41265-1b35-4d3a-99e2-42e55737d652", + "name": "fanSpeed", + "displayName": "Fan speed", + "type": "double", + "unit": "Rpm", + "defaultValue": 0, + "cached": false + }, + { + "id": "00c7ac1a-f931-46ce-a8ec-3247781adc23", + "name": "rfidAvailable", + "displayName": "RFID reader available", + "type": "bool", + "cached": false, + "defaultValue": false + }, + { + "id": "0bd96b5e-fec4-4ae4-81c2-17f23cb9a487", + "name": "authorizedUsername", + "displayName": "Authorized username", + "type": "QString", + "cached": false, + "defaultValue": "" + }, + { + "id": "f3e0fc14-387c-49d3-9e8d-ad7b3d18fc29", + "name": "authorizedDisplayName", + "displayName": "Authorized display name", + "type": "QString", + "cached": false, + "defaultValue": "" + }, + { + "id": "bd05d60a-1268-480f-aecd-b4c0ae37c513", + "name": "authorizedTagHash", + "displayName": "Authorized tag hash", + "type": "QString", + "cached": false, + "defaultValue": "" + }, + { + "id": "9c2eb309-5bf0-48fb-b4e6-7315a02a9a39", + "name": "rfidEnrollmentActive", + "displayName": "RFID enrollment active", + "displayNameAction": "Set RFID enrollment mode", + "type": "bool", + "writable": true, + "cached": false, + "defaultValue": false + } + ], + "actionTypes": [ + { + "id": "bb0ef68a-8a63-4604-8bda-5eec2dcf75c1", + "name": "tagAccepted", + "displayName": "Accept RFID tag" + }, + { + "id": "65a053b0-f40e-49ec-83c5-e6da8a2fdeb1", + "name": "tagRejected", + "displayName": "Reject RFID tag" + } + ], + "eventTypes": [ + { + "id": "d0666281-1526-4d3c-8cce-f5d701768013", + "name": "tagDetected", + "displayName": "RFID tag detected", + "paramTypes": [ + { + "id": "942c39f5-858d-4e56-85d6-819d4186caf9", + "name": "code", + "displayName": "Tag code", + "type": "QString" + } + ] + } + ] + } + ] } ] } - diff --git a/everest/jsonrpc/everestevse.cpp b/everest/jsonrpc/everestevse.cpp index 5f24002a..c1c6462a 100644 --- a/everest/jsonrpc/everestevse.cpp +++ b/everest/jsonrpc/everestevse.cpp @@ -211,7 +211,7 @@ void EverestEvse::initialize() void EverestEvse::processEvseStatus() { - if ((m_thing->thingClassId() == everestChargerAcThingClassId || m_thing->thingClassId() == everestChargerAcRfidThingClassId)) { + if ((m_thing->thingClassId() == everestChargerAcThingClassId || m_thing->thingClassId() == everestChargerAcRfidThingClassId || m_thing->thingClassId() == everestChargerPceThingClassId)) { m_thing->setStateValue(QStringLiteral("power"), m_evseStatus.chargingAllowed); m_thing->setStateValue(QStringLiteral("sessionEnergy"), m_evseStatus.chargedEnergyWh / 1000.0); m_thing->setStateValue(QStringLiteral("state"), m_evseStatus.evseStateString); @@ -248,7 +248,7 @@ void EverestEvse::processEvseStatus() void EverestEvse::processHardwareCapabilities() { - if ((m_thing->thingClassId() == everestChargerAcThingClassId || m_thing->thingClassId() == everestChargerAcRfidThingClassId)) { + if ((m_thing->thingClassId() == everestChargerAcThingClassId || m_thing->thingClassId() == everestChargerAcRfidThingClassId || m_thing->thingClassId() == everestChargerPceThingClassId)) { if (!m_hardwareCapabilities.phaseSwitchDuringCharging) { // Only option left is set the desired phase count to 3, force that value m_thing->setStatePossibleValues(QStringLiteral("desiredPhaseCount"), { 3 }); @@ -265,7 +265,7 @@ void EverestEvse::processHardwareCapabilities() void EverestEvse::processMeterData() { - if ((m_thing->thingClassId() == everestChargerAcThingClassId || m_thing->thingClassId() == everestChargerAcRfidThingClassId)) { + if ((m_thing->thingClassId() == everestChargerAcThingClassId || m_thing->thingClassId() == everestChargerAcRfidThingClassId || m_thing->thingClassId() == everestChargerPceThingClassId)) { m_thing->setStateValue(QStringLiteral("currentPower"), m_meterData.powerTotal); diff --git a/everest/rfid/everestrfidutils.h b/everest/rfid/everestrfidutils.h index 395adbff..b26cee79 100644 --- a/everest/rfid/everestrfidutils.h +++ b/everest/rfid/everestrfidutils.h @@ -31,4 +31,9 @@ inline bool everestRfidEligible(const QUrl &url, const QListchargerInfo(); + QCOMPARE(chargerInfo.vendor, QString("PCE")); + QCOMPARE(chargerInfo.model, QString("EV11.4 Wallbox R37 11kW")); + QCOMPARE(chargerInfo.serialNumber, QString("1234567890")); + QCOMPARE(chargerInfo.firmwareVersion, QString("0.10.9")); } void noReconnectWhenStopped() diff --git a/everest/tests/tst_rfidproviderclient.cpp b/everest/tests/tst_rfidproviderclient.cpp index 16330180..72fab481 100644 --- a/everest/tests/tst_rfidproviderclient.cpp +++ b/everest/tests/tst_rfidproviderclient.cpp @@ -145,6 +145,26 @@ private slots: } QCOMPARE(everestRfidEligible(QUrl(url), topology), eligible); } + + void pceVendor_data() + { + QTest::addColumn("vendor"); + QTest::addColumn("pce"); + QTest::newRow("upper") << "PCE" << true; + QTest::newRow("lower") << "pce" << true; + QTest::newRow("mixed-whitespace") << " Pce " << true; + QTest::newRow("prefix") << "PCEX" << false; + QTest::newRow("full-name") << "PC Electric Gesellschaft m.b.H." << false; + QTest::newRow("other") << "Chargebyte" << false; + QTest::newRow("empty") << "" << false; + } + + void pceVendor() + { + QFETCH(QString, vendor); + QFETCH(bool, pce); + QCOMPARE(everestIsPceVendor(vendor), pce); + } }; QTEST_GUILESS_MAIN(TestRfidProviderClient) #include "tst_rfidproviderclient.moc"