Implement missing states
This commit is contained in:
parent
dada6940d2
commit
4b230b4ae8
@ -328,6 +328,14 @@
|
|||||||
"writable": true,
|
"writable": true,
|
||||||
"defaultValue": 3
|
"defaultValue": 3
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "9226f350-9ffd-4e0d-808b-67da51496ecb",
|
||||||
|
"name": "state",
|
||||||
|
"displayName": "State",
|
||||||
|
"type": "QString",
|
||||||
|
"defaultValue": "",
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "2bb15b1e-43a2-4102-bbc2-04689bb749eb",
|
"id": "2bb15b1e-43a2-4102-bbc2-04689bb749eb",
|
||||||
"name": "totalEnergyConsumed",
|
"name": "totalEnergyConsumed",
|
||||||
@ -356,11 +364,93 @@
|
|||||||
"cached": false
|
"cached": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "9226f350-9ffd-4e0d-808b-67da51496ecb",
|
"id": "717723fa-1d04-4211-9419-2f4ecc680dc0",
|
||||||
"name": "state",
|
"name": "currentPowerPhaseA",
|
||||||
"displayName": "State",
|
"displayName": "Current power phase A",
|
||||||
"type": "QString",
|
"displayNameEvent": "Current power phase A changed",
|
||||||
"defaultValue": "",
|
"type": "double",
|
||||||
|
"unit": "Watt",
|
||||||
|
"defaultValue": 0.00,
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4f2e367e-3735-4164-ab29-ea0b2f4f244d",
|
||||||
|
"name": "currentPowerPhaseB",
|
||||||
|
"displayName": "Current power phase B",
|
||||||
|
"displayNameEvent": "Current power phase B changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "Watt",
|
||||||
|
"defaultValue": 0.00,
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0fb40c19-ff3f-4901-8445-4ed7ea5e225a",
|
||||||
|
"name": "currentPowerPhaseC",
|
||||||
|
"displayName": "Current power phase C",
|
||||||
|
"displayNameEvent": "Current power phase C changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "Watt",
|
||||||
|
"defaultValue": 0.00,
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cbbec08d-6abc-416e-929d-17ae381c496e",
|
||||||
|
"name": "currentPhaseA",
|
||||||
|
"displayName": "Phase A current",
|
||||||
|
"displayNameEvent": "Phase A current changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "Ampere",
|
||||||
|
"defaultValue": 0.00,
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "36c21980-866c-4f6f-b447-33eb4d16539f",
|
||||||
|
"name": "currentPhaseB",
|
||||||
|
"displayName": "Phase B current",
|
||||||
|
"displayNameEvent": "Phase B current changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "Ampere",
|
||||||
|
"defaultValue": 0.00,
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "43f6e2ee-88d1-40ac-89b6-2e2d83b6ca1e",
|
||||||
|
"name": "currentPhaseC",
|
||||||
|
"displayName": "Phase C current",
|
||||||
|
"displayNameEvent": "Phase C current changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "Ampere",
|
||||||
|
"defaultValue": 0.00,
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "aa0da7f5-c7da-4c6b-800b-844b4cba4637",
|
||||||
|
"name": "voltagePhaseA",
|
||||||
|
"displayName": "Phase A voltage",
|
||||||
|
"displayNameEvent": "Phase A volatage changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "Volt",
|
||||||
|
"defaultValue": 0.00,
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "22545ffc-2123-413d-b000-5d67e5994498",
|
||||||
|
"name": "voltagePhaseB",
|
||||||
|
"displayName": "Phase B voltage",
|
||||||
|
"displayNameEvent": "Phase B voltage changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "Volt",
|
||||||
|
"defaultValue": 0.00,
|
||||||
|
"cached": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "13847b09-528b-4164-90e7-78c680276877",
|
||||||
|
"name": "voltagePhaseC",
|
||||||
|
"displayName": "Phase C voltage",
|
||||||
|
"displayNameEvent": "Phase C voltage changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "Volt",
|
||||||
|
"defaultValue": 0.00,
|
||||||
"cached": false
|
"cached": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -67,6 +67,15 @@ EverestEvse::EverestEvse(EverestJsonRpcClient *client, Thing *thing, QObject *pa
|
|||||||
processHardwareCapabilities();
|
processHardwareCapabilities();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(m_client, &EverestJsonRpcClient::meterDataChanged, this, [this](int evseIndex, const EverestJsonRpcClient::MeterData &meterData){
|
||||||
|
// We are only insterested in our own status
|
||||||
|
if (m_index != evseIndex)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_meterData = meterData;
|
||||||
|
processMeterData();
|
||||||
|
});
|
||||||
|
|
||||||
if (m_client->available())
|
if (m_client->available())
|
||||||
qCDebug(dcEverest()) << "Evse: The connection is already available. Initializing the instance...";
|
qCDebug(dcEverest()) << "Evse: The connection is already available. Initializing the instance...";
|
||||||
|
|
||||||
@ -115,7 +124,6 @@ void EverestEvse::initialize()
|
|||||||
qCWarning(dcEverest()) << "Evse: Reply finished with an error" << reply->method() << error;
|
qCWarning(dcEverest()) << "Evse: Reply finished with an error" << reply->method() << error;
|
||||||
// FIXME: check what we do if an init call failes. Do we stay disconnected and show an error or do we ignore it...
|
// FIXME: check what we do if an init call failes. Do we stay disconnected and show an error or do we ignore it...
|
||||||
} else {
|
} else {
|
||||||
// No error, store the data
|
|
||||||
m_evseInfo = EverestJsonRpcClient::parseEvseInfo(result.value("info").toMap());
|
m_evseInfo = EverestJsonRpcClient::parseEvseInfo(result.value("info").toMap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,7 +147,7 @@ void EverestEvse::initialize()
|
|||||||
qCWarning(dcEverest()) << "Evse: Reply finished with an error" << reply->method() << error;
|
qCWarning(dcEverest()) << "Evse: Reply finished with an error" << reply->method() << error;
|
||||||
// FIXME: check what we do if an init call failes. Do we stay disconnected and show an error or do we ignore it...
|
// FIXME: check what we do if an init call failes. Do we stay disconnected and show an error or do we ignore it...
|
||||||
} else {
|
} else {
|
||||||
// No error, store the data
|
// Store data, thy will be processed once all replies arrived
|
||||||
m_hardwareCapabilities = EverestJsonRpcClient::parseHardwareCapabilities(result.value("hardware_capabilities").toMap());
|
m_hardwareCapabilities = EverestJsonRpcClient::parseHardwareCapabilities(result.value("hardware_capabilities").toMap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,7 +171,7 @@ void EverestEvse::initialize()
|
|||||||
qCWarning(dcEverest()) << "Evse: Reply finished with an error" << reply->method() << error;
|
qCWarning(dcEverest()) << "Evse: Reply finished with an error" << reply->method() << error;
|
||||||
// FIXME: check what we do if an init call failes. Do we stay disconnected and show an error or do we ignore it...
|
// FIXME: check what we do if an init call failes. Do we stay disconnected and show an error or do we ignore it...
|
||||||
} else {
|
} else {
|
||||||
// No error, store the data
|
// Store data, thy will be processed once all replies arrived
|
||||||
m_evseStatus = EverestJsonRpcClient::parseEvseStatus(result.value("status").toMap());
|
m_evseStatus = EverestJsonRpcClient::parseEvseStatus(result.value("status").toMap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,6 +179,34 @@ void EverestEvse::initialize()
|
|||||||
// Check if we are done with the init process of this EVSE
|
// Check if we are done with the init process of this EVSE
|
||||||
evaluateInitFinished(reply);
|
evaluateInitFinished(reply);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reply = m_client->evseGetMeterData(m_index);
|
||||||
|
m_pendingInitReplies.append(reply);
|
||||||
|
connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater);
|
||||||
|
connect(reply, &EverestJsonRpcReply::finished, this, [this, reply](){
|
||||||
|
qCDebug(dcEverest()) << "Evse: Reply finished" << m_client->serverUrl().toString() << reply->method();
|
||||||
|
if (reply->error()) {
|
||||||
|
qCWarning(dcEverest()) << "Evse: JsonRpc reply finished with error" << reply->method() << reply->method() << reply->error();
|
||||||
|
// FIXME: check what we do if an init call failes. Do we stay disconnected and show an error or do we ignore it...
|
||||||
|
} else {
|
||||||
|
QVariantMap result = reply->response().value("result").toMap();
|
||||||
|
EverestJsonRpcClient::ResponseError error = EverestJsonRpcClient::parseResponseError(result.value("error").toString());
|
||||||
|
if (error) {
|
||||||
|
if (error == EverestJsonRpcClient::ResponseErrorErrorNoDataAvailable) {
|
||||||
|
qCDebug(dcEverest()) << "Evse: There are no meter data available. Either there is no meter or the meter data are not available yet on EVSE side.";
|
||||||
|
} else {
|
||||||
|
// FIXME: check what we do if an init call failes. Do we stay disconnected and show an error or do we ignore it...
|
||||||
|
qCWarning(dcEverest()) << "Evse: Reply finished with an error" << reply->method() << error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Store data, thy will be processed once all replies arrived
|
||||||
|
m_meterData = EverestJsonRpcClient::parseMeterData(result.value("meter_data").toMap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we are done with the init process of this EVSE
|
||||||
|
evaluateInitFinished(reply);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EverestEvse::evaluateInitFinished(EverestJsonRpcReply *reply)
|
void EverestEvse::evaluateInitFinished(EverestJsonRpcReply *reply)
|
||||||
@ -187,14 +223,18 @@ void EverestEvse::evaluateInitFinished(EverestJsonRpcReply *reply)
|
|||||||
// Set all initial states
|
// Set all initial states
|
||||||
m_thing->setStateValue("connected", true);
|
m_thing->setStateValue("connected", true);
|
||||||
|
|
||||||
|
// Process all data after beeing conected
|
||||||
processEvseStatus();
|
processEvseStatus();
|
||||||
processHardwareCapabilities();
|
processHardwareCapabilities();
|
||||||
|
processMeterData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EverestEvse::processEvseStatus()
|
void EverestEvse::processEvseStatus()
|
||||||
{
|
{
|
||||||
if (m_thing->thingClassId() == everestChargerAcThingClassId) {
|
if (m_thing->thingClassId() == everestChargerAcThingClassId) {
|
||||||
|
m_thing->setStateValue(everestChargerAcPowerStateTypeId, m_evseStatus.chargingAllowed);
|
||||||
|
m_thing->setStateValue(everestChargerAcSessionEnergyStateTypeId, m_evseStatus.chargedEnergyWh / 1000.0);
|
||||||
m_thing->setStateValue(everestChargerAcStateStateTypeId, m_evseStatus.evseStateString);
|
m_thing->setStateValue(everestChargerAcStateStateTypeId, m_evseStatus.evseStateString);
|
||||||
m_thing->setStateValue(everestChargerAcChargingStateTypeId, m_evseStatus.evseState == EverestJsonRpcClient::EvseStateCharging);
|
m_thing->setStateValue(everestChargerAcChargingStateTypeId, m_evseStatus.evseState == EverestJsonRpcClient::EvseStateCharging);
|
||||||
m_thing->setStateValue(everestChargerAcPluggedInStateTypeId, m_evseStatus.evseState != EverestJsonRpcClient::EvseStateUnplugged);
|
m_thing->setStateValue(everestChargerAcPluggedInStateTypeId, m_evseStatus.evseState != EverestJsonRpcClient::EvseStateUnplugged);
|
||||||
@ -219,3 +259,25 @@ void EverestEvse::processHardwareCapabilities()
|
|||||||
m_thing->setStateMinValue(everestChargerAcMaxChargingCurrentStateTypeId, m_hardwareCapabilities.minCurrentImport == 0 ? 6 : m_hardwareCapabilities.minCurrentImport);
|
m_thing->setStateMinValue(everestChargerAcMaxChargingCurrentStateTypeId, m_hardwareCapabilities.minCurrentImport == 0 ? 6 : m_hardwareCapabilities.minCurrentImport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EverestEvse::processMeterData()
|
||||||
|
{
|
||||||
|
if (m_thing->thingClassId() == everestChargerAcThingClassId) {
|
||||||
|
|
||||||
|
m_thing->setStateValue(everestChargerAcCurrentPowerStateTypeId, m_meterData.powerTotal);
|
||||||
|
|
||||||
|
m_thing->setStateValue(everestChargerAcCurrentPowerPhaseAStateTypeId, m_meterData.powerL1);
|
||||||
|
m_thing->setStateValue(everestChargerAcCurrentPowerPhaseBStateTypeId, m_meterData.powerL2);
|
||||||
|
m_thing->setStateValue(everestChargerAcCurrentPowerPhaseCStateTypeId, m_meterData.powerL3);
|
||||||
|
|
||||||
|
m_thing->setStateValue(everestChargerAcCurrentPhaseAStateTypeId, m_meterData.currentL1);
|
||||||
|
m_thing->setStateValue(everestChargerAcCurrentPhaseBStateTypeId, m_meterData.currentL2);
|
||||||
|
m_thing->setStateValue(everestChargerAcCurrentPhaseCStateTypeId, m_meterData.currentL3);
|
||||||
|
|
||||||
|
m_thing->setStateValue(everestChargerAcVoltagePhaseAStateTypeId, m_meterData.voltageL1);
|
||||||
|
m_thing->setStateValue(everestChargerAcVoltagePhaseBStateTypeId, m_meterData.voltageL2);
|
||||||
|
m_thing->setStateValue(everestChargerAcVoltagePhaseCStateTypeId, m_meterData.voltageL3);
|
||||||
|
|
||||||
|
m_thing->setStateValue(everestChargerAcTotalEnergyConsumedStateTypeId, m_meterData.energyImportedTotal / 1000.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -57,6 +57,7 @@ private:
|
|||||||
EverestJsonRpcClient::EVSEInfo m_evseInfo;
|
EverestJsonRpcClient::EVSEInfo m_evseInfo;
|
||||||
EverestJsonRpcClient::EVSEStatus m_evseStatus;
|
EverestJsonRpcClient::EVSEStatus m_evseStatus;
|
||||||
EverestJsonRpcClient::HardwareCapabilities m_hardwareCapabilities;
|
EverestJsonRpcClient::HardwareCapabilities m_hardwareCapabilities;
|
||||||
|
EverestJsonRpcClient::MeterData m_meterData;
|
||||||
|
|
||||||
QVector<EverestJsonRpcReply *> m_pendingInitReplies;
|
QVector<EverestJsonRpcReply *> m_pendingInitReplies;
|
||||||
|
|
||||||
@ -65,6 +66,7 @@ private:
|
|||||||
|
|
||||||
void processEvseStatus();
|
void processEvseStatus();
|
||||||
void processHardwareCapabilities();
|
void processHardwareCapabilities();
|
||||||
|
void processMeterData();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EVERESTEVSE_H
|
#endif // EVERESTEVSE_H
|
||||||
|
|||||||
@ -35,6 +35,8 @@
|
|||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonParseError>
|
#include <QJsonParseError>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(dcEverestTraffic)
|
||||||
|
|
||||||
EverestJsonRpcClient::EverestJsonRpcClient(QObject *parent)
|
EverestJsonRpcClient::EverestJsonRpcClient(QObject *parent)
|
||||||
: QObject{parent},
|
: QObject{parent},
|
||||||
m_interface{new EverestJsonRpcInterface(this)}
|
m_interface{new EverestJsonRpcInterface(this)}
|
||||||
@ -69,7 +71,6 @@ EverestJsonRpcClient::EverestJsonRpcClient(QObject *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//D | Everest: <-- {"id":0,"jsonrpc":"2.0","result":{"api_version":"0.0.1","authentication_required":false,"charger_info":{"firmware_version":"unknown","model":"unknown","serial":"unknown","vendor":"unknown"},"everest_version":""}
|
|
||||||
m_apiVersion = result.value("api_version").toString();
|
m_apiVersion = result.value("api_version").toString();
|
||||||
m_everestVersion = result.value("everest_version").toString();
|
m_everestVersion = result.value("everest_version").toString();
|
||||||
m_authenticationRequired = result.value("authentication_required").toBool();
|
m_authenticationRequired = result.value("authentication_required").toBool();
|
||||||
@ -83,8 +84,7 @@ EverestJsonRpcClient::EverestJsonRpcClient(QObject *parent)
|
|||||||
EverestJsonRpcReply *reply = chargePointGetEVSEInfos();
|
EverestJsonRpcReply *reply = chargePointGetEVSEInfos();
|
||||||
connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater);
|
connect(reply, &EverestJsonRpcReply::finished, reply, &EverestJsonRpcReply::deleteLater);
|
||||||
connect(reply, &EverestJsonRpcReply::finished, this, [this, reply](){
|
connect(reply, &EverestJsonRpcReply::finished, this, [this, reply](){
|
||||||
qCDebug(dcEverest()) << "Reply finished" << m_interface->serverUrl().toString() << reply->method()
|
qCDebug(dcEverest()) << "Reply finished" << m_interface->serverUrl().toString() << reply->method();
|
||||||
<< qUtf8Printable(QJsonDocument::fromVariant(reply->response()).toJson(QJsonDocument::Indented));
|
|
||||||
|
|
||||||
if (reply->error()) {
|
if (reply->error()) {
|
||||||
qCWarning(dcEverest()) << "JsonRpc reply finished with error" << reply->method() << reply->error();
|
qCWarning(dcEverest()) << "JsonRpc reply finished with error" << reply->method() << reply->error();
|
||||||
@ -336,6 +336,66 @@ EverestJsonRpcClient::HardwareCapabilities EverestJsonRpcClient::parseHardwareCa
|
|||||||
return hardwareCapabilities;
|
return hardwareCapabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EverestJsonRpcClient::MeterData EverestJsonRpcClient::parseMeterData(const QVariantMap &meterDataMap)
|
||||||
|
{
|
||||||
|
MeterData meterData;
|
||||||
|
|
||||||
|
meterData.meterId = meterDataMap.value("meter_id").toString();
|
||||||
|
|
||||||
|
meterData.energyImportedL1 = meterDataMap.value("energy_Wh_import").toMap().value("L1").toFloat();
|
||||||
|
meterData.energyImportedL2 = meterDataMap.value("energy_Wh_import").toMap().value("L2").toFloat();
|
||||||
|
meterData.energyImportedL3 = meterDataMap.value("energy_Wh_import").toMap().value("L3").toFloat();
|
||||||
|
meterData.energyImportedTotal = meterDataMap.value("energy_Wh_import").toMap().value("total").toFloat();
|
||||||
|
|
||||||
|
// optional
|
||||||
|
if (meterDataMap.contains("serial_number"))
|
||||||
|
meterData.serialNumber = meterDataMap.value("serial_number").toString();
|
||||||
|
|
||||||
|
// optional
|
||||||
|
if (meterDataMap.contains("phase_seq_error"))
|
||||||
|
meterData.phaseSequenceError = meterDataMap.value("phase_seq_error").toBool();
|
||||||
|
|
||||||
|
// optional
|
||||||
|
if (meterDataMap.contains("power_W")) {
|
||||||
|
meterData.powerL1 = meterDataMap.value("power_W").toMap().value("L1").toFloat();
|
||||||
|
meterData.powerL2 = meterDataMap.value("power_W").toMap().value("L2").toFloat();
|
||||||
|
meterData.powerL3 = meterDataMap.value("power_W").toMap().value("L3").toFloat();
|
||||||
|
meterData.powerTotal = meterDataMap.value("power_W").toMap().value("total").toFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
// optional
|
||||||
|
if (meterDataMap.contains("voltage_V")) {
|
||||||
|
meterData.voltageL1 = meterDataMap.value("voltage_V").toMap().value("L1").toFloat();
|
||||||
|
meterData.voltageL2 = meterDataMap.value("voltage_V").toMap().value("L2").toFloat();
|
||||||
|
meterData.voltageL3 = meterDataMap.value("voltage_V").toMap().value("L3").toFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
// optional
|
||||||
|
if (meterDataMap.contains("current_A")) {
|
||||||
|
meterData.currentL1 = meterDataMap.value("current_A").toMap().value("L1").toFloat();
|
||||||
|
meterData.currentL2 = meterDataMap.value("current_A").toMap().value("L2").toFloat();
|
||||||
|
meterData.currentL3 = meterDataMap.value("current_A").toMap().value("L3").toFloat();
|
||||||
|
meterData.currentN = meterDataMap.value("current_A").toMap().value("N").toFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
// optional
|
||||||
|
if (meterDataMap.contains("energy_Wh_export")) {
|
||||||
|
meterData.energyExportedL1 = meterDataMap.value("energy_Wh_export").toMap().value("L1").toFloat();
|
||||||
|
meterData.energyExportedL2 = meterDataMap.value("energy_Wh_export").toMap().value("L2").toFloat();
|
||||||
|
meterData.energyExportedL3 = meterDataMap.value("energy_Wh_export").toMap().value("L3").toFloat();
|
||||||
|
meterData.energyExportedTotal = meterDataMap.value("energy_Wh_export").toMap().value("total").toFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
// optional
|
||||||
|
if (meterDataMap.contains("frequency_Hz")) {
|
||||||
|
meterData.frequencyL1 = meterDataMap.value("frequency_Hz").toMap().value("L1").toFloat();
|
||||||
|
meterData.frequencyL2 = meterDataMap.value("frequency_Hz").toMap().value("L2").toFloat();
|
||||||
|
meterData.frequencyL3 = meterDataMap.value("frequency_Hz").toMap().value("L3").toFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
return meterData;
|
||||||
|
}
|
||||||
|
|
||||||
void EverestJsonRpcClient::connectToServer(const QUrl &serverUrl)
|
void EverestJsonRpcClient::connectToServer(const QUrl &serverUrl)
|
||||||
{
|
{
|
||||||
m_interface->connectServer(serverUrl);
|
m_interface->connectServer(serverUrl);
|
||||||
@ -351,7 +411,7 @@ void EverestJsonRpcClient::sendRequest(EverestJsonRpcReply *reply)
|
|||||||
QVariantMap requestMap = reply->requestMap();
|
QVariantMap requestMap = reply->requestMap();
|
||||||
QByteArray data = QJsonDocument::fromVariant(requestMap).toJson(QJsonDocument::Compact) + '\n';
|
QByteArray data = QJsonDocument::fromVariant(requestMap).toJson(QJsonDocument::Compact) + '\n';
|
||||||
|
|
||||||
qCDebug(dcEverest()) << "-->" << m_interface->serverUrl().toString() << qUtf8Printable(data);
|
qCDebug(dcEverestTraffic()) << "-->" << m_interface->serverUrl().toString() << qUtf8Printable(data);
|
||||||
m_interface->sendData(data);
|
m_interface->sendData(data);
|
||||||
|
|
||||||
m_replies.insert(m_commandId, reply);
|
m_replies.insert(m_commandId, reply);
|
||||||
@ -362,7 +422,7 @@ void EverestJsonRpcClient::sendRequest(EverestJsonRpcReply *reply)
|
|||||||
|
|
||||||
void EverestJsonRpcClient::processDataPacket(const QByteArray &data)
|
void EverestJsonRpcClient::processDataPacket(const QByteArray &data)
|
||||||
{
|
{
|
||||||
qCDebug(dcEverest()) << "<--" << m_interface->serverUrl().toString() << qUtf8Printable(data);
|
qCDebug(dcEverestTraffic()) << "<--" << m_interface->serverUrl().toString() << qUtf8Printable(data);
|
||||||
|
|
||||||
QJsonParseError error;
|
QJsonParseError error;
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||||
@ -393,7 +453,6 @@ void EverestJsonRpcClient::processDataPacket(const QByteArray &data)
|
|||||||
} else {
|
} else {
|
||||||
reply->finishReply();
|
reply->finishReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Data without reply, check if this is a notification
|
// Data without reply, check if this is a notification
|
||||||
@ -405,7 +464,7 @@ void EverestJsonRpcClient::processDataPacket(const QByteArray &data)
|
|||||||
QString notification = dataMap.value("method").toString();
|
QString notification = dataMap.value("method").toString();
|
||||||
QVariantMap params = dataMap.value("params").toMap();
|
QVariantMap params = dataMap.value("params").toMap();
|
||||||
|
|
||||||
qCDebug(dcEverest()) << "Received notification" << notification << params;
|
qCDebug(dcEverest()) << "Received notification" << notification;
|
||||||
|
|
||||||
if (notification == "EVSE.StatusChanged") {
|
if (notification == "EVSE.StatusChanged") {
|
||||||
int evseIndex = params.value("evse_index").toInt();
|
int evseIndex = params.value("evse_index").toInt();
|
||||||
@ -413,14 +472,15 @@ void EverestJsonRpcClient::processDataPacket(const QByteArray &data)
|
|||||||
emit evseStatusChanged(evseIndex, evseStatus);
|
emit evseStatusChanged(evseIndex, evseStatus);
|
||||||
} else if (notification == "ChargePoint.ActiveErrorsChanged") {
|
} else if (notification == "ChargePoint.ActiveErrorsChanged") {
|
||||||
// TODO
|
// TODO
|
||||||
|
qCWarning(dcEverest()) << "Active errors changed" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson());
|
||||||
} else if (notification == "EVSE.HardwareCapabilitiesChanged") {
|
} else if (notification == "EVSE.HardwareCapabilitiesChanged") {
|
||||||
int evseIndex = params.value("evse_index").toInt();
|
int evseIndex = params.value("evse_index").toInt();
|
||||||
HardwareCapabilities hardwareCapabilities = EverestJsonRpcClient::parseHardwareCapabilities(params.value("hardware_capabilities").toMap());
|
HardwareCapabilities hardwareCapabilities = EverestJsonRpcClient::parseHardwareCapabilities(params.value("hardware_capabilities").toMap());
|
||||||
emit hardwareCapabilitiesChanged(evseIndex, hardwareCapabilities);
|
emit hardwareCapabilitiesChanged(evseIndex, hardwareCapabilities);
|
||||||
} else if (notification == "EVSE.MeterDataChanged") {
|
} else if (notification == "EVSE.MeterDataChanged") {
|
||||||
int evseIndex = params.value("evse_index").toInt();
|
int evseIndex = params.value("evse_index").toInt();
|
||||||
HardwareCapabilities hardwareCapabilities = EverestJsonRpcClient::parseHardwareCapabilities(params.value("hardware_capabilities").toMap());
|
MeterData meterData = EverestJsonRpcClient::parseMeterData(params.value("meter_data").toMap());
|
||||||
emit hardwareCapabilitiesChanged(evseIndex, hardwareCapabilities);
|
emit meterDataChanged(evseIndex, meterData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ class EverestJsonRpcClient : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// API Enums
|
// API Enums
|
||||||
|
|
||||||
enum ResponseError {
|
enum ResponseError {
|
||||||
@ -52,7 +53,7 @@ public:
|
|||||||
ResponseErrorErrorOutOfRange,
|
ResponseErrorErrorOutOfRange,
|
||||||
ResponseErrorErrorValuesNotApplied,
|
ResponseErrorErrorValuesNotApplied,
|
||||||
ResponseErrorErrorInvalidEVSEIndex,
|
ResponseErrorErrorInvalidEVSEIndex,
|
||||||
ResponseErrorErrorInvalidConnectorID,
|
ResponseErrorErrorInvalidConnectorId,
|
||||||
ResponseErrorErrorNoDataAvailable,
|
ResponseErrorErrorNoDataAvailable,
|
||||||
ResponseErrorErrorUnknownError
|
ResponseErrorErrorUnknownError
|
||||||
};
|
};
|
||||||
@ -102,7 +103,8 @@ public:
|
|||||||
EvseStateCharging,
|
EvseStateCharging,
|
||||||
EvseStateChargingPausedEV,
|
EvseStateChargingPausedEV,
|
||||||
EvseStateChargingPausedEVSE,
|
EvseStateChargingPausedEVSE,
|
||||||
EvseStateFinished
|
EvseStateFinished,
|
||||||
|
EvseStateSwitchingPhases
|
||||||
};
|
};
|
||||||
Q_ENUM(EvseState)
|
Q_ENUM(EvseState)
|
||||||
|
|
||||||
@ -134,14 +136,13 @@ public:
|
|||||||
} ACChargeStatus;
|
} ACChargeStatus;
|
||||||
|
|
||||||
typedef struct ACChargeParameters {
|
typedef struct ACChargeParameters {
|
||||||
// V 1.0.0 supported values
|
|
||||||
double maxCurrent = 0; // A
|
double maxCurrent = 0; // A
|
||||||
double maxPhaseCount = 0;
|
double maxPhaseCount = 0;
|
||||||
|
|
||||||
|
// Not supported yet with 1.0.0
|
||||||
// double maxChargePower = 0; // W
|
// double maxChargePower = 0; // W
|
||||||
// double minChargePower = 0; // W
|
// double minChargePower = 0; // W
|
||||||
// double nominalFrequency = 0; // Hz
|
// double nominalFrequency = 0; // Hz
|
||||||
|
|
||||||
} ACChargeParameters;
|
} ACChargeParameters;
|
||||||
|
|
||||||
typedef struct EVSEStatus {
|
typedef struct EVSEStatus {
|
||||||
@ -155,18 +156,16 @@ public:
|
|||||||
ChargeProtocol chargeProtocol = ChargeProtocolUnknown;
|
ChargeProtocol chargeProtocol = ChargeProtocolUnknown;
|
||||||
EvseState evseState = EvseStateUnplugged;
|
EvseState evseState = EvseStateUnplugged;
|
||||||
QString evseStateString;
|
QString evseStateString;
|
||||||
ACChargeStatus acChargeStatus;
|
|
||||||
ACChargeParameters acChargeParameters;
|
ACChargeStatus acChargeStatus; // optional
|
||||||
|
ACChargeParameters acChargeParameters; // optional
|
||||||
// TODO:
|
// TODO:
|
||||||
// o: "ac_charge_param": "$ACChargeParametersObj",
|
|
||||||
// o: "dc_charge_param": "$DCChargeParametersObj",
|
// o: "dc_charge_param": "$DCChargeParametersObj",
|
||||||
// o: "ac_charge_loop": "$ACChargeLoopObj",
|
// o: "dc_charge_status": "$DCChargeLoopObj",
|
||||||
// o: "dc_charge_loop": "$DCChargeLoopObj",
|
|
||||||
// o: display_parameters: "$DisplayParametersObj",
|
// o: display_parameters: "$DisplayParametersObj",
|
||||||
|
|
||||||
} EVSEStatus;
|
} EVSEStatus;
|
||||||
|
|
||||||
|
|
||||||
typedef struct HardwareCapabilities {
|
typedef struct HardwareCapabilities {
|
||||||
double maxCurrentExport = 0;
|
double maxCurrentExport = 0;
|
||||||
double maxCurrentImport = 0;
|
double maxCurrentImport = 0;
|
||||||
@ -179,57 +178,35 @@ public:
|
|||||||
bool phaseSwitchDuringCharging = false;
|
bool phaseSwitchDuringCharging = false;
|
||||||
} HardwareCapabilities;
|
} HardwareCapabilities;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
MeterDataObj {
|
|
||||||
|
|
||||||
o: "current_A": {
|
|
||||||
"L1": "float",
|
|
||||||
"L2": "float",
|
|
||||||
"L3": "float",
|
|
||||||
"N": "float"
|
|
||||||
},
|
|
||||||
"energy_Wh_import": {
|
|
||||||
"L1": "float",
|
|
||||||
"L2": "float",
|
|
||||||
"L3": "float",
|
|
||||||
"total": "float"
|
|
||||||
},
|
|
||||||
o: "energy_Wh_export": {
|
|
||||||
"L1": "float",
|
|
||||||
"L2": "float",
|
|
||||||
"L3": "float",
|
|
||||||
"total": "float"
|
|
||||||
},
|
|
||||||
o: "frequency_Hz": {
|
|
||||||
"L1": "float",
|
|
||||||
"L2": "float",
|
|
||||||
"L3": "float"
|
|
||||||
},
|
|
||||||
"meter_id": "string",
|
|
||||||
o: "serial_number": "string",
|
|
||||||
o: "phase_seq_error": "bool",
|
|
||||||
o: "power_W": {
|
|
||||||
"L1": "float",
|
|
||||||
"L2": "float",
|
|
||||||
"L3": "float",
|
|
||||||
"total": "float"
|
|
||||||
},
|
|
||||||
"timestamp": "string",
|
|
||||||
o: "voltage_V": {
|
|
||||||
"L1": "float",
|
|
||||||
"L2": "float",
|
|
||||||
"L3": "float"
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct MeterData {
|
typedef struct MeterData {
|
||||||
|
QString meterId;
|
||||||
|
QString serialNumber;
|
||||||
|
bool phaseSequenceError = false;
|
||||||
|
//quint64 timestamp = 0;
|
||||||
|
float powerL1 = 0; // W
|
||||||
|
float powerL2 = 0; // W
|
||||||
|
float powerL3 = 0; // W
|
||||||
|
float powerTotal = 0; // W
|
||||||
|
float currentL1 = 0; // A
|
||||||
|
float currentL2 = 0; // A
|
||||||
|
float currentL3 = 0; // A
|
||||||
|
float currentN = 0; // A
|
||||||
|
float voltageL1 = 0; // V
|
||||||
|
float voltageL2 = 0; // V
|
||||||
|
float voltageL3 = 0; // V
|
||||||
|
float energyImportedL1 = 0; // Wh
|
||||||
|
float energyImportedL2 = 0; // Wh
|
||||||
|
float energyImportedL3 = 0; // Wh
|
||||||
|
float energyImportedTotal = 0; // Wh
|
||||||
|
float energyExportedL1 = 0; // Wh
|
||||||
|
float energyExportedL2 = 0; // Wh
|
||||||
|
float energyExportedL3 = 0; // Wh
|
||||||
|
float energyExportedTotal = 0; // Wh
|
||||||
|
float frequencyL1 = 0; // Hz
|
||||||
|
float frequencyL2 = 0; // Hz
|
||||||
|
float frequencyL3 = 0; // Hz
|
||||||
} MeterData;
|
} MeterData;
|
||||||
|
|
||||||
|
|
||||||
explicit EverestJsonRpcClient(QObject *parent = nullptr);
|
explicit EverestJsonRpcClient(QObject *parent = nullptr);
|
||||||
|
|
||||||
QUrl serverUrl();
|
QUrl serverUrl();
|
||||||
@ -268,6 +245,7 @@ public:
|
|||||||
static ACChargeStatus parseACChargeStatus(const QVariantMap &acChargeStatusMap);
|
static ACChargeStatus parseACChargeStatus(const QVariantMap &acChargeStatusMap);
|
||||||
static ACChargeParameters parseACChargeParameters(const QVariantMap &acChargeParametersMap);
|
static ACChargeParameters parseACChargeParameters(const QVariantMap &acChargeParametersMap);
|
||||||
static HardwareCapabilities parseHardwareCapabilities(const QVariantMap &hardwareCapabilitiesMap);
|
static HardwareCapabilities parseHardwareCapabilities(const QVariantMap &hardwareCapabilitiesMap);
|
||||||
|
static MeterData parseMeterData(const QVariantMap &meterDataMap);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void connectToServer(const QUrl &serverUrl);
|
void connectToServer(const QUrl &serverUrl);
|
||||||
@ -280,8 +258,8 @@ signals:
|
|||||||
// Notifications
|
// Notifications
|
||||||
void evseStatusChanged(int evseIndex, const EverestJsonRpcClient::EVSEStatus &evseStatus);
|
void evseStatusChanged(int evseIndex, const EverestJsonRpcClient::EVSEStatus &evseStatus);
|
||||||
void hardwareCapabilitiesChanged(int evseIndex, const EverestJsonRpcClient::HardwareCapabilities &hardwareCapabilities);
|
void hardwareCapabilitiesChanged(int evseIndex, const EverestJsonRpcClient::HardwareCapabilities &hardwareCapabilities);
|
||||||
void meterDataChanged(int evseIndex, const EverestJsonRpcClient::HardwareCapabilities &hardwareCapabilities);
|
void meterDataChanged(int evseIndex, const EverestJsonRpcClient::MeterData &hardwareCapabilities);
|
||||||
// TODO void activeErrorsChanged();
|
// void activeErrorsChanged(); // TODO
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void sendRequest(EverestJsonRpcReply *reply);
|
void sendRequest(EverestJsonRpcReply *reply);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user