@zetra/citrineos-smartcharging 1.8.3-fork.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +6 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/module/1.6/MessageApi.d.ts +31 -0
- package/dist/module/1.6/MessageApi.js +69 -0
- package/dist/module/1.6/MessageApi.js.map +1 -0
- package/dist/module/2.0.1/MessageApi.d.ts +45 -0
- package/dist/module/2.0.1/MessageApi.js +443 -0
- package/dist/module/2.0.1/MessageApi.js.map +1 -0
- package/dist/module/interface.d.ts +5 -0
- package/dist/module/interface.js +5 -0
- package/dist/module/interface.js.map +1 -0
- package/dist/module/module.d.ts +98 -0
- package/dist/module/module.js +460 -0
- package/dist/module/module.js.map +1 -0
- package/dist/module/smartCharging/InternalSmartCharging.d.ts +29 -0
- package/dist/module/smartCharging/InternalSmartCharging.js +167 -0
- package/dist/module/smartCharging/InternalSmartCharging.js.map +1 -0
- package/dist/module/smartCharging/SmartCharging.d.ts +22 -0
- package/dist/module/smartCharging/SmartCharging.js +6 -0
- package/dist/module/smartCharging/SmartCharging.js.map +1 -0
- package/dist/module/smartCharging/index.d.ts +2 -0
- package/dist/module/smartCharging/index.js +5 -0
- package/dist/module/smartCharging/index.js.map +1 -0
- package/package.json +25 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/module/interface.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,sCAAsC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { BootstrapConfig, CallAction, HandlerProperties, ICache, IMessage, IMessageHandler, IMessageSender, SystemConfig } from '@citrineos/base';
|
|
2
|
+
import { AbstractModule, OCPP1_6, OCPP2_0_1, OCPPValidator } from '@citrineos/base';
|
|
3
|
+
import type { IChargingProfileRepository, IDeviceModelRepository, IOCPPMessageRepository, ITransactionEventRepository } from '@citrineos/data';
|
|
4
|
+
import { IdGenerator } from '@citrineos/util';
|
|
5
|
+
import type { ILogObj } from 'tslog';
|
|
6
|
+
import { Logger } from 'tslog';
|
|
7
|
+
import type { ISmartCharging } from './smartCharging/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Component that handles provisioning related messages.
|
|
10
|
+
*/
|
|
11
|
+
export declare class SmartChargingModule extends AbstractModule {
|
|
12
|
+
/**
|
|
13
|
+
* Fields
|
|
14
|
+
*/
|
|
15
|
+
_requests: CallAction[];
|
|
16
|
+
_responses: CallAction[];
|
|
17
|
+
protected _transactionEventRepository: ITransactionEventRepository;
|
|
18
|
+
protected _deviceModelRepository: IDeviceModelRepository;
|
|
19
|
+
protected _chargingProfileRepository: IChargingProfileRepository;
|
|
20
|
+
protected _ocppMessageRepository: IOCPPMessageRepository;
|
|
21
|
+
protected _smartChargingService: ISmartCharging;
|
|
22
|
+
private _idGenerator;
|
|
23
|
+
/**
|
|
24
|
+
* Constructor
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* This is the constructor function that initializes the {@link SmartChargingModule}.
|
|
28
|
+
*
|
|
29
|
+
* @param {BootstrapConfig & SystemConfig} config - The `config` contains configuration settings for the module.
|
|
30
|
+
*
|
|
31
|
+
* @param {ICache} [cache] - The cache instance which is shared among the modules & Central System to pass information such as blacklisted actions or boot status.
|
|
32
|
+
*
|
|
33
|
+
* @param {IMessageSender} [sender] - The `sender` parameter is an optional parameter that represents an instance of the {@link IMessageSender} interface.
|
|
34
|
+
* It is used to send messages from the central system to external systems or devices. If no `sender` is provided, a default {@link RabbitMqSender} instance is created and used.
|
|
35
|
+
*
|
|
36
|
+
* @param {IMessageHandler} [handler] - The `handler` parameter is an optional parameter that represents an instance of the {@link IMessageHandler} interface.
|
|
37
|
+
* It is used to handle incoming messages and dispatch them to the appropriate methods or functions. If no `handler` is provided, a default {@link RabbitMqReceiver} instance is created and used.
|
|
38
|
+
*
|
|
39
|
+
* @param {Logger<ILogObj>} [logger] - The `logger` parameter is an optional parameter that represents an instance of {@link Logger<ILogObj>}.
|
|
40
|
+
* It is used to propagate system wide logger settings and will serve as the parent logger for any sub-component logging. If no `logger` is provided, a default {@link Logger<ILogObj>} instance is created and used.
|
|
41
|
+
*
|
|
42
|
+
* @param {ITransactionEventRepository} [transactionEventRepository] - An optional parameter of type {@link ITransactionEventRepository}
|
|
43
|
+
* which represents a repository for accessing and manipulating transaction data.
|
|
44
|
+
* If no `transactionEventRepository` is provided, a default {@link sequelize:transactionEventRepository} instance is created and used.
|
|
45
|
+
*
|
|
46
|
+
* @param {IDeviceModelRepository} [deviceModelRepository] - An optional parameter of type {@link IDeviceModelRepository}
|
|
47
|
+
* which represents a repository for accessing and manipulating variable data.
|
|
48
|
+
* If no `deviceModelRepository` is provided, a default {@link sequelize:deviceModelRepository} instance is created and used.
|
|
49
|
+
*
|
|
50
|
+
* @param {IChargingProfileRepository} [chargingProfileRepository] - An optional parameter of type {@link IChargingProfileRepository}
|
|
51
|
+
* which represents a repository for accessing and manipulating charging profile data.
|
|
52
|
+
* If no `chargingProfileRepository` is provided, a default {@link sequelize:chargingProfileRepository} instance is created and used.
|
|
53
|
+
*
|
|
54
|
+
* @param {ISmartCharging} [smartChargingService] - An optional parameter of type {@link ISmartCharging} which
|
|
55
|
+
* provides smart charging functionalities, e.g., calculation and validation.
|
|
56
|
+
*
|
|
57
|
+
* @param {IdGenerator} [idGenerator] - An optional parameter of type {@link IdGenerator} which
|
|
58
|
+
* represents a generator for ids.
|
|
59
|
+
*/
|
|
60
|
+
constructor(config: BootstrapConfig & SystemConfig, cache: ICache, sender?: IMessageSender, handler?: IMessageHandler, logger?: Logger<ILogObj>, ocppValidator?: OCPPValidator, transactionEventRepository?: ITransactionEventRepository, deviceModelRepository?: IDeviceModelRepository, chargingProfileRepository?: IChargingProfileRepository, smartChargingService?: ISmartCharging, idGenerator?: IdGenerator, ocppMessageRepository?: IOCPPMessageRepository);
|
|
61
|
+
get transactionEventRepository(): ITransactionEventRepository;
|
|
62
|
+
get deviceModelRepository(): IDeviceModelRepository;
|
|
63
|
+
get chargingProfileRepository(): IChargingProfileRepository;
|
|
64
|
+
get ocppMessageRepository(): IOCPPMessageRepository;
|
|
65
|
+
/**
|
|
66
|
+
* Handle requests
|
|
67
|
+
*/
|
|
68
|
+
protected _handleNotifyEVChargingNeeds(message: IMessage<OCPP2_0_1.NotifyEVChargingNeedsRequest>, props?: HandlerProperties): Promise<void>;
|
|
69
|
+
protected _handleNotifyEVChargingSchedule(message: IMessage<OCPP2_0_1.NotifyEVChargingScheduleRequest>, props?: HandlerProperties): Promise<void>;
|
|
70
|
+
protected _handleNotifyChargingLimit(message: IMessage<OCPP2_0_1.NotifyChargingLimitRequest>, props?: HandlerProperties): Promise<void>;
|
|
71
|
+
protected _handleReportChargingProfiles(message: IMessage<OCPP2_0_1.ReportChargingProfilesRequest>, props?: HandlerProperties): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Handle responses
|
|
74
|
+
*/
|
|
75
|
+
protected _handleClearChargingProfile(message: IMessage<OCPP2_0_1.ClearChargingProfileResponse>, props?: HandlerProperties): Promise<void>;
|
|
76
|
+
protected _handleGetChargingProfiles(message: IMessage<OCPP2_0_1.GetChargingProfilesResponse>, props?: HandlerProperties): void;
|
|
77
|
+
protected _handleSetChargingProfile(message: IMessage<OCPP2_0_1.SetChargingProfileResponse>, props?: HandlerProperties): Promise<void>;
|
|
78
|
+
protected _handleClearedChargingLimit(message: IMessage<OCPP2_0_1.ClearedChargingLimitRequest>, props?: HandlerProperties): Promise<void>;
|
|
79
|
+
protected _handleGetCompositeSchedule(message: IMessage<OCPP2_0_1.GetCompositeScheduleResponse>, props?: HandlerProperties): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Generates a `SetChargingProfileRequest` from the given `NotifyEVChargingScheduleRequest`.
|
|
82
|
+
*
|
|
83
|
+
* This method creates a charging profile based on the EV's charging schedule.
|
|
84
|
+
*
|
|
85
|
+
* @param request - The `NotifyEVChargingScheduleRequest` containing EV's charging schedule.
|
|
86
|
+
* @param transaction - The transaction associated with the charging profile.
|
|
87
|
+
* @param stationId - Station ID
|
|
88
|
+
*
|
|
89
|
+
* @returns A `SetChargingProfileRequest` with a generated charging profile.
|
|
90
|
+
*/
|
|
91
|
+
private _generateSetChargingProfileRequest;
|
|
92
|
+
/**
|
|
93
|
+
* OCPP 1.6 response handlers
|
|
94
|
+
*/
|
|
95
|
+
protected _handleOcpp16SetChargingProfile(message: IMessage<OCPP1_6.SetChargingProfileResponse>, props?: HandlerProperties): Promise<void>;
|
|
96
|
+
protected _handleOcpp16ClearChargingProfile(message: IMessage<OCPP1_6.ClearChargingProfileResponse>, props?: HandlerProperties): Promise<void>;
|
|
97
|
+
protected _handleOcpp16GetCompositeSchedule(message: IMessage<OCPP1_6.GetCompositeScheduleResponse>, props?: HandlerProperties): Promise<void>;
|
|
98
|
+
}
|
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { AbstractModule, AsHandler, ChargingLimitSourceEnum, ChargingProfilePurposeEnum, ChargingStationSequenceTypeEnum, EventGroup, MessageOrigin, OCPP1_6, OCPP1_6_CallAction, OCPP2_0_1, OCPP2_0_1_CallAction, OCPPValidator, OCPPVersion, } from '@citrineos/base';
|
|
11
|
+
import { OCPP1_6_Mapper, OCPP2_0_1_Mapper, sequelize, SequelizeChargingStationSequenceRepository, Transaction, } from '@citrineos/data';
|
|
12
|
+
import { IdGenerator, RabbitMqReceiver, RabbitMqSender } from '@citrineos/util';
|
|
13
|
+
import { Logger } from 'tslog';
|
|
14
|
+
import { InternalSmartCharging } from './smartCharging/index.js';
|
|
15
|
+
/**
|
|
16
|
+
* Component that handles provisioning related messages.
|
|
17
|
+
*/
|
|
18
|
+
export class SmartChargingModule extends AbstractModule {
|
|
19
|
+
/**
|
|
20
|
+
* Fields
|
|
21
|
+
*/
|
|
22
|
+
_requests = [];
|
|
23
|
+
_responses = [];
|
|
24
|
+
_transactionEventRepository;
|
|
25
|
+
_deviceModelRepository;
|
|
26
|
+
_chargingProfileRepository;
|
|
27
|
+
_ocppMessageRepository;
|
|
28
|
+
_smartChargingService;
|
|
29
|
+
_idGenerator;
|
|
30
|
+
/**
|
|
31
|
+
* Constructor
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* This is the constructor function that initializes the {@link SmartChargingModule}.
|
|
35
|
+
*
|
|
36
|
+
* @param {BootstrapConfig & SystemConfig} config - The `config` contains configuration settings for the module.
|
|
37
|
+
*
|
|
38
|
+
* @param {ICache} [cache] - The cache instance which is shared among the modules & Central System to pass information such as blacklisted actions or boot status.
|
|
39
|
+
*
|
|
40
|
+
* @param {IMessageSender} [sender] - The `sender` parameter is an optional parameter that represents an instance of the {@link IMessageSender} interface.
|
|
41
|
+
* It is used to send messages from the central system to external systems or devices. If no `sender` is provided, a default {@link RabbitMqSender} instance is created and used.
|
|
42
|
+
*
|
|
43
|
+
* @param {IMessageHandler} [handler] - The `handler` parameter is an optional parameter that represents an instance of the {@link IMessageHandler} interface.
|
|
44
|
+
* It is used to handle incoming messages and dispatch them to the appropriate methods or functions. If no `handler` is provided, a default {@link RabbitMqReceiver} instance is created and used.
|
|
45
|
+
*
|
|
46
|
+
* @param {Logger<ILogObj>} [logger] - The `logger` parameter is an optional parameter that represents an instance of {@link Logger<ILogObj>}.
|
|
47
|
+
* It is used to propagate system wide logger settings and will serve as the parent logger for any sub-component logging. If no `logger` is provided, a default {@link Logger<ILogObj>} instance is created and used.
|
|
48
|
+
*
|
|
49
|
+
* @param {ITransactionEventRepository} [transactionEventRepository] - An optional parameter of type {@link ITransactionEventRepository}
|
|
50
|
+
* which represents a repository for accessing and manipulating transaction data.
|
|
51
|
+
* If no `transactionEventRepository` is provided, a default {@link sequelize:transactionEventRepository} instance is created and used.
|
|
52
|
+
*
|
|
53
|
+
* @param {IDeviceModelRepository} [deviceModelRepository] - An optional parameter of type {@link IDeviceModelRepository}
|
|
54
|
+
* which represents a repository for accessing and manipulating variable data.
|
|
55
|
+
* If no `deviceModelRepository` is provided, a default {@link sequelize:deviceModelRepository} instance is created and used.
|
|
56
|
+
*
|
|
57
|
+
* @param {IChargingProfileRepository} [chargingProfileRepository] - An optional parameter of type {@link IChargingProfileRepository}
|
|
58
|
+
* which represents a repository for accessing and manipulating charging profile data.
|
|
59
|
+
* If no `chargingProfileRepository` is provided, a default {@link sequelize:chargingProfileRepository} instance is created and used.
|
|
60
|
+
*
|
|
61
|
+
* @param {ISmartCharging} [smartChargingService] - An optional parameter of type {@link ISmartCharging} which
|
|
62
|
+
* provides smart charging functionalities, e.g., calculation and validation.
|
|
63
|
+
*
|
|
64
|
+
* @param {IdGenerator} [idGenerator] - An optional parameter of type {@link IdGenerator} which
|
|
65
|
+
* represents a generator for ids.
|
|
66
|
+
*/
|
|
67
|
+
constructor(config, cache, sender, handler, logger, ocppValidator, transactionEventRepository, deviceModelRepository, chargingProfileRepository, smartChargingService, idGenerator, ocppMessageRepository) {
|
|
68
|
+
super(config, cache, handler || new RabbitMqReceiver(config, logger), sender || new RabbitMqSender(config, logger), EventGroup.SmartCharging, logger, ocppValidator);
|
|
69
|
+
this._requests = config.modules.smartcharging?.requests ?? [];
|
|
70
|
+
this._responses = config.modules.smartcharging?.responses ?? [];
|
|
71
|
+
this._transactionEventRepository =
|
|
72
|
+
transactionEventRepository ||
|
|
73
|
+
new sequelize.SequelizeTransactionEventRepository(config, this._logger);
|
|
74
|
+
this._deviceModelRepository =
|
|
75
|
+
deviceModelRepository || new sequelize.SequelizeDeviceModelRepository(config, this._logger);
|
|
76
|
+
this._chargingProfileRepository =
|
|
77
|
+
chargingProfileRepository ||
|
|
78
|
+
new sequelize.SequelizeChargingProfileRepository(config, this._logger);
|
|
79
|
+
this._ocppMessageRepository =
|
|
80
|
+
ocppMessageRepository || new sequelize.SequelizeOCPPMessageRepository(config, this._logger);
|
|
81
|
+
this._smartChargingService =
|
|
82
|
+
smartChargingService || new InternalSmartCharging(this._chargingProfileRepository);
|
|
83
|
+
this._idGenerator =
|
|
84
|
+
idGenerator ||
|
|
85
|
+
new IdGenerator(new SequelizeChargingStationSequenceRepository(config, this._logger));
|
|
86
|
+
}
|
|
87
|
+
get transactionEventRepository() {
|
|
88
|
+
return this._transactionEventRepository;
|
|
89
|
+
}
|
|
90
|
+
get deviceModelRepository() {
|
|
91
|
+
return this._deviceModelRepository;
|
|
92
|
+
}
|
|
93
|
+
get chargingProfileRepository() {
|
|
94
|
+
return this._chargingProfileRepository;
|
|
95
|
+
}
|
|
96
|
+
get ocppMessageRepository() {
|
|
97
|
+
return this._ocppMessageRepository;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Handle requests
|
|
101
|
+
*/
|
|
102
|
+
async _handleNotifyEVChargingNeeds(message, props) {
|
|
103
|
+
this._logger.debug('NotifyEVChargingNeeds received:', message, props);
|
|
104
|
+
const request = message.payload;
|
|
105
|
+
const tenantId = message.context.tenantId;
|
|
106
|
+
const stationId = message.context.stationId;
|
|
107
|
+
const givenNeeds = request.chargingNeeds;
|
|
108
|
+
const activeTransaction = await this._transactionEventRepository.getActiveTransactionByStationIdAndEvseId(tenantId, stationId, request.evseId);
|
|
109
|
+
this._logger.info(`Found active transaction on station ${stationId} evse ${request.evseId}: ${JSON.stringify(activeTransaction)}`);
|
|
110
|
+
// OCPP 2.0.1 Part 2 K17.FR.06
|
|
111
|
+
const hasAcOrDcChargingParameters = givenNeeds.dcChargingParameters !== null || givenNeeds.acChargingParameters !== null;
|
|
112
|
+
this._logger.info(`Has AC or DC charging parameters: ${hasAcOrDcChargingParameters}`);
|
|
113
|
+
const matchedChargingType = ((givenNeeds.dcChargingParameters ?? false) &&
|
|
114
|
+
givenNeeds.requestedEnergyTransfer === OCPP2_0_1.EnergyTransferModeEnumType.DC) ||
|
|
115
|
+
((givenNeeds.acChargingParameters ?? false) &&
|
|
116
|
+
givenNeeds.requestedEnergyTransfer !== OCPP2_0_1.EnergyTransferModeEnumType.DC);
|
|
117
|
+
this._logger.info(`Matched chargingParameters and requestedEnergyTransfer type: ${matchedChargingType}`);
|
|
118
|
+
if (!activeTransaction || !hasAcOrDcChargingParameters || !matchedChargingType) {
|
|
119
|
+
await this.sendCallResultWithMessage(message, {
|
|
120
|
+
status: OCPP2_0_1.NotifyEVChargingNeedsStatusEnumType.Rejected,
|
|
121
|
+
});
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
let chargingProfile;
|
|
125
|
+
try {
|
|
126
|
+
chargingProfile = await this._smartChargingService.calculateChargingProfile(request, activeTransaction, tenantId, stationId);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
this._logger.error(`Failed to calculate charging profile: ${error}`);
|
|
130
|
+
await this.sendCallResultWithMessage(message, {
|
|
131
|
+
status: OCPP2_0_1.NotifyEVChargingNeedsStatusEnumType.Rejected,
|
|
132
|
+
});
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const chargingNeeds = await this._chargingProfileRepository.createChargingNeeds(tenantId, request, stationId);
|
|
136
|
+
this._logger.info(`Charging needs created: ${JSON.stringify(chargingNeeds)}`);
|
|
137
|
+
await this.sendCallResultWithMessage(message, {
|
|
138
|
+
status: OCPP2_0_1.NotifyEVChargingNeedsStatusEnumType.Accepted,
|
|
139
|
+
});
|
|
140
|
+
const storedChargingProfile = await this.chargingProfileRepository.createOrUpdateChargingProfile(tenantId, OCPP2_0_1_Mapper.ChargingProfileMapper.fromChargingProfileType(chargingProfile), stationId, request.evseId);
|
|
141
|
+
this._logger.info(`Charging profile created: ${JSON.stringify(storedChargingProfile)}`);
|
|
142
|
+
await this.sendCall(stationId, message.context.tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.SetChargingProfile, { evseId: request.evseId, chargingProfile });
|
|
143
|
+
}
|
|
144
|
+
async _handleNotifyEVChargingSchedule(message, props) {
|
|
145
|
+
this._logger.debug('NotifyEVChargingSchedule received:', message, props);
|
|
146
|
+
const request = message.payload;
|
|
147
|
+
const tenantId = message.context.tenantId;
|
|
148
|
+
const stationId = message.context.stationId;
|
|
149
|
+
// There are different definitions for Accepted and Rejected in NotifyEVChargingScheduleResponse
|
|
150
|
+
// in OCPP 2.0.1 V3 Part 2, see (1) 1.37.2 status field description and (2) K17.FR.11 and K17.FR.12
|
|
151
|
+
// We use (1) in our code, i.e., always return Accepted in response
|
|
152
|
+
await this.sendCallResultWithMessage(message, {
|
|
153
|
+
status: OCPP2_0_1.GenericStatusEnumType.Accepted,
|
|
154
|
+
});
|
|
155
|
+
const activeTransaction = await this._transactionEventRepository.getActiveTransactionByStationIdAndEvseId(tenantId, stationId, request.evseId);
|
|
156
|
+
if (!activeTransaction) {
|
|
157
|
+
this._logger.error(`No active transaction on station ${stationId} evse ${request.evseId}`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
this._logger.info(`Found active transaction on station ${stationId} evse ${request.evseId}: ${JSON.stringify(activeTransaction)}`);
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
await this._smartChargingService.checkLimitsOfChargingSchedule(request, tenantId, stationId, activeTransaction);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
this._logger.error(`EV charging schedule is NOT within limits of existing ChargingSchedule: ${error}`);
|
|
168
|
+
// Currently, we simply trust the given EV charging schedule and create a new charging profile based on it
|
|
169
|
+
const setChargingProfileRequest = await this._generateSetChargingProfileRequest(request, activeTransaction, tenantId, stationId);
|
|
170
|
+
await this.sendCall(stationId, message.context.tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.SetChargingProfile, setChargingProfileRequest);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async _handleNotifyChargingLimit(message, props) {
|
|
174
|
+
this._logger.debug('NotifyChargingLimit received:', message, props);
|
|
175
|
+
// Create response
|
|
176
|
+
const response = {};
|
|
177
|
+
const messageConfirmation = await this.sendCallResultWithMessage(message, response);
|
|
178
|
+
this._logger.debug('NotifyChargingLimit response sent: ', messageConfirmation);
|
|
179
|
+
}
|
|
180
|
+
async _handleReportChargingProfiles(message, props) {
|
|
181
|
+
this._logger.debug('ReportChargingProfiles received:', message, props);
|
|
182
|
+
const chargingProfiles = message.payload.chargingProfile;
|
|
183
|
+
const tenantId = message.context.tenantId;
|
|
184
|
+
for (const chargingProfile of chargingProfiles) {
|
|
185
|
+
await this._chargingProfileRepository.createOrUpdateChargingProfile(tenantId, OCPP2_0_1_Mapper.ChargingProfileMapper.fromChargingProfileType(chargingProfile), message.context.stationId, message.payload.evseId, OCPP2_0_1_Mapper.ChargingProfileMapper.fromChargingLimitSourceEnumType(message.payload.chargingLimitSource), true);
|
|
186
|
+
}
|
|
187
|
+
// Create response
|
|
188
|
+
const response = {};
|
|
189
|
+
const messageConfirmation = await this.sendCallResultWithMessage(message, response);
|
|
190
|
+
this._logger.debug('ReportChargingProfiles response sent: ', messageConfirmation);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Handle responses
|
|
194
|
+
*/
|
|
195
|
+
async _handleClearChargingProfile(message, props) {
|
|
196
|
+
this._logger.debug('ClearChargingProfile response received:', message, props);
|
|
197
|
+
const tenantId = message.context.tenantId;
|
|
198
|
+
if (message.payload.status === OCPP2_0_1.ClearChargingProfileStatusEnumType.Accepted) {
|
|
199
|
+
const stationId = message.context.stationId;
|
|
200
|
+
// Set existed profiles to isActive false
|
|
201
|
+
await this._chargingProfileRepository.updateAllByQuery(tenantId, {
|
|
202
|
+
isActive: false,
|
|
203
|
+
}, {
|
|
204
|
+
where: {
|
|
205
|
+
tenantId: tenantId,
|
|
206
|
+
stationId: stationId,
|
|
207
|
+
isActive: true,
|
|
208
|
+
},
|
|
209
|
+
returning: false,
|
|
210
|
+
});
|
|
211
|
+
// Request charging profiles to get the latest data
|
|
212
|
+
await this.sendCall(stationId, message.context.tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.GetChargingProfiles, {
|
|
213
|
+
requestId: await this._idGenerator.generateRequestId(message.context.tenantId, message.context.stationId, ChargingStationSequenceTypeEnum.getChargingProfiles),
|
|
214
|
+
chargingProfile: {
|
|
215
|
+
chargingLimitSource: [
|
|
216
|
+
OCPP2_0_1.ChargingLimitSourceEnumType.CSO,
|
|
217
|
+
OCPP2_0_1.ChargingLimitSourceEnumType.EMS,
|
|
218
|
+
OCPP2_0_1.ChargingLimitSourceEnumType.SO,
|
|
219
|
+
OCPP2_0_1.ChargingLimitSourceEnumType.Other,
|
|
220
|
+
],
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
this._logger.error(`Failed to clear charging profile: ${JSON.stringify(message.payload)}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
_handleGetChargingProfiles(message, props) {
|
|
229
|
+
this._logger.debug('GetChargingProfiles response received:', message, props);
|
|
230
|
+
}
|
|
231
|
+
async _handleSetChargingProfile(message, props) {
|
|
232
|
+
this._logger.debug('SetChargingProfile response received:', message, props);
|
|
233
|
+
const tenantId = message.context.tenantId;
|
|
234
|
+
const response = message.payload;
|
|
235
|
+
if (response.status === OCPP2_0_1.ChargingProfileStatusEnumType.Rejected) {
|
|
236
|
+
this._logger.error(`Failed to set charging profile: ${JSON.stringify(response)}`);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
const stationId = message.context.stationId;
|
|
240
|
+
// Set existed profiles to isActive false
|
|
241
|
+
await this._chargingProfileRepository.updateAllByQuery(tenantId, {
|
|
242
|
+
isActive: false,
|
|
243
|
+
}, {
|
|
244
|
+
where: {
|
|
245
|
+
tenantId: tenantId,
|
|
246
|
+
stationId: stationId,
|
|
247
|
+
isActive: true,
|
|
248
|
+
chargingLimitSource: OCPP2_0_1.ChargingLimitSourceEnumType.CSO,
|
|
249
|
+
},
|
|
250
|
+
returning: false,
|
|
251
|
+
});
|
|
252
|
+
// Request charging profiles to get the latest data
|
|
253
|
+
await this.sendCall(stationId, message.context.tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.GetChargingProfiles, {
|
|
254
|
+
requestId: await this._idGenerator.generateRequestId(message.context.tenantId, message.context.stationId, ChargingStationSequenceTypeEnum.getChargingProfiles),
|
|
255
|
+
chargingProfile: {
|
|
256
|
+
chargingLimitSource: [OCPP2_0_1.ChargingLimitSourceEnumType.CSO],
|
|
257
|
+
},
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async _handleClearedChargingLimit(message, props) {
|
|
262
|
+
this._logger.debug('ClearedChargingLimit request received:', message, props);
|
|
263
|
+
const response = {};
|
|
264
|
+
await this.sendCallResultWithMessage(message, response);
|
|
265
|
+
}
|
|
266
|
+
async _handleGetCompositeSchedule(message, props) {
|
|
267
|
+
this._logger.debug('GetCompositeSchedule response received:', message, props);
|
|
268
|
+
const tenantId = message.context.tenantId;
|
|
269
|
+
const response = message.payload;
|
|
270
|
+
if (response.status === OCPP2_0_1.GenericStatusEnumType.Accepted) {
|
|
271
|
+
if (response.schedule) {
|
|
272
|
+
const compositeSchedule = await this._chargingProfileRepository.createCompositeSchedule(tenantId, OCPP2_0_1_Mapper.ChargingProfileMapper.fromCompositeScheduleType(response.schedule), message.context.stationId);
|
|
273
|
+
this._logger.info(`Composite schedule created: ${JSON.stringify(compositeSchedule)}`);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
this._logger.error(`Missing schedule in response: ${response.status} ${JSON.stringify(response.statusInfo)}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
this._logger.error(`Failed to get composite schedule: ${response.status} ${JSON.stringify(response.statusInfo)}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Generates a `SetChargingProfileRequest` from the given `NotifyEVChargingScheduleRequest`.
|
|
285
|
+
*
|
|
286
|
+
* This method creates a charging profile based on the EV's charging schedule.
|
|
287
|
+
*
|
|
288
|
+
* @param request - The `NotifyEVChargingScheduleRequest` containing EV's charging schedule.
|
|
289
|
+
* @param transaction - The transaction associated with the charging profile.
|
|
290
|
+
* @param stationId - Station ID
|
|
291
|
+
*
|
|
292
|
+
* @returns A `SetChargingProfileRequest` with a generated charging profile.
|
|
293
|
+
*/
|
|
294
|
+
async _generateSetChargingProfileRequest(request, transaction, tenantId, stationId) {
|
|
295
|
+
const { chargingSchedule, evseId } = request;
|
|
296
|
+
const nativePurpose = ChargingProfilePurposeEnum.TxProfile;
|
|
297
|
+
chargingSchedule.id = await this._chargingProfileRepository.getNextChargingScheduleId(tenantId, stationId);
|
|
298
|
+
const chargingProfile = {
|
|
299
|
+
id: await this._chargingProfileRepository.getNextChargingProfileId(tenantId, stationId),
|
|
300
|
+
stackLevel: await this._chargingProfileRepository.getNextStackLevel(tenantId, stationId, transaction.id, nativePurpose),
|
|
301
|
+
chargingProfilePurpose: OCPP2_0_1.ChargingProfilePurposeEnumType.TxProfile,
|
|
302
|
+
chargingProfileKind: OCPP2_0_1.ChargingProfileKindEnumType.Absolute,
|
|
303
|
+
chargingSchedule: [chargingSchedule],
|
|
304
|
+
transactionId: transaction.transactionId,
|
|
305
|
+
};
|
|
306
|
+
return {
|
|
307
|
+
evseId,
|
|
308
|
+
chargingProfile,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* OCPP 1.6 response handlers
|
|
313
|
+
*/
|
|
314
|
+
async _handleOcpp16SetChargingProfile(message, props) {
|
|
315
|
+
this._logger.debug('OCPP 1.6 SetChargingProfileResponse received:', message, props);
|
|
316
|
+
const tenantId = message.context.tenantId;
|
|
317
|
+
const stationId = message.context.stationId;
|
|
318
|
+
if (message.payload.status === OCPP1_6.SetChargingProfileResponseStatus.Accepted) {
|
|
319
|
+
const originalMessage = await this._ocppMessageRepository.readOnlyOneByQuery(tenantId, {
|
|
320
|
+
where: {
|
|
321
|
+
tenantId: tenantId,
|
|
322
|
+
stationId: stationId,
|
|
323
|
+
correlationId: message.context.correlationId,
|
|
324
|
+
origin: MessageOrigin.ChargingStationManagementSystem,
|
|
325
|
+
},
|
|
326
|
+
});
|
|
327
|
+
if (originalMessage) {
|
|
328
|
+
const originalRequest = originalMessage.message[3];
|
|
329
|
+
const mapped = OCPP1_6_Mapper.ChargingProfileMapper.fromSetChargingProfileRequest(originalRequest.csChargingProfiles);
|
|
330
|
+
await this._chargingProfileRepository.createOrUpdateChargingProfile(tenantId, mapped, stationId, originalRequest.connectorId, ChargingLimitSourceEnum.CSO, true);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
this._logger.error(`OCPP 1.6 SetChargingProfile accepted but original request not found by CorrelationId ${message.context.correlationId}.`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
this._logger.error(`OCPP 1.6 SetChargingProfile rejected: ${JSON.stringify(message.payload)}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
async _handleOcpp16ClearChargingProfile(message, props) {
|
|
341
|
+
this._logger.debug('OCPP 1.6 ClearChargingProfileResponse received:', message, props);
|
|
342
|
+
const tenantId = message.context.tenantId;
|
|
343
|
+
if (message.payload.status === OCPP1_6.ClearChargingProfileResponseStatus.Accepted) {
|
|
344
|
+
const stationId = message.context.stationId;
|
|
345
|
+
// Set existed profiles to isActive false
|
|
346
|
+
await this._chargingProfileRepository.updateAllByQuery(tenantId, {
|
|
347
|
+
isActive: false,
|
|
348
|
+
}, {
|
|
349
|
+
where: {
|
|
350
|
+
tenantId: tenantId,
|
|
351
|
+
stationId: stationId,
|
|
352
|
+
isActive: true,
|
|
353
|
+
},
|
|
354
|
+
returning: false,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
this._logger.error(`OCPP 1.6 ClearChargingProfile failed: ${JSON.stringify(message.payload)}`);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
async _handleOcpp16GetCompositeSchedule(message, props) {
|
|
362
|
+
this._logger.debug('OCPP 1.6 GetCompositeScheduleResponse received:', message, props);
|
|
363
|
+
const tenantId = message.context.tenantId;
|
|
364
|
+
const stationId = message.context.stationId;
|
|
365
|
+
const response = message.payload;
|
|
366
|
+
if (response.status === OCPP1_6.GetCompositeScheduleResponseStatus.Accepted &&
|
|
367
|
+
response.chargingSchedule) {
|
|
368
|
+
const compositeSchedule = {
|
|
369
|
+
evseId: response.connectorId ?? 0,
|
|
370
|
+
duration: response.chargingSchedule.duration ?? 0,
|
|
371
|
+
scheduleStart: response.chargingSchedule.startSchedule ?? new Date().toISOString(),
|
|
372
|
+
chargingRateUnit: response.chargingSchedule
|
|
373
|
+
.chargingRateUnit,
|
|
374
|
+
chargingSchedulePeriod: response.chargingSchedule.chargingSchedulePeriod.map((p) => ({
|
|
375
|
+
startPeriod: p.startPeriod,
|
|
376
|
+
limit: p.limit,
|
|
377
|
+
numberPhases: p.numberPhases ?? undefined,
|
|
378
|
+
})),
|
|
379
|
+
};
|
|
380
|
+
const saved = await this._chargingProfileRepository.createCompositeSchedule(tenantId, compositeSchedule, stationId);
|
|
381
|
+
this._logger.info(`OCPP 1.6 Composite schedule created: ${JSON.stringify(saved)}`);
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
this._logger.error(`OCPP 1.6 GetCompositeSchedule failed: ${JSON.stringify(response)}`);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
__decorate([
|
|
389
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.NotifyEVChargingNeeds),
|
|
390
|
+
__metadata("design:type", Function),
|
|
391
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
392
|
+
__metadata("design:returntype", Promise)
|
|
393
|
+
], SmartChargingModule.prototype, "_handleNotifyEVChargingNeeds", null);
|
|
394
|
+
__decorate([
|
|
395
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.NotifyEVChargingSchedule),
|
|
396
|
+
__metadata("design:type", Function),
|
|
397
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
398
|
+
__metadata("design:returntype", Promise)
|
|
399
|
+
], SmartChargingModule.prototype, "_handleNotifyEVChargingSchedule", null);
|
|
400
|
+
__decorate([
|
|
401
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.NotifyChargingLimit),
|
|
402
|
+
__metadata("design:type", Function),
|
|
403
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
404
|
+
__metadata("design:returntype", Promise)
|
|
405
|
+
], SmartChargingModule.prototype, "_handleNotifyChargingLimit", null);
|
|
406
|
+
__decorate([
|
|
407
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.ReportChargingProfiles),
|
|
408
|
+
__metadata("design:type", Function),
|
|
409
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
410
|
+
__metadata("design:returntype", Promise)
|
|
411
|
+
], SmartChargingModule.prototype, "_handleReportChargingProfiles", null);
|
|
412
|
+
__decorate([
|
|
413
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.ClearChargingProfile),
|
|
414
|
+
__metadata("design:type", Function),
|
|
415
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
416
|
+
__metadata("design:returntype", Promise)
|
|
417
|
+
], SmartChargingModule.prototype, "_handleClearChargingProfile", null);
|
|
418
|
+
__decorate([
|
|
419
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.GetChargingProfiles),
|
|
420
|
+
__metadata("design:type", Function),
|
|
421
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
422
|
+
__metadata("design:returntype", void 0)
|
|
423
|
+
], SmartChargingModule.prototype, "_handleGetChargingProfiles", null);
|
|
424
|
+
__decorate([
|
|
425
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.SetChargingProfile),
|
|
426
|
+
__metadata("design:type", Function),
|
|
427
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
428
|
+
__metadata("design:returntype", Promise)
|
|
429
|
+
], SmartChargingModule.prototype, "_handleSetChargingProfile", null);
|
|
430
|
+
__decorate([
|
|
431
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.ClearedChargingLimit),
|
|
432
|
+
__metadata("design:type", Function),
|
|
433
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
434
|
+
__metadata("design:returntype", Promise)
|
|
435
|
+
], SmartChargingModule.prototype, "_handleClearedChargingLimit", null);
|
|
436
|
+
__decorate([
|
|
437
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.GetCompositeSchedule),
|
|
438
|
+
__metadata("design:type", Function),
|
|
439
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
440
|
+
__metadata("design:returntype", Promise)
|
|
441
|
+
], SmartChargingModule.prototype, "_handleGetCompositeSchedule", null);
|
|
442
|
+
__decorate([
|
|
443
|
+
AsHandler(OCPPVersion.OCPP1_6, OCPP1_6_CallAction.SetChargingProfile),
|
|
444
|
+
__metadata("design:type", Function),
|
|
445
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
446
|
+
__metadata("design:returntype", Promise)
|
|
447
|
+
], SmartChargingModule.prototype, "_handleOcpp16SetChargingProfile", null);
|
|
448
|
+
__decorate([
|
|
449
|
+
AsHandler(OCPPVersion.OCPP1_6, OCPP1_6_CallAction.ClearChargingProfile),
|
|
450
|
+
__metadata("design:type", Function),
|
|
451
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
452
|
+
__metadata("design:returntype", Promise)
|
|
453
|
+
], SmartChargingModule.prototype, "_handleOcpp16ClearChargingProfile", null);
|
|
454
|
+
__decorate([
|
|
455
|
+
AsHandler(OCPPVersion.OCPP1_6, OCPP1_6_CallAction.GetCompositeSchedule),
|
|
456
|
+
__metadata("design:type", Function),
|
|
457
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
458
|
+
__metadata("design:returntype", Promise)
|
|
459
|
+
], SmartChargingModule.prototype, "_handleOcpp16GetCompositeSchedule", null);
|
|
460
|
+
//# sourceMappingURL=module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/module/module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ISmartCharging } from './SmartCharging.js';
|
|
2
|
+
import { OCPP2_0_1 } from '@citrineos/base';
|
|
3
|
+
import type { IChargingProfileRepository } from '@citrineos/data';
|
|
4
|
+
import { Transaction } from '@citrineos/data';
|
|
5
|
+
import type { ILogObj } from 'tslog';
|
|
6
|
+
import { Logger } from 'tslog';
|
|
7
|
+
export declare class InternalSmartCharging implements ISmartCharging {
|
|
8
|
+
protected _chargingProfileRepository: IChargingProfileRepository;
|
|
9
|
+
protected readonly _logger: Logger<ILogObj>;
|
|
10
|
+
constructor(chargingProfileRepository: IChargingProfileRepository, logger?: Logger<ILogObj>);
|
|
11
|
+
/**
|
|
12
|
+
* Generates a `ChargingProfileType` from the given `NotifyEVChargingNeedsRequest`.
|
|
13
|
+
*
|
|
14
|
+
* This method creates a charging profile based on the EV's charging needs and the specified energy transfer mode.
|
|
15
|
+
* The profile includes the necessary parameters to set up a charging schedule for the EV.
|
|
16
|
+
*
|
|
17
|
+
* @param request - The `NotifyEVChargingNeedsRequest` containing details about the EV's charging requirements.
|
|
18
|
+
* @param transaction - The ID of the transaction associated with the charging profile.
|
|
19
|
+
* @param stationId - The ID of the station
|
|
20
|
+
* @returns A `ChargingProfileType`.
|
|
21
|
+
*
|
|
22
|
+
* @throws Error if the energy transfer mode is unsupported.
|
|
23
|
+
*/
|
|
24
|
+
calculateChargingProfile(request: OCPP2_0_1.NotifyEVChargingNeedsRequest, transaction: Transaction, tenantId: number, stationId: string): Promise<OCPP2_0_1.ChargingProfileType>;
|
|
25
|
+
checkLimitsOfChargingSchedule(request: OCPP2_0_1.NotifyEVChargingScheduleRequest, tenantId: number, stationId: string, transaction: Transaction): Promise<void>;
|
|
26
|
+
private _getChargingRateUnitAndLimit;
|
|
27
|
+
private _findExistingChargingProfileWithHighestStackLevel;
|
|
28
|
+
private _validateLimitAgainstExistingProfile;
|
|
29
|
+
}
|