Download data/climate_data.py from mabuseif/test-29: direct link, hf CLI and curl.
- Browser
- Download file 25.7 kB
-
https://huggingface.co/spaces/mabuseif/test-29/resolve/main/data/climate_data.py
- Command line
-
hf download hf://spaces/mabuseif/test-29/data/climate_data.py
-
curl -L -o climate_data.py https://huggingface.co/spaces/mabuseif/test-29/resolve/main/data/climate_data.py
25.7 kB
| """ | |
| ASHRAE 169 climate data module for HVAC Load Calculator. | |
| This module provides access to climate data for various locations based on ASHRAE 169 standard. | |
| """ | |
| from typing import Dict, List, Any, Optional, Tuple | |
| import pandas as pd | |
| import numpy as np | |
| import os | |
| import json | |
| from dataclasses import dataclass | |
| # Define paths | |
| DATA_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| class ClimateLocation: | |
| """Class representing a climate location with ASHRAE 169 data.""" | |
| id: str | |
| country: str | |
| state_province: str | |
| city: str | |
| latitude: float | |
| longitude: float | |
| elevation: float # meters | |
| climate_zone: str | |
| heating_degree_days: float # base 18°C | |
| cooling_degree_days: float # base 18°C | |
| # Design conditions | |
| winter_design_temp: float # 99.6% heating design temperature (°C) | |
| summer_design_temp_db: float # 0.4% cooling design dry-bulb temperature (°C) | |
| summer_design_temp_wb: float # 0.4% cooling design wet-bulb temperature (°C) | |
| summer_daily_range: float # Mean daily temperature range in summer (°C) | |
| # Monthly data | |
| monthly_temps: Dict[str, float] # Average monthly temperatures (°C) | |
| monthly_humidity: Dict[str, float] # Average monthly relative humidity (%) | |
| def to_dict(self) -> Dict[str, Any]: | |
| """Convert the climate location to a dictionary.""" | |
| return { | |
| "id": self.id, | |
| "country": self.country, | |
| "state_province": self.state_province, | |
| "city": self.city, | |
| "latitude": self.latitude, | |
| "longitude": self.longitude, | |
| "elevation": self.elevation, | |
| "climate_zone": self.climate_zone, | |
| "heating_degree_days": self.heating_degree_days, | |
| "cooling_degree_days": self.cooling_degree_days, | |
| "winter_design_temp": self.winter_design_temp, | |
| "summer_design_temp_db": self.summer_design_temp_db, | |
| "summer_design_temp_wb": self.summer_design_temp_wb, | |
| "summer_daily_range": self.summer_daily_range, | |
| "monthly_temps": self.monthly_temps, | |
| "monthly_humidity": self.monthly_humidity | |
| } | |
| class ClimateData: | |
| """Class for managing ASHRAE 169 climate data.""" | |
| def __init__(self): | |
| """Initialize climate data.""" | |
| self.locations = self._load_climate_locations() | |
| self.countries = sorted(list(set(loc.country for loc in self.locations.values()))) | |
| self.country_states = self._group_locations_by_country_state() | |
| def get_design_conditions(climate_zone: str) -> Dict[str, Dict[str, float]]: | |
| """ | |
| Get design conditions for a specific climate zone. | |
| Args: | |
| climate_zone: ASHRAE climate zone (e.g., '1A', '3B', '5A') | |
| Returns: | |
| Dictionary with summer and winter design conditions | |
| """ | |
| # Default design conditions by climate zone | |
| design_conditions_by_zone = { | |
| # Hot-Humid | |
| "1A": { | |
| "summer": {"db": 35.0, "wb": 28.0, "dp": 25.5}, | |
| "winter": {"db": 12.0, "rh": 80.0} | |
| }, | |
| # Hot-Dry | |
| "1B": { | |
| "summer": {"db": 42.0, "wb": 24.0, "dp": 18.0}, | |
| "winter": {"db": 10.0, "rh": 40.0} | |
| }, | |
| # Hot-Humid | |
| "2A": { | |
| "summer": {"db": 34.0, "wb": 26.5, "dp": 24.0}, | |
| "winter": {"db": 8.0, "rh": 75.0} | |
| }, | |
| # Hot-Dry | |
| "2B": { | |
| "summer": {"db": 40.0, "wb": 23.0, "dp": 16.5}, | |
| "winter": {"db": 6.0, "rh": 45.0} | |
| }, | |
| # Warm-Humid | |
| "3A": { | |
| "summer": {"db": 33.0, "wb": 25.0, "dp": 22.5}, | |
| "winter": {"db": 2.0, "rh": 70.0} | |
| }, | |
| # Warm-Dry | |
| "3B": { | |
| "summer": {"db": 38.0, "wb": 22.0, "dp": 15.0}, | |
| "winter": {"db": 4.0, "rh": 40.0} | |
| }, | |
| # Warm-Marine | |
| "3C": { | |
| "summer": {"db": 28.0, "wb": 20.0, "dp": 17.0}, | |
| "winter": {"db": 5.0, "rh": 80.0} | |
| }, | |
| # Mixed-Humid | |
| "4A": { | |
| "summer": {"db": 32.0, "wb": 24.0, "dp": 21.0}, | |
| "winter": {"db": -5.0, "rh": 70.0} | |
| }, | |
| # Mixed-Dry | |
| "4B": { | |
| "summer": {"db": 35.0, "wb": 20.0, "dp": 13.0}, | |
| "winter": {"db": -3.0, "rh": 45.0} | |
| }, | |
| # Mixed-Marine | |
| "4C": { | |
| "summer": {"db": 27.0, "wb": 19.0, "dp": 16.0}, | |
| "winter": {"db": -2.0, "rh": 80.0} | |
| }, | |
| # Cool-Humid | |
| "5A": { | |
| "summer": {"db": 31.0, "wb": 23.0, "dp": 20.0}, | |
| "winter": {"db": -15.0, "rh": 70.0} | |
| }, | |
| # Cool-Dry | |
| "5B": { | |
| "summer": {"db": 33.0, "wb": 18.0, "dp": 11.0}, | |
| "winter": {"db": -10.0, "rh": 45.0} | |
| }, | |
| # Cool-Marine | |
| "5C": { | |
| "summer": {"db": 25.0, "wb": 18.0, "dp": 15.0}, | |
| "winter": {"db": -5.0, "rh": 80.0} | |
| }, | |
| # Cold-Humid | |
| "6A": { | |
| "summer": {"db": 30.0, "wb": 22.0, "dp": 19.0}, | |
| "winter": {"db": -20.0, "rh": 70.0} | |
| }, | |
| # Cold-Dry | |
| "6B": { | |
| "summer": {"db": 31.0, "wb": 17.0, "dp": 10.0}, | |
| "winter": {"db": -15.0, "rh": 45.0} | |
| }, | |
| # Very Cold | |
| "7": { | |
| "summer": {"db": 28.0, "wb": 20.0, "dp": 17.0}, | |
| "winter": {"db": -25.0, "rh": 70.0} | |
| }, | |
| # Subarctic/Arctic | |
| "8": { | |
| "summer": {"db": 25.0, "wb": 18.0, "dp": 15.0}, | |
| "winter": {"db": -30.0, "rh": 70.0} | |
| } | |
| } | |
| # Return design conditions for the specified climate zone | |
| # If climate zone not found, return default values | |
| if climate_zone in design_conditions_by_zone: | |
| return design_conditions_by_zone[climate_zone] | |
| else: | |
| # Default to 4A if climate zone not found | |
| return design_conditions_by_zone["4A"] | |
| def get_monthly_temperatures(climate_zone: str) -> Dict[int, Dict[str, float]]: | |
| """ | |
| Get monthly average temperatures for a specific climate zone. | |
| Args: | |
| climate_zone: ASHRAE climate zone (e.g., '1A', '3B', '5A') | |
| Returns: | |
| Dictionary with monthly average temperatures indexed by month number (1-12) | |
| Each month contains 'avg_db', 'max_db', and 'min_db' values | |
| """ | |
| # Helper function to convert month name format to numeric format with min/max values | |
| def convert_month_format(month_data): | |
| month_names = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] | |
| result = {} | |
| for i, month in enumerate(month_names, 1): | |
| avg_temp = month_data[month] | |
| # Generate reasonable min/max values based on average | |
| min_temp = avg_temp - 5.0 | |
| max_temp = avg_temp + 5.0 | |
| result[i] = { | |
| 'avg_db': avg_temp, | |
| 'min_db': min_temp, | |
| 'max_db': max_temp | |
| } | |
| return result | |
| # Default monthly temperatures by climate zone (in month name format) | |
| monthly_temps_raw = { | |
| # Hot-Humid (like Miami) | |
| "1A": { | |
| "Jan": 20.0, "Feb": 20.5, "Mar": 22.0, "Apr": 24.0, "May": 26.0, | |
| "Jun": 28.0, "Jul": 29.0, "Aug": 29.0, "Sep": 28.0, "Oct": 26.0, | |
| "Nov": 23.0, "Dec": 21.0 | |
| }, | |
| # Hot-Dry (like Riyadh) | |
| "1B": { | |
| "Jan": 15.0, "Feb": 17.0, "Mar": 22.0, "Apr": 27.0, "May": 32.0, | |
| "Jun": 35.0, "Jul": 37.0, "Aug": 36.0, "Sep": 33.0, "Oct": 28.0, | |
| "Nov": 22.0, "Dec": 17.0 | |
| }, | |
| # Hot-Humid (like Houston) | |
| "2A": { | |
| "Jan": 12.0, "Feb": 13.5, "Mar": 17.0, "Apr": 21.0, "May": 25.0, | |
| "Jun": 28.0, "Jul": 29.0, "Aug": 29.0, "Sep": 27.0, "Oct": 22.0, | |
| "Nov": 17.0, "Dec": 13.0 | |
| }, | |
| # Hot-Dry (like Phoenix) | |
| "2B": { | |
| "Jan": 13.0, "Feb": 15.0, "Mar": 18.0, "Apr": 23.0, "May": 28.0, | |
| "Jun": 33.0, "Jul": 35.0, "Aug": 34.0, "Sep": 31.0, "Oct": 25.0, | |
| "Nov": 18.0, "Dec": 13.0 | |
| }, | |
| # Warm-Humid (like Atlanta) | |
| "3A": { | |
| "Jan": 6.0, "Feb": 8.0, "Mar": 12.0, "Apr": 17.0, "May": 21.0, | |
| "Jun": 25.0, "Jul": 27.0, "Aug": 26.0, "Sep": 23.0, "Oct": 18.0, | |
| "Nov": 12.0, "Dec": 7.0 | |
| }, | |
| # Warm-Dry (like Los Angeles) | |
| "3B": { | |
| "Jan": 14.6, "Feb": 15.1, "Mar": 15.8, "Apr": 17.1, "May": 18.3, | |
| "Jun": 20.1, "Jul": 22.3, "Aug": 22.9, "Sep": 22.1, "Oct": 20.3, | |
| "Nov": 17.2, "Dec": 14.9 | |
| }, | |
| # Warm-Marine (like San Francisco) | |
| "3C": { | |
| "Jan": 10.0, "Feb": 11.0, "Mar": 12.0, "Apr": 13.0, "May": 14.0, | |
| "Jun": 16.0, "Jul": 17.0, "Aug": 17.0, "Sep": 18.0, "Oct": 16.0, | |
| "Nov": 13.0, "Dec": 10.0 | |
| }, | |
| # Mixed-Humid (like New York) | |
| "4A": { | |
| "Jan": 0.5, "Feb": 2.1, "Mar": 6.3, "Apr": 12.5, "May": 18.2, | |
| "Jun": 23.1, "Jul": 25.8, "Aug": 24.9, "Sep": 20.7, "Oct": 14.3, | |
| "Nov": 8.2, "Dec": 2.4 | |
| }, | |
| # Mixed-Dry (like Albuquerque) | |
| "4B": { | |
| "Jan": 3.0, "Feb": 5.0, "Mar": 9.0, "Apr": 14.0, "May": 19.0, | |
| "Jun": 24.0, "Jul": 26.0, "Aug": 25.0, "Sep": 21.0, "Oct": 15.0, | |
| "Nov": 8.0, "Dec": 3.0 | |
| }, | |
| # Mixed-Marine (like Seattle) | |
| "4C": { | |
| "Jan": 5.0, "Feb": 6.0, "Mar": 8.0, "Apr": 10.0, "May": 13.0, | |
| "Jun": 16.0, "Jul": 18.0, "Aug": 18.0, "Sep": 16.0, "Oct": 12.0, | |
| "Nov": 8.0, "Dec": 5.0 | |
| }, | |
| # Cool-Humid (like Chicago) | |
| "5A": { | |
| "Jan": -3.5, "Feb": -1.2, "Mar": 4.1, "Apr": 10.3, "May": 16.5, | |
| "Jun": 22.1, "Jul": 24.8, "Aug": 23.9, "Sep": 19.7, "Oct": 12.8, | |
| "Nov": 5.2, "Dec": -1.4 | |
| }, | |
| # Cool-Dry (like Denver) | |
| "5B": { | |
| "Jan": 0.0, "Feb": 2.0, "Mar": 6.0, "Apr": 10.0, "May": 15.0, | |
| "Jun": 20.0, "Jul": 23.0, "Aug": 22.0, "Sep": 18.0, "Oct": 12.0, | |
| "Nov": 5.0, "Dec": 0.0 | |
| }, | |
| # Cool-Marine (like Vancouver) | |
| "5C": { | |
| "Jan": 3.0, "Feb": 4.0, "Mar": 6.0, "Apr": 9.0, "May": 12.0, | |
| "Jun": 15.0, "Jul": 17.0, "Aug": 17.0, "Sep": 14.0, "Oct": 10.0, | |
| "Nov": 6.0, "Dec": 3.0 | |
| }, | |
| # Cold-Humid (like Minneapolis) | |
| "6A": { | |
| "Jan": -9.0, "Feb": -6.0, "Mar": 0.0, "Apr": 8.0, "May": 15.0, | |
| "Jun": 20.0, "Jul": 23.0, "Aug": 22.0, "Sep": 17.0, "Oct": 10.0, | |
| "Nov": 1.0, "Dec": -6.0 | |
| }, | |
| # Cold-Dry (like Helena) | |
| "6B": { | |
| "Jan": -5.0, "Feb": -2.0, "Mar": 2.0, "Apr": 7.0, "May": 12.0, | |
| "Jun": 17.0, "Jul": 21.0, "Aug": 20.0, "Sep": 15.0, "Oct": 9.0, | |
| "Nov": 1.0, "Dec": -4.0 | |
| }, | |
| # Very Cold (like Duluth) | |
| "7": { | |
| "Jan": -12.0, "Feb": -9.0, "Mar": -3.0, "Apr": 5.0, "May": 12.0, | |
| "Jun": 17.0, "Jul": 20.0, "Aug": 19.0, "Sep": 14.0, "Oct": 7.0, | |
| "Nov": -1.0, "Dec": -9.0 | |
| }, | |
| # Subarctic/Arctic (like Fairbanks) | |
| "8": { | |
| "Jan": -20.0, "Feb": -16.0, "Mar": -10.0, "Apr": 0.0, "May": 10.0, | |
| "Jun": 16.0, "Jul": 18.0, "Aug": 15.0, "Sep": 8.0, "Oct": -2.0, | |
| "Nov": -12.0, "Dec": -18.0 | |
| } | |
| } | |
| # Return monthly temperatures for the specified climate zone | |
| # If climate zone not found, return default values | |
| if climate_zone in monthly_temps_raw: | |
| return convert_month_format(monthly_temps_raw[climate_zone]) | |
| else: | |
| # Default to 4A if climate zone not found | |
| return convert_month_format(monthly_temps_raw["4A"]) | |
| def _load_climate_locations(self) -> Dict[str, ClimateLocation]: | |
| """ | |
| Load climate location data. | |
| Returns: | |
| Dictionary of climate locations indexed by ID | |
| """ | |
| # This would typically load from a JSON or CSV file with ASHRAE 169 data | |
| # For now, we'll define some sample locations inline | |
| # Sample monthly data (for all locations in this example) | |
| months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] | |
| # New York monthly temperatures (°C) | |
| ny_temps = { | |
| "Jan": 0.5, "Feb": 2.1, "Mar": 6.3, "Apr": 12.5, "May": 18.2, | |
| "Jun": 23.1, "Jul": 25.8, "Aug": 24.9, "Sep": 20.7, "Oct": 14.3, | |
| "Nov": 8.2, "Dec": 2.4 | |
| } | |
| # New York monthly humidity (%) | |
| ny_humidity = { | |
| "Jan": 65, "Feb": 62, "Mar": 58, "Apr": 55, "May": 60, | |
| "Jun": 65, "Jul": 68, "Aug": 70, "Sep": 68, "Oct": 63, | |
| "Nov": 67, "Dec": 68 | |
| } | |
| # Los Angeles monthly temperatures (°C) | |
| la_temps = { | |
| "Jan": 14.6, "Feb": 15.1, "Mar": 15.8, "Apr": 17.1, "May": 18.3, | |
| "Jun": 20.1, "Jul": 22.3, "Aug": 22.9, "Sep": 22.1, "Oct": 20.3, | |
| "Nov": 17.2, "Dec": 14.9 | |
| } | |
| # Los Angeles monthly humidity (%) | |
| la_humidity = { | |
| "Jan": 63, "Feb": 67, "Mar": 70, "Apr": 71, "May": 74, | |
| "Jun": 75, "Jul": 76, "Aug": 76, "Sep": 74, "Oct": 70, | |
| "Nov": 65, "Dec": 63 | |
| } | |
| # Chicago monthly temperatures (°C) | |
| chi_temps = { | |
| "Jan": -3.5, "Feb": -1.2, "Mar": 4.1, "Apr": 10.3, "May": 16.5, | |
| "Jun": 22.1, "Jul": 24.8, "Aug": 23.9, "Sep": 19.7, "Oct": 12.8, | |
| "Nov": 5.2, "Dec": -1.4 | |
| } | |
| # Chicago monthly humidity (%) | |
| chi_humidity = { | |
| "Jan": 72, "Feb": 70, "Mar": 65, "Apr": 60, "May": 64, | |
| "Jun": 67, "Jul": 70, "Aug": 73, "Sep": 71, "Oct": 68, | |
| "Nov": 72, "Dec": 75 | |
| } | |
| # London monthly temperatures (°C) | |
| lon_temps = { | |
| "Jan": 5.2, "Feb": 5.5, "Mar": 7.4, "Apr": 9.9, "May": 13.3, | |
| "Jun": 16.7, "Jul": 18.7, "Aug": 18.3, "Sep": 15.9, "Oct": 12.2, | |
| "Nov": 8.3, "Dec": 5.9 | |
| } | |
| # London monthly humidity (%) | |
| lon_humidity = { | |
| "Jan": 84, "Feb": 80, "Mar": 76, "Apr": 72, "May": 70, | |
| "Jun": 70, "Jul": 71, "Aug": 72, "Sep": 75, "Oct": 80, | |
| "Nov": 84, "Dec": 86 | |
| } | |
| # Sydney monthly temperatures (°C) | |
| syd_temps = { | |
| "Jan": 23.5, "Feb": 23.4, "Mar": 22.1, "Apr": 19.5, "May": 16.5, | |
| "Jun": 14.1, "Jul": 13.4, "Aug": 14.5, "Sep": 16.6, "Oct": 18.8, | |
| "Nov": 20.6, "Dec": 22.6 | |
| } | |
| # Sydney monthly humidity (%) | |
| syd_humidity = { | |
| "Jan": 65, "Feb": 68, "Mar": 68, "Apr": 67, "May": 70, | |
| "Jun": 70, "Jul": 68, "Aug": 63, "Sep": 60, "Oct": 60, | |
| "Nov": 62, "Dec": 63 | |
| } | |
| # Create sample locations | |
| locations = { | |
| "US-NY-NYC": ClimateLocation( | |
| id="US-NY-NYC", | |
| country="United States", | |
| state_province="New York", | |
| city="New York", | |
| latitude=40.7128, | |
| longitude=-74.0060, | |
| elevation=10.0, | |
| climate_zone="4A", | |
| heating_degree_days=2600, | |
| cooling_degree_days=1200, | |
| winter_design_temp=-8.3, | |
| summer_design_temp_db=32.8, | |
| summer_design_temp_wb=25.6, | |
| summer_daily_range=8.3, | |
| monthly_temps=ny_temps, | |
| monthly_humidity=ny_humidity | |
| ), | |
| "US-CA-LAX": ClimateLocation( | |
| id="US-CA-LAX", | |
| country="United States", | |
| state_province="California", | |
| city="Los Angeles", | |
| latitude=34.0522, | |
| longitude=-118.2437, | |
| elevation=93.0, | |
| climate_zone="3B", | |
| heating_degree_days=800, | |
| cooling_degree_days=1200, | |
| winter_design_temp=8.3, | |
| summer_design_temp_db=32.2, | |
| summer_design_temp_wb=23.3, | |
| summer_daily_range=6.7, | |
| monthly_temps=la_temps, | |
| monthly_humidity=la_humidity | |
| ), | |
| "US-IL-CHI": ClimateLocation( | |
| id="US-IL-CHI", | |
| country="United States", | |
| state_province="Illinois", | |
| city="Chicago", | |
| latitude=41.8781, | |
| longitude=-87.6298, | |
| elevation=179.0, | |
| climate_zone="5A", | |
| heating_degree_days=3500, | |
| cooling_degree_days=1000, | |
| winter_design_temp=-16.7, | |
| summer_design_temp_db=33.3, | |
| summer_design_temp_wb=25.6, | |
| summer_daily_range=8.9, | |
| monthly_temps=chi_temps, | |
| monthly_humidity=chi_humidity | |
| ), | |
| "UK-LDN": ClimateLocation( | |
| id="UK-LDN", | |
| country="United Kingdom", | |
| state_province="England", | |
| city="London", | |
| latitude=51.5074, | |
| longitude=-0.1278, | |
| elevation=35.0, | |
| climate_zone="4A", | |
| heating_degree_days=2500, | |
| cooling_degree_days=200, | |
| winter_design_temp=-3.9, | |
| summer_design_temp_db=28.3, | |
| summer_design_temp_wb=20.0, | |
| summer_daily_range=10.0, | |
| monthly_temps=lon_temps, | |
| monthly_humidity=lon_humidity | |
| ), | |
| "AU-NSW-SYD": ClimateLocation( | |
| id="AU-NSW-SYD", | |
| country="Australia", | |
| state_province="New South Wales", | |
| city="Sydney", | |
| latitude=-33.8688, | |
| longitude=151.2093, | |
| elevation=3.0, | |
| climate_zone="3C", | |
| heating_degree_days=600, | |
| cooling_degree_days=900, | |
| winter_design_temp=7.2, | |
| summer_design_temp_db=31.1, | |
| summer_design_temp_wb=24.4, | |
| summer_daily_range=7.8, | |
| monthly_temps=syd_temps, | |
| monthly_humidity=syd_humidity | |
| ) | |
| } | |
| return locations | |
| def _group_locations_by_country_state(self) -> Dict[str, Dict[str, List[str]]]: | |
| """ | |
| Group locations by country and state/province. | |
| Returns: | |
| Nested dictionary of countries, states, and cities | |
| """ | |
| result = {} | |
| for loc in self.locations.values(): | |
| if loc.country not in result: | |
| result[loc.country] = {} | |
| if loc.state_province not in result[loc.country]: | |
| result[loc.country][loc.state_province] = [] | |
| result[loc.country][loc.state_province].append(loc.city) | |
| # Sort states and cities | |
| for country in result: | |
| for state in result[country]: | |
| result[country][state] = sorted(result[country][state]) | |
| return result | |
| def get_location(self, location_id: str) -> Optional[ClimateLocation]: | |
| """ | |
| Get climate location by ID. | |
| Args: | |
| location_id: Location identifier | |
| Returns: | |
| ClimateLocation object or None if not found | |
| """ | |
| return self.locations.get(location_id) | |
| def find_location(self, country: str, state_province: str = None, city: str = None) -> Optional[ClimateLocation]: | |
| """ | |
| Find a climate location by country, state/province, and city. | |
| Args: | |
| country: Country name | |
| state_province: State or province name (optional) | |
| city: City name (optional) | |
| Returns: | |
| ClimateLocation object or None if not found | |
| """ | |
| for loc in self.locations.values(): | |
| if loc.country == country: | |
| if state_province is None or loc.state_province == state_province: | |
| if city is None or loc.city == city: | |
| return loc | |
| return None | |
| def find_locations_by_climate_zone(self, climate_zone: str) -> List[ClimateLocation]: | |
| """ | |
| Find climate locations by climate zone. | |
| Args: | |
| climate_zone: ASHRAE climate zone | |
| Returns: | |
| List of ClimateLocation objects | |
| """ | |
| return [loc for loc in self.locations.values() if loc.climate_zone == climate_zone] | |
| def get_states_for_country(self, country: str) -> List[str]: | |
| """ | |
| Get states/provinces for a country. | |
| Args: | |
| country: Country name | |
| Returns: | |
| List of state/province names | |
| """ | |
| if country in self.country_states: | |
| return sorted(self.country_states[country].keys()) | |
| return [] | |
| def get_cities_for_state(self, country: str, state_province: str) -> List[str]: | |
| """ | |
| Get cities for a state/province. | |
| Args: | |
| country: Country name | |
| state_province: State or province name | |
| Returns: | |
| List of city names | |
| """ | |
| if country in self.country_states and state_province in self.country_states[country]: | |
| return self.country_states[country][state_province] | |
| return [] | |
| def get_location_id(self, country: str, state_province: str, city: str) -> Optional[str]: | |
| """ | |
| Get location ID for a city. | |
| Args: | |
| country: Country name | |
| state_province: State or province name | |
| city: City name | |
| Returns: | |
| Location ID or None if not found | |
| """ | |
| for loc_id, loc in self.locations.items(): | |
| if (loc.country == country and | |
| loc.state_province == state_province and | |
| loc.city == city): | |
| return loc_id | |
| return None | |
| def export_to_json(self, file_path: str) -> None: | |
| """ | |
| Export all climate data to a JSON file. | |
| Args: | |
| file_path: Path to the output JSON file | |
| """ | |
| data = {loc_id: loc.to_dict() for loc_id, loc in self.locations.items()} | |
| with open(file_path, 'w') as f: | |
| json.dump(data, f, indent=4) | |
| def from_json(cls, file_path: str) -> 'ClimateData': | |
| """ | |
| Create a ClimateData instance from a JSON file. | |
| Args: | |
| file_path: Path to the input JSON file | |
| Returns: | |
| A new ClimateData instance | |
| """ | |
| with open(file_path, 'r') as f: | |
| data = json.load(f) | |
| climate_data = cls() | |
| climate_data.locations = {} | |
| for loc_id, loc_dict in data.items(): | |
| climate_data.locations[loc_id] = ClimateLocation( | |
| id=loc_dict["id"], | |
| country=loc_dict["country"], | |
| state_province=loc_dict["state_province"], | |
| city=loc_dict["city"], | |
| latitude=loc_dict["latitude"], | |
| longitude=loc_dict["longitude"], | |
| elevation=loc_dict["elevation"], | |
| climate_zone=loc_dict["climate_zone"], | |
| heating_degree_days=loc_dict["heating_degree_days"], | |
| cooling_degree_days=loc_dict["cooling_degree_days"], | |
| winter_design_temp=loc_dict["winter_design_temp"], | |
| summer_design_temp_db=loc_dict["summer_design_temp_db"], | |
| summer_design_temp_wb=loc_dict["summer_design_temp_wb"], | |
| summer_daily_range=loc_dict["summer_daily_range"], | |
| monthly_temps=loc_dict["monthly_temps"], | |
| monthly_humidity=loc_dict["monthly_humidity"] | |
| ) | |
| climate_data.countries = sorted(list(set(loc.country for loc in climate_data.locations.values()))) | |
| climate_data.country_states = climate_data._group_locations_by_country_state() | |
| return climate_data | |
| # Create a singleton instance | |
| climate_data = ClimateData() | |
| # Export climate data to JSON if needed | |
| if __name__ == "__main__": | |
| climate_data.export_to_json(os.path.join(DATA_DIR, "climate_data.json")) | |