Controller / data_generator /rollout_runner.py
Gen-HVAC's picture
Upload 2 files
831718a verified
Raw
History Blame Contribute Delete
6.27 kB
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))