UNPKG

typed-ocpp

Version:

A library for type-aware parsing, serialization and validation of OCPP 1.6, OCPP 2.0 and OCPP 2.1 messages

131 lines 7.07 kB
import { startOfDay, addMilliseconds, startOfWeek, differenceInMilliseconds, addWeeks, addDays, addSeconds, min, differenceInSeconds } from 'date-fns'; import { AbstractChargingManager } from '../common/chargingmanager/chargingmanager.js'; export class ChargingManager extends AbstractChargingManager { _getScheduleFromProfile(context, profile, fromDate, toDate, unit) { const { csChargingProfiles: { chargingSchedule, validFrom, validTo, recurrencyKind, chargingProfileKind } } = profile; const schedule = []; if (validFrom && fromDate < new Date(validFrom)) { return schedule; } if (validTo && fromDate >= new Date(validTo)) { return schedule; } const { duration, chargingRateUnit, chargingSchedulePeriod, minChargingRate, startSchedule } = chargingSchedule; const scheduleStartEndDatePairs = []; switch (chargingProfileKind) { case 'Absolute': { const absoluteProfileStartDate = startSchedule ? new Date(startSchedule) : fromDate; const absoluteProfileEndDate = duration ? addSeconds(absoluteProfileStartDate, duration) : toDate; scheduleStartEndDatePairs.push([absoluteProfileStartDate, absoluteProfileEndDate]); } break; case 'Relative': { const relativeProfileStartDate = fromDate; const relativeProfileEndDate = duration ? addSeconds(relativeProfileStartDate, duration) : toDate; scheduleStartEndDatePairs.push([relativeProfileStartDate, relativeProfileEndDate]); } break; case 'Recurring': { let recurringProfileStartDate = startSchedule ? new Date(startSchedule) : fromDate; const startOfFn = recurrencyKind === 'Daily' ? startOfDay : startOfWeek; const addFn = recurrencyKind === 'Daily' ? addDays : addWeeks; recurringProfileStartDate = addMilliseconds(startOfFn(fromDate), differenceInMilliseconds(recurringProfileStartDate, startOfFn(recurringProfileStartDate))); while (recurringProfileStartDate < toDate) { let recurringProfileEndDate = addFn(recurringProfileStartDate, 1); let recurringProfileEndDateInclDuration = duration ? min([recurringProfileEndDate, addSeconds(recurringProfileStartDate, duration)]) : recurringProfileEndDate; scheduleStartEndDatePairs.push([recurringProfileStartDate, recurringProfileEndDateInclDuration]); recurringProfileStartDate = recurringProfileEndDate; } } break; } scheduleStartEndDatePairs.forEach(([scheduleStartDate, scheduleEndDate]) => { chargingSchedulePeriod.forEach((period, periodIndex) => { const { startPeriod, limit, numberPhases = 3 } = period; const nextPeriod = chargingSchedulePeriod[periodIndex + 1]; const periodStartDate = addSeconds(scheduleStartDate, startPeriod); const periodEndDate = nextPeriod ? addSeconds(scheduleStartDate, nextPeriod.startPeriod) : scheduleEndDate; schedule.push({ start: periodStartDate, end: periodEndDate, data: { charging: { min: context.model.convert(minChargingRate ?? 0, chargingRateUnit, unit, numberPhases), max: context.model.convert(limit >= 0 ? limit : 0, chargingRateUnit, unit, numberPhases), phases: { qty: numberPhases }, }, discharging: { min: context.model.convert(0, chargingRateUnit, unit, numberPhases), max: context.model.convert(limit < 0 ? Math.abs(limit) : 0, chargingRateUnit, unit, numberPhases), phases: { qty: numberPhases }, }, shouldDischarge: limit < 0, unit, }, }); }); }); return schedule; } setChargingProfile(request) { const { csChargingProfiles: { chargingProfilePurpose, stackLevel }, connectorId } = request; this._setChargingProfile(chargingProfilePurpose, connectorId, stackLevel, request); } clearChargingProfile(request) { this._clearChargingProfiles(request.chargingProfilePurpose, request.connectorId, request.stackLevel); } getConnectorSchedule(fromDate, toDate, connectorId, unit, model) { return this._getChargerSchedule(fromDate, toDate, connectorId, unit, model); } getConnectorLimitsAtDate(atDate, connectorId, unit, model) { return this._getChargerLimitsAtDate(atDate, connectorId, unit, model); } getConnectorCompositeSchedule(fromDate, toDate, chargerId, model) { const now = new Date(); const schedule = this._getChargerSchedule(fromDate, toDate, chargerId, 'W', model); const min_date = schedule[0].start; const max_date = schedule.at(-1).end; return { status: 'Accepted', connectorId: chargerId, chargingSchedule: { startSchedule: now.toISOString(), duration: differenceInSeconds(max_date, min_date), chargingRateUnit: 'W', chargingSchedulePeriod: schedule.map((interval) => { const { start, data: { charging, discharging, shouldDischarge } } = interval; return shouldDischarge ? { startPeriod: differenceInSeconds(start, min_date), limit: -1 * discharging.max, numberPhases: discharging.phases.qty, } : { startPeriod: differenceInSeconds(start, min_date), limit: charging.max, numberPhases: charging.phases.qty, }; }), }, }; } getConnectorCompositeProfile(fromDate, toDate, connectorId, model, opts) { const compositeSchedule = this.getConnectorCompositeSchedule(fromDate, toDate, connectorId, model); return { connectorId: compositeSchedule.connectorId, csChargingProfiles: { ...opts, chargingProfileKind: 'Absolute', validFrom: fromDate.toISOString(), validTo: fromDate.toISOString(), chargingSchedule: compositeSchedule.chargingSchedule, }, }; } } //# sourceMappingURL=chargingmanager.js.map