Fetch weather data for construction scheduling. Historical data, forecasts, and risk assessment for outdoor work.
数据来源:ClawHub。 在 ClawSkills 查看
选择你使用的 Agent
方法一:命令行安装(推荐)
推荐(无需提前安装 clawhub)
npx clawhub@latest --dir ~/.claude/skills install weather-api-1或使用 clawhub CLI(需提前安装)
clawhub --dir ~/.claude/skills install weather-api-1⚠️ 需要 Node.js 18+,没有 Node?请使用下方方法二直接下载 ZIP。 安装 Node.js →
方法二:手动下载安装(无需 Node)
下载 ZIP,解压后将文件夹放到以下路径,重启 Agent 即可:
安装路径
~/.claude/skills/weather-api-1/💡解压后将文件夹放到上方路径,重启 Agent 即可生效
--- slug: "weather-api" display_name: "Weather API" description: "Fetch weather data for construction scheduling. Historical data, forecasts, and risk assessment for outdoor work." ---
Weather impacts 50% of construction activities. This skill fetches weather data for scheduling, risk assessment, and productivity adjustments.
import requests
import pandas as pd
from typing import Dict, Any, List, Optional
from dataclasses import dataclass
from datetime import datetime, timedelta
from enum import Enum
class WeatherRisk(Enum):
"""Weather risk levels for construction."""
LOW = "low"
MODERATE = "moderate"
HIGH = "high"
CRITICAL = "critical"
@dataclass
class WeatherCondition:
"""Weather condition at a point in time."""
timestamp: datetime
temperature: float # Celsius
humidity: float # Percent
wind_speed: float # m/s
precipitation: float # mm
conditions: str
@dataclass
class WorkabilityAssessment:
"""Assessment of weather workability."""
date: datetime
risk_level: WeatherRisk
workable_hours: int
affected_activities: List[str]
recommendations: List[str]
class WeatherAPIClient:
"""Client for weather APIs."""
# Free tier endpoints
OPEN_METEO_BASE = "https://api.open-meteo.com/v1"
def __init__(self, api_key: Optional[str] = None):
self.api_key = api_key
def get_forecast(self, latitude: float, longitude: float,
days: int = 7) -> List[WeatherCondition]:
"""Get weather forecast."""
url = f"{self.OPEN_METEO_BASE}/forecast"
params = {
'latitude': latitude,
'longitude': longitude,
'hourly': 'temperature_2m,relative_humidity_2m,wind_speed_10m,precipitation',
'forecast_days': days
}
response = requests.get(url, params=params)
if response.status_code != 200:
raise Exception(f"API error: {response.status_code}")
data = response.json()
return self._parse_forecast(data)
def get_historical(self, latitude: float, longitude: float,
start_date: str, end_date: str) -> List[WeatherCondition]:
"""Get historical weather data."""
url = f"{self.OPEN_METEO_BASE}/archive"
params = {
'latitude': latitude,
'longitude': longitude,
'start_date': start_date,
'end_date': end_date,
'hourly': 'temperature_2m,relative_humidity_2m,wind_speed_10m,precipitation'
}
response = requests.get(url, params=params)
if response.status_code != 200:
raise Exception(f"API error: {response.status_code}")
data = response.json()
return self._parse_forecast(data)
def _parse_forecast(self, data: Dict) -> List[WeatherCondition]:
"""Parse API response to WeatherCondition list."""
conditions = []
hourly = data.get('hourly', {})
times = hourly.get('time', [])
temps = hourly.get('temperature_2m', [])
humidity = hourly.get('relative_humidity_2m', [])
wind = hourly.get('wind_speed_10m', [])
precip = hourly.get('precipitation', [])
for i in range(len(times)):
conditions.append(WeatherCondition(
timestamp=datetime.fromisoformat(times[i]),
temperature=temps[i] if i < len(temps) else 0,
humidity=humidity[i] if i < len(humidity) else 0,
wind_speed=wind[i] if i < len(wind) else 0,
precipitation=precip[i] if i < len(precip) else 0,
conditions=self._describe_conditions(
temps[i] if i < len(temps) else 0,
precip[i] if i < len(precip) else 0,
wind[i] if i < len(wind) else 0
)
))
return conditions
def _describe_conditions(self, temp: float, precip: float, wind: float) -> str:
"""Generate weather description."""
conditions = []
if temp < 0:
conditions.append("Freezing")
elif temp > 35:
conditions.append("Extreme heat")
elif temp > 30:
conditions.append("Hot")
elif temp < 10:
conditions.append("Cold")
if precip > 10:
conditions.append("Heavy rain")
elif precip > 2:
conditions.append("Rain")
elif precip > 0:
conditions.append("Light rain")
if wind > 15:
conditions.append("Strong winds")
elif wind > 10:
conditions.append("Windy")
return ", ".join(conditions) if conditions else "Clear"
def to_dataframe(self, conditions: List[WeatherCondition]) -> pd.DataFrame:
"""Convert conditions to DataFrame."""
data = [{
'timestamp': c.timestamp,
'temperature': c.temperature,
'humidity': c.humidity,
'wind_speed': c.wind_speed,
'precipitation': c.precipitation,
'conditions': c.conditions
} for c in conditions]
return pd.DataFrame(data)
class ConstructionWeatherRisk:
"""Assess weather risk for construction activities."""
# Activity-specific thresholds
THRESHOLDS = {
'concrete_pour': {
'min_temp': 5, 'max_temp': 35,
'max_wind': 12, 'max_precip': 0.5
},
'crane_work': {
'min_temp': -10, 'max_temp': 40,
'max_wind': 10, 'max_precip': 5
},
'exterior_paint': {
'min_temp': 10, 'max_temp': 35,
'max_wind': 8, 'max_precip': 0
},
'roofing': {
'min_temp': 5, 'max_temp': 38,
'max_wind': 12, 'max_precip': 0
},
'earthwork': {
'min_temp': -5, 'max_temp': 40,
'max_wind': 20, 'max_precip': 10
}
}
def assess_workability(self, condition: WeatherCondition,
activities: List[str] = None) -> WorkabilityAssessment:
"""Assess workability for given conditions."""
if activities is None:
activities = list(self.THRESHOLDS.keys())
affected = []
recommendations = []
for activity in activities:
if activity in self.THRESHOLDS:
thresh = self.THRESHOLDS[activity]
reasons = []
if condition.temperature < thresh['min_temp']:
reasons.append(f"Too cold ({condition.temperature}°C)")
if condition.temperature > thresh['max_temp']:
reasons.append(f"Too hot ({condition.temperature}°C)")
if condition.wind_speed > thresh['max_wind']:
reasons.append(f"High wind ({condition.wind_speed} m/s)")
if condition.precipitation > thresh['max_precip']:
reasons.append(f"Precipitation ({condition.precipitation} mm)")
if reasons:
affected.append(activity)
recommendations.append(f"{activity}: " + ", ".join(reasons))
# Determine overall risk level
if len(affected) >= len(activities) * 0.8:
risk = WeatherRisk.CRITICAL
workable = 0
elif len(affected) >= len(activities) * 0.5:
risk = WeatherRisk.HIGH
workable = 4
elif len(affected) > 0:
risk = WeatherRisk.MODERATE
workable = 6
else:
risk = WeatherRisk.LOW
workable = 8
return WorkabilityAssessment(
date=condition.timestamp,
...安装 Weather Api 1 后,可以对 AI 说这些话来触发它
Help me get started with Weather Api 1
Explains what Weather Api 1 does, walks through the setup, and runs a quick demo based on your current project
Use Weather Api 1 to fetch weather data for construction scheduling
Invokes Weather Api 1 with the right parameters and returns the result directly in the conversation
What can I do with Weather Api 1 in my data & analytics workflow?
Lists the top use cases for Weather Api 1, with example commands for each scenario
将技能文件夹放到 ~/.claude/skills/weather-api-1/ 目录(个人级,所有项目可用),或 .claude/skills/weather-api-1/(项目级)。重启 AI 客户端后,用 /weather-api-1 主动调用,或让 AI 根据上下文自动发现并使用。
Weather Api 1 支持 Claude、Cursor、OpenClaw,可与这些 AI 平台无缝集成,扩展其能力。
Weather Api 1 可免费安装使用。请查阅仓库了解许可证信息。
Fetch weather data for construction scheduling. Historical data, forecasts, and risk assessment for outdoor work.
Weather Api 1 属于「Data & Analytics」分类,该分类的技能帮助 AI 智能体在此领域执行专业任务。
Automate my data & analytics tasks using Weather Api 1
Identifies repetitive steps in your workflow and sets up Weather Api 1 to handle them automatically