X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2Focpp%2F1.6%2FOCPP16RequestService.ts;h=f4f1782ee97a6716e81206a1917c926221dd6e30;hb=e58068fde9b27e3de6733be24fc7b3dfac37331b;hp=1f19e858717b097990ceca04f9d3d9a7e73756fc;hpb=2891f7616d9f39d05f5c47876e29d2dbdbe9f6a5;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts index 1f19e858..f4f1782e 100644 --- a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts @@ -7,6 +7,7 @@ import { DiagnosticsStatusNotificationRequest, HeartbeatRequest, OCPP16BootNotif import { MeterValueUnit, MeterValuesRequest, OCPP16MeterValue, OCPP16MeterValueMeasurand, OCPP16MeterValuePhase } from '../../../types/ocpp/1.6/MeterValues'; import Constants from '../../../utils/Constants'; +import { ErrorType } from '../../../types/ocpp/ErrorType'; import MeasurandPerPhaseSampledValueTemplates from '../../../types/MeasurandPerPhaseSampledValueTemplates'; import MeasurandValues from '../../../types/MeasurandValues'; import { MessageType } from '../../../types/ocpp/MessageType'; @@ -15,7 +16,7 @@ import { OCPP16ChargePointErrorCode } from '../../../types/ocpp/1.6/ChargePointE import { OCPP16ChargePointStatus } from '../../../types/ocpp/1.6/ChargePointStatus'; import { OCPP16DiagnosticsStatus } from '../../../types/ocpp/1.6/DiagnosticsStatus'; import { OCPP16ServiceUtils } from './OCPP16ServiceUtils'; -import OCPPError from '../../OCPPError'; +import OCPPError from '../../../exception/OCPPError'; import OCPPRequestService from '../OCPPRequestService'; import Utils from '../../../utils/Utils'; import logger from '../../../utils/Logger'; @@ -26,7 +27,7 @@ export default class OCPP16RequestService extends OCPPRequestService { const payload: HeartbeatRequest = {}; await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.HEARTBEAT); } catch (error) { - this.handleRequestError(OCPP16RequestCommand.HEARTBEAT, error); + this.handleRequestError(OCPP16RequestCommand.HEARTBEAT, error as Error); } } @@ -44,9 +45,9 @@ export default class OCPP16RequestService extends OCPPRequestService { ...!Utils.isUndefined(meterSerialNumber) && { meterSerialNumber }, ...!Utils.isUndefined(meterType) && { meterType } }; - return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.BOOT_NOTIFICATION) as OCPP16BootNotificationResponse; + return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.BOOT_NOTIFICATION, true) as OCPP16BootNotificationResponse; } catch (error) { - this.handleRequestError(OCPP16RequestCommand.BOOT_NOTIFICATION, error); + this.handleRequestError(OCPP16RequestCommand.BOOT_NOTIFICATION, error as Error); } } @@ -60,7 +61,7 @@ export default class OCPP16RequestService extends OCPPRequestService { }; await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.STATUS_NOTIFICATION); } catch (error) { - this.handleRequestError(OCPP16RequestCommand.STATUS_NOTIFICATION, error); + this.handleRequestError(OCPP16RequestCommand.STATUS_NOTIFICATION, error as Error); } } @@ -69,10 +70,10 @@ export default class OCPP16RequestService extends OCPPRequestService { const payload: AuthorizeRequest = { ...!Utils.isUndefined(idTag) ? { idTag } : { idTag: Constants.TRANSACTION_DEFAULT_IDTAG }, }; - this.chargingStation.getConnector(connectorId).authorizeIdTag = idTag; + this.chargingStation.getConnectorStatus(connectorId).authorizeIdTag = idTag; return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.AUTHORIZE) as OCPP16AuthorizeResponse; } catch (error) { - this.handleRequestError(OCPP16RequestCommand.AUTHORIZE, error); + this.handleRequestError(OCPP16RequestCommand.AUTHORIZE, error as Error); } } @@ -86,7 +87,7 @@ export default class OCPP16RequestService extends OCPPRequestService { }; return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.START_TRANSACTION) as OCPP16StartTransactionResponse; } catch (error) { - this.handleRequestError(OCPP16RequestCommand.START_TRANSACTION, error); + this.handleRequestError(OCPP16RequestCommand.START_TRANSACTION, error as Error); } } @@ -94,9 +95,9 @@ export default class OCPP16RequestService extends OCPPRequestService { reason: OCPP16StopTransactionReason = OCPP16StopTransactionReason.NONE): Promise { try { let connectorId: number; - for (const connector in this.chargingStation.connectors) { - if (Utils.convertToInt(connector) > 0 && this.chargingStation.getConnector(Utils.convertToInt(connector))?.transactionId === transactionId) { - connectorId = Utils.convertToInt(connector); + for (const id of this.chargingStation.connectors.keys()) { + if (id > 0 && this.chargingStation.getConnectorStatus(id)?.transactionId === transactionId) { + connectorId = id; break; } } @@ -110,28 +111,27 @@ export default class OCPP16RequestService extends OCPPRequestService { meterStop, timestamp: new Date().toISOString(), ...reason && { reason }, - ...this.chargingStation.getTransactionDataMeterValues() && { transactionData: OCPP16ServiceUtils.buildTransactionDataMeterValues(this.chargingStation.getConnector(connectorId).transactionBeginMeterValue, transactionEndMeterValue) }, + ...this.chargingStation.getTransactionDataMeterValues() && { transactionData: OCPP16ServiceUtils.buildTransactionDataMeterValues(this.chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue, transactionEndMeterValue) }, }; return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.STOP_TRANSACTION) as OCPP16StartTransactionResponse; } catch (error) { - this.handleRequestError(OCPP16RequestCommand.STOP_TRANSACTION, error); + this.handleRequestError(OCPP16RequestCommand.STOP_TRANSACTION, error as Error); } } - // eslint-disable-next-line consistent-this public async sendMeterValues(connectorId: number, transactionId: number, interval: number, debug = false): Promise { try { const meterValue: OCPP16MeterValue = { timestamp: new Date().toISOString(), sampledValue: [], }; - const connector = this.chargingStation.getConnector(connectorId); + const connector = this.chargingStation.getConnectorStatus(connectorId); // SoC measurand const socSampledValueTemplate = this.chargingStation.getSampledValueTemplate(connectorId, OCPP16MeterValueMeasurand.STATE_OF_CHARGE); if (socSampledValueTemplate) { const socSampledValueTemplateValue = socSampledValueTemplate.value ? Utils.getRandomFloatFluctuatedRounded(parseInt(socSampledValueTemplate.value), socSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT) - : Utils.getRandomInt(100); + : Utils.getRandomInteger(100); meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(socSampledValueTemplate, socSampledValueTemplateValue)); const sampledValuesIndex = meterValue.sampledValue.length - 1; if (Utils.convertToInt(meterValue.sampledValue[sampledValuesIndex].value) > 100 || debug) { @@ -221,7 +221,7 @@ export default class OCPP16RequestService extends OCPPRequestService { break; default: logger.error(errMsg); - throw new Error(errMsg); + throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES); } meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(powerSampledValueTemplate, powerMeasurandValues.allPhases)); const sampledValuesIndex = meterValue.sampledValue.length - 1; @@ -287,7 +287,7 @@ export default class OCPP16RequestService extends OCPPRequestService { break; default: logger.error(errMsg); - throw new Error(errMsg); + throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES); } meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(currentSampledValueTemplate, currentMeasurandValues.allPhases)); const sampledValuesIndex = meterValue.sampledValue.length - 1; @@ -309,26 +309,25 @@ export default class OCPP16RequestService extends OCPPRequestService { if (energySampledValueTemplate) { OCPP16ServiceUtils.checkMeasurandPowerDivider(this.chargingStation, energySampledValueTemplate.measurand); const unitDivider = energySampledValueTemplate?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1; - const energyMeasurandValue = energySampledValueTemplate.value + const maxEnergyRounded = Utils.roundTo(((this.chargingStation.stationInfo.maxPower / this.chargingStation.stationInfo.powerDivider) * interval) / (3600 * 1000), 2); + const energyValueRounded = energySampledValueTemplate.value // Cumulate the fluctuated value around the static one ? Utils.getRandomFloatFluctuatedRounded(parseInt(energySampledValueTemplate.value), energySampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT) - : Utils.getRandomInt(this.chargingStation.stationInfo.maxPower / (this.chargingStation.stationInfo.powerDivider * 3600000) * interval); + : Utils.getRandomFloatRounded(maxEnergyRounded); // Persist previous value on connector if (connector && !Utils.isNullOrUndefined(connector.energyActiveImportRegisterValue) && connector.energyActiveImportRegisterValue >= 0 && !Utils.isNullOrUndefined(connector.transactionEnergyActiveImportRegisterValue) && connector.transactionEnergyActiveImportRegisterValue >= 0) { - connector.energyActiveImportRegisterValue += energyMeasurandValue; - connector.transactionEnergyActiveImportRegisterValue += energyMeasurandValue; + connector.energyActiveImportRegisterValue += energyValueRounded; + connector.transactionEnergyActiveImportRegisterValue += energyValueRounded; } else { connector.energyActiveImportRegisterValue = 0; connector.transactionEnergyActiveImportRegisterValue = 0; } meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(energySampledValueTemplate, - Utils.roundTo(this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId) / unitDivider, 4))); + Utils.roundTo(this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId) / unitDivider, 2))); const sampledValuesIndex = meterValue.sampledValue.length - 1; - const maxEnergy = Math.round(this.chargingStation.stationInfo.maxPower * 3600 / (this.chargingStation.stationInfo.powerDivider * interval)); - const maxEnergyRounded = Utils.roundTo(maxEnergy / unitDivider, 4); - if (Utils.convertToFloat(meterValue.sampledValue[sampledValuesIndex].value) > maxEnergyRounded || debug) { - logger.error(`${this.chargingStation.logPrefix()} MeterValues measurand ${meterValue.sampledValue[sampledValuesIndex].measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${meterValue.sampledValue[sampledValuesIndex].value}/${maxEnergyRounded}`); + if (energyValueRounded > maxEnergyRounded || debug) { + logger.error(`${this.chargingStation.logPrefix()} MeterValues measurand ${meterValue.sampledValue[sampledValuesIndex].measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${energyValueRounded}/${maxEnergyRounded}, duration: ${Utils.roundTo(interval / (3600 * 1000), 4)}h`); } } const payload: MeterValuesRequest = { @@ -338,7 +337,7 @@ export default class OCPP16RequestService extends OCPPRequestService { }; await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.METER_VALUES); } catch (error) { - this.handleRequestError(OCPP16RequestCommand.METER_VALUES, error); + this.handleRequestError(OCPP16RequestCommand.METER_VALUES, error as Error); } } @@ -351,7 +350,7 @@ export default class OCPP16RequestService extends OCPPRequestService { }; await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.METER_VALUES); } catch (error) { - this.handleRequestError(OCPP16RequestCommand.METER_VALUES, error); + this.handleRequestError(OCPP16RequestCommand.METER_VALUES, error as Error); } } @@ -364,7 +363,7 @@ export default class OCPP16RequestService extends OCPPRequestService { }; await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.METER_VALUES); } catch (error) { - this.handleRequestError(OCPP16RequestCommand.METER_VALUES, error); + this.handleRequestError(OCPP16RequestCommand.METER_VALUES, error as Error); } } @@ -375,7 +374,16 @@ export default class OCPP16RequestService extends OCPPRequestService { }; await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION); } catch (error) { - this.handleRequestError(OCPP16RequestCommand.METER_VALUES, error); + this.handleRequestError(OCPP16RequestCommand.METER_VALUES, error as Error); + } + } + + public async sendResult(messageId: string, resultMessageData: Record, commandName: OCPP16RequestCommand | OCPP16IncomingRequestCommand): Promise { + try { + // Send error + return await this.sendMessage(messageId, resultMessageData, MessageType.CALL_RESULT_MESSAGE, commandName); + } catch (err) { + this.handleRequestError(commandName as OCPP16RequestCommand, err as Error); } } @@ -384,7 +392,7 @@ export default class OCPP16RequestService extends OCPPRequestService { // Send error return await this.sendMessage(messageId, error, MessageType.CALL_ERROR_MESSAGE, commandName); } catch (err) { - this.handleRequestError(commandName as OCPP16RequestCommand, err); + this.handleRequestError(commandName as OCPP16RequestCommand, err as Error); } } }