Refactoring
This commit is contained in:
@@ -7,29 +7,82 @@ require 'open-uri'
|
||||
require 'nokogiri'
|
||||
|
||||
class Entsoe
|
||||
|
||||
URL = 'https://transparency.entsoe.eu'
|
||||
|
||||
def initialize(api_key)
|
||||
URL = 'https://transparency.entsoe.eu'
|
||||
|
||||
attr_reader :storage_cost
|
||||
|
||||
def initialize(api_key = "c2287e07-0c26-4950-b430-22b7f75a8f2e")
|
||||
@api_key = api_key
|
||||
@kwh_prices = {}
|
||||
@storage_cost = 0.05 # how much does it cost to store 1 kwh in battery
|
||||
end
|
||||
|
||||
def day_ahead_prices(date)
|
||||
def price_at(formatted_hour)
|
||||
unless @kwh_prices.key?(formatted_hour)
|
||||
@kwh_prices.merge!(query_day_ahead_prices(Date.parse(formatted_hour)))
|
||||
end
|
||||
@kwh_prices[formatted_hour]
|
||||
end
|
||||
|
||||
def prices_at(date)
|
||||
hour_start = date.beginning_of_day
|
||||
day_end = hour_start.advance(days: 1)
|
||||
result = {}
|
||||
while(hour_start < day_end) do
|
||||
formatted_hour = hour_start.strftime("%F-%H")
|
||||
result.merge!({ formatted_hour => price_at(formatted_hour)})
|
||||
hour_start = hour_start.advance(:hours => 1)
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def high_low_hours(date)
|
||||
sorted_prices = prices_at(date).to_a.sort_by(&:last) # sort according to price
|
||||
lowest_hour = sorted_prices.first[0]
|
||||
highest_hour = sorted_prices.last[0]
|
||||
# calculate hours where rate > charge_rate + storage_cost (typically 0.05)
|
||||
charge_rate = sorted_prices.first[1] # assume we charge at lowest hour
|
||||
high_hours = sorted_prices.select{|p| p[1] > charge_rate + storage_cost}.to_h.keys
|
||||
|
||||
return lowest_hour,highest_hour,high_hours
|
||||
end
|
||||
|
||||
def query_day_ahead_prices(date)
|
||||
start_date = date.beginning_of_day
|
||||
end_date = date.end_of_day
|
||||
|
||||
# A44 - Document type => Price Document
|
||||
# A01 - Process type => Day Ahead
|
||||
# NL = '10YNL----------L'
|
||||
|
||||
domain = '10YNL----------L'
|
||||
url = URL + "/api?securityToken=%s&documentType=A44&processType=A01&in_Domain=%s&out_Domain=%s&periodStart=%s&periodEnd=%s" % [@api_key, domain, domain, start_date.iso8601, end_date.iso8601]
|
||||
p url
|
||||
url = URL + "/api?securityToken=%s&documentType=A44&in_Domain=%s&out_Domain=%s&periodStart=%s&periodEnd=%s" % [@api_key, domain, domain, start_date.strftime("%Y%m%d%H%M"), end_date.strftime("%Y%m%d%H00")]
|
||||
#p url
|
||||
|
||||
base_request(date, url)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def base_request(url)
|
||||
# get position and amount from XML snippet
|
||||
# <Point>
|
||||
# <position>1</position>
|
||||
# <price.amount>196.23</price.amount>
|
||||
# </Point>
|
||||
#
|
||||
# convert price to EUR per kwh, including VAT (21%)
|
||||
#
|
||||
def parse_point(xml)
|
||||
return xml.children[1].text.to_i, ((xml.children[3].text.to_f/1000)*1.21).round(5)
|
||||
end
|
||||
|
||||
def base_request(date, url)
|
||||
formatted_date = date.strftime("%F")
|
||||
|
||||
doc = Nokogiri::XML(URI.open(url))
|
||||
end
|
||||
prices = doc.xpath('.//xmlns:Point').map{|p| parse_point(p)}
|
||||
|
||||
#returns a hash with keys formatted "yyyy-mm-dd-hr" and values price (per kwh)
|
||||
prices.map{|p| ["%s-%02d" % [formatted_date,(p[0]-1)], p[1]]}.to_h
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user