Spaces:
Sleeping
Sleeping
iso_ne_fetch: fetch_long_history_mwh for Chronos's 720h context
Browse files- iso_ne_fetch.py +42 -3
iso_ne_fetch.py
CHANGED
|
@@ -49,6 +49,7 @@ assert abs(ZONE_PROPORTIONS.sum() - 1.0) < 1e-3
|
|
| 49 |
|
| 50 |
ASSETS_DIR = Path(__file__).parent / "assets"
|
| 51 |
SAMPLE_CSV = ASSETS_DIR / "sample_demand_2022.csv"
|
|
|
|
| 52 |
|
| 53 |
# In-memory cache: {timestamp_hash: (timestamp, ndarray)}
|
| 54 |
_CACHE: dict = {}
|
|
@@ -134,8 +135,46 @@ def fetch_recent_demand_mwh(end_dt: Optional[datetime] = None):
|
|
| 134 |
return arr, "sample-2022"
|
| 135 |
|
| 136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
if __name__ == "__main__":
|
| 138 |
arr, src = fetch_recent_demand_mwh()
|
| 139 |
-
print(f"
|
| 140 |
-
|
| 141 |
-
print(f"
|
|
|
|
| 49 |
|
| 50 |
ASSETS_DIR = Path(__file__).parent / "assets"
|
| 51 |
SAMPLE_CSV = ASSETS_DIR / "sample_demand_2022.csv"
|
| 52 |
+
SAMPLE_CSV_LONG = ASSETS_DIR / "sample_demand_2022_long.csv" # 720 h, 2022-12-02..12-31
|
| 53 |
|
| 54 |
# In-memory cache: {timestamp_hash: (timestamp, ndarray)}
|
| 55 |
_CACHE: dict = {}
|
|
|
|
| 135 |
return arr, "sample-2022"
|
| 136 |
|
| 137 |
|
| 138 |
+
def fetch_long_history_mwh(end_dt: Optional[datetime] = None,
|
| 139 |
+
hours: int = 720):
|
| 140 |
+
"""Fetch a long per-zone demand history (default 720 h = 30 days) ending
|
| 141 |
+
at end_dt, for use as Chronos-Bolt context.
|
| 142 |
+
|
| 143 |
+
Strategy:
|
| 144 |
+
1. Read the bundled long-history CSV (720 hourly rows from 2022-12).
|
| 145 |
+
2. Splice in the 24 freshest hours from the live API / cache (so the
|
| 146 |
+
tail of the history reflects recent live demand) when available.
|
| 147 |
+
|
| 148 |
+
Returns:
|
| 149 |
+
(array of shape (hours, 8), source_label). source_label ends in
|
| 150 |
+
"+live" when the tail 24 h came from the API, "+sample" otherwise.
|
| 151 |
+
"""
|
| 152 |
+
if end_dt is None:
|
| 153 |
+
end_dt = datetime.now(timezone.utc).replace(minute=0, second=0, microsecond=0)
|
| 154 |
+
|
| 155 |
+
# 1. Bundled long-history CSV (always present)
|
| 156 |
+
if not SAMPLE_CSV_LONG.exists():
|
| 157 |
+
# Fall back to short CSV repeated; less faithful but never crashes.
|
| 158 |
+
short = _load_sample_csv()
|
| 159 |
+
long_arr = np.tile(short, (hours // 24 + 1, 1))[:hours]
|
| 160 |
+
return long_arr.astype(np.float32), "sample-2022-tiled"
|
| 161 |
+
|
| 162 |
+
df = pd.read_csv(SAMPLE_CSV_LONG)
|
| 163 |
+
long_arr = df[ZONE_COLS].tail(hours).to_numpy(dtype=np.float32)
|
| 164 |
+
if long_arr.shape != (hours, 8):
|
| 165 |
+
# Something odd; return what we have and tag.
|
| 166 |
+
return long_arr.astype(np.float32), "sample-2022-short"
|
| 167 |
+
|
| 168 |
+
# 2. Try to splice 24 freshest hours from the live API
|
| 169 |
+
fresh = _try_iso_ne_api(end_dt)
|
| 170 |
+
if fresh is not None and fresh.shape == (24, 8):
|
| 171 |
+
long_arr[-24:] = fresh
|
| 172 |
+
return long_arr, "sample-2022+live"
|
| 173 |
+
return long_arr, "sample-2022"
|
| 174 |
+
|
| 175 |
+
|
| 176 |
if __name__ == "__main__":
|
| 177 |
arr, src = fetch_recent_demand_mwh()
|
| 178 |
+
print(f"recent (24 h): source={src}, shape={arr.shape}")
|
| 179 |
+
long_arr, long_src = fetch_long_history_mwh()
|
| 180 |
+
print(f"long ({len(long_arr)} h): source={long_src}, shape={long_arr.shape}")
|