From ddbd6af3458042c8db41921aa2a739db36be68da Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Fri, 26 Oct 2018 15:38:06 +0100 Subject: [PATCH] Add CSV download of H2 curves --- app/controllers/api/v3/curves_controller.rb | 10 ++++ app/models/api/v3/hydrogen_csv_presenter.rb | 63 +++++++++++++++++++++ config/routes.rb | 4 ++ 3 files changed, 77 insertions(+) create mode 100644 app/models/api/v3/hydrogen_csv_presenter.rb diff --git a/app/controllers/api/v3/curves_controller.rb b/app/controllers/api/v3/curves_controller.rb index 18b56fa56..f1a839414 100644 --- a/app/controllers/api/v3/curves_controller.rb +++ b/app/controllers/api/v3/curves_controller.rb @@ -53,6 +53,16 @@ def household_heat_curves end end + # Downloads the total demand and supply for hydrogen, with additional + # columns for the storage demand and supply. + def hydrogen + presenter = Api::V3::HydrogenCSVPresenter.new(scenario.gql.future_graph) + + send_csv('hydrogen') do |csv| + presenter.to_csv_rows.each { |row| csv << row } + end + end + private def merit_required diff --git a/app/models/api/v3/hydrogen_csv_presenter.rb b/app/models/api/v3/hydrogen_csv_presenter.rb new file mode 100644 index 000000000..868b2addb --- /dev/null +++ b/app/models/api/v3/hydrogen_csv_presenter.rb @@ -0,0 +1,63 @@ +module Api + module V3 + # Creates CSV rows describing hydrogen production. + class HydrogenCSVPresenter + def initialize(graph) + @graph = graph + end + + # Public: Creates an array of rows for a CSV file containing the loads of + # hydrogen producers and consumers. + # + # Returns an array of arrays. + def to_csv_rows + # Empty CSV if time-resolved calculations are not enabled. + unless @graph.plugin(:time_resolve)&.hydrogen + return [['Merit order and time-resolved calculation are not ' \ + 'enabled for this scenario']] + end + + [*producer_columns, *consumer_columns].transpose + end + + private + + # Internal: Data about hydrogen production. + def producer_columns + converters_of_type(:producer, :import, :storage).map do |converter| + column_from_converter(converter, :output) + end + end + + # Internal: Data about consumption production. + def consumer_columns + converters_of_type(:consumer, :export, :storage).map do |converter| + column_from_converter(converter, :input) + end + end + + # Internal: Creates a column representing data for a converter in a + # direction. + def column_from_converter(converter, direction) + loads = converter.converter_api + .public_send("hydrogen_#{direction}_curve").map { |val| val.round(2) } + + ["#{converter.key}.#{direction}", *loads] + end + + def converters_of_type(*types) + types.flat_map { |type| converters[type] }.sort_by(&:key) + end + + def converters + @converters ||= @graph.converters.select(&:hydrogen) + .each_with_object({}) do |converter, data| + next unless converter.hydrogen + + data[converter.hydrogen.type] ||= [] + data[converter.hydrogen.type].push(converter) + end + end + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 6ae56a7dd..3e5632172 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -44,6 +44,10 @@ to: 'curves#household_heat_curves', as: :curves_household_heat_download + get 'curves/hydrogen', + to: 'curves#hydrogen', + as: :curves_hydrogen_download + # Old paths for Merit downloads. get 'merit/loads', to: redirect('api/v3/scenarios/%{scenario_id}/curves/loads') get 'merit/price', to: redirect('api/v3/scenarios/%{scenario_id}/curves/price')