@@ -73,7 +73,7 @@ func (mpc *MPCController) Optimize(forecast []TimeSlot) []ControlDecision {
7373 // Use dynamic programming for optimization
7474 // State: SOC level, Time: hour
7575 // We'll discretize SOC into steps for tractability
76- socSteps := 20
76+ socSteps := 200
7777 socStep := (mpc .Config .BatteryMaxSOC - mpc .Config .BatteryMinSOC ) / float64 (socSteps )
7878
7979 // DP table: [time][soc_index] -> (best_profit, best_decision)
@@ -171,9 +171,9 @@ func (mpc *MPCController) generateFeasibleDecisions(currentSOC float64, slot Tim
171171 {0 , 0 }, // Idle
172172 }
173173
174- // Add charge options
175- for i := 1 ; i <= 5 ; i ++ {
176- charge := float64 (i ) * mpc .Config .BatteryMaxCharge / 5 .0
174+ // Add charge options (more granular for better arbitrage opportunities)
175+ for i := 1 ; i <= 10 ; i ++ {
176+ charge := float64 (i ) * mpc .Config .BatteryMaxCharge / 10 .0
177177 if mpc .canCharge (currentSOC , charge ) {
178178 batteryActions = append (batteryActions , struct {
179179 charge float64
@@ -182,9 +182,9 @@ func (mpc *MPCController) generateFeasibleDecisions(currentSOC float64, slot Tim
182182 }
183183 }
184184
185- // Add discharge options
186- for i := 1 ; i <= 5 ; i ++ {
187- discharge := float64 (i ) * mpc .Config .BatteryMaxDischarge / 5 .0
185+ // Add discharge options (more granular for better arbitrage opportunities)
186+ for i := 1 ; i <= 10 ; i ++ {
187+ discharge := float64 (i ) * mpc .Config .BatteryMaxDischarge / 10 .0
188188 if mpc .canDischarge (currentSOC , discharge ) {
189189 batteryActions = append (batteryActions , struct {
190190 charge float64
@@ -229,15 +229,46 @@ func (mpc *MPCController) generateFeasibleDecisions(currentSOC float64, slot Tim
229229}
230230
231231// calculateProfit computes the profit for a decision
232+ // This accounts for:
233+ // 1. Charging battery when prices are low (cost reflected in GridImport)
234+ // 2. Discharging battery to support load when prices are high (savings reflected in reduced GridImport)
235+ // 3. Exporting excess power when export prices are favorable
232236func (mpc * MPCController ) calculateProfit (dec ControlDecision , slot TimeSlot ) float64 {
237+ // Revenue from exporting to grid
233238 revenue := dec .GridExport * slot .ExportPrice
234- cost := dec .GridImport * slot .ImportPrice
235239
236- // Battery degradation cost
240+ // Cost of importing from grid (includes charging battery from grid when prices are low)
241+ importCost := dec .GridImport * slot .ImportPrice
242+
243+ // Calculate the value of battery operations for arbitrage
244+ // When we discharge battery to support load, we avoid importing at current price
245+ // When we charge battery from grid, we pay current price but can use it later at higher prices
246+
247+ // Actual energy delivered from battery (accounting for efficiency)
248+ batteryDischargeEnergy := dec .BatteryDischarge // kWh delivered
249+
250+ // The discharge value: we avoid importing power at the current price
251+ // This is beneficial when import price is high
252+ dischargeValue := batteryDischargeEnergy * mpc .Config .BatteryEfficiency * slot .ImportPrice
253+
254+ // The charge cost: we store energy for future use
255+ // This is beneficial when import price is low (to use when prices are high)
256+ // The cost is already included in importCost, but we account for storage losses
257+ chargeLoss := dec .BatteryCharge * (1 - mpc .Config .BatteryEfficiency ) * slot .ImportPrice
258+
259+ // Battery degradation cost (wear and tear from cycling)
237260 batteryThroughput := dec .BatteryCharge + dec .BatteryDischarge
238261 degradationCost := batteryThroughput * mpc .Config .BatteryDegradationCost
239262
240- return revenue - cost - degradationCost
263+ // Net profit calculation:
264+ // + Revenue from exports
265+ // - Cost of imports (includes grid charging of battery)
266+ // + Value from discharging battery (avoids expensive imports)
267+ // - Cost of charging losses
268+ // - Battery degradation
269+ profit := revenue - importCost + dischargeValue - chargeLoss - degradationCost
270+
271+ return profit
241272}
242273
243274// Helper functions
0 commit comments