From ccb8589a4bcaaed746a62aa81faf6e0b5fc07b0e Mon Sep 17 00:00:00 2001 From: Aart van Halteren Date: Mon, 20 Feb 2023 18:13:50 +0100 Subject: [PATCH] Refactor to prepare for getting monthly overview --- app/helpers/ReadingsMailer.rb | 7 +++-- app/models/cost.rb | 57 +++++++++++++++++++++++++++-------- app/models/reading.rb | 19 ++++++++++++ 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/app/helpers/ReadingsMailer.rb b/app/helpers/ReadingsMailer.rb index 07ec11c..ce8792b 100644 --- a/app/helpers/ReadingsMailer.rb +++ b/app/helpers/ReadingsMailer.rb @@ -25,6 +25,9 @@ class ReadingsMailer # Fetch today's usage usage_today = Reading.diff_on(date) + consumption_today, production_today = Reading.consumed_and_produced_for_diff(usage_today) + + # Calculate costs for oxxio and easy energy c = Cost.new oxxio_cost = c.oxxio_energy_cost(date.to_s,usage_today[:total_kwh_consumed_high]-usage_today[:total_kwh_produced_high], usage_today[:total_kwh_consumed_low]-usage_today[:total_kwh_produced_low]) easy_cost = c.easy_energy_cost_barplot(date) # side effect: generates a PNG @@ -41,8 +44,8 @@ class ReadingsMailer text_part do body "Summary for #{date}\n -------------------------------\n\n - Total kWH electricity consumed: #{usage_today[:total_kwh_consumed_high] + usage_today[:total_kwh_consumed_low]}\n - Total kWH electricity produced: #{usage_today[:total_kwh_produced_high] + usage_today[:total_kwh_produced_low]}\n + Total kWH electricity consumed: #{consumption_today}\n + Total kWH electricity produced: #{production_today}\n Total m3 gas consumed: #{usage_today[:total_m3_gas_consumed]}\n\n kWH cost (Oxxio): EUR #{ oxxio_cost }\n kWH cost (EasyEnergy): EUR #{ easy_cost }\n diff --git a/app/models/cost.rb b/app/models/cost.rb index 480f8de..3a86cac 100644 --- a/app/models/cost.rb +++ b/app/models/cost.rb @@ -116,24 +116,57 @@ class Cost g.data :costs, costs g.write("plots/easy_tariff_%s.png" % date.strftime("%F")) end - - def easy_energy_cost_barplot(date) - hour_start = date.in_time_zone(zone).beginning_of_day - day_end = hour_start.advance(days: 1) + + # calculate the hourly cost between start_hour and end_hour + def easy_energy_hourly_cost_between(start_hour, end_hour) + begin_hour = start_hour costs = [] - while(hour_start < day_end) do + while(begin_hour < end_hour) do # get usage_kwh/return_kwh for one hour - hour_end = hour_start.end_of_hour - hour_readings = Reading.where("created_at > :begin AND created_at < :end", {:begin => hour_start, :end => hour_end}) + begin_hour_plus1 = begin_hour.end_of_hour + hour_readings = Reading.where("created_at > :begin AND created_at < :end", {:begin => begin_hour, :end => begin_hour_plus1}) hour_diff = hour_readings.last ? hour_readings.last.diff(hour_readings.first) : UNKNOWN_READING - usage_kwh = hour_diff[:total_kwh_consumed_high] + hour_diff[:total_kwh_consumed_low] - return_kwh = hour_diff[:total_kwh_produced_high] + hour_diff[:total_kwh_produced_low] - - formatted_hour = hour_start.strftime("%F %H") + # helper to remove distiction between low/high tarif consumption + usage_kwh, return_kwh = Reading.consumed_and_produced_for_diff(hour_diff) + + formatted_hour = begin_hour.strftime("%F %H") costs << easy_energy_cost(formatted_hour, usage_kwh, return_kwh) # do the next hour - hour_start = hour_start.advance(:hours => 1) + begin_hour = begin_hour.advance(:hours => 1) end + # give the result + costs + end + + def easy_energy_daily_cost_between(start_day, end_day) + curr_day = start_day + costs = [] + while (curr_day <= end_day) do + hour_start = curr_day.in_time_zone(zone).beginning_of_day + hour_end = hour_start.advance(days: 1) + + costs_24hours = easy_energy_hourly_cost_between(hour_start,hour_end) + if costs_24hours.any?{ |e| e.nil? } + p "Not all Reading data between %s and %s is available!" % [I18n.localize(start_day, format: "%e %B %Y"), I18n.localize(end_day, format: "%e %B %Y")] + end + # add the sum of 24 hours + costs << costs_24hours.compact.sum + # do the next day + curr_day = curr_day.advance(:days => 1) + end + # give the result + costs + end + + def easy_energy_hourly_cost_for(date) + hour_start = date.in_time_zone(zone).beginning_of_day + day_end = hour_start.advance(days: 1) + easy_energy_hourly_cost_between(hour_start, day_end) + end + + def easy_energy_cost_barplot(date) + # get array with 24 hourly cost values + costs = easy_energy_hourly_cost_for(date) # create plot hours = (0..23).to_a diff --git a/app/models/reading.rb b/app/models/reading.rb index 548ed55..83a7325 100644 --- a/app/models/reading.rb +++ b/app/models/reading.rb @@ -76,6 +76,14 @@ class Reading < ActiveRecord::Base @@max_charge_kwh end + # do not make distinction between high and low consumption/production + def consumed_and_produced_for_diff(d) + + usage_kwh = (d[:total_kwh_consumed_high].nil? || d[:total_kwh_consumed_low].nil?) ? nil : d[:total_kwh_consumed_high] + d[:total_kwh_consumed_low] + return_kwh = (d[:total_kwh_produced_high].nil? || d[:total_kwh_produced_low].nil?) ? nil : d[:total_kwh_produced_high] + d[:total_kwh_produced_low] + + return usage_kwh, return_kwh + end def diff_on(date) readings_on = day(date) @@ -87,5 +95,16 @@ class Reading < ActiveRecord::Base { :total_kwh_consumed_high => 0, :total_kwh_consumed_low => 0, :total_kwh_produced_high => 0, :total_kwh_produced_low => 0, :total_m3_gas_consumed => 0 } end end + + def diff_between(from_date, to_date) + readings_on_days = days(from_date, to_date) + first = readings_on_days.first + last = readings_on_days.last + if last + last.diff(first) + else + { :total_kwh_consumed_high => 0, :total_kwh_consumed_low => 0, :total_kwh_produced_high => 0, :total_kwh_produced_low => 0, :total_m3_gas_consumed => 0 } + end + end end end