Skip to content

Commit

Permalink
updated wrapper naming scheme
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristophGehbauer committed Apr 2, 2024
1 parent 6771db2 commit 0aa4ba7
Show file tree
Hide file tree
Showing 11 changed files with 316 additions and 224 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
logs

# Python compiled files #
#########################
*.pyc
Expand Down
207 changes: 109 additions & 98 deletions afc/ctrlWrapper.py

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions afc/defaultConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ def default_parameter(tariff_name='e19-2020', hvac_control=True,
parameter['objective']['weight_actuation'] = weight_actuation # Weight of facade actuation
parameter['objective']['weight_glare'] = weight_glare # Weight of glare penalty in objective
parameter['objective']['weight_view'] = 0 # Weight of view penalty in objective
parameter['objective']['weight_ghg'] = 0 # Weight of GHG emissions
parameter['solver_options'] = {} # Pyomo solver options
parameter['solver_options']['seconds'] = int(60) # Maximal solver time, in seconds
#parameter['solver_options']['maxIterations'] = int(1e6) # Maximal iterations
Expand Down
2 changes: 1 addition & 1 deletion afc/glare/view_angle.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def sun_in_view(view_dist, view_height, window_bottom_height, window_top_height,
right_azi: Right aziumth when sun in view through the window
"""
if view_height > window_top_height:
print("WARNING: view_angle: Window below viewpoint.")
# print("WARNING: view_angle: Window below viewpoint.")
bot_alt, top_alt, left_azi, right_azi, view_window_angle = 0, 0, 0, 0, 0
else:
bot_vw = abs(window_bottom_height - view_height)
Expand Down
5 changes: 4 additions & 1 deletion afc/optModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,8 @@ def objective_function(model):
+ model.sum_export_revenue * parameter['objective']['weight_export'] \
+ model.sum_zone_actuation * parameter['objective']['weight_actuation'] \
+ model.sum_glare_penalty * parameter['objective']['weight_glare'] \
+ model.sum_view_penalty * parameter['objective']['weight_view']
+ model.sum_view_penalty * parameter['objective']['weight_view'] \
+ model.co2_total * parameter['objective']['weight_ghg']
#+ model.sum_regulation_revenue * parameter['objective']['weight_regulation']
model.objective = Objective(rule=objective_function, sense=minimize, doc='objective function')
return model
Expand Down Expand Up @@ -499,6 +500,8 @@ def afc_output_list():
'index': 'temps'}) # room, slab
ctrlOutputs.append({'data': 'zone_temp_max', 'df_label': 'Temperature %s Max [C]',
'index': 'temps'}) # room, slab
ctrlOutputs.append({'data': 'co2_profile_total', 'df_label': 'GHG Emissions [kg]'})

for d in ctrlOutputs:
d['name'] = d['data']
return ctrlOutputs
Expand Down
4 changes: 2 additions & 2 deletions afc/utility/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ def plot_standard1(data, title=None, plot=True, tight=True):
labels=['Room','Slab'])
axs[5].plot(data[['Temperature 0 Max [C]']], color='blue', linestyle='--')
axs[5].plot(data[['Temperature 0 Min [C]']], color='red', linestyle='--')
axs[5].plot(data[['Temperature 1 Max [C]']], color='blue', linestyle=':')
axs[5].plot(data[['Temperature 1 Min [C]']], color='red', linestyle=':')
#axs[5].plot(data[['Temperature 1 Max [C]']], color='blue', linestyle=':')
#axs[5].plot(data[['Temperature 1 Min [C]']], color='red', linestyle=':')
plot_plot_xy(axs[6],data[['Glare [-]']],title='Glare Level',ylab='DGP [1]',
labels=['Glare'])
axs[6].plot(data[['Glare Max [-]']], color='black', linestyle='--')
Expand Down
67 changes: 67 additions & 0 deletions afc/utility/thermostat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Advanced Fenestration Controller (AFC) Copyright (c) 2023, The
# Regents of the University of California, through Lawrence Berkeley
# National Laboratory (subject to receipt of any required approvals
# from the U.S. Dept. of Energy). All rights reserved.

""""Advanced Fenestration Controller
Thermostat control module.
"""

def afc_to_hvac_setpoint(ctrl_outputs, tdead=0.5):
"""Utility to convert from AFC to thermostat setpoints."""

# no control by default
hvac_mode = 'X'
new_cool_set = float(ctrl_outputs['cool_set'])
new_heat_set = float(ctrl_outputs['heat_set'])

if ctrl_outputs['hvac_control'] and ctrl_outputs['feasible']:

# float by default
hvac_mode = 'F'

# get new setpoints if not occupied (make sure within bounds)
if not ctrl_outputs['occupied']:

# cooling
if ctrl_outputs['power_cool'] > 1:
hvac_mode = 'C'
new_cool_set = min(ctrl_outputs['cool_set'],
ctrl_outputs['t_room'])
# make sure cool > heat
new_cool_set = max(new_cool_set, new_heat_set + tdead)

# heating
elif ctrl_outputs['power_heat'] > 1:
hvac_mode = 'H'
new_heat_set = max(ctrl_outputs['heat_set'],
ctrl_outputs['t_room'])
# make sure heat < cool
new_heat_set = min(new_heat_set, new_cool_set - tdead)

return {'feasible': ctrl_outputs['feasible'],
'mode': hvac_mode,
'csp': new_cool_set,
'hsp': new_heat_set}

def compute_thermostat_setpoints(df, feasible, control_hvac, occupied):
"""wrapper to compute thermostat setpoints"""

cool_set = df['Temperature 0 Max [C]'].values[0]
heat_set = df['Temperature 0 Min [C]'].values[0]
t_room = df['Temperature 0 [C]'].values[1]
power_cool = df['Power Cooling [W]'].iloc[0]
power_heat = df['Power Heating [W]'].iloc[0]

ctrl_outputs = {
'hvac_control': control_hvac,
'feasible': feasible,
't_room': t_room,
'cool_set': cool_set,
'heat_set': heat_set,
'occupied': occupied,
'power_cool': power_cool,
'power_heat': power_heat,
}

return afc_to_hvac_setpoint(ctrl_outputs, tdead=0.5)
5 changes: 4 additions & 1 deletion dev/Development-Controller.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,8 @@
" + model.sum_export_revenue * parameter['objective']['weight_export'] \\\n",
" + model.sum_zone_actuation * parameter['objective']['weight_actuation'] \\\n",
" + model.sum_glare_penalty * parameter['objective']['weight_glare'] \\\n",
" + model.sum_view_penalty * parameter['objective']['weight_view']\n",
" + model.sum_view_penalty * parameter['objective']['weight_view'] \\\n",
" + model.co2_total * parameter['objective']['weight_ghg']\n",
" #+ model.sum_regulation_revenue * parameter['objective']['weight_regulation']\n",
" model.objective = Objective(rule=objective_function, sense=minimize, doc='objective function')\n",
" return model\n",
Expand Down Expand Up @@ -600,6 +601,8 @@
" 'index': 'temps'}) # room, slab\n",
" ctrlOutputs.append({'data': 'zone_temp_max', 'df_label': 'Temperature %s Max [C]',\n",
" 'index': 'temps'}) # room, slab\n",
" ctrlOutputs.append({'data': 'co2_profile_total', 'df_label': 'GHG Emissions [kg]'})\n",
"\n",
" for d in ctrlOutputs:\n",
" d['name'] = d['data']\n",
" return ctrlOutputs\n",
Expand Down
222 changes: 116 additions & 106 deletions dev/Development-ControllerWrapper.ipynb

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions examples/example_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def example1():
weather_path = os.path.join(os.path.dirname(root), 'dev', 'resources', 'weather',
'USA_CA_San.Francisco.Intl.AP.724940_TMY3.csv')
weather, info = read_tmy3(weather_path, coerce_year=2023)
#weather = weather.resample('5T').interpolate()
#weather = weather.resample('5min').interpolate()
st = dtm.datetime(2023, 7, 1)
wf = weather.loc[st:st+pd.DateOffset(hours=24),]
df = wf[['temp_air','dni','dhi','wind_speed']].copy()
Expand All @@ -49,7 +49,6 @@ def example1():
inputs = make_inputs(parameter, df)

# Query controller
#log = ctrl.do_step(inputs=inputs) # first run to initialize
log = ctrl.do_step(inputs=inputs) # run controller

# Print results
Expand All @@ -59,7 +58,7 @@ def example1():
# 'opt_duration','outputs_duration','duration']))
#print('Optimization:')
#pprint.pprint(ctrl.get_output(keys=['opt_objective','opt_duration','opt_termination','duration']))
df = pd.DataFrame(ctrl.get_output(keys=['df_output'])['df_output'])
df = pd.DataFrame(ctrl.get_output(keys=['output-data'])['output-data'])
df.index = pd.to_datetime(pd.to_numeric(df.index), unit='ms')
print('Facade actuation during the day (when DNI > 0).')
print('Facade 0 = bottom zone, Facade 1 = middle zone, Facade 2 = top zone')
Expand Down
20 changes: 8 additions & 12 deletions test/test_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test1():
weather_path = os.path.join(os.path.dirname(root), 'dev', 'resources', 'weather',
'USA_CA_San.Francisco.Intl.AP.724940_TMY3.csv')
weather, info = read_tmy3(weather_path, coerce_year=2023)
weather = weather.resample('5T').interpolate()
weather = weather.resample('5min').interpolate()
st = dtm.datetime(2023, 7, 1)
wf = weather.loc[st:st+pd.DateOffset(hours=24),]
df = wf[['temp_air','dni','dhi','wind_speed']].copy()
Expand All @@ -45,17 +45,13 @@ def test1():
inputs = make_inputs(parameter, df)

# Query controller
ctrl.do_step(inputs=inputs) # Initialize
print('Log-message:\n', ctrl.do_step(inputs=inputs))
print('Duration:\n', ctrl.get_output(keys=['rad_duration','varts_duration','optall_duration','glare_duration',
'opt_duration','outputs_duration','duration']))
print('Optimization:\n', ctrl.get_output(keys=['opt_objective','opt_duration','opt_termination','duration']))
df = pd.DataFrame(ctrl.get_output(keys=['df_output'])['df_output'])
ctrl.do_step(inputs=inputs)
df = pd.DataFrame(ctrl.get_output(keys=['output-data'])['output-data'])
df.index = pd.to_datetime(df.index, unit='ms')

# check
res = ctrl.get_output(keys=['opt_objective','opt_duration','opt_termination','duration'])
assert 19 < res['opt_objective'] < 20.5
assert res['opt_duration'] < 5
assert res['opt_termination'] == 'optimal'
assert res['duration'] < 60*5
res = ctrl.get_output(keys=['opt-stats', 'duration'])
assert 19.5 < res['opt-stats']['objective'] < 20.5
assert res['opt-stats']['duration'] < 5
assert res['opt-stats']['termination'] == 'optimal'
assert res['duration']['all'] < 60*5

0 comments on commit 0aa4ba7

Please sign in to comment.