From 4a1857a25fbcc203def0c0b1a6c5ebcb19602fe6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sat, 12 Jun 2021 21:23:46 +0200 Subject: [PATCH] Add support for unit in meter values. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- README.md | 2 +- package-lock.json | 96 +++++++++++-------- package.json | 4 +- src/charging-station/ChargingStation.ts | 1 - .../ocpp/1.6/OCPP16RequestService.ts | 43 +++++---- .../ocpp/1.6/OCPP16ServiceUtils.ts | 4 +- src/types/Connectors.ts | 4 +- 7 files changed, 86 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index 148665b4..c544417a 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ chargePointModel | | '' | string | charging stations model chargePointVendor | | '' | string | charging stations vendor chargeBoxSerialNumberPrefix | | '' | string | charging stations serial number prefix firmwareVersion | | '' | string | charging stations firmware version -power | | | integer\|integer[] | charging stations maximum power value(s) +power | | | float\|float[] | charging stations maximum power value(s) powerSharedByConnectors | true/false | false | boolean | charging stations power shared by its connectors powerUnit | W/kW | W | string | charging stations power unit currentOutType | AC/DC | AC | string | charging stations current out type diff --git a/package-lock.json b/package-lock.json index 102dd164..0be6e913 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1480,14 +1480,14 @@ } }, "@octokit/core": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.4.0.tgz", - "integrity": "sha512-6/vlKPP8NF17cgYXqucdshWqmMZGXkuvtcrWCgU5NOI0Pl2GjlmZyWgBMrU8zJ3v2MJlM6++CiB45VKYmhiWWg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.0.tgz", + "integrity": "sha512-IKcyllVQe6KPwPPFIaKdbhNNQhmmHIj69PXOseBF6/NglXoKHVe79syEfZj0bz7sP87MOl5jLZadV3slgdZ1vQ==", "dev": true, "requires": { "@octokit/auth-token": "^2.4.4", "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.4.12", + "@octokit/request": "^5.6.0", "@octokit/request-error": "^2.0.5", "@octokit/types": "^6.0.3", "before-after-hook": "^2.2.0", @@ -1495,9 +1495,9 @@ } }, "@octokit/endpoint": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.11.tgz", - "integrity": "sha512-fUIPpx+pZyoLW4GCs3yMnlj2LfoXTWDUVPTC4V3MUEKZm48W+XYpeWSZCv+vYF1ZABUm2CqnDVf1sFtIYrj7KQ==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", "dev": true, "requires": { "@octokit/types": "^6.0.3", @@ -1514,35 +1514,35 @@ } }, "@octokit/graphql": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.2.tgz", - "integrity": "sha512-WmsIR1OzOr/3IqfG9JIczI8gMJUMzzyx5j0XXQ4YihHtKlQc+u35VpVoOXhlKAlaBntvry1WpAzPl/a+s3n89Q==", + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.4.tgz", + "integrity": "sha512-SWTdXsVheRmlotWNjKzPOb6Js6tjSqA2a8z9+glDJng0Aqjzti8MEWOtuT8ZSu6wHnci7LZNuarE87+WJBG4vg==", "dev": true, "requires": { - "@octokit/request": "^5.3.0", + "@octokit/request": "^5.6.0", "@octokit/types": "^6.0.3", "universal-user-agent": "^6.0.0" } }, "@octokit/openapi-types": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-7.2.3.tgz", - "integrity": "sha512-V1ycxkR19jqbIl3evf2RQiMRBvTNRi+Iy9h20G5OP5dPfEF6GJ1DPlUeiZRxo2HJxRr+UA4i0H1nn4btBDPFrw==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-7.3.2.tgz", + "integrity": "sha512-oJhK/yhl9Gt430OrZOzAl2wJqR0No9445vmZ9Ey8GjUZUpwuu/vmEFP0TDhDXdpGDoxD6/EIFHJEcY8nHXpDTA==", "dev": true }, "@octokit/plugin-paginate-rest": { - "version": "2.13.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.13.3.tgz", - "integrity": "sha512-46lptzM9lTeSmIBt/sVP/FLSTPGx6DCzAdSX3PfeJ3mTf4h9sGC26WpaQzMEq/Z44cOcmx8VsOhO+uEgE3cjYg==", + "version": "2.13.5", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.13.5.tgz", + "integrity": "sha512-3WSAKBLa1RaR/7GG+LQR/tAZ9fp9H9waE9aPXallidyci9oZsfgsLn5M836d3LuDC6Fcym+2idRTBpssHZePVg==", "dev": true, "requires": { - "@octokit/types": "^6.11.0" + "@octokit/types": "^6.13.0" } }, "@octokit/plugin-request-log": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.3.tgz", - "integrity": "sha512-4RFU4li238jMJAzLgAwkBAw+4Loile5haQMQr+uhFq27BmyJXcXSKvoQKqh0agsZEiUlW6iSv3FAgvmGkur7OQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", "dev": true }, "@octokit/plugin-rest-endpoint-methods": { @@ -1556,13 +1556,13 @@ } }, "@octokit/request": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.5.0.tgz", - "integrity": "sha512-jxbMLQdQ3heFMZUaTLSCqcKs2oAHEYh7SnLLXyxbZmlULExZ/RXai7QUWWFKowcGGPlCZuKTZg0gSKHWrfYEoQ==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.0.tgz", + "integrity": "sha512-4cPp/N+NqmaGQwbh3vUsYqokQIzt7VjsgTYVXiwpUP2pxd5YiZB2XuTedbb0SPtv9XS7nzAKjAuQxmY8/aZkiA==", "dev": true, "requires": { "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.0.0", + "@octokit/request-error": "^2.1.0", "@octokit/types": "^6.16.1", "is-plain-object": "^5.0.0", "node-fetch": "^2.6.1", @@ -1584,9 +1584,9 @@ } }, "@octokit/request-error": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.5.tgz", - "integrity": "sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", "dev": true, "requires": { "@octokit/types": "^6.0.3", @@ -1607,12 +1607,12 @@ } }, "@octokit/types": { - "version": "6.16.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.16.2.tgz", - "integrity": "sha512-wWPSynU4oLy3i4KGyk+J1BLwRKyoeW2TwRHgwbDz17WtVFzSK2GOErGliruIx8c+MaYtHSYTx36DSmLNoNbtgA==", + "version": "6.16.4", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.16.4.tgz", + "integrity": "sha512-UxhWCdSzloULfUyamfOg4dJxV9B+XjgrIZscI0VCbp4eNrjmorGEw+4qdwcpTsu6DIrm9tQsFQS2pK5QkqQ04A==", "dev": true, "requires": { - "@octokit/openapi-types": "^7.2.3" + "@octokit/openapi-types": "^7.3.2" } }, "@rollup/plugin-json": { @@ -11869,9 +11869,9 @@ "dev": true }, "release-it": { - "version": "14.8.0", - "resolved": "https://registry.npmjs.org/release-it/-/release-it-14.8.0.tgz", - "integrity": "sha512-XCw4kzJqdKgtis97HcNZ45r5dx+tZhcG1Yu2IEBKym1SceXiLBbycLsfqJQ8z+VLimClKpDeBdJkU03Vo/yFqw==", + "version": "14.9.0", + "resolved": "https://registry.npmjs.org/release-it/-/release-it-14.9.0.tgz", + "integrity": "sha512-Pn9GH60jKkL+dUkVxCyyiIhA9oySu/Q+8F9aExCggcppxfZbhRCxMgmk/iFh+/oejdzQq9zCZSudA2CmWOSKxQ==", "dev": true, "requires": { "@iarna/toml": "2.2.5", @@ -12023,9 +12023,9 @@ } }, "cacheable-request": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz", - "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", "dev": true, "requires": { "clone-response": "^1.0.2", @@ -12033,7 +12033,7 @@ "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", + "normalize-url": "^6.0.1", "responselike": "^2.0.0" }, "dependencies": { @@ -12458,6 +12458,12 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "normalize-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.0.1.tgz", + "integrity": "sha512-VU4pzAuh7Kip71XEmO9aNREYAdMHFGTVj/i+CaTImS8x0i1d3jUZkXhqluy/PRgjPLMgsLQulYY3PJ/aSbSjpQ==", + "dev": true + }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -12639,6 +12645,12 @@ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true + }, "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", @@ -14575,9 +14587,9 @@ } }, "tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" }, "tsutils": { "version": "3.21.0", diff --git a/package.json b/package.json index 87c4f8dd..f8b51b3a 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "mongodb": "^3.6.9", "poolifier": "^2.0.2", "source-map-support": "^0.5.19", - "tslib": "^2.2.0", + "tslib": "^2.3.0", "uuid": "^8.3.2", "winston": "^3.3.3", "winston-daily-rotate-file": "^4.5.5", @@ -93,7 +93,7 @@ "mochawesome": "^6.2.2", "npm-check": "^5.9.2", "nyc": "^15.1.0", - "release-it": "^14.8.0", + "release-it": "^14.9.0", "rollup": "^2.51.2", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-copy": "^3.4.0", diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index ac704ea8..6dce9a37 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -561,7 +561,6 @@ export default class ChargingStation { try { // Parse the message [messageType, messageId, commandName, commandPayload, errorDetails] = JSON.parse(messageEvent.toString()) as IncomingRequest; - // Check the Type of message switch (messageType) { // Incoming Message diff --git a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts index 4f2cac67..3c01d452 100644 --- a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts @@ -1,8 +1,8 @@ +import { ACElectricUtils, DCElectricUtils } from '../../../utils/ElectricUtils'; import { AuthorizeRequest, OCPP16AuthorizeResponse, OCPP16StartTransactionResponse, OCPP16StopTransactionReason, OCPP16StopTransactionResponse, StartTransactionRequest, StopTransactionRequest } from '../../../types/ocpp/1.6/Transaction'; import { HeartbeatRequest, OCPP16BootNotificationRequest, OCPP16IncomingRequestCommand, OCPP16RequestCommand, StatusNotificationRequest } from '../../../types/ocpp/1.6/Requests'; -import { MeterValue, MeterValueContext, MeterValuePhase, MeterValuesRequest, OCPP16MeterValueMeasurand, OCPP16SampledValue } from '../../../types/ocpp/1.6/MeterValues'; +import { MeterValue, MeterValueContext, MeterValuePhase, MeterValueUnit, MeterValuesRequest, OCPP16MeterValueMeasurand, OCPP16SampledValue } from '../../../types/ocpp/1.6/MeterValues'; -import { ACElectricUtils } from '../../../utils/ElectricUtils'; import Constants from '../../../utils/Constants'; import { CurrentOutType } from '../../../types/ChargingStationTemplate'; import MeasurandValues from '../../../types/MeasurandValues'; @@ -145,24 +145,25 @@ export default class OCPP16RequestService extends OCPPRequestService { OCPP16ServiceUtils.checkMeasurandPowerDivider(self.chargingStation, meterValuesTemplate[index].measurand); const errMsg = `${self.chargingStation.logPrefix()} MeterValues measurand ${meterValuesTemplate[index].measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: Unknown ${self.chargingStation.getCurrentOutType()} currentOutType in template file ${self.chargingStation.stationTemplateFile}, cannot calculate ${meterValuesTemplate[index].measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER} measurand value`; const powerMeasurandValues = {} as MeasurandValues; + const unitDivider = meterValuesTemplate[index]?.unit === MeterValueUnit.KILO_WATT ? 1000 : 1; const maxPower = Math.round(self.chargingStation.stationInfo.maxPower / self.chargingStation.stationInfo.powerDivider); const maxPowerPerPhase = Math.round((self.chargingStation.stationInfo.maxPower / self.chargingStation.stationInfo.powerDivider) / self.chargingStation.getNumberOfPhases()); switch (self.chargingStation.getCurrentOutType()) { case CurrentOutType.AC: if (Utils.isUndefined(meterValuesTemplate[index].value)) { - powerMeasurandValues.L1 = Utils.getRandomFloatRounded(maxPowerPerPhase); + powerMeasurandValues.L1 = Utils.getRandomFloatRounded(maxPowerPerPhase / unitDivider); powerMeasurandValues.L2 = 0; powerMeasurandValues.L3 = 0; if (self.chargingStation.getNumberOfPhases() === 3) { - powerMeasurandValues.L2 = Utils.getRandomFloatRounded(maxPowerPerPhase); - powerMeasurandValues.L3 = Utils.getRandomFloatRounded(maxPowerPerPhase); + powerMeasurandValues.L2 = Utils.getRandomFloatRounded(maxPowerPerPhase / unitDivider); + powerMeasurandValues.L3 = Utils.getRandomFloatRounded(maxPowerPerPhase / unitDivider); } powerMeasurandValues.allPhases = Utils.roundTo(powerMeasurandValues.L1 + powerMeasurandValues.L2 + powerMeasurandValues.L3, 2); } break; case CurrentOutType.DC: if (Utils.isUndefined(meterValuesTemplate[index].value)) { - powerMeasurandValues.allPhases = Utils.getRandomFloatRounded(maxPower); + powerMeasurandValues.allPhases = Utils.getRandomFloatRounded(maxPower / unitDivider); } break; default: @@ -171,8 +172,9 @@ export default class OCPP16RequestService extends OCPPRequestService { } meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(meterValuesTemplate[index], powerMeasurandValues.allPhases)); const sampledValuesIndex = meterValue.sampledValue.length - 1; - if (Utils.convertToFloat(meterValue.sampledValue[sampledValuesIndex].value) > maxPower || debug) { - logger.error(`${self.chargingStation.logPrefix()} MeterValues measurand ${meterValue.sampledValue[sampledValuesIndex].measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${meterValue.sampledValue[sampledValuesIndex].value}/${maxPower}`); + const maxPowerRounded = Utils.roundTo(maxPower / unitDivider, 2); + if (Utils.convertToFloat(meterValue.sampledValue[sampledValuesIndex].value) > maxPowerRounded || debug) { + logger.error(`${self.chargingStation.logPrefix()} MeterValues measurand ${meterValue.sampledValue[sampledValuesIndex].measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${meterValue.sampledValue[sampledValuesIndex].value}/${maxPowerRounded}`); } for (let phase = 1; self.chargingStation.getNumberOfPhases() === 3 && phase <= self.chargingStation.getNumberOfPhases(); phase++) { const phaseValue = `L${phase}-N`; @@ -200,7 +202,7 @@ export default class OCPP16RequestService extends OCPPRequestService { } break; case CurrentOutType.DC: - maxAmperage = ACElectricUtils.amperageTotalFromPower(self.chargingStation.stationInfo.maxPower / self.chargingStation.stationInfo.powerDivider, self.chargingStation.getVoltageOut()); + maxAmperage = DCElectricUtils.amperage(self.chargingStation.stationInfo.maxPower / self.chargingStation.stationInfo.powerDivider, self.chargingStation.getVoltageOut()); if (Utils.isUndefined(meterValuesTemplate[index].value)) { currentMeasurandValues.allPhases = Utils.getRandomFloatRounded(maxAmperage); } @@ -222,24 +224,26 @@ export default class OCPP16RequestService extends OCPPRequestService { // Energy.Active.Import.Register measurand (default) } else if (!meterValuesTemplate[index].measurand || meterValuesTemplate[index].measurand === OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER) { OCPP16ServiceUtils.checkMeasurandPowerDivider(self.chargingStation, meterValuesTemplate[index].measurand); + const unitDivider = meterValuesTemplate[index]?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1; if (Utils.isUndefined(meterValuesTemplate[index].value)) { - const measurandValue = Utils.getRandomInt(self.chargingStation.stationInfo.maxPower / (self.chargingStation.stationInfo.powerDivider * 3600000) * interval); + const energyMeasurandValue = Utils.getRandomInt(self.chargingStation.stationInfo.maxPower / (self.chargingStation.stationInfo.powerDivider * 3600000) * interval); // Persist previous value in connector if (connector && !Utils.isNullOrUndefined(connector.energyActiveImportRegisterValue) && connector.energyActiveImportRegisterValue >= 0 && !Utils.isNullOrUndefined(connector.transactionEnergyActiveImportRegisterValue) && connector.transactionEnergyActiveImportRegisterValue >= 0) { - connector.energyActiveImportRegisterValue += measurandValue; - connector.transactionEnergyActiveImportRegisterValue += measurandValue; + connector.energyActiveImportRegisterValue += energyMeasurandValue; + connector.transactionEnergyActiveImportRegisterValue += energyMeasurandValue; } else { connector.energyActiveImportRegisterValue = 0; connector.transactionEnergyActiveImportRegisterValue = 0; } } meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(meterValuesTemplate[index], - self.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId))); + Utils.roundTo(self.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId) / unitDivider, 4))); const sampledValuesIndex = meterValue.sampledValue.length - 1; - const maxConsumption = Math.round(self.chargingStation.stationInfo.maxPower * 3600 / (self.chargingStation.stationInfo.powerDivider * interval)); - if (Utils.convertToFloat(meterValue.sampledValue[sampledValuesIndex].value) > maxConsumption || debug) { - logger.error(`${self.chargingStation.logPrefix()} MeterValues measurand ${meterValue.sampledValue[sampledValuesIndex].measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${meterValue.sampledValue[sampledValuesIndex].value}/${maxConsumption}`); + const maxEnergy = Math.round(self.chargingStation.stationInfo.maxPower * 3600 / (self.chargingStation.stationInfo.powerDivider * interval)); + const maxEnergyRounded = Utils.roundTo(maxEnergy / unitDivider, 4); + if (Utils.convertToFloat(meterValue.sampledValue[sampledValuesIndex].value) > maxEnergyRounded || debug) { + logger.error(`${self.chargingStation.logPrefix()} MeterValues measurand ${meterValue.sampledValue[sampledValuesIndex].measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${meterValue.sampledValue[sampledValuesIndex].value}/${maxEnergyRounded}`); } // Unsupported measurand } else { @@ -266,7 +270,9 @@ export default class OCPP16RequestService extends OCPPRequestService { for (let index = 0; index < meterValuesTemplate.length; index++) { // Energy.Active.Import.Register measurand (default) if (!meterValuesTemplate[index].measurand || meterValuesTemplate[index].measurand === OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER) { - meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(meterValuesTemplate[index], meterBegin, MeterValueContext.TRANSACTION_BEGIN)); + const unitDivider = meterValuesTemplate[index]?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1; + meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(meterValuesTemplate[index], + Utils.roundTo(meterBegin / unitDivider, 4), MeterValueContext.TRANSACTION_BEGIN)); } } const payload: MeterValuesRequest = { @@ -286,7 +292,8 @@ export default class OCPP16RequestService extends OCPPRequestService { for (let index = 0; index < meterValuesTemplate.length; index++) { // Energy.Active.Import.Register measurand (default) if (!meterValuesTemplate[index].measurand || meterValuesTemplate[index].measurand === OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER) { - meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(meterValuesTemplate[index], meterEnd, MeterValueContext.TRANSACTION_END)); + const unitDivider = meterValuesTemplate[index]?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1; + meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(meterValuesTemplate[index], Utils.roundTo(meterEnd / unitDivider, 4), MeterValueContext.TRANSACTION_END)); } } const payload: MeterValuesRequest = { diff --git a/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts b/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts index 5a2bfa9c..853b46aa 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts @@ -33,7 +33,7 @@ export class OCPP16ServiceUtils { }; } - public static getMeasurandDefaultUnit(measurandType: OCPP16MeterValueMeasurand): MeterValueUnit { + public static getMeasurandDefaultUnit(measurandType: OCPP16MeterValueMeasurand): MeterValueUnit | undefined { switch (measurandType) { case OCPP16MeterValueMeasurand.CURRENT_EXPORT: case OCPP16MeterValueMeasurand.CURRENT_IMPORT: @@ -53,7 +53,7 @@ export class OCPP16ServiceUtils { } } - public static getMeasurandDefaultLocation(measurandType: OCPP16MeterValueMeasurand): MeterValueLocation { + public static getMeasurandDefaultLocation(measurandType: OCPP16MeterValueMeasurand): MeterValueLocation | undefined { switch (measurandType) { case OCPP16MeterValueMeasurand.STATE_OF_CHARGE: return MeterValueLocation.EV; diff --git a/src/types/Connectors.ts b/src/types/Connectors.ts index 0a2a6f39..14415180 100644 --- a/src/types/Connectors.ts +++ b/src/types/Connectors.ts @@ -12,8 +12,8 @@ export interface Connector { transactionId?: number; transactionSetInterval?: NodeJS.Timeout; idTag?: string; - energyActiveImportRegisterValue?: number; - transactionEnergyActiveImportRegisterValue?: number; + energyActiveImportRegisterValue?: number; // In Wh + transactionEnergyActiveImportRegisterValue?: number; // In Wh chargingProfiles?: ChargingProfile[] } -- 2.34.1