]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/log
e-mobility-charging-stations-simulator.git
22 hours agochore: release main (#1780) main ocpp-server@v4.4.0 simulator@v4.4.0 v4 v4.4 webui@v4.4.0
Jérôme Benoit [Tue, 7 Apr 2026 23:07:30 +0000 (01:07 +0200)] 
chore: release main (#1780)

* chore: release main

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
22 hours agorefactor(tests): harmonize crypto test data and improve test quality
Jérôme Benoit [Tue, 7 Apr 2026 22:52:42 +0000 (00:52 +0200)] 
refactor(tests): harmonize crypto test data and improve test quality

- Reorganize OCPP20CertificateTestData: move CA/leaf certificates into
  Real X.509 section, simplify JSDoc to consistent one-line format
- Add round-trip tests (derLength → readDerLength) replacing duplicate
  raw byte assertions
- Add semantic test for extractDerIssuer (DER hash vs string DN hash)
- Replace eslint-disable || workaround with assert.match regex
- Update Asn1DerUtils @description to cover parsing functions

22 hours agofix(ocpp): use Volatile instead of invented Ephemeral for CertificatePrivateKey persi...
Jérôme Benoit [Tue, 7 Apr 2026 22:39:21 +0000 (00:39 +0200)] 
fix(ocpp): use Volatile instead of invented Ephemeral for CertificatePrivateKey persistence

Remove non-spec PersistenceEnumType.Ephemeral value. Use existing
Volatile which correctly prevents disk persistence and is already
used for ~25 other runtime-only variables in the registry.

22 hours agorefactor(crypto): modernize crypto APIs and harden certificate handling
Jérôme Benoit [Tue, 7 Apr 2026 22:30:11 +0000 (00:30 +0200)] 
refactor(crypto): modernize crypto APIs and harden certificate handling

- Migrate createHash() to crypto.hash() one-shot API (Node.js 22+)
- Migrate createSign() to crypto.sign() one-shot API
- Add derLength() bounds check for lengths > 0xFFFF
- Change CertificatePrivateKey persistence to Ephemeral
- Add logger.debug in deriveSigningMethodFromPublicKeyHex catch block
- Harden validateCertificatePath with async realpath for symlink
  protection (falls back to resolve for not-yet-created paths)
- Add X.509 chain validation in validateCertificateX509: verify issuer
  linkage and signatures for all certificates, validate validity
  period for entire chain (not just leaf), document leaf-first ordering
- Implement RFC 6960 §4.1.1 compliant issuerNameHash via DER issuer
  extraction from certificate raw bytes (extractDerIssuer)
- Move DER parsing functions (readDerLength, skipDerElement,
  extractDerIssuer) to Asn1DerUtils with proper JSDoc
- Rename readDerTagLength to readDerLength for accuracy
- Add unit tests for DER parsing functions and chain validation
- Add real CA + leaf certificate test fixtures

24 hours agorefactor(ocpp): use Node.js crypto for EC curve derivation
Jérôme Benoit [Tue, 7 Apr 2026 20:57:22 +0000 (22:57 +0200)] 
refactor(ocpp): use Node.js crypto for EC curve derivation

Replace manual ASN.1 OID hex substring matching with
crypto.createPublicKey which parses the DER structure via OpenSSL,
validates the EC point, and returns the named curve directly. Map
Node.js curve names (e.g. prime256v1) to SigningMethodEnumType.

24 hours agofeat(ocpp): add signing prerequisites validation and EC curve auto-derivation
Jérôme Benoit [Tue, 7 Apr 2026 20:42:02 +0000 (22:42 +0200)] 
feat(ocpp): add signing prerequisites validation and EC curve auto-derivation

- Add deriveSigningMethodFromPublicKeyHex: extracts EC curve OID from
  ASN.1 DER public key and maps to SigningMethodEnumType
- Add validateSigningPrerequisites: checks public key presence, curve
  detection, and config/key curve consistency
- Integrate validation in OCPP 2.0 (OCPPServiceUtils.buildMeterValue)
  and OCPP 1.6 (readSigningConfigForConnector) signing paths
- On validation failure: log warning and gracefully fallback to unsigned
  meter values instead of producing invalid signed data
- Add unit tests for deriveSigningMethodFromPublicKeyHex and
  validateSigningPrerequisites covering all paths

25 hours agofeat(ocpp): auto-derive signing method from EC public key curve
Jérôme Benoit [Tue, 7 Apr 2026 20:08:55 +0000 (22:08 +0200)] 
feat(ocpp): auto-derive signing method from EC public key curve

- Add deriveSigningMethodFromPublicKeyHex that extracts EC curve OID
  from ASN.1 DER public key and maps to SigningMethodEnumType
- Add validateSigningPrerequisites that validates public key presence,
  curve detection, and config consistency — returns enabled/disabled
  with reason
- Integrate validation in OCPP 2.0 (OCPPServiceUtils.buildMeterValue)
  and OCPP 1.6 (readSigningConfigForConnector) signing paths
- On validation failure: log error and gracefully fallback to unsigned
  meter values instead of producing invalid signed data
- Move TEST_PUBLIC_KEY_HEX to ChargingStationTestConstants for reuse
- Update test fixtures to use valid secp256k1 ASN.1 EC public key

25 hours agofix(ocpp): conform signingMethod to OCA spec and fix template curve mismatch
Jérôme Benoit [Tue, 7 Apr 2026 19:30:56 +0000 (21:30 +0200)] 
fix(ocpp): conform signingMethod to OCA spec and fix template curve mismatch

- Set signingMethod to empty string when using OCMF encoding per OCA
  Application Note Table 11: SA field already in signedMeterData
- Add FiscalMetering.SigningMethod=ECDSA-secp256k1-SHA256 to
  keba-ocpp2-signed template to match the secp256k1 public key from
  OCA spec §5.3 example
- Update tests to expect empty signingMethod for OCMF payloads
- Remove unused SigningMethodEnumType imports from test files

26 hours agorefactor(tests): harmonize test file names and @file descriptions
Jérôme Benoit [Tue, 7 Apr 2026 19:07:33 +0000 (21:07 +0200)] 
refactor(tests): harmonize test file names and @file descriptions

- Rename test files to follow Source-Focus.test.ts convention:
  OCPP16SignedMeterValues → OCPP16ServiceUtils-SignedMeterValues
  OCPP20SignedMeterValues → OCPP20RequestBuilders-SignedMeterValues
  OCPP16SchemaValidation → OCPP16ServiceUtils-SchemaValidation
  OCPP20SchemaValidation → OCPP20IncomingRequestService-SchemaValidation
  OCPP16VendorParametersKey → Configuration (in tests/types/)
- Harmonize all @file tags to 'Tests for <SourceModule> [focus]' pattern
- Fix module name mismatches, dot notation, and inverted descriptions
- Integration tests use descriptive 'Tests for OCPP X.Y <feature>' style

26 hours agorefactor(tests): rename OCPP16VendorParametersKey test to match source file
Jérôme Benoit [Tue, 7 Apr 2026 18:46:56 +0000 (20:46 +0200)] 
refactor(tests): rename OCPP16VendorParametersKey test to match source file

Rename to Configuration.test.ts to follow the established convention
where test file names match their corresponding source file names.

26 hours agofeat(ocpp): add EncodingMethodEnumType enum for signed meter value encoding methods
Jérôme Benoit [Tue, 7 Apr 2026 18:39:26 +0000 (20:39 +0200)] 
feat(ocpp): add EncodingMethodEnumType enum for signed meter value encoding methods

- Add EncodingMethodEnumType enum with OCMF and EDL values based on
  OCA Application Note and OCPP 2.0.1/2.1 specs
- Use enum in SignedMeterData interface and wire types (with string
  union for extensibility)
- Replace hardcoded 'OCMF' string constant with enum value
- Update all tests to use EncodingMethodEnumType consistently

27 hours agofix(ocpp): populate signingMethod field and add SigningMethodEnumType enum
Jérôme Benoit [Tue, 7 Apr 2026 18:20:34 +0000 (20:20 +0200)] 
fix(ocpp): populate signingMethod field and add SigningMethodEnumType enum

- Fix signingMethod being empty string in SignedMeterValueType payload
- Add SigningMethodEnumType enum per OCA Application Note Table 12 and
  OCPP 2.1 Appendix 7.4 with all 7 standardized values
- Propagate FiscalMetering.SigningMethod config variable to the signed
  meter data generator with fallback to ECDSA-secp256r1-SHA256
- Add OCPP 1.6 vendor key SigningMethod and read it in
  readSigningConfigForConnector
- Add MeterPublicKey and SigningMethod mappings to OCPP2_PARAMETER_KEY_MAP
- Use SigningMethodEnumType in all interfaces and type definitions
- Update README vendor-specific keys documentation

28 hours agofeat(ocpp): add signed meter values support for OCPP 1.6 and 2.0.x (#1775)
Jérôme Benoit [Tue, 7 Apr 2026 17:05:43 +0000 (19:05 +0200)] 
feat(ocpp): add signed meter values support for OCPP 1.6 and 2.0.x (#1775)

* feat(types): export OCPP16MeterValueFormat and add OCPP16SignedMeterValue

* feat(ocpp1.6): add vendor configuration keys for signed meter values

* feat(ocpp2.0): add variable registry entries for signed meter readings

* feat(mock-server): handle signed meter value payloads

* feat(ocpp): add simulated signed meter data generator

* feat(ocpp): add PublicKeyWithSignedMeterValue enum and state tracking

* feat(ocpp2.0): populate signedMeterValue in sampled value building

* feat(ocpp1.6): add signed meter value support to sampled value building

* feat(templates): add station templates with signed meter value config

* docs: document signed meter values configuration

* fix(lint): apply formatter fixes to signed meter value files

* fix(ocpp): fix publicKey state tracking and reset in signed meter values

* fix(ocpp): fix OCMF payload, hash, and public key encoding

* fix(ocpp): add defensive guards and improve signing code quality

* fix(ocpp2.0): respect SignStartedReadings and SignUpdatedReadings sub-switches

* [autofix.ci] apply automated fixes

* fix(ocpp): consistent publicKey state update, version-gated vendor keys, use enum constants

* [autofix.ci] apply automated fixes

* refactor(ocpp): use union types in common code and correct enum classification per OCPP specs

- Use VendorParametersKey (union) in ChargingStation.ts, not OCPP16VendorParametersKey
- Remove VERSION_16 guard: OCPP2_PARAMETER_KEY_MAP resolves keys per version
- Add 6 mapping entries to OCPP2_PARAMETER_KEY_MAP for signed MV config keys
- Classify enums per OCPP 2.0.1 base spec: SignReadings and
  PublicKeyWithSignedMeterValue in OCPP20OptionalVariableName (Required: no)
- Classify Application Note-only variables (SignStartedReadings,
  SignUpdatedReadings, PublicKey, SigningMethod) in OCPP20VendorVariableName
- Replace all string literals with enum references in variable registry

* [autofix.ci] apply automated fixes

* fix(ocpp): fix corrupted Measurands entry, Wh/kWh unit handling, context mapping, and enum validation

- Fix AlignedDataCtrlr.Measurands variable corrupted by lint auto-sort (was SignUpdatedReadings)
- Add meterValueUnit to SignedMeterDataParams to handle kWh input without double-division
- Replace unsafe context cast with explicit OCPP20-to-generator context mapping
- Extract parsePublicKeyWithSignedMeterValue helper (hoisted Set, shared across OCPP versions)
- Use MeterValueUnit enum constant instead of string literal for kWh comparison

* [autofix.ci] apply automated fixes

* refactor(ocpp): use MeterValueContext/MeterValueUnit enums and barrel imports instead of string literals

* style: apply prettier formatting to SignedMeterDataGenerator test

* fix(ocpp): add vendorSpecific flag, guard publicKey inclusion on key availability, add kWh test

* refactor(ocpp): use PublicKeyWithSignedMeterValueEnumType.Never instead of string literal

* test(ocpp): add JSDoc header, TX=P/Clock tests, non-energy measurand and transactionData force tests

* test(ocpp1.6): add periodic signing tests with mock timers for startUpdatedMeterValues

* refactor(test): use beforeEach for station creation in OCPP16SignedMeterValues per style guide

* fix(ocpp): treat undefined context as periodic for SignUpdatedReadings, conditional try/catch for signing-forced transactionData, use node:assert/strict import

* refactor(ocpp2.0): add defaultValue and enumeration to PublicKeyWithSignedMeterValue registry entry

* refactor(ocpp1.6): remove redundant nullish coalescing on publicKeyHex

* refactor(ocpp): use BaseError, return tuple in OCPP 2.0 builder, extract config reading in OCPP 1.6

* refactor(ocpp): harmonize naming, signatures, and data structures across signing paths

- SignedMeterData extends JsonObject: eliminates as-cast to OCPP16SignedMeterValue
- Rename publicKeyConfig to publicKeyWithSignedMeterValue: consistent with OCPP 2.0 interface
- Rename meterValueWh to meterValue: unit-agnostic (generator handles via meterValueUnit)
- Remove unused OCPP16SignedMeterValue import

* fix(mock-server): log signed meter values in TransactionEvent.Ended and add test

* fix(ocpp): include Transaction.Begin MV in TransactionEvent(Ended) per spec §4.1.2, set signingMethod to empty string per spec §3.2.1

* refactor(ocpp): rename SignedMeter* files to follow OCPP* naming convention

* refactor(ocpp): extract generic SignedSampledValueResult<T> to shared utils

* refactor(ocpp): extract shared SigningConfig interface, OCPP20SampledValueSigningConfig extends it

* refactor(ocpp): use roundTo helper instead of Number/toFixed for kWh conversion

* style(mock-server): reorder signed MV tests to follow Started/Updated/Ended lifecycle

* refactor(ocpp): move SampledValueSigningConfig to shared utils, remove version-specific type import from common code

* fix(ocpp): map StartTxnSampledData to SampledDataCtrlr.TxStartedMeasurands, remove VERSION_16 guard

* [autofix.ci] apply automated fixes

* style: remove unnecessary parenthetical from eslint cspell comment

* style: rename Configuration.test.ts to OCPP16VendorParametersKey.test.ts to reflect content

* refactor(ocpp): rename ocpp20SigningConfig/State to signingConfig/State (version-agnostic)

* style: harmonize blank lines in OCPP20VariableRegistry between component sections

* [autofix.ci] apply automated fixes

* style: remove unjustified blank lines before inline comments within same component section

* fix(ocpp2.0): add missing DeviceDataCtrlr section comment in variable registry

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
33 hours agochore(deps): update dependency @cspell/eslint-plugin to v10 (#1779)
renovate[bot] [Tue, 7 Apr 2026 11:56:56 +0000 (11:56 +0000)] 
chore(deps): update dependency @cspell/eslint-plugin to v10 (#1779)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
33 hours agochore(deps): update all non-major dependencies (#1778)
renovate[bot] [Tue, 7 Apr 2026 11:41:14 +0000 (13:41 +0200)] 
chore(deps): update all non-major dependencies (#1778)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 days agochore(deps): lock file maintenance (#1777)
renovate[bot] [Mon, 6 Apr 2026 17:57:25 +0000 (19:57 +0200)] 
chore(deps): lock file maintenance (#1777)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 days agochore(deps): lock file maintenance
Jérôme Benoit [Mon, 6 Apr 2026 17:03:06 +0000 (19:03 +0200)] 
chore(deps): lock file maintenance

Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
2 days agochore(deps): update all non-major dependencies (#1776)
renovate[bot] [Mon, 6 Apr 2026 11:45:11 +0000 (13:45 +0200)] 
chore(deps): update all non-major dependencies (#1776)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
3 days agochore: release main (#1773) ocpp-server@v4.3.1 simulator@v4.3.1 v4.3 webui@v4.3.1
Jérôme Benoit [Sun, 5 Apr 2026 15:57:05 +0000 (17:57 +0200)] 
chore: release main (#1773)

* chore: release main

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
3 days agotest: harmonize RemoteStartTransaction tests across OCPP stacks
Jérôme Benoit [Sun, 5 Apr 2026 15:46:39 +0000 (17:46 +0200)] 
test: harmonize RemoteStartTransaction tests across OCPP stacks

OCPP 1.6:
- Remove fabricated TC_0XX_CS codes (no official 1.6 test case spec)
- Reorder tests by category: happy path, input validation, availability,
  transaction state, event listeners

OCPP 2.0:
- Add 2 EVSE availability tests (skip inoperative, all inoperative)
- Add official TC refs where tests match Part 6 spec (TC_F_02_CS,
  TC_F_03_CS, TC_K_37_CS)
- Harmonize FR comment format on new tests

3 days agofix(ocpp): check connector availability in RemoteStartTransaction auto-selection...
Rishabh Vaish [Sun, 5 Apr 2026 15:08:24 +0000 (08:08 -0700)] 
fix(ocpp): check connector availability in RemoteStartTransaction auto-selection (#1774)

* fix(ocpp): check connector availability in RemoteStartTransaction auto-selection

The OCPP 1.6 RemoteStartTransaction handler's connector auto-selection
(when connectorId is omitted) only checked transactionStarted and
reservation status but not administrative availability. This meant an
Inoperative connector could be selected, causing the request to be
rejected even when other Operative connectors were free.

Added isConnectorAvailable() check to the auto-selection loop, matching
the behavior already present in the OCPP 2.0 selectAvailableEvse().

* [autofix.ci] apply automated fixes

* Update tests/charging-station/ocpp/1.6/OCPP16IncomingRequestService-RemoteStartTransaction.test.ts

* Apply suggestion from @jerome-benoit

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
4 days agodocs: restructure memories for logical coherence
Jérôme Benoit [Sat, 4 Apr 2026 13:14:44 +0000 (15:14 +0200)] 
docs: restructure memories for logical coherence

- code_style_conventions: reorder sections (general TS → domain → process
  → other → pitfalls), deduplicate BaseError constraint and payload
  validation, move Utility Usage Rules next to other TS patterns
- task_completion_checklist: add inline comments to all 3 sections

4 days agochore: release main (#1771) ocpp-server@v4.3.0 simulator@v4.3.0 webui@v4.3.0
Jérôme Benoit [Sat, 4 Apr 2026 12:59:53 +0000 (14:59 +0200)] 
chore: release main (#1771)

* chore: release main

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
4 days agodocs: remove standalone ruff hint from checklist memory
Jérôme Benoit [Sat, 4 Apr 2026 01:13:38 +0000 (03:13 +0200)] 
docs: remove standalone ruff hint from checklist memory

4 days agodocs: remove barrel workaround hint from conventions memory
Jérôme Benoit [Sat, 4 Apr 2026 01:13:01 +0000 (03:13 +0200)] 
docs: remove barrel workaround hint from conventions memory

4 days agodocs: update serena memories after full codebase audit
Jérôme Benoit [Sat, 4 Apr 2026 01:07:14 +0000 (03:07 +0200)] 
docs: update serena memories after full codebase audit

- code_style_conventions: add constant unit suffixes, BaseError import
  constraint, utility usage rules, Vue UI conventions, Python conventions,
  testing patterns (AAA, __testable__, flushMicrotasks), enum merging,
  console.* rules, fix WeakMap description accuracy
- project_overview: add auth subsystem, UI server transports, design
  patterns table, coverage thresholds, update tech stack versions
- task_completion_checklist: add ruff standalone commands for Python

4 days agorefactor(ui): use EMPTY_VALUE_PLACEHOLDER in Utils.ts and test assertions
Jérôme Benoit [Fri, 3 Apr 2026 23:15:41 +0000 (01:15 +0200)] 
refactor(ui): use EMPTY_VALUE_PLACEHOLDER in Utils.ts and test assertions

Replace remaining hardcoded 'Ø' in getWebSocketStateName() and 4 test
assertions with the centralized EMPTY_VALUE_PLACEHOLDER constant.
Consolidate duplicate Constants import in Utils.ts.

4 days agofix(ui): enable authorize for all OCPP versions in StartTransaction
Jérôme Benoit [Fri, 3 Apr 2026 21:43:43 +0000 (23:43 +0200)] 
fix(ui): enable authorize for all OCPP versions in StartTransaction

The OCPP 2.0.x authorize restriction was a UI-only limitation — the
simulator stack already handles Authorize for both 1.6 and 2.0.x.
Remove the isOCPP20x guard so the checkbox is available for all versions.

5 days agorefactor(ocpp-server): inline _parse_set/get_variable_specs thin wrappers
Jérôme Benoit [Fri, 3 Apr 2026 21:08:11 +0000 (23:08 +0200)] 
refactor(ocpp-server): inline _parse_set/get_variable_specs thin wrappers

Remove redundant _parse_set_variable_specs and _parse_get_variable_specs
one-liner wrappers — call _parse_variable_specs(specs, require_value=...)
directly at all call sites

5 days agorefactor: enforce utility usage and centralize constants across all components
Jérôme Benoit [Fri, 3 Apr 2026 20:56:28 +0000 (22:56 +0200)] 
refactor: enforce utility usage and centralize constants across all components

- Replace .length/.size checks with isEmpty/isNotEmptyArray in 7 src/ files
- Replace Number.parseInt/parseFloat with convertToInt in OCPPServiceUtils
  (intentional fail-fast: malformed templates now throw instead of silent NaN)
- Keep Number.parseFloat in getLimitFromSampledValueTemplateCustomValue
  (NaN fallback contract requires it)
- Centralize route names (ROUTE_NAMES), placeholder (EMPTY_VALUE_PLACEHOLDER),
  and localStorage key in Vue UI (11 files)
- Extract 13 magic values to constants in Python ocpp-server
- Rename constants: WORKER_SET_VERSION, DEFAULT_RATE_WINDOW_MS, MS_PER_HOUR,
  DEFAULT_*_SECONDS in Python, DEFAULT_*_BYTES in UIServerSecurity

5 days agorefactor: add unit suffixes to time-related constants and fix heartbeat unit mismatch
Jérôme Benoit [Fri, 3 Apr 2026 20:06:40 +0000 (22:06 +0200)] 
refactor: add unit suffixes to time-related constants and fix heartbeat unit mismatch

- Rename 19 constants to include _MS or _SECONDS suffix (Constants, OCPPConstants, WorkerConstants)
- Remove redundant // Ms and // Seconds comments from definitions
- Fix pre-existing bug: resetLimits set HeartbeatInterval to 60000 seconds instead of 60
- Remove 97 redundant heartbeatInterval overrides in tests (mock default already correct)

5 days agorefactor: improve helper/utility usage consistency across codebase
Jérôme Benoit [Fri, 3 Apr 2026 19:23:45 +0000 (21:23 +0200)] 
refactor: improve helper/utility usage consistency across codebase

- Make worker module standalone by inlining mergeDeepRight in WorkerUtils
- Replace console/chalk with structured logger calls in Bootstrap
- Extract magic numbers to named constants (auth cache, WS reconnect)
- Use setupConnectorWithTransaction helper in transaction tests
- Remove dead test helper OCPPAuthIntegrationTest
- Fix 'shutdowning' typo in graceful shutdown log message

5 days agorefactor(tests): extract hardcoded values to constants
Jérôme Benoit [Fri, 3 Apr 2026 17:36:08 +0000 (19:36 +0200)] 
refactor(tests): extract hardcoded values to constants

- extract TEST_TIMEOUT_MS constant for 9 setTimeout(30000) calls in
  UIMCPServer.test.ts
- use Constants.DEFAULT_ATG_CONFIGURATION instead of inline ATG config
  objects in SharedLRUCache, ChargingStationConfigurationUtils, and
  AutomaticTransactionGenerator tests
- add TEST_RESERVATION_EXPIRY_MS constant and replace 6 hardcoded
  3600000 values in reservation and transaction tests

5 days ago[autofix.ci] apply automated fixes
autofix-ci[bot] [Fri, 3 Apr 2026 17:05:49 +0000 (17:05 +0000)] 
[autofix.ci] apply automated fixes

5 days agorefactor: dry improvements in web UI and OCPP mock server
Jérôme Benoit [Fri, 3 Apr 2026 17:02:57 +0000 (19:02 +0200)] 
refactor: dry improvements in web UI and OCPP mock server

Web UI:
- extract localStorage key constants (UI_SERVER_CONFIGURATION_INDEX_KEY,
  TOGGLE_BUTTON_KEY_PREFIX, SHARED_TOGGLE_BUTTON_KEY_PREFIX)
- add deleteLocalStorageByKeyPattern() utility with safe collect-then-
  delete iteration
- add getWebSocketStateName() utility replacing duplicated switch
- remove redundant .trim() calls (already handled by v-model.trim)

OCPP mock server:
- extract FALLBACK_TRANSACTION_ID constant and shared helper method
- replace 20-case match/case with _COMMAND_HANDLERS dict dispatch
- unify _parse_set/get_variable_specs into shared _parse_variable_specs
- add ClassVar annotation for proper mypy typing

5 days agorefactor: use utility functions consistently across codebase
Jérôme Benoit [Fri, 3 Apr 2026 16:33:14 +0000 (18:33 +0200)] 
refactor: use utility functions consistently across codebase

Replace manual patterns with existing utility functions to improve DRY
compliance:

- Use isEmpty/isNotEmptyArray/isNotEmptyString instead of .length checks
- Use convertToInt/convertToFloat instead of Number.parseInt/Number
- Use roundTo instead of Math.round(x * N) / N
- Use ensureError in catch blocks for proper error type narrowing
- Add UNIT_DIVIDER_KILO, MILLISECONDS_PER_HOUR and
  DEFAULT_EXPONENTIAL_BACKOFF_JITTER_MS to Constants

Note: isEmpty/isNotEmptyString apply whitespace trimming, which
tightens validation for identifiers and configuration values.

5 days agorefactor: use getErrorMessage helper and extract auth cache constant
Jérôme Benoit [Fri, 3 Apr 2026 15:42:38 +0000 (17:42 +0200)] 
refactor: use getErrorMessage helper and extract auth cache constant

Replace 7 instanceof Error ternary patterns with getErrorMessage()
for consistent error message extraction. Extract hardcoded
maxEntries 1000 to Constants.DEFAULT_AUTH_CACHE_MAX_ENTRIES
across InMemoryAuthCache, AuthComponentFactory, and
OCPPAuthServiceImpl.

5 days agofix(tests): use version-agnostic StandardParametersKey
Jérôme Benoit [Fri, 3 Apr 2026 15:17:43 +0000 (17:17 +0200)] 
fix(tests): use version-agnostic StandardParametersKey

Replace OCPP16StandardParametersKey import in common test
with version-agnostic StandardParametersKey union type.

5 days agorefactor: replace string literals with OCPP enum constants
Jérôme Benoit [Fri, 3 Apr 2026 15:09:52 +0000 (17:09 +0200)] 
refactor: replace string literals with OCPP enum constants

Add AllowReset and MasterPassGroupId to OCPP20OptionalVariableName
enum. Replace all hardcoded OCPP variable name strings with enum
references in source and test files. Move EVSE Component section
comment to correct position.

5 days agorefactor: use string/array helper functions consistently
Jérôme Benoit [Fri, 3 Apr 2026 14:27:05 +0000 (16:27 +0200)] 
refactor: use string/array helper functions consistently

Replace 9 manual .trim().length checks with isEmpty() and
isNotEmptyString() helpers. Replace Array.isArray+length
guards with isNotEmptyArray() in StatisticUtils. Simplify
isValidIdentifierValue to delegate to isNotEmptyString.
Replace hardcoded SecurityCtrlr.OrganizationName string
with OCPP20ComponentName/RequiredVariableName enums.

5 days agofix(deps): update all non-major dependencies (#1772)
renovate[bot] [Fri, 3 Apr 2026 13:53:47 +0000 (15:53 +0200)] 
fix(deps): update all non-major dependencies (#1772)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
5 days agorefactor: use utility helpers consistently across codebase
Jérôme Benoit [Fri, 3 Apr 2026 13:41:36 +0000 (15:41 +0200)] 
refactor: use utility helpers consistently across codebase

Replace manual * 1000 with secondsToMilliseconds() in auth
cache, remote strategy, and OCPP20 incoming request. Replace
manual / 1000 with millisecondsToSeconds() in auth helpers,
auth service, and cert signing retry. Replace 'in' operator
with has() in auth service. Replace configurationKey find
with getConfigurationKey() in OCPP20RequestService. Use
formatDurationMilliSeconds for reconnect delay log. Keep
ms precision in auth service logs (sub-second durations).

5 days agorefactor(webui): remove redundant CSTable re-mount on toggle
Jérôme Benoit [Fri, 3 Apr 2026 12:50:27 +0000 (14:50 +0200)] 
refactor(webui): remove redundant CSTable re-mount on toggle

The @clicked handler on the Add Charging Stations toggle
forced a CSTable re-mount on every click. This is unnecessary
since watch($chargingStations) already handles re-renders
when data changes via WS server notifications.

5 days ago[autofix.ci] apply automated fixes
autofix-ci[bot] [Fri, 3 Apr 2026 12:45:51 +0000 (12:45 +0000)] 
[autofix.ci] apply automated fixes

5 days agofeat(webui): remove reload button (auto-refresh via WebSocket)
Jérôme Benoit [Fri, 3 Apr 2026 12:42:46 +0000 (14:42 +0200)] 
feat(webui): remove reload button (auto-refresh via WebSocket)

The WS server pushes refresh notifications on state changes,
making the manual reload button redundant. Remove ReloadButton
component, its styles, tests, and stub. Simplify need-refresh
handler to only reset add-stations toggle (data refresh and
CSTable re-render handled by server notification + watcher).
Remove dead --spacing-xl CSS variable from all themes.

5 days agorefactor(webui): migrate globalProperties to provide/inject
Jérôme Benoit [Fri, 3 Apr 2026 11:57:37 +0000 (13:57 +0200)] 
refactor(webui): migrate globalProperties to provide/inject

Replace Vue 2-style app.config.globalProperties with Vue 3
provide/inject using typed InjectionKeys. Create useConfiguration
and useTemplates composables. Remove dead globalProperties
fallback paths and refreshChargingStations no-op. Update test
mounts to use provide. Clean ComponentCustomProperties from
shims-vue.d.ts.

5 days agorefactor(webui): align $ prefix convention on composable locals
Jérôme Benoit [Fri, 3 Apr 2026 11:00:52 +0000 (13:00 +0200)] 
refactor(webui): align $ prefix convention on composable locals

Rename uiClient to $uiClient in 4 components (convention:
composable-returned Vue service instances use $ prefix).
Rename ref to $chargingStations in Utils.ts (was shadowing
Vue ref import). Keep chargingStationsRef unchanged in
ChargingStationsView (would shadow globalProperty in template).

5 days agofix: restrict test coverage to src/ runtime code only
Jérôme Benoit [Thu, 2 Apr 2026 22:47:34 +0000 (00:47 +0200)] 
fix: restrict test coverage to src/ runtime code only

Add --test-coverage-include glob to exclude tests, scripts,
package.json and other non-runtime files from coverage report.
Aligns with web UI vitest coverage config pattern.

5 days agorefactor(tests): migrate hardcoded test tags to shared constants
Jérôme Benoit [Thu, 2 Apr 2026 21:48:18 +0000 (23:48 +0200)] 
refactor(tests): migrate hardcoded test tags to shared constants

Replace 41 hardcoded tag/token strings across 13 test files
with imports from ChargingStationTestConstants. Includes
test utility factories. Normalize import paths to shortest
relative form and merge duplicate imports.

6 days agorefactor(tests): use setupConnectorWithTransaction shared helper
Jérôme Benoit [Thu, 2 Apr 2026 21:08:43 +0000 (23:08 +0200)] 
refactor(tests): use setupConnectorWithTransaction shared helper

Replace 19 inline transaction setup patterns across 3 test
files with the shared setupConnectorWithTransaction helper.
Only migrates sites where both transactionStarted and
transactionId are set together.

6 days agorefactor(tests): migrate inline mock stations to shared factory
Jérôme Benoit [Thu, 2 Apr 2026 20:49:24 +0000 (22:49 +0200)] 
refactor(tests): migrate inline mock stations to shared factory

Replace inline as-unknown-as ChargingStation casts in
CertificateAuthStrategy and OCPP20AuthAdapter tests with
createMockAuthServiceTestStation factory. Add inAcceptedState
method to the shared auth test station factory.

6 days agorefactor(tests): consolidate duplicate test helpers
Jérôme Benoit [Thu, 2 Apr 2026 19:48:40 +0000 (21:48 +0200)] 
refactor(tests): consolidate duplicate test helpers

Extract createStationWithRequestHandler to shared
TestLifecycleHelpers, eliminating duplication between
OCPPConnectorStatusOperations and OCPPServiceOperations tests.
Extend setupConnectorWithTransaction to support string
transactionId and pending mode, replacing local
setupTransaction/setupPendingTransaction helpers.

6 days agochore(deps): security update of lodash and lodash-es
Jérôme Benoit [Thu, 2 Apr 2026 18:59:02 +0000 (20:59 +0200)] 
chore(deps): security update of lodash and lodash-es

Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
6 days agofeat(ocpp): add spec-required DisplayMessageCtrlr variables
Jérôme Benoit [Thu, 2 Apr 2026 18:52:28 +0000 (20:52 +0200)] 
feat(ocpp): add spec-required DisplayMessageCtrlr variables

Add DisplayMessages, SupportedFormats, SupportedPriorities to
OCPP20VariableRegistry per OCPP 2.0.1 spec §3.1.8. Use
OCPP20MessageFormatEnumType for SupportedFormats enumeration.
Connector.ConnectorType deferred (requires isComponentValid
design change per OpenSpec process).

6 days agodocs: add missing ChargingStation.WebSocketPingInterval to README
Jérôme Benoit [Thu, 2 Apr 2026 17:34:17 +0000 (19:34 +0200)] 
docs: add missing ChargingStation.WebSocketPingInterval to README

Variable was present in OCPP20VariableRegistry but not
documented in the supported variables list.

6 days agochore: release main (#1768) ocpp-server@v4.2.0 simulator@v4.2.0 v4.2 webui@v4.2.0
Jérôme Benoit [Thu, 2 Apr 2026 16:59:10 +0000 (18:59 +0200)] 
chore: release main (#1768)

* chore: release main

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
6 days agorefactor(ocpp): consolidate payload validation into shared utility
Jérôme Benoit [Thu, 2 Apr 2026 15:06:12 +0000 (17:06 +0200)] 
refactor(ocpp): consolidate payload validation into shared utility

Extract 4 near-identical validation methods into 1 shared
validatePayload function in OCPPServiceUtils. Each service
method becomes a thin wrapper delegating to the shared logic.
Preserves clone/date-conversion behavior per caller and
error message capitalization for OCPP protocol compliance.

6 days agorefactor(ocpp): consolidate MeterValues validators and helpers
Jérôme Benoit [Thu, 2 Apr 2026 13:05:46 +0000 (15:05 +0200)] 
refactor(ocpp): consolidate MeterValues validators and helpers

Replace 5 near-identical validators with 1 generic
validateMeasurandValue using options pattern for phase
and interval. Merge addLineToLineVoltageToMeterValue into
addPhaseVoltageToMeterValue with nominalVoltage and optional
noTemplateFallback params preserving voltage simulation
semantics. Inline dead getMeasurandDefaultContext and
getMeasurandDefault. Extract magic numbers as constants.

6 days agofix(deps): update all non-major dependencies (#1770)
renovate[bot] [Thu, 2 Apr 2026 11:51:54 +0000 (11:51 +0000)] 
fix(deps): update all non-major dependencies (#1770)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
6 days agorefactor(ocpp): consolidate variable access in auth adapter
Jérôme Benoit [Thu, 2 Apr 2026 11:58:12 +0000 (13:58 +0200)] 
refactor(ocpp): consolidate variable access in auth adapter

Remove getVariableValue/getDefaultVariableValue wrappers from
OCPP20AuthAdapter in favor of OCPP20ServiceUtils.readVariableAs*
helpers. Fixes LocalAuthListCtrlr.Enabled default discrepancy
between adapter (true) and registry (false). Add readVariableAsString
helper for consistent string variable access.

6 days agorefactor(ocpp): remove dead barrel re-exports
Jérôme Benoit [Thu, 2 Apr 2026 11:33:56 +0000 (13:33 +0200)] 
refactor(ocpp): remove dead barrel re-exports

Remove 19 unused re-exports from ocpp/index.ts (12) and
auth/index.ts (7). All consumers import directly from source
files. Convert OCPPIncomingRequestService and OCPPRequestService
to type-only exports matching their sole consumer.

6 days agorefactor(ocpp): remove unnecessary exports from internal helpers
Jérôme Benoit [Thu, 2 Apr 2026 10:52:51 +0000 (12:52 +0200)] 
refactor(ocpp): remove unnecessary exports from internal helpers

De-export 14 MeterValue helper functions in OCPPServiceUtils
that are now only used internally after builder consolidation.
Make readVariableAsIntervalMs private in OCPP20ServiceUtils.

6 days agorefactor(ocpp): consolidate variable reading through shared helpers
Jérôme Benoit [Thu, 2 Apr 2026 10:14:47 +0000 (12:14 +0200)] 
refactor(ocpp): consolidate variable reading through shared helpers

Promote readVariableAs* helpers to public on OCPP20ServiceUtils.
Replace 10 inline getVariables + manual parsing patterns with
helper calls. Remove duplicated getVariableValue from
CertSigningRetryManager and parseBooleanVariable from
OCPP20AuthAdapter. Replace last parseInt with convertToIntOrNaN.

6 days agofix(ocpp): align OCPP 2.x auth adapter version to VERSION_201
Jérôme Benoit [Thu, 2 Apr 2026 00:27:55 +0000 (02:27 +0200)] 
fix(ocpp): align OCPP 2.x auth adapter version to VERSION_201

OCPP20AuthAdapter was the only 2.x component identifying as
VERSION_20 while all services use VERSION_201. Align adapter
and CertificateAuthStrategy to match the established convention.

6 days agorefactor(ocpp): consolidate MeterValue builders into shared core
Jérôme Benoit [Wed, 1 Apr 2026 23:50:56 +0000 (01:50 +0200)] 
refactor(ocpp): consolidate MeterValue builders into shared core

Merge buildOCPP16MeterValue and buildOCPP20MeterValue into
buildMeterValue, eliminating ~250 lines of duplicated logic.
Version differences resolved via switch: evseId + sampled
value builder callback.

6 days agorefactor(ocpp): harmonize sampled value builders between versions
Jérôme Benoit [Wed, 1 Apr 2026 23:02:04 +0000 (01:02 +0200)] 
refactor(ocpp): harmonize sampled value builders between versions

Align OCPP 1.6 unit field to conditional inclusion pattern
matching OCPP 2.0, and normalize null checks to != null
convention in both builders.

6 days agofeat(ocpp): align OCPP 2.0 meter value builder with 1.6 parity
Jérôme Benoit [Wed, 1 Apr 2026 22:45:21 +0000 (00:45 +0200)] 
feat(ocpp): align OCPP 2.0 meter value builder with 1.6 parity

Add per-phase power/current validation and breakdown to
OCPP 2.0 builder, matching OCPP 1.6 implementation.
Reorder measurands: SoC, Voltage, Power, Current, Energy.

Harmonize MeterValues test structure between versions:
extract 1.6 tests to dedicated file, add cross-version
parameterized builder output tests, add missing 2.0
edge case and interval restart test coverage.

6 days agofix(ocpp): wire context param through OCPP 1.6 meter value builder
Jérôme Benoit [Wed, 1 Apr 2026 21:25:59 +0000 (23:25 +0200)] 
fix(ocpp): wire context param through OCPP 1.6 meter value builder

The context parameter was silently dropped during extraction
to OCPP16RequestBuilders, unlike the OCPP 2.0 version which
correctly passes it to all internal calls.

7 days agorefactor: remove unnecessary type casts and improve type safety
Jérôme Benoit [Wed, 1 Apr 2026 20:03:57 +0000 (22:03 +0200)] 
refactor: remove unnecessary type casts and improve type safety

- Remove redundant as any cast in __testable__/index.ts
- Rewrite isEmpty() with native type guards (typeof/instanceof)
- Replace parameter mutation with const in WorkerFactory
- Remove unnecessary cast in MessageChannelUtils

7 days agotest(ocpp): add assertion messages to assert.ok(.includes()) checks in VariableManage...
Jérôme Benoit [Wed, 1 Apr 2026 18:20:37 +0000 (20:20 +0200)] 
test(ocpp): add assertion messages to assert.ok(.includes()) checks in VariableManager tests

7 days agotest(ocpp): move mapStopReasonToOCPP20 tests to OCPP20RequestBuilders.test.ts
Jérôme Benoit [Wed, 1 Apr 2026 18:04:41 +0000 (20:04 +0200)] 
test(ocpp): move mapStopReasonToOCPP20 tests to OCPP20RequestBuilders.test.ts

Align test file structure with source: function moved to
OCPP20RequestBuilders.ts, tests follow to the 2.0/ directory.

7 days agorefactor(ocpp): complete version-separation in OCPPServiceUtils
Jérôme Benoit [Wed, 1 Apr 2026 17:53:28 +0000 (19:53 +0200)] 
refactor(ocpp): complete version-separation in OCPPServiceUtils

Replace buildSampledValue version-switch with resolveSampledValueFields
helper + version-specific buildOCPP16SampledValue/buildOCPP20SampledValue.
Move mapStopReasonToOCPP20 to OCPP20RequestBuilders where it belongs.

OCPPServiceUtils.ts is now 100% version-agnostic — zero OCPP 1.6/2.0
types, zero inline version switches. All version-specific logic lives
in version-specific leaf modules (RequestBuilders, ServiceUtils).

7 days agotest(ocpp): harmonize test constants and assertion messages
Jérôme Benoit [Wed, 1 Apr 2026 17:25:46 +0000 (19:25 +0200)] 
test(ocpp): harmonize test constants and assertion messages

Replace hardcoded station IDs, tokens, and transaction IDs with
shared constants from ChargingStationTestConstants.ts across 8 test
files. Add TEST_TRANSACTION_UUID constant. Add descriptive messages
to 55 assert.ok() numeric comparison calls across 20+ test files
per TEST_STYLE_GUIDE.md requirements.

7 days agorefactor(ocpp): align builder naming and harmonize test structure
Jérôme Benoit [Wed, 1 Apr 2026 16:45:50 +0000 (18:45 +0200)] 
refactor(ocpp): align builder naming and harmonize test structure

Rename buildMeterValueForOCPP16/20 and buildSampledValueForOCPP16/20
to buildOCPP16/20MeterValue and buildOCPP16/20SampledValue matching
the established buildOCPP{version}{Thing} convention.

Merge IdTagAuthorization.test.ts into OCPPServiceOperations.test.ts
(source file was deleted). Move buildBootNotificationRequest tests
from OCPPServiceOperations.test.ts to OCPPServiceUtils-pure.test.ts
(function was moved to Utils).

7 days agorefactor(ocpp): consolidate meter value builders into RequestBuilders
Jérôme Benoit [Wed, 1 Apr 2026 16:17:13 +0000 (18:17 +0200)] 
refactor(ocpp): consolidate meter value builders into RequestBuilders

Merge OCPP16MeterValueBuilders.ts and OCPP20MeterValueBuilders.ts
into their respective OCPP16RequestBuilders.ts and OCPP20RequestBuilders.ts
files. Version-specific pure builders belong in a single leaf module
per stack, not separate files per builder type.

7 days agorefactor(ocpp): extract version-specific builders and transaction operations
Jérôme Benoit [Wed, 1 Apr 2026 16:08:16 +0000 (18:08 +0200)] 
refactor(ocpp): extract version-specific builders and transaction operations

Extract meter value builders into OCPP16/20MeterValueBuilders.ts leaf
modules. Extract boot notification builders into OCPP16/20RequestBuilders.ts
leaf modules. Move buildBootNotificationRequest dispatcher from Operations
to Utils. Extract OCPP 2.0 startTransactionOnConnector and
stopTransactionOnConnector into OCPP20ServiceUtils, removing inline
OCPP 2.0 enums and logic from the shared Operations module.

OCPPServiceUtils reduced from 2095 to 1648 lines.

7 days agorefactor(ocpp): extract connector status operations into dedicated module
Jérôme Benoit [Wed, 1 Apr 2026 15:13:47 +0000 (17:13 +0200)] 
refactor(ocpp): extract connector status operations into dedicated module

Move sendAndSetConnectorStatus, restoreConnectorStatus, and
checkConnectorStatusTransition into OCPPConnectorStatusOperations.ts
to enforce the operations/utils semantic separation without creating
circular dependencies. The new module depends only on Constants
(leaf modules), not on version-specific ServiceUtils.

7 days agorefactor(ocpp): move isIdTagAuthorized into OCPPServiceOperations
Jérôme Benoit [Wed, 1 Apr 2026 14:23:42 +0000 (16:23 +0200)] 
refactor(ocpp): move isIdTagAuthorized into OCPPServiceOperations

The circular dependency that motivated the separate IdTagAuthorization
file no longer exists after auth module refactoring. Move the function
to OCPPServiceOperations alongside other cross-stack transaction
helpers and delete the standalone file.

7 days agochore(deps): update all non-major dependencies (#1769)
renovate[bot] [Wed, 1 Apr 2026 10:32:10 +0000 (12:32 +0200)] 
chore(deps): update all non-major dependencies (#1769)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
7 days agochore: fix formatting whitespace and update MCP SDK version pin comment
Jérôme Benoit [Wed, 1 Apr 2026 00:11:15 +0000 (02:11 +0200)] 
chore: fix formatting whitespace and update MCP SDK version pin comment

7 days agorefactor(ocpp): consolidate Ajv type alias in OCPPServiceUtils
Jérôme Benoit [Tue, 31 Mar 2026 23:32:29 +0000 (01:32 +0200)] 
refactor(ocpp): consolidate Ajv type alias in OCPPServiceUtils

Export the Ajv type alias from OCPPServiceUtils and import it in
OCPPIncomingRequestService, OCPPRequestService, and OCPPResponseService
instead of each file duplicating the _Ajv.default type extraction.

7 days agorefactor: move constants to domain-appropriate locations
Jérôme Benoit [Tue, 31 Mar 2026 23:15:35 +0000 (01:15 +0200)] 
refactor: move constants to domain-appropriate locations

Move UNKNOWN_OCPP_COMMAND to OCPPConstants (cross-OCPP), DEFAULT_IDTAG
to OCPP16Constants (OCPP 1.6 only), OCPP_VALUE_ABSOLUTE_MAX_LENGTH to
OCPP20Constants renamed as MAX_VARIABLE_VALUE_LENGTH (OCPP 2.0 only).
Extract magic numbers: SECURITY_EVENT_RETRY_DELAY_MS in OCPP20Constants,
CLIENT_NOTIFICATION_DEBOUNCE_MS in AbstractUIServer,
DEFAULT_WS_RECONNECT_TIMEOUT_OFFSET in Constants.

7 days agochore: release main (#1767) ocpp-server@v4.1.1 simulator@v4.1.1 v4.1 webui@v4.1.1
Jérôme Benoit [Tue, 31 Mar 2026 22:38:35 +0000 (00:38 +0200)] 
chore: release main (#1767)

* chore: release main

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
7 days agorefactor(log): quote and truncate all auth identifiers in log messages
Jérôme Benoit [Tue, 31 Mar 2026 22:34:20 +0000 (00:34 +0200)] 
refactor(log): quote and truncate all auth identifiers in log messages

Wrap all idTag/idToken/identifier values in single quotes and apply
truncateId() consistently across OCPP 1.6, 2.0, and auth module log
messages. Removes eslint-disable comments for restrict-template-expressions
where ?? '' fallback eliminates the type issue.

7 days agofix(ocpp): warn on OCPP 1.6 keys in template only, silent remap for internal code
Jérôme Benoit [Tue, 31 Mar 2026 22:03:59 +0000 (00:03 +0200)] 
fix(ocpp): warn on OCPP 1.6 keys in template only, silent remap for internal code

Simplify OCPP2_PARAMETER_KEY_MAP to a plain Map<string, string> and
make resolveKey always silent. Move warning to a one-shot template
validation pass (warnOnOCPP16TemplateKeys) called after template
loading, before init defaults. Warnings now only fire when the
operator uses OCPP 1.6 key names in an OCPP 2.0 station template,
not when internal cross-version code resolves keys.

7 days agochore: release main (#1763) ocpp-server@v4.1.0 simulator@v4.1.0 webui@v4.1.0
Jérôme Benoit [Tue, 31 Mar 2026 21:34:09 +0000 (23:34 +0200)] 
chore: release main (#1763)

* chore: release main

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
7 days agochore: remove accidentally committed test plan
Jérôme Benoit [Tue, 31 Mar 2026 21:27:43 +0000 (23:27 +0200)] 
chore: remove accidentally committed test plan

7 days agorefactor(auth): remove getAuthCache from interfaces, own cache in service
Jérôme Benoit [Tue, 31 Mar 2026 21:26:14 +0000 (23:26 +0200)] 
refactor(auth): remove getAuthCache from interfaces, own cache in service

Remove getAuthCache() from AuthStrategy and OCPPAuthService interfaces.
Store authCache directly as private field on OCPPAuthServiceImpl during
initializeStrategies(), eliminating indirect access through LocalAuthStrategy
for clearCache, invalidateCache, and updateCacheEntry operations.

Add getTestAuthCache() helper to MockFactories to encapsulate cache
access in tests. Harmonize all test files to use the shared helper
instead of ad-hoc cast chains. Fix broken OCPPAuthIntegrationTest
references and extract KNOWN_STRATEGIES constant.

8 days agofix(auth): trigger post-authorize by default when DisablePostAuthorize not configured
Jérôme Benoit [Tue, 31 Mar 2026 20:32:02 +0000 (22:32 +0200)] 
fix(auth): trigger post-authorize by default when DisablePostAuthorize not configured

Change shouldTriggerPostAuthorize from === false to !== true so that
non-Accepted local/cached tokens correctly trigger remote re-auth
when disablePostAuthorize is undefined (not configured). Previously,
undefined === false evaluated to false, silently skipping re-auth.

Also flatten redundant double try/catch in OCPP20AuthAdapter.

8 days agorefactor: merge duplicate same-kind imports from identical sources
Jérôme Benoit [Tue, 31 Mar 2026 20:20:00 +0000 (22:20 +0200)] 
refactor: merge duplicate same-kind imports from identical sources

8 days agofix(auth): use Math.floor for TTL computation to avoid serving expired cache entries
Jérôme Benoit [Tue, 31 Mar 2026 20:14:39 +0000 (22:14 +0200)] 
fix(auth): use Math.floor for TTL computation to avoid serving expired cache entries

8 days agorefactor(auth): rename parsed to expiry in updateCacheEntry
Jérôme Benoit [Tue, 31 Mar 2026 20:09:33 +0000 (22:09 +0200)] 
refactor(auth): rename parsed to expiry in updateCacheEntry

8 days agorefactor(auth): make updateCacheEntry API OCPP version-agnostic
Jérôme Benoit [Tue, 31 Mar 2026 20:06:21 +0000 (22:06 +0200)] 
refactor(auth): make updateCacheEntry API OCPP version-agnostic

Decouple updateCacheEntry from OCPP 2.0-specific types by accepting
AuthorizationStatus and optional expiryDate instead of pre-built
AuthorizationResult and TTL. This centralizes result construction,
date conversion, TTL computation, and expired-entry guards in the
auth service, eliminating duplicated logic across OCPP 1.6 and 2.0
callers. Also change OCPPAuthAdapter generic default from
OCPP20IdTokenType|string to unknown to remove the last OCPP
version-specific type from the auth service interface.

8 days agotest(ocpp): strengthen mock call verification in OCPP 2.0 handler tests
Jérôme Benoit [Tue, 31 Mar 2026 19:26:36 +0000 (21:26 +0200)] 
test(ocpp): strengthen mock call verification in OCPP 2.0 handler tests

Replace loose assertions (assert.ok(>0), boolean flags) with strict
mock.fn() callCount() and argument verification across 4 test files:

- UnlockConnector: verify exact call count + STATUS_NOTIFICATION command
- ClearCache: replace 3 boolean flags with mock.fn() + callCount()
- CertificateSigned: verify closeWSConnection called/not-called per cert type
- ChangeAvailability: capture requestHandler via factory, verify side effects

8 days agofix(ocpp): correct P0/P1 spec conformity gaps for OCPP 1.6 and 2.0.1
Jérôme Benoit [Tue, 31 Mar 2026 18:51:32 +0000 (20:51 +0200)] 
fix(ocpp): correct P0/P1 spec conformity gaps for OCPP 1.6 and 2.0.1

Addresses 7 non-conformities identified during algorithmic conformity audit:

P0 - OCPP-J protocol layer:
- Add MessageTypeNotSupported and RpcFrameworkError error codes (2.0.1 §4.3)
- Send CALLERROR with messageId "-1" on JSON parse failure (2.0.1 §4.2.3)
- Implement RetryBackOff reconnection algorithm using spec variables (2.0.1 §8.1-§8.3)

P1 - OCPP 1.6 logic fixes:
- Update authorization cache on Authorize/Start/StopTransaction responses
- Fix clearChargingProfiles to use AND logic per Errata 3.25

P1 - OCPP 2.0.1 security lifecycle:
- Add certificate signing retry with exponential back-off (A02.FR.17-19)
- Add security event notification queue with guaranteed delivery (A04.FR.02)
- Update authorization cache on AuthorizeResponse (C10.FR.04)

Infrastructure:
- Consolidate exponential backoff into computeExponentialBackOffDelay()
- Replace string literals with OCPP20OptionalVariableName enum entries
- Export OCPP16IdTagInfo type, make getAuthCache() non-optional on AuthStrategy
- Factor updateAuthorizationCache() into ServiceUtils for both 1.6 and 2.0

8 days agochore(deps): lock file maintenance (#1765)
renovate[bot] [Tue, 31 Mar 2026 15:07:37 +0000 (17:07 +0200)] 
chore(deps): lock file maintenance (#1765)

* chore(deps): lock file maintenance

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
8 days agorefactor: reduce code duplication across OCPP services, UI server, and configuration
Jérôme Benoit [Tue, 31 Mar 2026 14:41:58 +0000 (16:41 +0200)] 
refactor: reduce code duplication across OCPP services, UI server, and configuration

- Centralize AJV instantiation into createAjv() factory in OCPPServiceUtils
- Centralize payload validator config creation into createPayloadConfigs() generic
  factory, simplifying OCPP16/20ServiceUtils from multi-line .map() to one-liners
- Move rate limiter creation from module-level duplicates in UIHttpServer and
  UIMCPServer to a shared instance property on AbstractUIServer
- Extract 200-line checkDeprecatedConfigurationKeys() and helpers from
  Configuration.ts into dedicated ConfigurationMigration.ts module

8 days agofix(deps): update all non-major dependencies (#1766)
renovate[bot] [Tue, 31 Mar 2026 13:46:49 +0000 (15:46 +0200)] 
fix(deps): update all non-major dependencies (#1766)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
8 days agorefactor(ocpp): extract version-specific logic from consumer layer
Jérôme Benoit [Tue, 31 Mar 2026 00:30:22 +0000 (02:30 +0200)] 
refactor(ocpp): extract version-specific logic from consumer layer

Move remaining version-specific logic from charging-station/ consumer
layer into the ocpp/ component:

- Create OCPPServiceFactory.ts with createOCPPServices() factory that
  instantiates version-specific OCPP services, removing 6 version-
  specific class imports from ChargingStation.ts
- Move createBootNotificationRequest from Helpers.ts into version-
  specific buildBootNotificationRequest methods in OCPP16ServiceUtils
  and OCPP20ServiceUtils, with dispatcher in OCPPServiceOperations.ts

ChargingStation.ts no longer has any direct knowledge of OCPP version-
specific service classes. All version dispatch is handled by the ocpp/
component through factories and dispatchers.

Add unit tests for createOCPPServices (4 tests) and
buildBootNotificationRequest (6 tests) in existing test files.

8 days agodocs: fix JSDoc using historical language instead of current-state descriptions
Jérôme Benoit [Mon, 30 Mar 2026 23:03:46 +0000 (01:03 +0200)] 
docs: fix JSDoc using historical language instead of current-state descriptions

Replace history-telling patterns ('previously', 'no longer valid',
'unused but required by interface', 'kept for API consistency') with
descriptions of current behavior.