-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathheating_and_weather_multi_years.py
More file actions
181 lines (137 loc) · 7.27 KB
/
Copy pathheating_and_weather_multi_years.py
File metadata and controls
181 lines (137 loc) · 7.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import json
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
below_degrees = 16
energy_source = 'Gas'
max_tank_liters = 1560
minimum_tank_level_percent = 25
maximum_tank_level_percent = 85
# unit, maximum y-display-value, y-display-ticks
heating_consumption_unit = ['kWh', 5000, 250]
# heating_consumption_unit = ['Liter', 700, 100]
# heating_consumption_unit = ['%', 60, 5]
with open("data/heat_period_config.json", "r") as f:
date_ranges = json.load(f)
heating_consumption_data = './data/heat_consumption_data.csv'
electric_heat_consumption_data = './data/electric_heat_consumption_data.csv'
weather_data_file_template = './data/weather_data_{}.json'
temperature_bin_size = 4
tank_df = pd.read_csv(heating_consumption_data, parse_dates=['Date'], dayfirst=True)
latest_consumption_date = tank_df['Date'].max()
try:
electric_df = pd.read_csv(electric_heat_consumption_data, dtype={'Date': str})
electric_df['Date'] = pd.to_datetime(electric_df['Date'], format='%m.%Y')
except (FileNotFoundError, ValueError):
electric_df = pd.DataFrame(columns=['Date', 'kWh'])
tank_df['Tank level in %'] = (tank_df['Tank level in %']
.apply(lambda x: ((x - minimum_tank_level_percent) /
(maximum_tank_level_percent - minimum_tank_level_percent)) * 100))
available_colors = ['gray', 'red', 'green', 'blue', 'black', 'purple', 'brown', 'orange', 'yellow', 'gray']
colors = []
weather_data = []
for year in date_ranges.keys():
with open(weather_data_file_template.format(year), 'r') as f:
weather_data_per_year = json.load(f)
weather_data.extend(weather_data_per_year)
weather_df = pd.DataFrame(weather_data)
weather_df['date'] = pd.to_datetime(weather_df['date'])
row = - 1
added_electric_label = False
def energy_converter(energy_consumption_in_percent, heating_unit, max_tank_liters):
# 100% = 1560L volle Tankfüllung von 0 auf 100%
# 47% = 47 * 1560 / 100 L
# Ein Liter (l) Flüssiggas enthält ca. 7.13 Kilowattstunden (kWh) Brennwert Energie.
# https://fluessiggas.de/wissen/fluessiggas/fluessiggas-umrechnung/#fluessiggas-rechner
if heating_unit == 'kWh':
return energy_consumption_in_percent * (max_tank_liters / 100) * 7.13
elif heating_unit == 'Liter':
return energy_consumption_in_percent * (max_tank_liters / 100)
return energy_consumption_in_percent
def fill_missing_values(tank_df, dates_filter):
tank_year = tank_df.copy()
tank_year.set_index('Date', inplace=True)
all_dates = tank_year.index.union(dates_filter).sort_values().drop_duplicates()
tank_year = tank_year.reindex(all_dates)
tank_year = tank_year[~tank_year.index.duplicated(keep='first')]
tank_year.interpolate(method='pchip', limit_area='inside', inplace=True)
tank_year = tank_year.loc[dates_filter]
# Reset the index
tank_year.reset_index(inplace=True)
tank_year.rename(columns={'index': 'Date'}, inplace=True)
return tank_year
fig, ax = plt.subplots(2, 1, figsize=(10, 10))
years = [int(year) for year in date_ranges.keys()]
labels_for_plot = []
sum_below_degrees_for_plot = []
for year in years:
row = row + 1
colors.append(available_colors[row])
date_range_of_interest = date_ranges[str(year)]
start_date = pd.to_datetime(date_range_of_interest["start"])
end_date = pd.to_datetime(date_range_of_interest["end"])
if end_date > latest_consumption_date:
end_date = latest_consumption_date
if start_date > latest_consumption_date:
continue
all_dates_filter = pd.date_range(start_date, end_date)
tank_year = fill_missing_values(tank_df, all_dates_filter)
weather_df['min_temperature'] = weather_df['temperature'].apply(lambda x: x['min'])
weather_df['max_temperature'] = weather_df['temperature'].apply(lambda x: x['max'])
weather_df['avg_temperature'] = (weather_df['min_temperature'] + weather_df['max_temperature']) / 2
merged_df = pd.merge(tank_year, weather_df, left_on='Date', right_on='date', how='outer')
merged_df = merged_df[
(merged_df['Date'].dt.year >= years[0]) & (merged_df['Date'].dt.year <= years[years.__len__() - 1] + 1)]
merged_df['{} Consumption in %'.format(energy_source)] = -merged_df['Tank level in %'].diff()
total_energy_consumption = merged_df['{} Consumption in %'.format(energy_source)].sum()
total_energy_consumption = energy_converter(total_energy_consumption,
heating_consumption_unit[0],
max_tank_liters)
merged_df['below_degrees'] = below_degrees - merged_df[merged_df['avg_temperature'] < below_degrees][
'avg_temperature']
sum_below_degrees = merged_df['below_degrees'].sum()
energyPerWinter = 0
if sum_below_degrees > 0:
energyPerWinter = round(total_energy_consumption / sum_below_degrees, 2)
label = '{}/{}\n{}'.format(year, year + 1, round(energyPerWinter, 2))
gas_label = '{} Consumption'.format(energy_source) if row == 0 else ""
ax[0].bar(label, total_energy_consumption, color=colors[row], alpha=0.6, label=gas_label)
electric_year = electric_df[(electric_df['Date'] >= start_date) & (electric_df['Date'] <= end_date)]
total_electric_kwh = electric_year['kWh'].sum()
if total_electric_kwh > 0:
if heating_consumption_unit[0] == 'Liter':
total_electric_display = 0
elif heating_consumption_unit[0] == 'kWh':
total_electric_display = total_electric_kwh
else:
total_electric_display = (total_electric_kwh / 7.13) / (max_tank_liters / 100)
electric_label = 'Electric Heat (MSZ-LN)' if not added_electric_label else ""
ax[0].bar(label, total_electric_display, bottom=total_energy_consumption, color='magenta', alpha=0.8, label=electric_label)
added_electric_label = True
labels_for_plot.append(label)
sum_below_degrees_for_plot.append(sum_below_degrees)
ax2 = ax[0].twinx()
ax2.plot(labels_for_plot, sum_below_degrees_for_plot, color='blue', marker='o', linewidth=2, label='Degrees < {}°'.format(below_degrees))
ax2.set_ylabel('Sum of degrees under {}°'.format(below_degrees), color='blue')
ax2.tick_params(axis='y', labelcolor='blue')
ax2.set_ylim(bottom=0)
weather_df.set_index('date', inplace=True)
monthly_avg_temperatures = weather_df['avg_temperature'].resample('ME').mean()
ax[0].set_xlabel('Heating period and consumption / Sum of degrees under {}° (the lower the better)'.format(
below_degrees))
ax[0].set_ylabel('Total consumption ({})'.format(heating_consumption_unit[0]))
ax[0].set_title('Total {} consumption per year'.format(energy_source))
ax[0].set_yticks(np.arange(0, heating_consumption_unit[1], heating_consumption_unit[2]))
ax[0].grid(True, axis='y')
ax2.legend(loc='upper right')
ax[1].plot(monthly_avg_temperatures.index, monthly_avg_temperatures.values)
ax[1].set_xlim([mdates.date2num(pd.Timestamp('{}-07-01'.format(years[0]))),
mdates.date2num(pd.Timestamp('{}-08-30'.format(years[years.__len__() - 1] + 1)))])
ax[1].set_title('Monthly average temperatures')
ax[1].set_xlabel('Month')
ax[1].set_ylabel('Average temperature')
ax[1].set_yticks(np.arange(0, 30, 5))
ax[1].grid(True, axis='y')
plt.tight_layout()
plt.show()