Spaces:
Sleeping
Sleeping
Enhance WeatherAppProEnhanced with new charting methods for temperature, precipitation, wind, and humidity; improve data handling for forecast formats and error logging.
Browse files
app.py
CHANGED
@@ -267,8 +267,7 @@ class WeatherAppProEnhanced:
|
|
267 |
<h3>🗺️ Weather Map</h3>
|
268 |
<p>Ask about weather in a city to see it on the map!</p>
|
269 |
</div>
|
270 |
-
</div>
|
271 |
-
"""
|
272 |
|
273 |
def _create_default_chart(self) -> go.Figure:
|
274 |
"""Create default empty chart with professional dark styling"""
|
@@ -313,6 +312,198 @@ class WeatherAppProEnhanced:
|
|
313 |
)
|
314 |
|
315 |
return fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
316 |
|
317 |
def _get_weather_emoji(self, condition: str) -> str:
|
318 |
"""Get appropriate emoji for weather condition"""
|
@@ -1278,14 +1469,13 @@ class WeatherAppProEnhanced:
|
|
1278 |
|
1279 |
cities = result.get('cities', [])
|
1280 |
forecast_city_sync = cities[0] if cities else ""
|
1281 |
-
|
1282 |
-
# 🔄 Auto-sync forecast with MCP enhancements
|
1283 |
synced_forecast_text = gr.update()
|
1284 |
synced_temp_chart = gr.update()
|
1285 |
synced_precip_chart = gr.update()
|
1286 |
synced_wind_chart = gr.update()
|
1287 |
synced_humidity_chart = gr.update()
|
1288 |
-
|
1289 |
if forecast_city_sync:
|
1290 |
try:
|
1291 |
# 🚀 Enhanced forecast with MCP data
|
@@ -1338,12 +1528,17 @@ class WeatherAppProEnhanced:
|
|
1338 |
|
1339 |
lat, lon = coords
|
1340 |
forecast_data = self.weather_client.get_forecast(lat, lon)
|
1341 |
-
hourly_data = self.weather_client.get_hourly_forecast(lat, lon, hours=24) # For precip, wind, humidity
|
1342 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1343 |
temp_fig = self._create_temperature_chart(forecast_data) if forecast_data else self._create_default_chart()
|
1344 |
-
precip_fig = self._create_precipitation_chart(
|
1345 |
-
wind_fig = self._create_wind_chart(
|
1346 |
-
humidity_fig = self._create_humidity_chart(
|
1347 |
|
1348 |
return forecast_text, temp_fig, precip_fig, wind_fig, humidity_fig, "" # Clear input
|
1349 |
|
@@ -1422,8 +1617,7 @@ class WeatherAppProEnhanced:
|
|
1422 |
'forecast': city_data.get('forecast', []),
|
1423 |
'current': city_data.get('current', {})
|
1424 |
}
|
1425 |
-
|
1426 |
-
# Add MCP enhancements if available
|
1427 |
if mcp_data and city in mcp_data:
|
1428 |
city_info['mcp_enhancements'] = mcp_data[city]
|
1429 |
|
@@ -1437,7 +1631,7 @@ class WeatherAppProEnhanced:
|
|
1437 |
except Exception as e:
|
1438 |
logger.error(f"Error updating enhanced map: {e}")
|
1439 |
return self._get_current_map()
|
1440 |
-
|
1441 |
def _handle_enhanced_forecast(self, city_name: str, mcp_data: dict = None):
|
1442 |
"""Handle forecast with MCP enhancements"""
|
1443 |
try:
|
@@ -1467,12 +1661,12 @@ class WeatherAppProEnhanced:
|
|
1467 |
if coords:
|
1468 |
lat, lon = coords
|
1469 |
forecast_data = self.weather_client.get_forecast(lat, lon)
|
1470 |
-
hourly_data = self.weather_client.get_hourly_forecast(lat, lon, hours=24)
|
1471 |
|
|
|
1472 |
temp_fig = self._create_temperature_chart(forecast_data) if forecast_data else self._create_default_chart()
|
1473 |
-
precip_fig = self._create_precipitation_chart(
|
1474 |
-
wind_fig = self._create_wind_chart(
|
1475 |
-
humidity_fig = self._create_humidity_chart(
|
1476 |
|
1477 |
return enhanced_forecast, temp_fig, precip_fig, wind_fig, humidity_fig, ""
|
1478 |
else:
|
@@ -1480,148 +1674,7 @@ class WeatherAppProEnhanced:
|
|
1480 |
|
1481 |
except Exception as e:
|
1482 |
logger.error(f"Error in enhanced forecast: {e}")
|
1483 |
-
return f"❌ Error getting enhanced forecast: {str(e)}", self._create_default_chart(), self._create_default_chart(), self._create_default_chart(), self._create_default_chart(), ""
|
1484 |
-
|
1485 |
-
def _create_temperature_chart(self, forecast_data: Dict) -> go.Figure:
|
1486 |
-
"""Create temperature chart from forecast data"""
|
1487 |
-
try:
|
1488 |
-
periods = forecast_data.get('periods', [])[:7] # 7 day forecast
|
1489 |
-
|
1490 |
-
times = [p.get('name', f'Day {i+1}') for i, p in enumerate(periods)]
|
1491 |
-
temps = [p.get('temperature', 0) for p in periods]
|
1492 |
-
|
1493 |
-
fig = go.Figure()
|
1494 |
-
fig.add_trace(go.Scatter(
|
1495 |
-
x=times, y=temps,
|
1496 |
-
mode='lines+markers',
|
1497 |
-
name='Temperature',
|
1498 |
-
line=dict(color='#3b82f6', width=3),
|
1499 |
-
marker=dict(size=8)
|
1500 |
-
))
|
1501 |
-
|
1502 |
-
fig.update_layout(
|
1503 |
-
title="🌡️ 7-Day Temperature Forecast",
|
1504 |
-
xaxis_title="Time Period",
|
1505 |
-
yaxis_title="Temperature (°F)",
|
1506 |
-
template="plotly_dark",
|
1507 |
-
height=300,
|
1508 |
-
paper_bgcolor='rgba(0,0,0,0)',
|
1509 |
-
plot_bgcolor='rgba(0,0,0,0)',
|
1510 |
-
font=dict(color='white')
|
1511 |
-
)
|
1512 |
-
|
1513 |
-
return fig
|
1514 |
-
|
1515 |
-
except Exception as e:
|
1516 |
-
logger.error(f"Error creating temperature chart: {e}")
|
1517 |
-
return self._create_default_chart()
|
1518 |
-
|
1519 |
-
def _create_precipitation_chart(self, forecast_data: Dict) -> go.Figure:
|
1520 |
-
"""Create precipitation chart"""
|
1521 |
-
try:
|
1522 |
-
periods = forecast_data.get('periods', [])[:7]
|
1523 |
-
|
1524 |
-
times = [p.get('name', f'Day {i+1}') for i, p in enumerate(periods)]
|
1525 |
-
precip = [p.get('precipitationProbability', 0) or 0 for p in periods]
|
1526 |
-
|
1527 |
-
fig = go.Figure()
|
1528 |
-
fig.add_trace(go.Bar(
|
1529 |
-
x=times, y=precip,
|
1530 |
-
name='Precipitation Chance',
|
1531 |
-
marker_color='#06b6d4'
|
1532 |
-
))
|
1533 |
-
|
1534 |
-
fig.update_layout(
|
1535 |
-
title="🌧️ Precipitation Probability",
|
1536 |
-
xaxis_title="Time Period",
|
1537 |
-
yaxis_title="Chance of Rain (%)",
|
1538 |
-
template="plotly_dark",
|
1539 |
-
height=300,
|
1540 |
-
paper_bgcolor='rgba(0,0,0,0)',
|
1541 |
-
plot_bgcolor='rgba(0,0,0,0)',
|
1542 |
-
font=dict(color='white')
|
1543 |
-
)
|
1544 |
-
|
1545 |
-
return fig
|
1546 |
-
|
1547 |
-
except Exception as e:
|
1548 |
-
logger.error(f"Error creating precipitation chart: {e}")
|
1549 |
-
return self._create_default_chart()
|
1550 |
-
|
1551 |
-
def _create_wind_chart(self, forecast_data: Dict) -> go.Figure:
|
1552 |
-
"""Create wind speed chart"""
|
1553 |
-
try:
|
1554 |
-
periods = forecast_data.get('periods', [])[:7]
|
1555 |
-
|
1556 |
-
times = [p.get('name', f'Day {i+1}') for i, p in enumerate(periods)]
|
1557 |
-
# Extract wind speed from wind string (e.g., "SW 10 mph")
|
1558 |
-
winds = []
|
1559 |
-
for p in periods:
|
1560 |
-
wind_str = p.get('windSpeed', '0 mph')
|
1561 |
-
try:
|
1562 |
-
wind_val = int(''.join(filter(str.isdigit, wind_str.split()[0])))
|
1563 |
-
winds.append(wind_val)
|
1564 |
-
except:
|
1565 |
-
winds.append(0)
|
1566 |
-
|
1567 |
-
fig = go.Figure()
|
1568 |
-
fig.add_trace(go.Scatter(
|
1569 |
-
x=times, y=winds,
|
1570 |
-
mode='lines+markers',
|
1571 |
-
name='Wind Speed',
|
1572 |
-
line=dict(color='#10b981', width=3),
|
1573 |
-
marker=dict(size=8)
|
1574 |
-
))
|
1575 |
-
|
1576 |
-
fig.update_layout(
|
1577 |
-
title="🌬️ Wind Speed Forecast",
|
1578 |
-
xaxis_title="Time Period",
|
1579 |
-
yaxis_title="Wind Speed (mph)",
|
1580 |
-
template="plotly_dark",
|
1581 |
-
height=300,
|
1582 |
-
paper_bgcolor='rgba(0,0,0,0)',
|
1583 |
-
plot_bgcolor='rgba(0,0,0,0)',
|
1584 |
-
font=dict(color='white')
|
1585 |
-
)
|
1586 |
-
|
1587 |
-
return fig
|
1588 |
-
|
1589 |
-
except Exception as e:
|
1590 |
-
logger.error(f"Error creating wind chart: {e}")
|
1591 |
-
return self._create_default_chart()
|
1592 |
-
|
1593 |
-
def _create_humidity_chart(self, forecast_data: Dict) -> go.Figure:
|
1594 |
-
"""Create humidity chart"""
|
1595 |
-
try:
|
1596 |
-
periods = forecast_data.get('periods', [])[:7]
|
1597 |
-
|
1598 |
-
times = [p.get('name', f'Day {i+1}') for i, p in enumerate(periods)]
|
1599 |
-
# Simulate humidity data (real API might have this)
|
1600 |
-
humidity = [60 + (i * 5) % 40 for i in range(len(periods))]
|
1601 |
-
|
1602 |
-
fig = go.Figure()
|
1603 |
-
fig.add_trace(go.Bar(
|
1604 |
-
x=times, y=humidity,
|
1605 |
-
name='Relative Humidity',
|
1606 |
-
marker_color='#8b5cf6'
|
1607 |
-
))
|
1608 |
-
|
1609 |
-
fig.update_layout(
|
1610 |
-
title="💧 Humidity Levels",
|
1611 |
-
xaxis_title="Time Period",
|
1612 |
-
yaxis_title="Relative Humidity (%)",
|
1613 |
-
template="plotly_dark",
|
1614 |
-
height=300,
|
1615 |
-
paper_bgcolor='rgba(0,0,0,0)',
|
1616 |
-
plot_bgcolor='rgba(0,0,0,0)',
|
1617 |
-
font=dict(color='white')
|
1618 |
-
)
|
1619 |
-
|
1620 |
-
return fig
|
1621 |
-
|
1622 |
-
except Exception as e:
|
1623 |
-
logger.error(f"Error creating humidity chart: {e}")
|
1624 |
-
return self._create_default_chart()
|
1625 |
|
1626 |
# ...existing code...
|
1627 |
def main():
|
|
|
267 |
<h3>🗺️ Weather Map</h3>
|
268 |
<p>Ask about weather in a city to see it on the map!</p>
|
269 |
</div>
|
270 |
+
</div> """
|
|
|
271 |
|
272 |
def _create_default_chart(self) -> go.Figure:
|
273 |
"""Create default empty chart with professional dark styling"""
|
|
|
312 |
)
|
313 |
|
314 |
return fig
|
315 |
+
|
316 |
+
def _create_temperature_chart(self, forecast_data) -> go.Figure:
|
317 |
+
"""Create temperature chart from forecast data"""
|
318 |
+
try:
|
319 |
+
# Handle both list and dict formats
|
320 |
+
if isinstance(forecast_data, list):
|
321 |
+
periods = forecast_data[:7] # Direct list of periods
|
322 |
+
elif isinstance(forecast_data, dict):
|
323 |
+
periods = forecast_data.get('periods', [])[:7] # Dict with periods key
|
324 |
+
else:
|
325 |
+
periods = []
|
326 |
+
|
327 |
+
if not periods:
|
328 |
+
return self._create_default_chart()
|
329 |
+
|
330 |
+
times = [p.get('name', f'Day {i+1}') for i, p in enumerate(periods)]
|
331 |
+
temps = [p.get('temperature', 0) for p in periods]
|
332 |
+
|
333 |
+
fig = go.Figure()
|
334 |
+
fig.add_trace(go.Scatter(
|
335 |
+
x=times, y=temps,
|
336 |
+
mode='lines+markers',
|
337 |
+
name='Temperature',
|
338 |
+
line=dict(color='#3b82f6', width=3),
|
339 |
+
marker=dict(size=8)
|
340 |
+
))
|
341 |
+
|
342 |
+
fig.update_layout(
|
343 |
+
title="🌡️ 7-Day Temperature Forecast",
|
344 |
+
xaxis_title="Time Period",
|
345 |
+
yaxis_title="Temperature (°F)",
|
346 |
+
template="plotly_dark",
|
347 |
+
height=300,
|
348 |
+
paper_bgcolor='rgba(0,0,0,0)',
|
349 |
+
plot_bgcolor='rgba(0,0,0,0)',
|
350 |
+
font=dict(color='white')
|
351 |
+
)
|
352 |
+
|
353 |
+
return fig
|
354 |
+
|
355 |
+
except Exception as e:
|
356 |
+
logger.error(f"Error creating temperature chart: {e}")
|
357 |
+
return self._create_default_chart()
|
358 |
+
|
359 |
+
def _create_precipitation_chart(self, forecast_data) -> go.Figure:
|
360 |
+
"""Create precipitation chart"""
|
361 |
+
try:
|
362 |
+
# Handle both list and dict formats
|
363 |
+
if isinstance(forecast_data, list):
|
364 |
+
periods = forecast_data[:7] # Direct list of periods
|
365 |
+
elif isinstance(forecast_data, dict):
|
366 |
+
periods = forecast_data.get('periods', [])[:7] # Dict with periods key
|
367 |
+
else:
|
368 |
+
periods = []
|
369 |
+
|
370 |
+
if not periods:
|
371 |
+
return self._create_default_chart()
|
372 |
+
|
373 |
+
times = [p.get('name', f'Day {i+1}') for i, p in enumerate(periods)]
|
374 |
+
precip = [p.get('precipitationProbability', 0) or 0 for p in periods]
|
375 |
+
|
376 |
+
fig = go.Figure()
|
377 |
+
fig.add_trace(go.Bar(
|
378 |
+
x=times, y=precip,
|
379 |
+
name='Precipitation Chance',
|
380 |
+
marker_color='#06b6d4'
|
381 |
+
))
|
382 |
+
|
383 |
+
fig.update_layout(
|
384 |
+
title="🌧️ Precipitation Probability",
|
385 |
+
xaxis_title="Time Period",
|
386 |
+
yaxis_title="Chance of Rain (%)",
|
387 |
+
template="plotly_dark",
|
388 |
+
height=300,
|
389 |
+
paper_bgcolor='rgba(0,0,0,0)',
|
390 |
+
plot_bgcolor='rgba(0,0,0,0)',
|
391 |
+
font=dict(color='white')
|
392 |
+
)
|
393 |
+
|
394 |
+
return fig
|
395 |
+
|
396 |
+
except Exception as e:
|
397 |
+
logger.error(f"Error creating precipitation chart: {e}")
|
398 |
+
return self._create_default_chart()
|
399 |
+
|
400 |
+
def _create_wind_chart(self, forecast_data) -> go.Figure:
|
401 |
+
"""Create wind speed chart"""
|
402 |
+
try:
|
403 |
+
# Handle both list and dict formats
|
404 |
+
if isinstance(forecast_data, list):
|
405 |
+
periods = forecast_data[:7] # Direct list of periods
|
406 |
+
elif isinstance(forecast_data, dict):
|
407 |
+
periods = forecast_data.get('periods', [])[:7] # Dict with periods key
|
408 |
+
else:
|
409 |
+
periods = []
|
410 |
+
|
411 |
+
if not periods:
|
412 |
+
return self._create_default_chart()
|
413 |
+
|
414 |
+
times = [p.get('name', f'Day {i+1}') for i, p in enumerate(periods)]
|
415 |
+
# Extract wind speed from wind string (e.g., "SW 10 mph")
|
416 |
+
winds = []
|
417 |
+
for p in periods:
|
418 |
+
wind_str = p.get('windSpeed', '0 mph')
|
419 |
+
try:
|
420 |
+
# Extract numeric part from wind speed string
|
421 |
+
import re
|
422 |
+
wind_match = re.search(r'\d+', str(wind_str))
|
423 |
+
wind_val = int(wind_match.group()) if wind_match else 0
|
424 |
+
winds.append(wind_val)
|
425 |
+
except:
|
426 |
+
winds.append(0)
|
427 |
+
|
428 |
+
fig = go.Figure()
|
429 |
+
fig.add_trace(go.Scatter(
|
430 |
+
x=times, y=winds,
|
431 |
+
mode='lines+markers',
|
432 |
+
name='Wind Speed',
|
433 |
+
line=dict(color='#10b981', width=3),
|
434 |
+
marker=dict(size=8)
|
435 |
+
))
|
436 |
+
|
437 |
+
fig.update_layout(
|
438 |
+
title="🌬️ Wind Speed Forecast",
|
439 |
+
xaxis_title="Time Period",
|
440 |
+
yaxis_title="Wind Speed (mph)",
|
441 |
+
template="plotly_dark",
|
442 |
+
height=300,
|
443 |
+
paper_bgcolor='rgba(0,0,0,0)',
|
444 |
+
plot_bgcolor='rgba(0,0,0,0)',
|
445 |
+
font=dict(color='white')
|
446 |
+
)
|
447 |
+
|
448 |
+
return fig
|
449 |
+
|
450 |
+
except Exception as e:
|
451 |
+
logger.error(f"Error creating wind chart: {e}")
|
452 |
+
return self._create_default_chart()
|
453 |
+
|
454 |
+
def _create_humidity_chart(self, forecast_data) -> go.Figure:
|
455 |
+
"""Create humidity chart"""
|
456 |
+
try:
|
457 |
+
# Handle both list and dict formats
|
458 |
+
if isinstance(forecast_data, list):
|
459 |
+
periods = forecast_data[:7] # Direct list of periods
|
460 |
+
elif isinstance(forecast_data, dict):
|
461 |
+
periods = forecast_data.get('periods', [])[:7] # Dict with periods key
|
462 |
+
else:
|
463 |
+
periods = []
|
464 |
+
|
465 |
+
if not periods:
|
466 |
+
return self._create_default_chart()
|
467 |
+
|
468 |
+
times = [p.get('name', f'Day {i+1}') for i, p in enumerate(periods)]
|
469 |
+
|
470 |
+
# Try to get real humidity data, or simulate if not available
|
471 |
+
humidity = []
|
472 |
+
for i, p in enumerate(periods):
|
473 |
+
# Check if humidity data exists
|
474 |
+
rel_humidity = p.get('relativeHumidity')
|
475 |
+
if rel_humidity and isinstance(rel_humidity, dict):
|
476 |
+
humidity_val = rel_humidity.get('value', 60 + (i * 5) % 40)
|
477 |
+
elif rel_humidity and isinstance(rel_humidity, (int, float)):
|
478 |
+
humidity_val = rel_humidity
|
479 |
+
else:
|
480 |
+
# Simulate realistic humidity values (50-90%)
|
481 |
+
humidity_val = 60 + (i * 5) % 40
|
482 |
+
humidity.append(humidity_val)
|
483 |
+
|
484 |
+
fig = go.Figure()
|
485 |
+
fig.add_trace(go.Bar(
|
486 |
+
x=times, y=humidity,
|
487 |
+
name='Relative Humidity',
|
488 |
+
marker_color='#8b5cf6'
|
489 |
+
))
|
490 |
+
|
491 |
+
fig.update_layout(
|
492 |
+
title="💧 Humidity Levels",
|
493 |
+
xaxis_title="Time Period",
|
494 |
+
yaxis_title="Relative Humidity (%)",
|
495 |
+
template="plotly_dark",
|
496 |
+
height=300,
|
497 |
+
paper_bgcolor='rgba(0,0,0,0)',
|
498 |
+
plot_bgcolor='rgba(0,0,0,0)',
|
499 |
+
font=dict(color='white')
|
500 |
+
)
|
501 |
+
|
502 |
+
return fig
|
503 |
+
|
504 |
+
except Exception as e:
|
505 |
+
logger.error(f"Error creating humidity chart: {e}")
|
506 |
+
return self._create_default_chart()
|
507 |
|
508 |
def _get_weather_emoji(self, condition: str) -> str:
|
509 |
"""Get appropriate emoji for weather condition"""
|
|
|
1469 |
|
1470 |
cities = result.get('cities', [])
|
1471 |
forecast_city_sync = cities[0] if cities else ""
|
1472 |
+
# 🔄 Auto-sync forecast with MCP enhancements
|
|
|
1473 |
synced_forecast_text = gr.update()
|
1474 |
synced_temp_chart = gr.update()
|
1475 |
synced_precip_chart = gr.update()
|
1476 |
synced_wind_chart = gr.update()
|
1477 |
synced_humidity_chart = gr.update()
|
1478 |
+
|
1479 |
if forecast_city_sync:
|
1480 |
try:
|
1481 |
# 🚀 Enhanced forecast with MCP data
|
|
|
1528 |
|
1529 |
lat, lon = coords
|
1530 |
forecast_data = self.weather_client.get_forecast(lat, lon)
|
|
|
1531 |
|
1532 |
+
# Debug: Check what format forecast_data is
|
1533 |
+
logger.info(f"Forecast data type: {type(forecast_data)}")
|
1534 |
+
if forecast_data:
|
1535 |
+
logger.info(f"Forecast data sample: {forecast_data[:1] if isinstance(forecast_data, list) else list(forecast_data.keys()) if isinstance(forecast_data, dict) else 'Unknown format'}")
|
1536 |
+
|
1537 |
+
# Use the same forecast data for all charts since they now handle both formats
|
1538 |
temp_fig = self._create_temperature_chart(forecast_data) if forecast_data else self._create_default_chart()
|
1539 |
+
precip_fig = self._create_precipitation_chart(forecast_data) if forecast_data else self._create_default_chart()
|
1540 |
+
wind_fig = self._create_wind_chart(forecast_data) if forecast_data else self._create_default_chart()
|
1541 |
+
humidity_fig = self._create_humidity_chart(forecast_data) if forecast_data else self._create_default_chart()
|
1542 |
|
1543 |
return forecast_text, temp_fig, precip_fig, wind_fig, humidity_fig, "" # Clear input
|
1544 |
|
|
|
1617 |
'forecast': city_data.get('forecast', []),
|
1618 |
'current': city_data.get('current', {})
|
1619 |
}
|
1620 |
+
# Add MCP enhancements if available
|
|
|
1621 |
if mcp_data and city in mcp_data:
|
1622 |
city_info['mcp_enhancements'] = mcp_data[city]
|
1623 |
|
|
|
1631 |
except Exception as e:
|
1632 |
logger.error(f"Error updating enhanced map: {e}")
|
1633 |
return self._get_current_map()
|
1634 |
+
|
1635 |
def _handle_enhanced_forecast(self, city_name: str, mcp_data: dict = None):
|
1636 |
"""Handle forecast with MCP enhancements"""
|
1637 |
try:
|
|
|
1661 |
if coords:
|
1662 |
lat, lon = coords
|
1663 |
forecast_data = self.weather_client.get_forecast(lat, lon)
|
|
|
1664 |
|
1665 |
+
# Use the same forecast data for all charts (they handle the format internally)
|
1666 |
temp_fig = self._create_temperature_chart(forecast_data) if forecast_data else self._create_default_chart()
|
1667 |
+
precip_fig = self._create_precipitation_chart(forecast_data) if forecast_data else self._create_default_chart()
|
1668 |
+
wind_fig = self._create_wind_chart(forecast_data) if forecast_data else self._create_default_chart()
|
1669 |
+
humidity_fig = self._create_humidity_chart(forecast_data) if forecast_data else self._create_default_chart()
|
1670 |
|
1671 |
return enhanced_forecast, temp_fig, precip_fig, wind_fig, humidity_fig, ""
|
1672 |
else:
|
|
|
1674 |
|
1675 |
except Exception as e:
|
1676 |
logger.error(f"Error in enhanced forecast: {e}")
|
1677 |
+
return f"❌ Error getting enhanced forecast: {str(e)}", self._create_default_chart(), self._create_default_chart(), self._create_default_chart(), self._create_default_chart(), "" # Chart creation methods are defined above in the main class
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1678 |
|
1679 |
# ...existing code...
|
1680 |
def main():
|