mirror of
https://github.com/nymea/nymea-plugins.git
synced 2026-06-30 22:09:34 +02:00
Add EVerest DC charger and extend the RpcApi regarding DC charging
This commit is contained in:
parent
2dbab9be5d
commit
cd61b5e8bb
@ -408,13 +408,17 @@ void IntegrationPluginEverest::setupThing(ThingSetupInfo *info)
|
||||
if (available) {
|
||||
thing->setStateValue(everestConnectionApiVersionStateTypeId, connection->client()->apiVersion());
|
||||
|
||||
// Sync things with availabe EvseInfos
|
||||
// Sync things with availabe EvseInfos from this connection
|
||||
|
||||
QList<int> indexList;
|
||||
ThingDescriptors descriptors;
|
||||
qCDebug(dcEverest()) << "The client is now available, synching things...";
|
||||
|
||||
// First check if we have a thing for each index, if not, create the thing for it
|
||||
foreach (const EverestJsonRpcClient::EVSEInfo &evseInfo, connection->client()->evseInfos()) {
|
||||
|
||||
// FIXME: somehow we need to now if this evse is AC or DC in order to spawn the right child thingclass.
|
||||
// Collect all EVSE index in onder to check later if we have a thing for a dissapeard index.
|
||||
indexList.append(evseInfo.index);
|
||||
|
||||
// Check if we already have a child device for this index
|
||||
bool alreadyAdded = false;
|
||||
@ -427,19 +431,42 @@ void IntegrationPluginEverest::setupThing(ThingSetupInfo *info)
|
||||
}
|
||||
|
||||
if (!alreadyAdded) {
|
||||
qCDebug(dcEverest()) << "-> Adding new discovered AC charger on" << connection->client()->serverUrl();
|
||||
ThingDescriptor descriptor(everestChargerAcThingClassId, evseInfo.id, evseInfo.description, thing->id());
|
||||
descriptor.setParams(ParamList() << Param(everestChargerAcThingIndexParamTypeId, evseInfo.index));
|
||||
descriptors.append(descriptor);
|
||||
if (evseInfo.supportedEnergyTransferModes.contains(EverestJsonRpcClient::EnergyTransferModeDC)
|
||||
|| evseInfo.supportedEnergyTransferModes.contains(EverestJsonRpcClient::EnergyTransferModeDC_ACDP)
|
||||
|| evseInfo.supportedEnergyTransferModes.contains(EverestJsonRpcClient::EnergyTransferModeDC_ACDP_BPT)
|
||||
|| evseInfo.supportedEnergyTransferModes.contains(EverestJsonRpcClient::EnergyTransferModeDC_BPT)
|
||||
|| evseInfo.supportedEnergyTransferModes.contains(EverestJsonRpcClient::EnergyTransferModeDC_combo_core)
|
||||
|| evseInfo.supportedEnergyTransferModes.contains(EverestJsonRpcClient::EnergyTransferModeDC_core)
|
||||
|| evseInfo.supportedEnergyTransferModes.contains(EverestJsonRpcClient::EnergyTransferModeDC_extended)
|
||||
|| evseInfo.supportedEnergyTransferModes.contains(EverestJsonRpcClient::EnergyTransferModeDC_unique)) {
|
||||
|
||||
qCDebug(dcEverest()) << "-> Adding new discovered DC charger on" << connection->client()->serverUrl();
|
||||
ThingDescriptor descriptor(everestChargerDcThingClassId, evseInfo.id, evseInfo.description, thing->id());
|
||||
descriptor.setParams(ParamList() << Param(everestChargerDcThingIndexParamTypeId, evseInfo.index));
|
||||
descriptors.append(descriptor);
|
||||
} else {
|
||||
// If not a DC charger, default to AC
|
||||
qCDebug(dcEverest()) << "-> Adding new discovered AC charger on" << connection->client()->serverUrl();
|
||||
ThingDescriptor descriptor(everestChargerAcThingClassId, evseInfo.id, evseInfo.description, thing->id());
|
||||
descriptor.setParams(ParamList() << Param(everestChargerAcThingIndexParamTypeId, evseInfo.index));
|
||||
descriptors.append(descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: evaluate if any thing dissapeared
|
||||
// Check if we have things for an index which does not exist for this connection any more
|
||||
QList<ThingId> thingIdsToRemove;
|
||||
foreach (Thing *childThing, myThings().filterByParentId(thing->id())) {
|
||||
int thingIndex = childThing->paramValue("index").toInt();
|
||||
if (!indexList.contains(thingIndex)) {
|
||||
qCDebug(dcEverest()) << "Removing thing" << childThing->name() << "because the index" << thingIndex << "does not exist any more on this connection.";
|
||||
emit autoThingDisappeared(childThing->id());
|
||||
}
|
||||
}
|
||||
|
||||
if (!descriptors.isEmpty()) {
|
||||
emit autoThingsAppeared(descriptors);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@ -447,7 +474,7 @@ void IntegrationPluginEverest::setupThing(ThingSetupInfo *info)
|
||||
|
||||
connection->start();
|
||||
return;
|
||||
} else if (thing->thingClassId() == everestChargerAcThingClassId) {
|
||||
} else if (thing->thingClassId() == everestChargerAcThingClassId || thing->thingClassId() == everestChargerDcThingClassId) {
|
||||
|
||||
Thing *parentThing = myThings().findById(thing->parentId());
|
||||
EverestConnection *connection = m_everstConnections.value(parentThing);
|
||||
@ -601,12 +628,82 @@ void IntegrationPluginEverest::executeAction(ThingActionInfo *info)
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
info->thing()->setStateValue(everestChargerAcDesiredPhaseCountStateTypeId, phaseCount);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (info->thing()->thingClassId() == everestChargerDcThingClassId) {
|
||||
Thing *thing = info->thing();
|
||||
Thing *parentThing = myThings().findById(thing->parentId());
|
||||
EverestConnection *connection = m_everstConnections.value(parentThing);
|
||||
if (!connection) {
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!thing->stateValue(everestChargerDcConnectedStateTypeId).toBool()) {
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
|
||||
EverestEvse *evse = connection->getEvse(thing);
|
||||
if (!evse) {
|
||||
info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->action().actionTypeId() == everestChargerDcPowerActionTypeId) {
|
||||
bool power = info->action().paramValue(everestChargerDcPowerActionPowerParamTypeId).toBool();
|
||||
qCDebug(dcEverest()) << "Execute power action" << power;
|
||||
EverestJsonRpcReply *reply = evse->setChargingAllowed(power) ;
|
||||
connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater);
|
||||
connect(reply, &EverestJsonRpcReply::finished, this, [info, reply, power](){
|
||||
if (reply->error()) {
|
||||
qCWarning(dcEverest()) << "Execute action reply finished with error" << reply->error();
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap result = reply->response().value("result").toMap();
|
||||
EverestJsonRpcClient::ResponseError error = EverestJsonRpcClient::parseResponseError(result.value("error").toString());
|
||||
if (error) {
|
||||
qCWarning(dcEverest()) << "Execute action reply finished with an error" << reply->method() << error;
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcEverest()) << "Execute power action finished successfully" << reply->method() << error;
|
||||
info->thing()->setStateValue(everestChargerDcPowerStateTypeId, power);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
} else if (info->action().actionTypeId() == everestChargerDcChargingPowerActionTypeId) {
|
||||
double chargingPower = info->action().paramValue(everestChargerDcChargingPowerActionChargingPowerParamTypeId).toDouble();
|
||||
qCDebug(dcEverest()) << "Execute action set max charging power" << chargingPower << "[W]";
|
||||
EverestJsonRpcReply *reply = evse->setDCChargingPower(chargingPower) ;
|
||||
connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater);
|
||||
connect(reply, &EverestJsonRpcReply::finished, this, [info, reply, chargingPower](){
|
||||
if (reply->error()) {
|
||||
qCWarning(dcEverest()) << "Execute action reply finished with error" << reply->error();
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap result = reply->response().value("result").toMap();
|
||||
EverestJsonRpcClient::ResponseError error = EverestJsonRpcClient::parseResponseError(result.value("error").toString());
|
||||
if (error) {
|
||||
qCWarning(dcEverest()) << "Execute action reply finished with an error" << reply->method() << error;
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcEverest()) << "Execute power set chargingn power finished successfully" << reply->method() << error;
|
||||
info->thing()->setStateValue(everestChargerDcChargingPowerStateTypeId, chargingPower);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -634,7 +731,7 @@ void IntegrationPluginEverest::thingRemoved(Thing *thing)
|
||||
}
|
||||
} else if (thing->thingClassId() == everestConnectionThingClassId) {
|
||||
m_everstConnections.take(thing)->deleteLater();
|
||||
} else if (thing->thingClassId() == everestChargerAcThingClassId) {
|
||||
} else if (thing->thingClassId() == everestChargerAcThingClassId || thing->thingClassId() == everestChargerDcThingClassId) {
|
||||
Thing *parentThing = myThings().findById(thing->parentId());
|
||||
EverestConnection *connection = m_everstConnections.value(parentThing);
|
||||
if (!connection)
|
||||
@ -643,5 +740,3 @@ void IntegrationPluginEverest::thingRemoved(Thing *thing)
|
||||
connection->removeThing(thing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -181,7 +181,7 @@
|
||||
"setupMethod": "JustAdd",
|
||||
"createMethods": [ "Discovery", "User" ],
|
||||
"interfaces": [ "gateway", "networkdevice" ],
|
||||
"providedInterfaces": [ "evchargerac" ],
|
||||
"providedInterfaces": [ "evchargerac", "evchargerdc" ],
|
||||
"discoveryParamTypes": [
|
||||
{
|
||||
"id": "cd1cfca6-22f7-4d31-a95f-f642e0e1470f",
|
||||
@ -480,7 +480,266 @@
|
||||
"eventTypes": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "everestChargerDc",
|
||||
"displayName": "EVerest charger DC",
|
||||
"id": "b31e14dd-43e0-4278-b517-d50afd6806ec",
|
||||
"createMethods": ["auto"],
|
||||
"interfaces": [ "evchargerdc", "connectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "4a3e03ed-44ea-4a32-9f7f-b4e6b1647921",
|
||||
"name": "index",
|
||||
"displayName": "Index",
|
||||
"type": "uint",
|
||||
"defaultValue": 0
|
||||
}
|
||||
],
|
||||
"settingsTypes": [],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "e02d8186-a678-4e5a-aea7-460109617a02",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"type": "bool",
|
||||
"defaultValue": true
|
||||
},
|
||||
{
|
||||
"id": "c7b313bf-d12d-434f-b754-d0ada7209fe5",
|
||||
"name": "power",
|
||||
"displayName": "Charging enabled",
|
||||
"displayNameAction": "Enable/disable charging",
|
||||
"type": "bool",
|
||||
"defaultValue": true,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "4dc2b506-990b-4e84-8a4b-444aba489ac2",
|
||||
"name": "currentPower",
|
||||
"displayName": "Current measured power",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "4c1415c2-bb2e-412a-9861-12ad8daa9051",
|
||||
"name": "chargingPower",
|
||||
"displayName": "Charging power",
|
||||
"displayNameAction": "Set charging power",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "aa130c3c-56a5-4a23-8802-7bee78dee6d2",
|
||||
"name": "chargingCapabilities",
|
||||
"displayName": "Charging capabilities",
|
||||
"type": "QString",
|
||||
"possibleValues": ["charging", "discharging", "bidirectional"],
|
||||
"defaultValue": "charging"
|
||||
},
|
||||
{
|
||||
"id": "2e17f569-807e-4906-8748-0bd094cfd5d2",
|
||||
"name": "chargingState",
|
||||
"displayName": "Charging state",
|
||||
"type": "QString",
|
||||
"possibleValues": ["idle", "charging", "discharging"],
|
||||
"defaultValue": "idle"
|
||||
},
|
||||
{
|
||||
"id": "bd8fa91f-0bf6-474c-b6bb-3d68d466d379",
|
||||
"name": "charging",
|
||||
"displayName": "Charging",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "7cb1984a-c172-4f25-94f8-487dcd7881ab",
|
||||
"name": "state",
|
||||
"displayName": "State",
|
||||
"type": "QString",
|
||||
"defaultValue": "",
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "a4597881-958b-4b5b-87aa-941820fef84d",
|
||||
"name": "sessionEnergy",
|
||||
"displayName": "Session energy",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0,
|
||||
"suggestLogging": true
|
||||
},
|
||||
{
|
||||
"id": "7dedd1a2-6c99-4c85-8511-319f45b4fc56",
|
||||
"name": "minChargingPower",
|
||||
"displayName": "Minimal charging power",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 100
|
||||
},
|
||||
{
|
||||
"id": "e1f1936e-e038-4820-bb7c-46404859ae42",
|
||||
"name": "maxChargingPower",
|
||||
"displayName": "Maximal charging power",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 50000
|
||||
},
|
||||
{
|
||||
"id": "60ce60bd-0a6b-4f76-b51b-c6d342b2a277",
|
||||
"name": "minDischargingPower",
|
||||
"displayName": "Minimal discharging power",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": -100
|
||||
},
|
||||
{
|
||||
"id": "5bd483e4-aae6-4e53-b208-d7caa5b7fbc6",
|
||||
"name": "maxDischargingPower",
|
||||
"displayName": "Maximal discharging power",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": -50000
|
||||
},
|
||||
{
|
||||
"id": "020e30ce-e3db-41ad-8066-a819ac1d4bd5",
|
||||
"name": "pluggedIn",
|
||||
"displayName": "Car is plugged in",
|
||||
"type": "bool",
|
||||
"defaultValue": true,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "bdb910aa-63c0-4af4-8f21-f9e2de601928",
|
||||
"name": "currentPowerPhaseA",
|
||||
"displayName": "Current power phase A",
|
||||
"displayNameEvent": "Current power phase A changed",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0.00,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "e1e5142f-e8a3-4fac-9ebd-ec467a1cdac5",
|
||||
"name": "currentPowerPhaseB",
|
||||
"displayName": "Current power phase B",
|
||||
"displayNameEvent": "Current power phase B changed",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0.00,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "d0ca61a1-057c-4fd2-bf91-0ba9c4fcff9e",
|
||||
"name": "currentPowerPhaseC",
|
||||
"displayName": "Current power phase C",
|
||||
"displayNameEvent": "Current power phase C changed",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0.00,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "4d49dbb6-6ca7-4ecd-949f-d2d5b3ebee04",
|
||||
"name": "currentPhaseA",
|
||||
"displayName": "Phase A current",
|
||||
"displayNameEvent": "Phase A current changed",
|
||||
"type": "double",
|
||||
"unit": "Ampere",
|
||||
"defaultValue": 0.00,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "41febbb0-5265-4aa9-aa91-1ed9dbd5e35a",
|
||||
"name": "currentPhaseB",
|
||||
"displayName": "Phase B current",
|
||||
"displayNameEvent": "Phase B current changed",
|
||||
"type": "double",
|
||||
"unit": "Ampere",
|
||||
"defaultValue": 0.00,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "c7d1832b-b0a7-4cbe-b7f7-ee91732f5a45",
|
||||
"name": "currentPhaseC",
|
||||
"displayName": "Phase C current",
|
||||
"displayNameEvent": "Phase C current changed",
|
||||
"type": "double",
|
||||
"unit": "Ampere",
|
||||
"defaultValue": 0.00,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "3a2aced4-e9aa-4e5a-b96b-68978f5d5c3b",
|
||||
"name": "voltagePhaseA",
|
||||
"displayName": "Phase A voltage",
|
||||
"displayNameEvent": "Phase A volatage changed",
|
||||
"type": "double",
|
||||
"unit": "Volt",
|
||||
"defaultValue": 0.00,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "97273965-dc8f-4be9-a6c5-1eeb5bebc3ad",
|
||||
"name": "voltagePhaseB",
|
||||
"displayName": "Phase B voltage",
|
||||
"displayNameEvent": "Phase B voltage changed",
|
||||
"type": "double",
|
||||
"unit": "Volt",
|
||||
"defaultValue": 0.00,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "2a62c222-ad9c-42bc-807a-d4e345d46a76",
|
||||
"name": "voltagePhaseC",
|
||||
"displayName": "Phase C voltage",
|
||||
"displayNameEvent": "Phase C voltage changed",
|
||||
"type": "double",
|
||||
"unit": "Volt",
|
||||
"defaultValue": 0.00,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "9bfc98a0-92f7-4b46-b390-72d8da721778",
|
||||
"name": "totalEnergyConsumed",
|
||||
"displayName": "Total consumed energy",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "782e6a0c-62e5-4b36-947c-c66ee1fa1737",
|
||||
"name": "totalEnergyProduced",
|
||||
"displayName": "Total returned energy",
|
||||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"id": "d526c751-51e0-4c69-a88e-ae33db38b182",
|
||||
"name": "temperature",
|
||||
"displayName": "Temperature",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0.0,
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"id": "dda0fdfd-a21d-46ee-85b0-8e9e469af3d3",
|
||||
"name": "fanSpeed",
|
||||
"displayName": "Fan speed",
|
||||
"type": "double",
|
||||
"unit": "Rpm",
|
||||
"defaultValue": 0,
|
||||
"cached": false
|
||||
}
|
||||
],
|
||||
"actionTypes": [ ]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@ -106,6 +106,9 @@ void EverestConnection::setMonitor(NetworkDeviceMonitor *monitor)
|
||||
if (m_monitor) {
|
||||
connect(m_monitor, &NetworkDeviceMonitor::reachableChanged, this, &EverestConnection::onMonitorReachableChanged);
|
||||
}
|
||||
|
||||
if (m_monitor->reachable())
|
||||
onMonitorReachableChanged(true);
|
||||
}
|
||||
|
||||
void EverestConnection::start()
|
||||
|
||||
@ -96,13 +96,17 @@ EverestJsonRpcReply *EverestEvse::setACChargingPhaseCount(int phaseCount)
|
||||
return m_client->evseSetACChargingPhaseCount(m_index, phaseCount);
|
||||
}
|
||||
|
||||
EverestJsonRpcReply *EverestEvse::setDCChargingPower(double chargingPower)
|
||||
{
|
||||
return m_client->evseSetDCChargingPower(m_index, chargingPower);
|
||||
}
|
||||
|
||||
void EverestEvse::initialize()
|
||||
{
|
||||
qCDebug(dcEverest()) << "Evse: Starting to initialize the data for" << m_thing->name();
|
||||
|
||||
// Fetch all initial data for this device, once done we get notifications on data changes
|
||||
|
||||
|
||||
EverestJsonRpcReply *reply = m_client->evseGetInfo(m_index);
|
||||
connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater);
|
||||
connect(reply, &EverestJsonRpcReply::finished, this, [this, reply](){
|
||||
@ -166,6 +170,7 @@ void EverestEvse::initialize()
|
||||
// Store data, thy will be processed once all replies arrived
|
||||
m_evseStatus = EverestJsonRpcClient::parseEvseStatus(result.value("status").toMap());
|
||||
|
||||
|
||||
EverestJsonRpcReply *reply = m_client->evseGetMeterData(m_index);
|
||||
connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater);
|
||||
connect(reply, &EverestJsonRpcReply::finished, this, [this, reply](){
|
||||
@ -219,6 +224,25 @@ void EverestEvse::processEvseStatus()
|
||||
if (m_evseStatus.acChargeParameters.maxCurrent > 0)
|
||||
m_thing->setStateValue(everestChargerAcMaxChargingCurrentStateTypeId, m_evseStatus.acChargeParameters.maxCurrent);
|
||||
|
||||
} else if (m_thing->thingClassId() == everestChargerDcThingClassId) {
|
||||
|
||||
m_thing->setStateValue(everestChargerDcPowerStateTypeId, m_evseStatus.chargingAllowed);
|
||||
m_thing->setStateValue(everestChargerDcSessionEnergyStateTypeId, m_evseStatus.chargedEnergyWh / 1000.0);
|
||||
m_thing->setStateValue(everestChargerDcStateStateTypeId, m_evseStatus.evseStateString);
|
||||
m_thing->setStateValue(everestChargerDcChargingStateTypeId, m_evseStatus.evseState == EverestJsonRpcClient::EvseStateCharging);
|
||||
m_thing->setStateValue(everestChargerDcPluggedInStateTypeId, m_evseStatus.evseState != EverestJsonRpcClient::EvseStateUnplugged);
|
||||
|
||||
|
||||
if (m_evseStatus.evseState == EverestJsonRpcClient::EvseStateCharging) {
|
||||
if (m_thing->stateValue(everestChargerDcCurrentPowerStateTypeId).toDouble() > 0) {
|
||||
m_thing->setStateValue(everestChargerDcChargingStateStateTypeId, "charging");
|
||||
} else {
|
||||
m_thing->setStateValue(everestChargerDcChargingStateStateTypeId, "discharging");
|
||||
}
|
||||
} else {
|
||||
m_thing->setStateValue(everestChargerDcChargingStateStateTypeId, "idle");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,5 +282,23 @@ void EverestEvse::processMeterData()
|
||||
m_thing->setStateValue(everestChargerAcVoltagePhaseCStateTypeId, m_meterData.voltageL3);
|
||||
|
||||
m_thing->setStateValue(everestChargerAcTotalEnergyConsumedStateTypeId, m_meterData.energyImportedTotal / 1000.0);
|
||||
} else if (m_thing->thingClassId() == everestChargerDcThingClassId) {
|
||||
|
||||
m_thing->setStateValue(everestChargerDcCurrentPowerStateTypeId, m_meterData.powerTotal);
|
||||
|
||||
m_thing->setStateValue(everestChargerDcCurrentPowerPhaseAStateTypeId, m_meterData.powerL1);
|
||||
m_thing->setStateValue(everestChargerDcCurrentPowerPhaseBStateTypeId, m_meterData.powerL2);
|
||||
m_thing->setStateValue(everestChargerDcCurrentPowerPhaseCStateTypeId, m_meterData.powerL3);
|
||||
|
||||
m_thing->setStateValue(everestChargerDcCurrentPhaseAStateTypeId, m_meterData.currentL1);
|
||||
m_thing->setStateValue(everestChargerDcCurrentPhaseBStateTypeId, m_meterData.currentL2);
|
||||
m_thing->setStateValue(everestChargerDcCurrentPhaseCStateTypeId, m_meterData.currentL3);
|
||||
|
||||
m_thing->setStateValue(everestChargerDcVoltagePhaseAStateTypeId, m_meterData.voltageL1);
|
||||
m_thing->setStateValue(everestChargerDcVoltagePhaseBStateTypeId, m_meterData.voltageL2);
|
||||
m_thing->setStateValue(everestChargerDcVoltagePhaseCStateTypeId, m_meterData.voltageL3);
|
||||
|
||||
m_thing->setStateValue(everestChargerDcTotalEnergyConsumedStateTypeId, m_meterData.energyImportedTotal / 1000.0);
|
||||
m_thing->setStateValue(everestChargerDcTotalEnergyProducedStateTypeId, m_meterData.energyExportedTotal/ 1000.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ public:
|
||||
EverestJsonRpcReply *setChargingAllowed(bool allowed);
|
||||
EverestJsonRpcReply *setACChargingCurrent(double current);
|
||||
EverestJsonRpcReply *setACChargingPhaseCount(int phaseCount);
|
||||
EverestJsonRpcReply *setDCChargingPower(double chargingPower);
|
||||
|
||||
private:
|
||||
EverestJsonRpcClient *m_client = nullptr;
|
||||
|
||||
@ -239,6 +239,24 @@ EverestJsonRpcReply *EverestJsonRpcClient::evseSetACChargingPhaseCount(int evseI
|
||||
return reply;
|
||||
}
|
||||
|
||||
EverestJsonRpcReply *EverestJsonRpcClient::evseSetDCChargingPower(int evseIndex, double chargingPower)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("evse_index", evseIndex);
|
||||
params.insert("max_power", chargingPower);
|
||||
|
||||
EverestJsonRpcReply *reply = createReply("EVSE.SetDCChargingPower", params);
|
||||
qCDebug(dcEverest()) << "Calling" << reply->method() << params;
|
||||
sendRequest(reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
EverestJsonRpcClient::EnergyTransferMode EverestJsonRpcClient::parseEnergyTransferMode(const QString &energyTransferModeString)
|
||||
{
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<EnergyTransferMode>();
|
||||
return static_cast<EnergyTransferMode>(metaEnum.keyToValue(QString("EnergyTransferMode").append(energyTransferModeString).toUtf8()));
|
||||
}
|
||||
|
||||
EverestJsonRpcClient::ResponseError EverestJsonRpcClient::parseResponseError(const QString &responseErrorString)
|
||||
{
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<ResponseError>();
|
||||
@ -272,6 +290,9 @@ EverestJsonRpcClient::EVSEInfo EverestJsonRpcClient::parseEvseInfo(const QVarian
|
||||
foreach (const QVariant &connectorInfoVariant, evseInfoMap.value("available_connectors").toList()) {
|
||||
evseInfo.availableConnectors.append(parseConnectorInfo(connectorInfoVariant.toMap()));
|
||||
}
|
||||
foreach (const QVariant &energyTransferModeVariant, evseInfoMap.value("supported_energy_transfer_modes").toList()) {
|
||||
evseInfo.supportedEnergyTransferModes.append(parseEnergyTransferMode(energyTransferModeVariant.toString()));
|
||||
}
|
||||
return evseInfo;
|
||||
}
|
||||
|
||||
@ -310,6 +331,10 @@ EverestJsonRpcClient::EVSEStatus EverestJsonRpcClient::parseEvseStatus(const QVa
|
||||
if (evseStatusMap.contains("ac_charge_param"))
|
||||
evseStatus.acChargeParameters = EverestJsonRpcClient::parseACChargeParameters(evseStatusMap.value("ac_charge_param").toMap());
|
||||
|
||||
// optional
|
||||
if (evseStatusMap.contains("display_parameters"))
|
||||
evseStatus.displayParameters = EverestJsonRpcClient::parseDisplayParameters(evseStatusMap.value("display_parameters").toMap());
|
||||
|
||||
return evseStatus;
|
||||
}
|
||||
|
||||
@ -403,6 +428,39 @@ EverestJsonRpcClient::MeterData EverestJsonRpcClient::parseMeterData(const QVari
|
||||
return meterData;
|
||||
}
|
||||
|
||||
EverestJsonRpcClient::DisplayParameters EverestJsonRpcClient::parseDisplayParameters(const QVariantMap &displayParametersMap)
|
||||
{
|
||||
// As of now (EVerest 2026.02.0) the display paraters are not completely defined yet and marked as incomplete.
|
||||
// Treat all properties as optional until the object is specified upstream.
|
||||
|
||||
DisplayParameters displayParameters;
|
||||
if (displayParametersMap.contains("start_soc")) {
|
||||
displayParameters.startSoc = displayParametersMap.value("start_soc").toInt() ;
|
||||
} else if (displayParametersMap.contains("present_soc")) {
|
||||
displayParameters.presentSoc = displayParametersMap.value("present_soc").toInt();
|
||||
} else if (displayParametersMap.contains("minimum_soc")) {
|
||||
displayParameters.minimumSoc = displayParametersMap.value("minimum_soc").toInt();
|
||||
} else if (displayParametersMap.contains("target_soc")) {
|
||||
displayParameters.targetSoc = displayParametersMap.value("target_soc").toInt();
|
||||
} else if (displayParametersMap.contains("maximum_soc")) {
|
||||
displayParameters.maximumSoc = displayParametersMap.value("maximum_soc").toInt();
|
||||
} else if (displayParametersMap.contains("remaining_time_to_minimum_soc")) {
|
||||
displayParameters.remainingTimeToMinimumSoc = displayParametersMap.value("remaining_time_to_minimum_soc").toInt();
|
||||
} else if (displayParametersMap.contains("remaining_time_to_target_soc")) {
|
||||
displayParameters.remainingTimeToTargetSoc = displayParametersMap.value("remaining_time_to_target_soc").toInt();
|
||||
} else if (displayParametersMap.contains("remaining_time_to_maximum_soc")) {
|
||||
displayParameters.remainingTimeToMaximumSoc = displayParametersMap.value("remaining_time_to_maximum_soc").toInt();
|
||||
} else if (displayParametersMap.contains("charging_complete")) {
|
||||
displayParameters.chargingComplete = displayParametersMap.value("charging_complete").toBool();
|
||||
} else if (displayParametersMap.contains("battery_energy_capacity")) {
|
||||
displayParameters.batteryEnergyCapacity = displayParametersMap.value("battery_energy_capacity").toDouble();
|
||||
} else if (displayParametersMap.contains("inlet_hot")) {
|
||||
displayParameters.inletHot = displayParametersMap.value("inlet_hot").toBool();
|
||||
}
|
||||
|
||||
return displayParameters;
|
||||
}
|
||||
|
||||
void EverestJsonRpcClient::connectToServer(const QUrl &serverUrl)
|
||||
{
|
||||
m_interface->connectServer(serverUrl);
|
||||
|
||||
@ -102,6 +102,26 @@ public:
|
||||
};
|
||||
Q_ENUM(EvseState)
|
||||
|
||||
enum EnergyTransferMode {
|
||||
EnergyTransferModeUnknown,
|
||||
EnergyTransferModeAC_single_phase_core,
|
||||
EnergyTransferModeAC_two_phase,
|
||||
EnergyTransferModeAC_three_phase_core,
|
||||
EnergyTransferModeDC_core,
|
||||
EnergyTransferModeDC_extended,
|
||||
EnergyTransferModeDC_combo_core,
|
||||
EnergyTransferModeDC_unique,
|
||||
EnergyTransferModeDC,
|
||||
EnergyTransferModeAC_BPT,
|
||||
EnergyTransferModeAC_BPT_DER,
|
||||
EnergyTransferModeAC_DER,
|
||||
EnergyTransferModeDC_BPT,
|
||||
EnergyTransferModeDC_ACDP,
|
||||
EnergyTransferModeDC_ACDP_BPT,
|
||||
EnergyTransferModeWPT
|
||||
};
|
||||
Q_ENUM(EnergyTransferMode)
|
||||
|
||||
// API Objects
|
||||
|
||||
typedef struct ChargerInfo {
|
||||
@ -123,6 +143,7 @@ public:
|
||||
QString description; // optional
|
||||
bool bidirectionalCharging = false;
|
||||
QList<ConnectorInfo> availableConnectors;
|
||||
QList<EnergyTransferMode> supportedEnergyTransferModes;
|
||||
} EVSEInfo;
|
||||
|
||||
typedef struct ACChargeStatus {
|
||||
@ -139,6 +160,20 @@ public:
|
||||
// double nominalFrequency = 0; // Hz
|
||||
} ACChargeParameters;
|
||||
|
||||
typedef struct DisplayParameters {
|
||||
int startSoc = -1;
|
||||
int presentSoc = -1;
|
||||
int minimumSoc = -1;
|
||||
int targetSoc = -1;
|
||||
int maximumSoc = -1;
|
||||
int remainingTimeToMinimumSoc = -1;
|
||||
int remainingTimeToTargetSoc = -1;
|
||||
int remainingTimeToMaximumSoc = -1;
|
||||
bool chargingComplete = false;
|
||||
double batteryEnergyCapacity = -1;
|
||||
bool inletHot = false;
|
||||
} DisplayParameters;
|
||||
|
||||
typedef struct EVSEStatus {
|
||||
double chargedEnergyWh = 0;
|
||||
double dischargedEnergyWh = 0;
|
||||
@ -153,10 +188,10 @@ public:
|
||||
|
||||
ACChargeStatus acChargeStatus; // optional
|
||||
ACChargeParameters acChargeParameters; // optional
|
||||
DisplayParameters displayParameters; // optional
|
||||
// TODO:
|
||||
// o: "dc_charge_param": "$DCChargeParametersObj",
|
||||
// o: "dc_charge_status": "$DCChargeLoopObj",
|
||||
// o: display_parameters: "$DisplayParametersObj",
|
||||
|
||||
} EVSEStatus;
|
||||
|
||||
@ -223,6 +258,7 @@ public:
|
||||
EverestJsonRpcReply *evseSetChargingAllowed(int evseIndex, bool allowed);
|
||||
EverestJsonRpcReply *evseSetACChargingCurrent(int evseIndex, double current);
|
||||
EverestJsonRpcReply *evseSetACChargingPhaseCount(int evseIndex, int phaseCount);
|
||||
EverestJsonRpcReply *evseSetDCChargingPower(int evseIndex, double chargingPower);
|
||||
|
||||
// API parser methods
|
||||
|
||||
@ -231,6 +267,7 @@ public:
|
||||
static ConnectorType parseConnectorType(const QString &connectorTypeString);
|
||||
static ChargeProtocol parseChargeProtocol(const QString &chargeProtocolString);
|
||||
static EvseState parseEvseState(const QString &evseStateString);
|
||||
static EnergyTransferMode parseEnergyTransferMode(const QString &energyTransferModeString);
|
||||
|
||||
// Objects
|
||||
static EVSEInfo parseEvseInfo(const QVariantMap &evseInfoMap);
|
||||
@ -240,6 +277,7 @@ public:
|
||||
static ACChargeParameters parseACChargeParameters(const QVariantMap &acChargeParametersMap);
|
||||
static HardwareCapabilities parseHardwareCapabilities(const QVariantMap &hardwareCapabilitiesMap);
|
||||
static MeterData parseMeterData(const QVariantMap &meterDataMap);
|
||||
static DisplayParameters parseDisplayParameters(const QVariantMap &displayParametersMap);
|
||||
|
||||
public slots:
|
||||
void connectToServer(const QUrl &serverUrl);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user