File size: 6,272 Bytes
831718a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gymnasium as gym
import sinergym 
import pandas as pd
import numpy as np
import os
import json
import sys
from unihvac.find_files import (
    detect_paths,
    find_manifest,
    find_building_and_weather_from_manifest,
)
from unihvac.tables import (
    print_monthly_tables_extra,
    print_monthly_tables_split,
)
from unihvac.rollout import run_rollout_to_df
from unihvac.data_generator import save_dt_training_data




# ============================================
# FOR TABLE
pd.set_option("display.max_columns", None)
pd.set_option("display.width", 240)      
pd.set_option("display.max_colwidth", 32)
pd.set_option("display.float_format", lambda x: f"{x:,.2f}")
# ============================================

# ==============================================================================
#  USER CONFIGURATION
# ==============================================================================
TARGET_LOCATION = "Fairbanks"  
TARGET_THERMAL = "default"   
TARGET_OCCUPANCY = "standard"    


HEATING_SP = 21.0
COOLING_SP = 24.0

# ==========================================
# PATH DISCOVERY (ROBUST)
# ==========================================
paths = detect_paths(outputs_dirname="baseline_results")
# Get manifest (patched preferred)
manifest_path = find_manifest(paths, building="OfficeSmall", prefer_patched=True)
output_root = str(paths.outputs_root)
os.makedirs(output_root, exist_ok=True)

OUTPUT_DIR = "rollout_run"

TIME_STEP_HOURS = 900.0 / 3600.0  # 0.25 h

# ==========================================
# 3. COMMON ACTUATORS & VARIABLES
# ==========================================
hot_actuators = {
    "Htg_Core": ("Zone Temperature Control", "Heating Setpoint", "CORE_ZN"),
    "Clg_Core": ("Zone Temperature Control", "Cooling Setpoint", "CORE_ZN"),
    "Htg_P1": ("Zone Temperature Control", "Heating Setpoint", "PERIMETER_ZN_1"),
    "Clg_P1": ("Zone Temperature Control", "Cooling Setpoint", "PERIMETER_ZN_1"),
    "Htg_P2": ("Zone Temperature Control", "Heating Setpoint", "PERIMETER_ZN_2"),
    "Clg_P2": ("Zone Temperature Control", "Cooling Setpoint", "PERIMETER_ZN_2"),
    "Htg_P3": ("Zone Temperature Control", "Heating Setpoint", "PERIMETER_ZN_3"),
    "Clg_P3": ("Zone Temperature Control", "Cooling Setpoint", "PERIMETER_ZN_3"),
    "Htg_P4": ("Zone Temperature Control", "Heating Setpoint", "PERIMETER_ZN_4"),
    "Clg_P4": ("Zone Temperature Control", "Cooling Setpoint", "PERIMETER_ZN_4"),
}

hot_variables = {
    "outdoor_temp": ("Site Outdoor Air DryBulb Temperature", "Environment"),
    "core_temp": ("Zone Air Temperature", "Core_ZN"),
    "perim1_temp": ("Zone Air Temperature", "Perimeter_ZN_1"),
    "perim2_temp": ("Zone Air Temperature", "Perimeter_ZN_2"),
    "perim3_temp": ("Zone Air Temperature", "Perimeter_ZN_3"),
    "perim4_temp": ("Zone Air Temperature", "Perimeter_ZN_4"),
    "elec_power": ("Facility Total HVAC Electricity Demand Rate", "Whole Building"),
    "core_occ_count": ("Zone People Occupant Count", "CORE_ZN"),
    "perim1_occ_count": ("Zone People Occupant Count", "PERIMETER_ZN_1"),
    "perim2_occ_count": ("Zone People Occupant Count", "PERIMETER_ZN_2"),
    "perim3_occ_count": ("Zone People Occupant Count", "PERIMETER_ZN_3"),
    "perim4_occ_count": ("Zone People Occupant Count", "PERIMETER_ZN_4"),
    "outdoor_dewpoint": ("Site Outdoor Air Dewpoint Temperature", "Environment"),
    "outdoor_wetbulb": ("Site Outdoor Air Wetbulb Temperature", "Environment"),
    "core_rh": ("Zone Air Relative Humidity", "CORE_ZN"),
    "perim1_rh": ("Zone Air Relative Humidity", "PERIMETER_ZN_1"),
    "perim2_rh": ("Zone Air Relative Humidity", "PERIMETER_ZN_2"),
    "perim3_rh": ("Zone Air Relative Humidity", "PERIMETER_ZN_3"),
    "perim4_rh": ("Zone Air Relative Humidity", "PERIMETER_ZN_4"),
}

class BaselineReward:

    def __init__(self, *args, **kwargs):
        pass
    def __call__(self, obs_dict):
        return 0.0, {}
# ==========================================
# 5. RBC CONTROLLER (CONSTANT SETPOINTS)
# ==========================================
def get_constant_rbc():
    h_sp, c_sp = HEATING_SP, COOLING_SP
    action = np.array([h_sp, c_sp] * 5, dtype=np.float32)
    return action, h_sp, c_sp



def run_baseline_for_location(location, building_path, weather_path):
    print("\n" + "=" * 80)
    print(f"Running baseline for location: {location}")
    print(f" Building: {building_path}")
    print(f" Weather: {weather_path}")
    print("=" * 80)

    out_dir = os.path.join(output_root, location)
    os.makedirs(out_dir, exist_ok=True)
    def policy_fn(obs, info, step):
        action, _, _ = get_constant_rbc()
        return action
    df = run_rollout_to_df(
        building_path=str(building_path),
        weather_path=str(weather_path),
        variables=hot_variables,
        actuators=hot_actuators,
        policy_fn=policy_fn,
        location=location,
        timestep_hours=TIME_STEP_HOURS,
        heating_sp=HEATING_SP,
        cooling_sp=COOLING_SP,
        reward=BaselineReward,
        max_steps=None,  
        verbose=True,        
    )
  
    print("setpoint_htg min/max:", df["setpoint_htg"].min(), df["setpoint_htg"].max())
    print("setpoint_clg min/max:", df["setpoint_clg"].min(), df["setpoint_clg"].max())
    print("comfort_violation min/mean/max:", df["comfort_violation_degCh"].min(),
        df["comfort_violation_degCh"].mean(), df["comfort_violation_degCh"].max())


    df["setpoint_htg"] = HEATING_SP
    df["setpoint_clg"] = COOLING_SP

    # 7) Print the same tables
    print_monthly_tables_extra(df, location)
    print_monthly_tables_split(df, location, time_step_hours=TIME_STEP_HOURS)

    # Save raw timeseries for inspection
    df.to_csv(os.path.join(out_dir, "baseline_timeseries.csv"), index=False)
    save_dt_training_data(df, out_dir, location=location)

    if "month" in df.columns:
        monthly_energy = df.groupby("month")
        return df, monthly_energy

    return df, None



if __name__ == "__main__":
    bpath, wpath = find_building_and_weather_from_manifest(
        manifest_path,
        location=TARGET_LOCATION,
        occupancy=TARGET_OCCUPANCY,
        thermal=TARGET_THERMAL,
        require_patched=True,
    )
    run_baseline_for_location(TARGET_LOCATION, str(bpath), str(wpath))