OCPP WS IOocpp-ws-io
Smart Charge Engine

Charging Strategies

Built-in allocation strategies — Equal Share, Priority, Time-of-Use — plus runtime swapping and custom strategies.

Charging Strategies

The engine ships with three built-in allocation strategies. Pass algorithm in the engine config, or swap it at runtime with engine.setAlgorithm().


Equal Share (Default)

Best for: Public parking, hospitality, retail — any site where fairness across all connected EVs matters.

Every active session gets an equal slice of available grid power after hardware caps are applied. Sessions with lower hardware limits consume less; the surplus is redistributed to the remaining sessions.

const engine = new SmartChargingEngine({
  siteId: "SITE-01",
  maxGridPowerKw: 100,
  algorithm: Strategies.EQUAL_SHARE, // default
  dispatcher: /* ... */,
});

Allocation example (100kW site, 5% safety margin → 95kW effective):

SessionHardware CapAllocated
CP-0122 kW22 kW (capped)
CP-0222 kW22 kW (capped)
CP-0350 kW51 kW → capped to 50 kW

After capping, unallocated surplus is redistributed across remaining eligible sessions in the same cycle.


Priority

Best for: Fleet depots, employee lots, subscription tiers — where some vehicles should always get more power.

Sessions are ranked by priority (higher = more). Higher-priority sessions are allocated first. Lower-priority sessions receive leftover grid capacity. When grid is constrained, low-priority sessions may receive only minChargeRateKw.

const engine = new SmartChargingEngine({
  siteId: "SITE-FLEET",
  maxGridPowerKw: 80,
  algorithm: Strategies.PRIORITY,
  dispatcher: /* ... */,
});

engine.addSession({
  transactionId: "tx-001",
  clientId: "CP-FLEET-01",
  maxHardwarePowerKw: 50,
  priority: 10,          // ← high: fleet truck, must be ready by 6 AM
  minChargeRateKw: 3.7,
});

engine.addSession({
  transactionId: "tx-002",
  clientId: "CP-VISITOR-01",
  maxHardwarePowerKw: 22,
  priority: 1,           // ← low: public visitor, best-effort
  minChargeRateKw: 1.4,
});

Time-of-Use (TOU)

Best for: Sites with time-of-day electricity pricing — charge faster during cheap off-peak hours, slower during expensive peak hours.

Combines Equal Share allocation with a configurable schedule of power multipliers. During peak hours, the effective grid limit is reduced. During off-peak hours, it may be increased.

const engine = new SmartChargingEngine({
  siteId: "SITE-TOU",
  maxGridPowerKw: 100,
  algorithm: Strategies.TIME_OF_USE,
  touConfig: {
    peakHours: { start: 18, end: 22 },     // 6 PM – 10 PM
    offPeakHours: { start: 0, end: 6 },    // midnight – 6 AM
    peakMultiplier: 0.4,                    // 40% of grid during peak
    offPeakMultiplier: 1.0,                 // 100% during off-peak
    shoulderMultiplier: 0.75,               // 75% all other times
  },
  dispatcher: /* ... */,
});

// Pair with auto-dispatch to continuously adjust as time changes
engine.startAutoDispatch(60_000); // recalculate every 60s

Power schedule example (100kW site):

TimeMultiplierEffective Grid
00:00 – 06:00 (off-peak)1.0100 kW
06:00 – 18:00 (shoulder)0.7575 kW
18:00 – 22:00 (peak)0.440 kW
22:00 – 00:00 (shoulder)0.7575 kW

Runtime Strategy Swap

Switch strategy on a live engine without any downtime:

// Evening peak — switch to TOU to reduce draw
engine.setAlgorithm(Strategies.TIME_OF_USE);
await engine.dispatch(); // immediately rebalance with new strategy

// Fleet arrives overnight — switch to Priority
engine.setAlgorithm(Strategies.PRIORITY);
await engine.dispatch();

Minimum Charge Rate

All strategies respect minChargeRateKw per session. Even when the grid is heavily constrained, a session will never drop below its minimum:

engine.addSession({
  transactionId: "tx-xr5",
  clientId: "CP-01",
  maxHardwarePowerKw: 22,
  minChargeRateKw: 1.4, // 6A × 230V — below this some EVs fault
});

If the site is so constrained that even minimums cannot be satisfied, the engine respects priority to decide who gets their minimum first.


Custom Strategy (Advanced)

The engine accepts any function conforming to the ChargingStrategy type:

import type { ChargingStrategy } from "ocpp-smart-charge-engine/strategies";

const myStrategy: ChargingStrategy = (sessions, availableKw) => {
  // sessions: ChargingSession[]
  // availableKw: effective grid budget after safety margin
  // Return: SessionProfile[] with allocatedKw per session
  return sessions.map((s) => ({
    ...s,
    allocatedKw: Math.min(s.maxHardwarePowerKw, availableKw / sessions.length),
    allocatedW: /* ... */,
    allocatedAmps: /* ... */,
  }));
};

const engine = new SmartChargingEngine({
  siteId: "CUSTOM",
  maxGridPowerKw: 100,
  algorithm: myStrategy,
  dispatcher: /* ... */,
});

On this page