From 515c93032e477b0b9d5a4c522b88e61cbca38188 Mon Sep 17 00:00:00 2001 From: Nicholas Jones Date: Tue, 28 Jan 2025 13:50:40 -0300 Subject: [PATCH] Add MADIC/LAFON model --- src/lib/ChargeStation/configurations/index.js | 2 + .../configurations/madic-lafon-ocpp-16.ts | 14 +++++ .../madic-lafon/override-session-uid.ts | 15 +++++ .../madic-lafon/session-stop-initiated.ts | 59 +++++++++++++++++++ src/lib/settings.ts | 20 +++++++ 5 files changed, 110 insertions(+) create mode 100644 src/lib/ChargeStation/configurations/madic-lafon-ocpp-16.ts create mode 100644 src/lib/ChargeStation/eventHandlers/ocpp-16/madic-lafon/override-session-uid.ts create mode 100644 src/lib/ChargeStation/eventHandlers/ocpp-16/madic-lafon/session-stop-initiated.ts diff --git a/src/lib/ChargeStation/configurations/index.js b/src/lib/ChargeStation/configurations/index.js index 83ea879..0d639bf 100644 --- a/src/lib/ChargeStation/configurations/index.js +++ b/src/lib/ChargeStation/configurations/index.js @@ -4,6 +4,7 @@ import AlpitronicCCVOCPP16 from './alpitronic-ccv-ocpp-16'; import SichargeOCPP16 from './sicharge-ocpp-16'; import AdsTecOCPP16 from './ads-tec-ocpp-16'; import ETotemOCPP16 from './e-totem-ocpp-16'; +import MadicLafonOCPP16 from 'lib/ChargeStation/configurations/madic-lafon-ocpp-16'; const options = { 'default-ocpp1.6': DefaultOCPP16, @@ -12,6 +13,7 @@ const options = { 'sicharge-ocpp1.6': SichargeOCPP16, 'ads-tec-ocpp1.6': AdsTecOCPP16, 'e-totem-ocpp1.6': ETotemOCPP16, + 'madic/lafon-ocpp1.6': MadicLafonOCPP16, }; export function getOCPPConfigurationOptions() { diff --git a/src/lib/ChargeStation/configurations/madic-lafon-ocpp-16.ts b/src/lib/ChargeStation/configurations/madic-lafon-ocpp-16.ts new file mode 100644 index 0000000..6da3509 --- /dev/null +++ b/src/lib/ChargeStation/configurations/madic-lafon-ocpp-16.ts @@ -0,0 +1,14 @@ +import DefaultOCPP16 from 'lib/ChargeStation/configurations/default-ocpp-16'; +import { EventTypes as e } from 'lib/ChargeStation/eventHandlers/event-types'; +import sendAuthorizeOrStartTransaction from 'lib/ChargeStation/eventHandlers/ocpp-16/send-authorize-or-start-transaction'; +import overrideSessionUid from 'lib/ChargeStation/eventHandlers/ocpp-16/madic-lafon/override-session-uid'; +import sendStopTransactionWithCost from 'lib/ChargeStation/eventHandlers/ocpp-16/madic-lafon/session-stop-initiated'; + +export default { + ...DefaultOCPP16, + [e.SessionStartInitiated]: [ + overrideSessionUid, + sendAuthorizeOrStartTransaction, + ], + [e.SessionStopInitiated]: [sendStopTransactionWithCost], +}; diff --git a/src/lib/ChargeStation/eventHandlers/ocpp-16/madic-lafon/override-session-uid.ts b/src/lib/ChargeStation/eventHandlers/ocpp-16/madic-lafon/override-session-uid.ts new file mode 100644 index 0000000..09cfe4c --- /dev/null +++ b/src/lib/ChargeStation/eventHandlers/ocpp-16/madic-lafon/override-session-uid.ts @@ -0,0 +1,15 @@ +import { ChargeStationEventHandler } from 'lib/ChargeStation/eventHandlers'; +import { AuthorizationType } from 'lib/settings'; + +const overrideSessionUid: ChargeStationEventHandler = async (params) => { + const { session, chargepoint } = params; + if (session.options.authorizationType !== AuthorizationType.CreditCard) { + return; // retain current idTag + } + + session.options.uid = chargepoint.configuration.getVariableValue( + 'IDTagBankCard' + ) as string; +}; + +export default overrideSessionUid; diff --git a/src/lib/ChargeStation/eventHandlers/ocpp-16/madic-lafon/session-stop-initiated.ts b/src/lib/ChargeStation/eventHandlers/ocpp-16/madic-lafon/session-stop-initiated.ts new file mode 100644 index 0000000..f4ba480 --- /dev/null +++ b/src/lib/ChargeStation/eventHandlers/ocpp-16/madic-lafon/session-stop-initiated.ts @@ -0,0 +1,59 @@ +import { sleep } from 'utils/csv'; +import { ChargeStationEventHandler } from 'lib/ChargeStation/eventHandlers'; +import { StopTransactionRequest } from 'schemas/ocpp/1.6/StopTransaction'; + +const sendStopTransactionWithCost: ChargeStationEventHandler = async ({ + chargepoint, + session, +}) => { + chargepoint.sessions[session.connectorId].isStoppingSession = true; + chargepoint.sessions[session.connectorId].tickInterval?.stop(); + + await sleep(1000); + + // Calculations below are just general approximations of how costs may be applied. + const priceTime = chargepoint.configuration.getVariableValue( + 'ChargePriceTime' + ) as number; + const priceEnergy = chargepoint.configuration.getVariableValue( + 'ChargePriceEnergy' + ) as number; + + const startTime = session.startTime; + const stopTime = session.stopTime as Date; + const durationMinutes = + (stopTime.getTime() - startTime.getTime()) / 1000 / 60; + + const durationCost = durationMinutes * priceTime; + const kWhCost = session.kwhElapsed * priceEnergy; + const sessionCost = durationCost + kWhCost; + + chargepoint.writeCall( + 'StopTransaction', + { + idTag: session.options.uid, + meterStop: Math.round(session.kwhElapsed * 1000), + timestamp: stopTime.toISOString(), + reason: 'EVDisconnected', + transactionId: Number(session.transactionId), + transactionData: [ + { + timestamp: stopTime.toISOString(), + sampledValue: [ + { + value: sessionCost.toFixed(2), + context: 'Transaction.End', + location: 'Body', + unit: 'Celcius', + format: 'Raw', + measurand: 'Temperature', + }, + ], + }, + ], + }, + session + ); +}; + +export default sendStopTransactionWithCost; diff --git a/src/lib/settings.ts b/src/lib/settings.ts index fb37b51..ed60a5f 100644 --- a/src/lib/settings.ts +++ b/src/lib/settings.ts @@ -56,6 +56,8 @@ const isAdsTec = (settings: Settings) => settings.chargePointModel === 'ads-tec'; const isETotem = (settings: Settings) => settings.chargePointModel === 'e-totem'; +const isMadicLafon = (settings: Settings) => + settings.chargePointModel === 'madic/lafon'; export const settingsList: SettingsListSetting[] = [ { @@ -277,6 +279,24 @@ export const defaultVariableConfig16: Variable16[] = [ value: 1, predicate: isAdsTec, }, + { + key: 'IDTagBankCard', + description: 'IdTag used when authorizing payment card sessions', + value: 'PleaseSetToken', + predicate: isMadicLafon, + }, + { + key: 'ChargePriceTime', + description: 'Per minute price', + value: 0, + predicate: isMadicLafon, + }, + { + key: 'ChargePriceEnergy', + description: 'Per kWh price', + value: 0, + predicate: isMadicLafon, + }, { key: 'SupportedFileTransferProtocols', description: 'Supported file transfer protocols',