SmartCer formulation¶
Version: 1.0
Status: authoritative reference for the physics and the economics implemented in smartcer/core/ and for the reward in smartcer/gym/rewards/. Any change to those equations must update this file in the same commit.
1. Sources¶
[S22] M. Stentati, S. Paoletti, A. Vicino, Optimization of energy communities in the Italian incentive system, IEEE PES ISGT-Europe 2022. Battery dynamics, node energy balance, social welfare. This is the model of the MILP oracle used in training.
[M23] L. Guiducci, G. Palma, M. Stentati, A. Rizzo, S. Paoletti, A Reinforcement Learning approach to the management of Renewable Energy Communities, MECO 2023. Action definition, dynamic action bounds, constraint penalty, reward, actor state, rule-based controller, Fit Score.
Where the two papers differ, the battery dynamics of [S22] prevail, because the optimal actions computed by the MILP must be executable in the environment. Deviations are listed in section 14.
2. Community, nodes and time¶
A community has a set U of nodes. Node types:
producer: generation g, no load, optional battery;
consumer: load l, no generation, optional battery (with the charge rule of section 6 a consumer battery can never charge);
prosumer: generation g and load l, optional battery.
Time is discrete with step Δt in hours (default 1.0). The CSV frequency must match Δt.
Internal units: power in kW, energy in kWh, prices in €/kWh.
CSV units are declared per scenario with
units:kWh(energy per step, default, the 0.6.2 format and the papers) orkW(average power over the step). The loader converts everything to per-step energies g_{u,t}, l_{u,t} in kWh.
3. Symbols¶
Symbol |
Meaning |
Unit |
Config key or CSV column |
|---|---|---|---|
g_{u,t} |
generation of node u in step t |
kWh |
|
l_{u,t} |
load of node u in step t |
kWh |
|
π^egr_{u,t} |
sell price |
€/kWh |
|
π^igr_{u,t} |
buy price |
€/kWh |
|
π^inc_t |
unit incentive on shared energy (model |
€/kWh |
|
π^sto_u |
unit cost of storage usage |
€/kWh |
|
S^max_u |
battery capacity |
kWh |
|
S^min_u |
minimum state of charge |
kWh |
|
S^ini_u |
initial state of charge |
kWh |
|
P^cha_u, P^dis_u |
maximum charge and discharge power, node side |
kW |
|
η^cha_u, η^dis_u |
charge and discharge efficiency |
– |
|
α_u |
self-discharge per hour (fraction of the state of charge lost in one hour) |
– |
|
σ |
penalty coefficient |
– |
|
s_{u,t} |
state of charge at the end of step t |
kWh |
state |
a_{u,t} |
normalised action |
– |
action |
4. Action and battery power¶
One action per node with a battery, a_{u,t} ∈ [−1, 1], in the fixed order storage_node_ids. Positive values charge, negative values discharge ([M23] Sec. III-A, with separate limits as in [S22] eq. 4-5):
Charge and discharge are never simultaneous by construction.
5. Battery dynamics¶
[S22] eq. 6-8, with optional self-discharge applied before the step and clamped at S^min (α = 0 reproduces the papers). α_u is defined per hour and converted to the step, so that the loss per hour does not depend on ΔT:
Both power limits act on the node side: in charge the node supplies p^cha ΔT and the cell stores η^cha p^cha ΔT; in discharge the cell releases p^dis ΔT / η^dis and the node receives p^dis ΔT. No degradation is modelled.
6. Dynamic action bounds¶
Derived from section 5 and from the charge rule (no charging from the grid):
The charge cap c_{u,t} depends on storage.charge_limit:
production(default, [M23] eq. 1): c_{u,t} = g_{u,t};surplus(option): c_{u,t} = max(0, g_{u,t} − l_{u,t}).
Feasible actions lie in [−A^lower_{u,t}, A^upper_{u,t}].
7. Clipping and constraint penalty¶
An action outside the feasible interval is replaced by the nearest bound before it is applied, and penalised ([M23] eq. 6-7):
where U_b is the set of nodes with a battery. Equivalently, k_{u,t} is the clipped power in kW divided by P^cha_u (charge) or P^dis_u (discharge).
8. Node energy balance¶
[S22] eq. 13 and 16-17. The net energy exchanged with the grid, and its split into export and import:
The complementarity constraint e^gri · i^gri = 0 of [S22] eq. 12 holds by construction. Contracted export and import limits ([S22] eq. 10-11) are not modelled.
11. Reward¶
Default reward type welfare ([M23] eq. 8):
Other reward types, kept for compatibility and reported per node in info:
profit: per-node π^egr e^gri − π^igr i^gri − storage cost, plus the incentive for the collective variant;energy(0.6.2 legacy): −(i^gri_{u,t})² per node.
With m_{u,t} the per-node term above, each of these types has two variants:
collective: R_t = M_t − σ K_t, with M_t = Σ_u m_{u,t} over all nodes, plus I_t for
profit(so that the collectiveprofitequalswelfare);per node (
reward_per_node, the 0.6.2single_agent): r_{u,t} = m_{u,t} − σ k_{u,t} for every u ∈ U_b, reported ininfo, and the scalar reward is R_t = Σ_{u ∈ U_b} r_{u,t}.
welfare has no per-node variant.
With N = |U_b| batteries the penalty of the per-node variant is Σ_{u ∈ U_b} σ k_{u,t} = N σ K_t, N times the collective one, and the main terms differ too: collective and per-node rewards, including their training curves, are not numerically comparable.
No running reward scaling inside the environment; scaling, if wanted, is applied by a wrapper or by the training library.
12. Information timing¶
Controlled by observe_current_step:
True(as in [M23]): when the agent chooses a_{u,t}, the observation contains g_{u,t}, l_{u,t}, the prices of step t and the bounds A^upper_{u,t}, A^lower_{u,t} of section 6.False(causal): the observation contains g and l of step t − 1; prices of step t remain observable (day-ahead sell prices, fixed buy prices); the observed A^upper is computed without the charge-cap term so that it does not reveal g_{u,t}. The environment still applies the full bounds of section 6 when clipping.
Forecasts, when added, cover steps t + 1 … t + H with True and t … t + H − 1 with False.
13. Baseline controller and comparison metric¶
Rule-based controller ([M23] Algorithm 1), computed in energy (node side) and converted to an action. It reads g and l of step t. The energies a battery can take and deliver in step t are those of the dynamic bounds of section 6 (power limits, charge cap, efficiencies, S^min, S^max, self-discharge):
A charge energy x gives the action x / (P^cha_u ΔT), a discharge energy x the action −x / (P^dis_u ΔT). Every action lies in [−A^lower_{u,t}, A^upper_{u,t}], so the controller is never clipped or penalised (K_t = 0). Two modes:
node(each battery follows its own node; intended for single-node use), with d = g_{u,t} − l_{u,t}:if u is a producer and g_{u,t} = 0: discharge E^dis_{u,t} (rule of 0.6.2; with d = g a producer would never discharge);
otherwise, if d ≥ 0: charge min(d, E^cha_{u,t});
otherwise: discharge min(−d, E^dis_{u,t}).
community(the batteries follow the community balance; reference baseline), with B_t = Σ_{u ∈ U} g_{u,t} − Σ_{u ∈ U} l_{u,t} over all nodes:if B_t > 0: every battery charges f E^cha_{u,t} with f = min(1, B_t / Σ_{v ∈ U_b} E^cha_{v,t}), that is min(B_t, Σ E^cha) split pro rata to E^cha;
if B_t < 0: every battery discharges f E^dis_{u,t} with f = min(1, −B_t / Σ_{v ∈ U_b} E^dis_{v,t});
if B_t = 0, or the sum is 0: idle.
With
charge_limit: productiona battery may charge from its own node’s generation while that node imports (B_t > 0 but g_{u,t} < l_{u,t}): the charge respects c_{u,t} = g_{u,t}, and under the virtual sharing model the extra import is covered by the community surplus.
The rule-based controller is a reference, not a lower bound: it is not required to beat idle batteries.
Fit Score ([M23] eq. 11) between the daily welfare series of a reference T1 (the MILP oracle) and of a controller T2:
14. Declared deviations from the papers¶
Item |
Papers |
SmartCer 1.0 |
Reason |
|---|---|---|---|
Dynamic bounds |
[M23] eq. 1-2 use (c − SoC)/ΔT and SoC/ΔT, without η or S^min |
derived from [S22] dynamics, with η and S^min (section 6) |
the [M23] bounds allow a discharge that drives the state of charge below S^min (defect of 0.6.2) |
Power rating |
[M23]: a single rated power r_u |
separate P^cha_u and P^dis_u as in [S22]; P^cha = P^dis = r_u recovers [M23] |
generality at no cost |
Incentive |
uniform π^inc_t |
|
the default must match the MILP objective |
SoC in the actor state |
[M23] Tab. II lists a “periodic” encoder |
scaled to [S^min, S^max] |
likely typo in the table |
End-of-day constraints |
[M23]: batteries empty at the start and end of each day in the MILP |
none; S^end not modelled |
simplification |
Contracted grid limits |
[S22] eq. 10-11 |
not modelled |
not binding with the charge rule and fixed loads |
Demand and generation flexibility |
[S22] eq. 1-3, costs π^reg, π^fle |
not modelled |
shiftable loads are outside the scope of the RL agent |
10. Social welfare¶
[M23] eq. 3, that is [S22] eq. 14 without the flexibility terms:
The storage term charges the energy that enters or leaves the cell. Producers have no buy price requirement: under the charge rule they never import.