File size: 5,505 Bytes
77b0eff
 
 
 
187fcd9
1e25fc9
187fcd9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77b0eff
 
 
 
 
187fcd9
 
 
 
 
 
77b0eff
1e25fc9
77b0eff
 
 
187fcd9
77b0eff
 
 
 
187fcd9
 
77b0eff
 
 
 
 
187fcd9
 
77b0eff
187fcd9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77b0eff
26e237b
77b0eff
26e237b
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
125
126
import dash
from dash import dcc, html, Input, Output
import plotly.graph_objs as go
import requests
import os
from datetime import datetime

# Assuming weather_model.py exists; if not, we'll inline it
try:
    from weather_model import get_weather_data
except ImportError:
    def get_weather_data(city, days, api_key):
        try:
            geo_url = f"http://api.openweathermap.org/geo/1.0/direct?q={city}&limit=1&appid={api_key}"
            geo_response = requests.get(geo_url).json()
            if not geo_response:
                return None
            lat, lon = geo_response[0]['lat'], geo_response[0]['lon']

            url = f"http://api.openweathermap.org/data/2.5/onecall?lat={lat}&lon={lon}&exclude=minutely,hourly&units=metric&appid={api_key}"
            response = requests.get(url).json()

            current = {
                'temp': response['current']['temp'],
                'weather': response['current']['weather'][0]['description'],
                'humidity': response['current']['humidity'],
                'wind_speed': response['current']['wind_speed']
            }

            forecast = []
            for i in range(min(days, len(response['daily']))):
                day = response['daily'][i]
                forecast.append({
                    'date': datetime.fromtimestamp(day['dt']).strftime('%Y-%m-%d'),
                    'temp': day['temp']['day'],
                    'precipitation': day.get('rain', 0) + day.get('snow', 0),
                    'wind_speed': day['wind_speed'],
                    'weather': day['weather'][0]['main']
                })

            return {'current': current, 'forecast': forecast}
        except Exception as e:
            print(f"Error fetching weather data: {e}")
            return None

# Initialize Dash app
app = dash.Dash(__name__)
app.title = "Weather Forecast Dashboard"

# Use environment variable for API key
API_KEY = os.getenv("OPENWEATHERMAP_API_KEY", "53d50455f91b6bc3c920959e2954576d")

# Fixed locations
LOCATIONS = ["Hyderabad", "Jogulamba Gadwal", "Bangalore"]
DAYS = 5  # Fixed 5-day forecast

# Layout
app.layout = html.Div([
    html.Div([
        html.H1("Weather Forecast Dashboard", style={'textAlign': 'center', 'color': '#FFFFFF'}),
        html.P("Current weather for Hyderabad, Gadwal, and Karnataka (Bangalore).", 
               style={'textAlign': 'center', 'color': '#D3D9D4'})
    ], style={'backgroundColor': '#212A31', 'padding': '20px'}),

    html.Div([
        html.H2("Weather Overview", style={'color': '#FFFFFF', 'padding': '10px'}),
        html.Div(id='weather-display', style={'display': 'flex', 'flexWrap': 'wrap', 'justifyContent': 'space-around'})
    ], style={'backgroundColor': '#2E3944', 'padding': '20px', 'borderRadius': '10px'}),
], style={'backgroundColor': '#1A2329', 'fontFamily': 'Arial', 'minHeight': '100vh'})

# Callback to update dashboard
@app.callback(
    Output('weather-display', 'children'),
    Input('weather-display', 'id')  # Dummy input to trigger on load
)
def update_dashboard(_):
    weather_components = []
    
    for city in LOCATIONS:
        weather_data = get_weather_data(city, DAYS, API_KEY)
        if not weather_data:
            weather_components.append(
                html.Div(f"Error: Could not fetch data for {city}", style={'color': '#FF5555', 'padding': '10px'})
            )
            continue

        current = weather_data['current']
        forecast = weather_data['forecast']

        # Text Summary
        summary = html.Div([
            html.H3(f"{city}", style={'color': '#FFFFFF'}),
            html.P(f"Current Temp: {current['temp']}°C", style={'color': '#D3D9D4'}),
            html.P(f"Condition: {current['weather']}", style={'color': '#D3D9D4'}),
            html.P(f"Humidity: {current['humidity']}%", style={'color': '#D3D9D4'}),
            html.P(f"Wind Speed: {current['wind_speed']} km/h", style={'color': '#D3D9D4'}),
        ], style={'width': '30%', 'padding': '10px'})

        # Donut Charts
        temp_values = [f['temp'] for f in forecast]
        temp_fig = go.Figure(data=[go.Pie(labels=[f['date'] for f in forecast], values=temp_values, hole=.3)])
        temp_fig.update_layout(title=f"{city} - Temperature (°C)", template='plotly_dark')

        precip_values = [f['precipitation'] for f in forecast]
        precip_fig = go.Figure(data=[go.Pie(labels=[f['date'] for f in forecast], values=precip_values, hole=.3)])
        precip_fig.update_layout(title=f"{city} - Precipitation (mm)", template='plotly_dark')

        wind_values = [f['wind_speed'] for f in forecast]
        wind_fig = go.Figure(data=[go.Pie(labels=[f['date'] for f in forecast], values=wind_values, hole=.3)])
        wind_fig.update_layout(title=f"{city} - Wind Speed (km/h)", template='plotly_dark')

        # Combine into a city section
        city_section = html.Div([
            summary,
            dcc.Graph(figure=temp_fig, style={'width': '20%', 'display': 'inline-block'}),
            dcc.Graph(figure=precip_fig, style={'width': '20%', 'display': 'inline-block'}),
            dcc.Graph(figure=wind_fig, style={'width': '20%', 'display': 'inline-block'}),
        ], style={'margin': '20px', 'backgroundColor': '#2E3944', 'borderRadius': '10px', 'padding': '10px'})

        weather_components.append(city_section)

    return weather_components

# Run server on port 7860 for Hugging Face Spaces
if __name__ == '__main__':
    app.run_server(debug=True, host='0.0.0.0', port=7860)