[EMSP] Update charging station connector when a session update is received though OCPI
MODIFY
src/client/ocpi/CpoOCPIClient.ts
src/client/ocpi/CpoOCPIClient.ts
@@ -669,7 +669,7 @@ export default class CpoOCPIClient extends OCPIClient {
tenantID: this.tenant.id,
action: ServerAction.OCPI_CHECK_SESSIONS,
message: 'Session checked with result',
- module: MODULE_NAME, method: 'checkLocation',
+ module: MODULE_NAME, method: 'checkSession',
detailedMessages: { response : response.data }
});
const session = response.data.data as OCPISession;

MODIFY
src/client/ocpi/EmspOCPIClient.ts
src/client/ocpi/EmspOCPIClient.ts
@@ -33,6 +33,7 @@ import _ from 'lodash';
import axios from 'axios';
import moment from 'moment';
import { v4 as uuid } from 'uuid';
+import { OCPIJobResult } from '../../types/ocpi/OCPIJobResult';
const MODULE_NAME = 'EmspOCPIClient';
@@ -455,7 +456,55 @@ export default class EmspOCPIClient extends OCPIClient {
}
}
- async pushToken(token: OCPIToken) {
+ async checkToken(tokenUid: string): Promise<boolean> {
+ // Get tokens endpoint url
+ const tokensUrl = this.getEndpointUrl('tokens', ServerAction.OCPI_CHECK_TOKENS);
+ // Read configuration to retrieve
+ const countryCode = this.getLocalCountryCode(ServerAction.OCPI_CHECK_TOKENS);
+ const partyID = this.getLocalPartyID(ServerAction.OCPI_CHECK_TOKENS);
+ // Build url to IOP
+ const fullUrl = tokensUrl + `/${countryCode}/${partyID}/${tokenUid}`;
+ // Log
+ Logging.logDebug({
+ tenantID: this.tenant.id,
+ action: ServerAction.OCPI_CHECK_TOKENS,
+ message: `Get token at ${fullUrl}`,
+ module: MODULE_NAME, method: 'getToken',
+ detailedMessages: { tokenUid }
+ });
+ // Call IOP
+ const response = await axios.get(fullUrl,
+ {
+ headers: {
+ Authorization: `Token ${this.ocpiEndpoint.token}`
+ },
+ timeout: 10000
+ });
+ if (response.status === 200 && response.data) {
+ Logging.logDebug({
+ tenantID: this.tenant.id,
+ action: ServerAction.OCPI_CHECK_LOCATIONS,
+ message: 'Token checked with result',
+ module: MODULE_NAME, method: 'checkToken',
+ detailedMessages: { response : response.data }
+ });
+ const checkedToken = response.data.data as OCPILocation;
+ if (checkedToken) {
+ return true;
+ }
+ }
+ // Check response
+ if (!response.data) {
+ throw new BackendError({
+ action: ServerAction.OCPI_CHECK_TOKENS,
+ message: `Get token failed with status ${JSON.stringify(response)}`,
+ module: MODULE_NAME, method: 'getToken',
+ detailedMessages: { response: response.data }
+ });
+ }
+ }
+
+ async pushToken(token: OCPIToken): Promise<boolean> {
// Get tokens endpoint url
const tokensUrl = this.getEndpointUrl('tokens', ServerAction.OCPI_PUSH_TOKENS);
// Read configuration to retrieve
@@ -489,6 +538,7 @@ export default class EmspOCPIClient extends OCPIClient {
detailedMessages: { response: response.data }
});
}
+ return this.checkToken(token.uid);
}
async remoteStartSession(chargingStation: ChargingStation, connectorId: number, tagId: string): Promise<OCPICommandResponse> {

MODIFY
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/OCPISessionsService.ts
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/OCPISessionsService.ts
@@ -17,6 +17,8 @@ import TransactionStorage from '../../../../storage/mongodb/TransactionStorage';
import UserStorage from '../../../../storage/mongodb/UserStorage';
import Utils from '../../../../utils/Utils';
import moment from 'moment';
+import { Connector } from '../../../../types/ChargingStation';
+import { ChargePointStatus } from '../../../../types/ocpp/OCPPServer';
const MODULE_NAME = 'EMSPSessionsEndpoint';
@@ -159,7 +161,9 @@ export default class OCPISessionsService {
userID: transaction.userID
};
}
+
await TransactionStorage.saveTransaction(tenantId, transaction);
+ await this.updateConnector(tenantId, transaction);
}
public static async processCdr(tenantId: string, cdr: OCPICdr) {
@@ -231,6 +235,39 @@ export default class OCPISessionsService {
transaction.ocpiData.cdr = cdr;
await TransactionStorage.saveTransaction(tenantId, transaction);
+ await this.updateConnector(tenantId, transaction);
+ }
+
+ public static async updateConnector(tenantId: string, transaction: Transaction) {
+ const chargingStation = await ChargingStationStorage.getChargingStation(tenantId, transaction.chargeBoxID);
+ if (chargingStation && chargingStation.connectors) {
+ for (const connector of chargingStation.connectors) {
+ if (connector.connectorId === transaction.connectorId && connector.currentTransactionID === 0 || connector.currentTransactionID === transaction.id) {
+ if (!transaction.stop) {
+ connector.status = transaction.status;
+ connector.currentTransactionID = transaction.id;
+ connector.currentInactivityStatus = transaction.currentInactivityStatus;
+ connector.currentTagID = transaction.tagID;
+ connector.currentStateOfCharge = transaction.currentStateOfCharge;
+ connector.currentInstantWatts = transaction.currentInstantWatts;
+ connector.currentTotalConsumptionWh = transaction.currentTotalConsumptionWh;
+ connector.currentTransactionDate = transaction.currentTimestamp;
+ connector.currentTotalInactivitySecs = transaction.currentTotalInactivitySecs;
+ } else {
+ connector.status = ChargePointStatus.AVAILABLE;
+ connector.currentTransactionID = 0;
+ connector.currentTransactionDate = null;
+ connector.currentTagID = null;
+ connector.currentTotalConsumptionWh = 0;
+ connector.currentStateOfCharge = 0;
+ connector.currentTotalInactivitySecs = 0;
+ connector.currentInstantWatts = 0;
+ connector.currentInactivityStatus = null;
+ }
+ await ChargingStationStorage.saveChargingStation(tenantId, chargingStation);
+ }
+ }
+ }
}
private static async computeConsumption(tenantId: string, transaction: Transaction, session: OCPISession) {

MODIFY
src/server/ocpp/services/OCPPService.ts
src/server/ocpp/services/OCPPService.ts
@@ -1792,7 +1792,7 @@ export default class OCPPService {
'chargeBoxID': activeTransaction.chargeBoxID,
'transactionId': activeTransaction.id,
'meterStop': (activeTransaction.lastEnergyActiveImportMeterValue ? activeTransaction.lastEnergyActiveImportMeterValue.value : activeTransaction.meterStart),
- 'timestamp': Utils.convertToDate(activeTransaction.lastEnergyActiveImportMeterValue.timestamp).toISOString(),
+ 'timestamp': Utils.convertToDate(activeTransaction.lastEnergyActiveImportMeterValue ? activeTransaction.lastEnergyActiveImportMeterValue.timestamp : activeTransaction.timestamp).toISOString(),
}, false, true);
// Check
if (result.status === 'Invalid') {

MODIFY
src/server/rest/service/TransactionService.ts
src/server/rest/service/TransactionService.ts
@@ -310,7 +310,7 @@ export default class TransactionService {
chargeBoxID: chargingStation.id,
idTag: req.user.tagIDs[0],
timestamp: Utils.convertToDate(transaction.lastEnergyActiveImportMeterValue ? transaction.lastEnergyActiveImportMeterValue.timestamp : transaction.timestamp).toISOString(),
- meterStop: transaction.lastEnergyActiveImportMeterValue.value ? transaction.lastEnergyActiveImportMeterValue.value : transaction.meterStart
+ meterStop: transaction.lastEnergyActiveImportMeterValue ? transaction.lastEnergyActiveImportMeterValue.value : transaction.meterStart
},
true
);

MODIFY
src/types/Server.ts
src/types/Server.ts
@@ -116,6 +116,7 @@ export enum ServerAction {
OCPI_CHECK_CDRS = 'OcpiCheckCdrs',
OCPI_CHECK_SESSIONS = 'OcpiCheckSessions',
OCPI_CHECK_LOCATIONS = 'OcpiCheckLocations',
+ OCPI_CHECK_TOKENS = 'OcpiCheckTokens',
OCPI_PUSH_TOKENS = 'OcpiPushTokens',
OCPI_PUSH_SESSIONS = 'OcpiPushSessions',
OCPI_PUSH_CDRS = 'OcpiPushCdrs',

[EMSP] Update charging station connector when a session update is received though OCPI