import type { JSONSchemaType } from 'ajv';
-import { type ChargingStation, getIdTagsFile } from '../../../charging-station';
+import { OCPP16Constants } from './OCPP16Constants';
+import { type ChargingStation, hasFeatureProfile } from '../../../charging-station';
import { OCPPError } from '../../../exception';
import {
- type ConnectorStatus,
+ type ClearChargingProfileRequest,
CurrentType,
ErrorType,
type JsonType,
MeterValueContext,
MeterValueLocation,
MeterValueUnit,
- OCPP16AuthorizationStatus,
- type OCPP16AuthorizeRequest,
- type OCPP16AuthorizeResponse,
+ OCPP16AvailabilityType,
+ type OCPP16ChangeAvailabilityResponse,
+ OCPP16ChargePointStatus,
type OCPP16ChargingProfile,
type OCPP16IncomingRequestCommand,
type OCPP16MeterValue,
getRandomFloatRounded,
getRandomInteger,
isNotEmptyArray,
- isNotEmptyString,
isNullOrUndefined,
isUndefined,
logger,
featureProfile: OCPP16SupportedFeatureProfiles,
command: OCPP16RequestCommand | OCPP16IncomingRequestCommand,
): boolean {
- if (!chargingStation.hasFeatureProfile(featureProfile)) {
+ if (!hasFeatureProfile(chargingStation, featureProfile)) {
logger.warn(
`${chargingStation.logPrefix()} Trying to '${command}' without '${featureProfile}' feature enabled in ${
OCPP16StandardParametersKey.SupportedFeatureProfiles
const phaseValue = `L${phase}-N`;
meterValue.sampledValue.push(
OCPP16ServiceUtils.buildSampledValue(
- (powerPerPhaseSampledValueTemplates[`L${phase}`] as SampledValueTemplate) ??
- powerSampledValueTemplate,
- powerMeasurandValues[`L${phase}`] as number,
+ powerPerPhaseSampledValueTemplates[
+ `L${phase}` as keyof MeasurandPerPhaseSampledValueTemplates
+ ]! ?? powerSampledValueTemplate,
+ powerMeasurandValues[`L${phase}` as keyof MeasurandPerPhaseSampledValueTemplates],
undefined,
phaseValue as OCPP16MeterValuePhase,
),
const phaseValue = `L${phase}`;
meterValue.sampledValue.push(
OCPP16ServiceUtils.buildSampledValue(
- (currentPerPhaseSampledValueTemplates[phaseValue] as SampledValueTemplate) ??
- currentSampledValueTemplate,
- currentMeasurandValues[phaseValue] as number,
+ currentPerPhaseSampledValueTemplates[
+ phaseValue as keyof MeasurandPerPhaseSampledValueTemplates
+ ]! ?? currentSampledValueTemplate,
+ currentMeasurandValues[phaseValue as keyof MeasurandPerPhaseSampledValueTemplates],
undefined,
phaseValue as OCPP16MeterValuePhase,
),
`${chargingStation.logPrefix()} MeterValues measurand ${
meterValue.sampledValue[sampledValuesIndex].measurand ??
OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
- }: connector id ${connectorId}, transaction id ${connector?.transactionId}, value: ${energyValueRounded}/${connectorMaximumEnergyRounded}, duration: ${roundTo(
- interval / (3600 * 1000),
- 4,
- )}h`,
+ }: connector id ${connectorId}, transaction id ${connector?.transactionId}, value: ${energyValueRounded}/${connectorMaximumEnergyRounded}, duration: ${interval}ms`,
);
}
}
return meterValues;
}
+ public static changeAvailability = async (
+ chargingStation: ChargingStation,
+ connectorId: number,
+ chargePointStatus: OCPP16ChargePointStatus,
+ availabilityType: OCPP16AvailabilityType,
+ ): Promise<OCPP16ChangeAvailabilityResponse> => {
+ let response: OCPP16ChangeAvailabilityResponse =
+ OCPP16Constants.OCPP_AVAILABILITY_RESPONSE_ACCEPTED;
+ const connectorStatus = chargingStation.getConnectorStatus(connectorId)!;
+ if (connectorStatus?.transactionStarted === true) {
+ response = OCPP16Constants.OCPP_AVAILABILITY_RESPONSE_SCHEDULED;
+ }
+ connectorStatus.availability = availabilityType;
+ if (response === OCPP16Constants.OCPP_AVAILABILITY_RESPONSE_ACCEPTED) {
+ await OCPP16ServiceUtils.sendAndSetConnectorStatus(
+ chargingStation,
+ connectorId,
+ chargePointStatus,
+ );
+ }
+ return response;
+ };
+
public static setChargingProfile(
chargingStation: ChargingStation,
connectorId: number,
!cpReplaced && chargingStation.getConnectorStatus(connectorId)?.chargingProfiles?.push(cp);
}
+ public static clearChargingProfiles = (
+ chargingStation: ChargingStation,
+ commandPayload: ClearChargingProfileRequest,
+ chargingProfiles: OCPP16ChargingProfile[] | undefined,
+ ): boolean => {
+ let clearedCP = false;
+ if (isNotEmptyArray(chargingProfiles)) {
+ chargingProfiles?.forEach((chargingProfile: OCPP16ChargingProfile, index: number) => {
+ let clearCurrentCP = false;
+ if (chargingProfile.chargingProfileId === commandPayload.id) {
+ clearCurrentCP = true;
+ }
+ if (
+ !commandPayload.chargingProfilePurpose &&
+ chargingProfile.stackLevel === commandPayload.stackLevel
+ ) {
+ clearCurrentCP = true;
+ }
+ if (
+ !chargingProfile.stackLevel &&
+ chargingProfile.chargingProfilePurpose === commandPayload.chargingProfilePurpose
+ ) {
+ clearCurrentCP = true;
+ }
+ if (
+ chargingProfile.stackLevel === commandPayload.stackLevel &&
+ chargingProfile.chargingProfilePurpose === commandPayload.chargingProfilePurpose
+ ) {
+ clearCurrentCP = true;
+ }
+ if (clearCurrentCP) {
+ chargingProfiles.splice(index, 1);
+ logger.debug(
+ `${chargingStation.logPrefix()} Matching charging profile(s) cleared: %j`,
+ chargingProfile,
+ );
+ clearedCP = true;
+ }
+ });
+ }
+ return clearedCP;
+ };
+
public static parseJsonSchemaFile<T extends JsonType>(
relativePath: string,
moduleName?: string,
);
}
- public static async isIdTagAuthorized(
- chargingStation: ChargingStation,
- connectorId: number,
- idTag: string,
- ): Promise<boolean> {
- let authorized = false;
- const connectorStatus: ConnectorStatus = chargingStation.getConnectorStatus(connectorId)!;
- if (OCPP16ServiceUtils.isIdTagLocalAuthorized(chargingStation, idTag)) {
- connectorStatus.localAuthorizeIdTag = idTag;
- connectorStatus.idTagLocalAuthorized = true;
- authorized = true;
- } else if (chargingStation.getMustAuthorizeAtRemoteStart() === true) {
- connectorStatus.authorizeIdTag = idTag;
- authorized = await OCPP16ServiceUtils.isIdTagRemoteAuthorized(chargingStation, idTag);
- } else {
- logger.warn(
- `${chargingStation.logPrefix()} The charging station configuration expects authorize at
- remote start transaction but local authorization or authorize isn't enabled`,
- );
- }
- return authorized;
- }
-
private static buildSampledValue(
sampledValueTemplate: SampledValueTemplate,
value: number,
return MeterValueUnit.VOLT;
}
}
-
- private static isIdTagLocalAuthorized(chargingStation: ChargingStation, idTag: string): boolean {
- return (
- chargingStation.getLocalAuthListEnabled() === true &&
- chargingStation.hasIdTags() === true &&
- isNotEmptyString(
- chargingStation.idTagsCache
- .getIdTags(getIdTagsFile(chargingStation.stationInfo)!)
- ?.find((tag) => tag === idTag),
- )
- );
- }
-
- private static async isIdTagRemoteAuthorized(
- chargingStation: ChargingStation,
- idTag: string,
- ): Promise<boolean> {
- const authorizeResponse: OCPP16AuthorizeResponse =
- await chargingStation.ocppRequestService.requestHandler<
- OCPP16AuthorizeRequest,
- OCPP16AuthorizeResponse
- >(chargingStation, OCPP16RequestCommand.AUTHORIZE, {
- idTag: idTag,
- });
- return authorizeResponse?.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED;
- }
}