Adds timezone to Entsoe prices
This commit is contained in:
@@ -10,30 +10,32 @@ class Entsoe
|
|||||||
|
|
||||||
URL = 'https://transparency.entsoe.eu'
|
URL = 'https://transparency.entsoe.eu'
|
||||||
|
|
||||||
attr_accessor :no_grid_charge_months
|
attr_accessor :no_grid_charge_months, :zone
|
||||||
attr_reader :storage_cost
|
attr_reader :storage_cost
|
||||||
|
|
||||||
def initialize(storage_cost = 0.05, api_key = "c2287e07-0c26-4950-b430-22b7f75a8f2e")
|
def initialize(zone = "Amsterdam", storage_cost = 0.05, api_key = "c2287e07-0c26-4950-b430-22b7f75a8f2e")
|
||||||
@api_key = api_key
|
@api_key = api_key
|
||||||
@kwh_prices = {}
|
@kwh_prices = {}
|
||||||
@storage_cost = storage_cost # how much does it cost to store 1 kwh in battery
|
@storage_cost = storage_cost # how much does it cost to store 1 kwh in battery
|
||||||
@no_grid_charge_months = [5,6,7] # months where we assume there is enough surplus from sun power
|
@no_grid_charge_months = [5,6,7] # months where we assume there is enough surplus from sun power
|
||||||
|
@zone = zone
|
||||||
end
|
end
|
||||||
|
|
||||||
def price_at(formatted_hour)
|
def price_at(formatted_hour)
|
||||||
unless @kwh_prices.key?(formatted_hour)
|
unless @kwh_prices.key?(formatted_hour)
|
||||||
p "Fetching Entsoe tariffs for %s" % formatted_hour
|
p "Fetching Entsoe tariffs for %s" % formatted_hour
|
||||||
@kwh_prices.merge!(query_day_ahead_prices(Date.parse(formatted_hour)))
|
prices = query_day_ahead_prices(Date.parse(formatted_hour))
|
||||||
|
@kwh_prices.merge!(hourly_format(prices))
|
||||||
end
|
end
|
||||||
@kwh_prices[formatted_hour]
|
@kwh_prices[formatted_hour]
|
||||||
end
|
end
|
||||||
|
|
||||||
def prices_at(date)
|
def prices_at(date)
|
||||||
hour_start = date.beginning_of_day
|
hour_start = date.beginning_of_day.in_time_zone(@zone)
|
||||||
day_end = hour_start.advance(days: 1)
|
day_end = hour_start.advance(days: 1)
|
||||||
result = {}
|
result = {}
|
||||||
while(hour_start < day_end) do
|
while(hour_start < day_end) do
|
||||||
formatted_hour = hour_start.strftime("%F-%H")
|
formatted_hour = hour_start.strftime("%F %H")
|
||||||
result.merge!({ formatted_hour => price_at(formatted_hour)})
|
result.merge!({ formatted_hour => price_at(formatted_hour)})
|
||||||
hour_start = hour_start.advance(:hours => 1)
|
hour_start = hour_start.advance(:hours => 1)
|
||||||
end
|
end
|
||||||
@@ -79,6 +81,11 @@ class Entsoe
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def hourly_format(prices)
|
||||||
|
# in memory hash @kwh_prices is in @zone timezone
|
||||||
|
prices.to_a.map{|p| [p[0].in_time_zone(@zone).strftime("%F %H"),p[1]]}.to_h
|
||||||
|
end
|
||||||
|
|
||||||
# get position and amount from XML snippet
|
# get position and amount from XML snippet
|
||||||
# <Point>
|
# <Point>
|
||||||
# <position>1</position>
|
# <position>1</position>
|
||||||
@@ -88,16 +95,20 @@ class Entsoe
|
|||||||
# convert price to EUR per kwh, including VAT (21%)
|
# convert price to EUR per kwh, including VAT (21%)
|
||||||
#
|
#
|
||||||
def parse_point(xml)
|
def parse_point(xml)
|
||||||
return xml.children[1].text.to_i, ((xml.children[3].text.to_f/1000)*1.21).round(5)
|
return xml.xpath(".//xmlns:position").text.to_i, ((xml.xpath(".//xmlns:price.amount").text.to_f/1000)*1.21).round(5)
|
||||||
end
|
end
|
||||||
|
|
||||||
def base_request(date, url)
|
def base_request(date, url)
|
||||||
formatted_date = date.strftime("%F")
|
formatted_date = date.strftime("%F")
|
||||||
|
|
||||||
doc = Nokogiri::XML(URI.open(url))
|
doc = Nokogiri::XML(URI.open(url))
|
||||||
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 = doc.xpath('.//xmlns:Point').map{|p| parse_point(p)}
|
||||||
prices.map{|p| ["%s-%02d" % [formatted_date,(p[0]-1)], p[1]]}.to_h
|
# get start_time (in UTC) from XML docment
|
||||||
|
start_time = DateTime.parse(doc.xpath('.//xmlns:period.timeInterval//xmlns:start').text)
|
||||||
|
|
||||||
|
#returns a hash with keys formatted "yyyy-mm-dd hr" and values price (per kwh)
|
||||||
|
# <position> tag runs from 1-24. We need hours from 00-23, therefore substracting 1
|
||||||
|
prices.map{|p| [start_time.advance(hours: (p[0]-1)), p[1]]}.to_h
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
10
db/migrate/003_creates_prices.rb
Normal file
10
db/migrate/003_creates_prices.rb
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
class CreatesPrices << ActiveRecord::Migration[4.2]
|
||||||
|
def change
|
||||||
|
create_table :prices do |t|
|
||||||
|
t.datetime :hour
|
||||||
|
t.float :usage_kwh
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :prices, :hour
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user