Files
Overlays/weather_overlay/main.py

84 lines
3.4 KiB
Python

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from starlette.middleware.cors import CORSMiddleware
import httpx
import json
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["https://overlays.ramforth.net", "http://192.168.10.16"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# OpenWeatherMap API Configuration
OPENWEATHERMAP_API_KEY = "88764d3fd0fec25358ebce447f9f8d0b"
OPENWEATHERMAP_URL = "http://api.openweathermap.org/data/2.5/weather"
async def get_weather_data(location: str):
params = {
"q": location,
"appid": OPENWEATHERMAP_API_KEY,
"units": "metric" # or "imperial" for Fahrenheit
}
async with httpx.AsyncClient() as client:
try:
response = await client.get(OPENWEATHERMAP_URL, params=params)
response.raise_for_status() # Raise an exception for bad status codes
data = response.json()
# Extract relevant information
weather_description = data["weather"][0]["description"]
temperature = data["main"]["temp"]
humidity = data["main"]["humidity"]
wind_speed = data["wind"]["speed"]
wind_deg = data["wind"]["deg"]
return {
"location": data["name"],
"description": weather_description,
"temperature": temperature,
"humidity": humidity,
"wind_speed": wind_speed,
"wind_direction_deg": wind_deg
}
except httpx.HTTPStatusError as e:
print(f"HTTP error occurred: {e.response.status_code} - {e.response.text}")
return {"error": f"Could not fetch weather data for {location}. HTTP Error: {e.response.status_code}"}
except httpx.RequestError as e:
print(f"An error occurred while requesting {e.request.url!r}: {e}")
return {"error": f"Network error while fetching weather data for {location}."}
except KeyError as e:
print(f"Key error in weather data parsing: {e}. Full response: {data}")
return {"error": f"Error parsing weather data for {location}. Missing key: {e}"}
except Exception as e:
print(f"An unexpected error occurred: {e}")
return {"error": f"An unexpected error occurred while fetching weather for {location}."}
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
try:
message = json.loads(data)
location = message.get("location")
if location:
weather_data = await get_weather_data(location)
await websocket.send_json(weather_data)
else:
await websocket.send_json({"error": "No location provided in message."})
except json.JSONDecodeError:
await websocket.send_json({"error": "Invalid JSON format received."})
except Exception as e:
print(f"Error in websocket processing: {e}")
await websocket.send_json({"error": f"Server error: {e}"})
except WebSocketDisconnect:
print("Client disconnected")
except Exception as e:
print(f"Unexpected WebSocket error: {e}")