File size: 3,868 Bytes
13fc29d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Download IMS weather data for station 43 (Sde Boker) and cache to Data/ims/.
Resamples 10min to 15min. Use --list-channels to discover channel IDs for RH, Rain, WS, BP.

Usage:
  python -m scripts.download_ims_data --list-channels
  python -m scripts.download_ims_data --from 2024-01-01 --to 2024-12-31
  python -m scripts.download_ims_data --years 2
"""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

# Project root on path for config and src
PROJECT_ROOT = Path(__file__).resolve().parent.parent
if str(PROJECT_ROOT) not in sys.path:
    sys.path.insert(0, str(PROJECT_ROOT))

try:
    from dotenv import load_dotenv
    load_dotenv(PROJECT_ROOT / ".env")
except ImportError:
    pass


def main() -> None:
    parser = argparse.ArgumentParser(
        description="Fetch IMS station 43 data and cache to Data/ims/ (15min resolution)."
    )
    parser.add_argument(
        "--list-channels",
        action="store_true",
        help="List channel IDs and names for station 43 (to find RH, Rain, WS, BP).",
    )
    parser.add_argument(
        "--from",
        dest="from_date",
        metavar="YYYY-MM-DD",
        help="Start date (inclusive).",
    )
    parser.add_argument(
        "--to",
        dest="to_date",
        metavar="YYYY-MM-DD",
        help="End date (inclusive).",
    )
    parser.add_argument(
        "--years",
        type=float,
        default=2,
        metavar="N",
        help="If --from/--to not set, fetch last N years (default: 2).",
    )
    parser.add_argument(
        "--chunk-days",
        type=int,
        default=7,
        metavar="D",
        help="Split range into D-day chunks (default: 7 for better API success). Use 0 to disable chunking.",
    )
    args = parser.parse_args()

    from src.ims_client import IMSClient
    from config import settings

    client = IMSClient()

    if args.list_channels:
        try:
            channels = client.list_channels(settings.IMS_STATION_ID)
        except Exception as e:
            print(f"Error fetching station metadata: {e}", file=sys.stderr)
            sys.exit(1)
        if not channels:
            print("No channels returned. Check API response structure.")
            sys.exit(0)
        print(f"Station {settings.IMS_STATION_ID} channels:")
        print("-" * 60)
        for ch in sorted(channels, key=lambda x: (x.get("channelId") or 0)):
            cid = ch.get("channelId", "?")
            name = ch.get("name", "?")
            units = ch.get("units", "")
            active = ch.get("active", True)
            print(f"  {cid:>4}  {name:<12}  {units:<8}  active={active}")
        return

    # Determine date range
    from datetime import datetime, timedelta, timezone

    end = datetime.now(timezone.utc).date()
    if args.from_date and args.to_date:
        start = datetime.strptime(args.from_date, "%Y-%m-%d").date()
        end = datetime.strptime(args.to_date, "%Y-%m-%d").date()
    elif args.from_date:
        start = datetime.strptime(args.from_date, "%Y-%m-%d").date()
    else:
        start = end - timedelta(days=int(args.years * 365.25))

    from_s = start.strftime("%Y-%m-%d")
    to_s = end.strftime("%Y-%m-%d")
    chunk_days = args.chunk_days if args.chunk_days else None

    print(f"Fetching IMS station {settings.IMS_STATION_ID} from {from_s} to {to_s} (chunk_days={chunk_days})...")
    try:
        df = client.fetch_and_cache(from_s, to_s, chunk_days=chunk_days)
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)

    if df.empty:
        print("No data returned. Check token and date range.")
        sys.exit(1)

    out_path = settings.IMS_CACHE_DIR / "ims_merged_15min.csv"
    print(f"Saved {len(df)} rows (15min) to {out_path}")
    print(f"Columns: {list(df.columns)}")


if __name__ == "__main__":
    main()