eco2mix-simulator/simu.rb

72 lines
2.5 KiB
Ruby
Executable File

#!/usr/bin/env ruby
PRODUCTIONS = {
nuclear: { power: 0, load: 0.75, current: 61_400 },
solar: { power: 196_004, load: 0.15, current: 9_600 },
onshore_wind: { power: 62_764, load: 0.23, current: 16_019 },
offshore_wind: { power: 131_105, load: 0.30, current: 0 },
hydraulic: { power: 22_831, load: 0.30, current: 25_500 }
}
STORAGES = {
seasonal: { power: 0, capacity: 0 },
weekly: { power: 0, capacity: 0 },
daily: { power: 0, capacity: 0 }
}
require 'awesome_print'
require 'csv'
require 'pry-byebug'
require 'date'
require 'active_support/core_ext/numeric/time'
STORAGE = 0
OVER_PRODUCTION = { min: 0, max: 0, sum: 0 }
UNDER_PRODUCTION = { min: 0, max: 0, sum: 0 }
blackout_duration = 0
def simulate(type, value, current = nil)
production = PRODUCTIONS.fetch type
power = production.fetch :power
current ||= production.fetch :current
# ap type: type, value: value, current: current, power: power, value: value
[power.to_f * value.to_f / current.to_f, 0].max
end
def humanize(secs)
[[60, :seconds], [60, :minutes], [24, :hours], [Float::INFINITY, :days]].map{ |count, name|
if secs > 0
secs, n = secs.divmod(count)
"#{n.to_i} #{name}" unless n.to_i==0
end
}.compact.reverse.join(' ')
end
CSV.foreach './eCO2mix_RTE_En-cours-Consolide.xls', headers: true, col_sep: "\t" do |row|
next unless row['Périmètre'] == 'France' && row['Consommation']
date, hour = row['Date'], row['Heures']
date = DateTime.parse "#{date}T#{hour}"
nuclear = simulate :nuclear, row['Nucléaire'].to_i
onshore_wind = simulate :onshore_wind, row['Eolien'].to_i
offshore_wind = simulate :offshore_wind, row['Eolien'].to_i, PRODUCTIONS.dig(:onshore_wind, :current)
solar = simulate :solar, row['Solaire'].to_i
hydraulic = simulate :hydraulic, row['Hydraulique'].to_i
consumption = row['Consommation'].to_i
total = nuclear + onshore_wind + offshore_wind + solar + hydraulic
delta = total - consumption
if delta < 0
delta *= -1
UNDER_PRODUCTION[:min] = [UNDER_PRODUCTION[:min], delta].min
UNDER_PRODUCTION[:max] = [UNDER_PRODUCTION[:max], delta].max
UNDER_PRODUCTION[:sum] += delta
blackout_duration += 30.minutes
else
OVER_PRODUCTION[:min] = [OVER_PRODUCTION[:min], delta].min
OVER_PRODUCTION[:max] = [OVER_PRODUCTION[:max], delta].max
OVER_PRODUCTION[:sum] += delta
end
end
ap over: OVER_PRODUCTION, under: UNDER_PRODUCTION, blackout: humanize(blackout_duration)