Spaces:
Runtime error
Runtime error
| # app.py (QUANTUM FINAL: Қарапайым, Әдемі & Нақты) | |
| import gradio as gr | |
| import requests | |
| import pandas as pd | |
| from openmeteo_requests import Client | |
| import openmeteo_requests | |
| from PIL import Image | |
| import torch | |
| import timm | |
| from torchvision import transforms | |
| from datetime import datetime | |
| import pytz | |
| import numpy as np | |
| # --- 0. Қазақша Классификация Сөздігі (Өсімдіктерге басымдықпен) --- | |
| # Бұл ImageNet-ке негізделген, бірақ қазақшаға бейімделген | |
| KZ_LABELS = { | |
| 0: "Ауылшаруашылық техникасы", | |
| 1: "Мал (Жылқы/Сиыр)", | |
| 2: "Ит / Қасқыр", | |
| 3: "Құс", | |
| 4: "Қоқыс (Пластик/Қағаз)", | |
| 5: "Шыны / Металл қалдықтары", | |
| 6: "Өсімдік Ауруы (Шіріген)", # Өсімдік ауруларына нақтырақ | |
| 7: "Өсімдік (Дені сау)", | |
| 10: "Көлік / Жүк машинасы", | |
| 12: "Қой/Ешкі", | |
| 16: "Дәнді дақылдар", | |
| 20: "Ағаш / Орман", | |
| 25: "Шөп / Жайылым", | |
| } | |
| # --- 1. Тұрақты Параметрлер & Геодеректер --- | |
| BAYAN_ULGII_LAT = 48.97 | |
| BAYAN_ULGII_LON = 89.97 | |
| DEVICE = "cpu" | |
| TIMEZONE = "Asia/Ulaanbaatar" | |
| # --- 2. Ауа Райы Кодтарының Қазақша Аудармасы --- | |
| def translate_weather_code(code): | |
| if code in [0]: return "Күн ашық ☀️" | |
| if code in [1, 2]: return "Аздаған бұлт 🌤️" | |
| if code in [3]: return "Бұлтты ☁️" | |
| if code in [45, 48]: return "Тұман 🌫️" | |
| if code in [51, 53, 55, 61, 63]: return "Аздаған жаңбыр 🌧️" | |
| if code in [65, 80, 81, 82]: return "Нөсер/Қатты жаңбыр ⛈️" | |
| if code in [56, 57, 66, 67, 71, 73]: return "Қар/Аязды жаңбыр 🌨️" | |
| if code in [75, 77, 85, 86]: return "Қалың қар ❄️" | |
| if code in [95, 96, 99]: return "Найзағай ⚡" | |
| return "Белгісіз" | |
| # --- 3. Модельдерді Жүктеу (Тұрақтылықты күшейту) --- | |
| TRASH_AVAILABLE = False | |
| ANIMAL_PLANT_AVAILABLE = False | |
| try: | |
| # Ең жеңіл ML моделі (Мал/Өсімдік) | |
| animal_plant_model = timm.create_model('shufflenet_v2_x0_5', pretrained=True).to(DEVICE).eval() | |
| # Жақсы дәлдікті ML моделі (Қоқыс) | |
| trash_model = timm.create_model('efficientnet_b0', pretrained=True).to(DEVICE).eval() | |
| transform_common = transforms.Compose([ | |
| transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), | |
| transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), | |
| ]) | |
| ANIMAL_PLANT_AVAILABLE = True | |
| TRASH_AVAILABLE = True | |
| print("✅ Барлық жеңіл модельдер сәтті жүктелді.") | |
| except Exception as e: | |
| print(f"❌ Модельдерді жүктеу кезінде қате: {e}. ML функциялары іске қосылмайды.") | |
| # --- 4. Ауа Райы Логикасы --- | |
| def get_weather_data(): | |
| lat, lon = BAYAN_ULGII_LAT, BAYAN_ULGII_LON | |
| try: | |
| openmeteo = Client(requests) | |
| url = "https://api.open-meteo.com/v1/forecast" | |
| params = { | |
| "latitude": lat, "longitude": lon, | |
| "daily": ["weather_code", "temperature_2m_max", "temperature_2m_min", "precipitation_sum", "wind_speed_10m_max"], | |
| "timezone": "auto", "forecast_days": 7 | |
| } | |
| responses = openmeteo.weather_api(url, params=params) | |
| response = responses[0] | |
| daily = response.Daily() | |
| time_stamps = daily.Time() | |
| time_series = pd.to_datetime(time_stamps, unit="s").tz_localize(pytz.utc).tz_convert(TIMEZONE) | |
| # Деректерді алу және дөңгелектеу | |
| temp_max = daily.Variables(1).ValuesAsNumpy() | |
| temp_min = daily.Variables(2).ValuesAsNumpy() | |
| precip_sum = daily.Variables(3).ValuesAsNumpy() | |
| wind_speed = daily.Variables(4).ValuesAsNumpy() | |
| weather_code = daily.Variables(0).ValuesAsNumpy() | |
| daily_data = { | |
| "Күн": time_series.strftime('%d.%m'), | |
| "Сипаттама": [translate_weather_code(code) for code in weather_code], | |
| "Макс. Темп (°C)": temp_max.round(1), | |
| "Мин. Темп (°C)": temp_min.round(1), | |
| "Жауын-шашын (мм)": precip_sum.round(1), | |
| "Жел Жылдамдығы (км/сағ)": wind_speed.round(1) | |
| } | |
| df = pd.DataFrame(daily_data) | |
| # 4.1.1. ⚠️ Ерекше Экологиялық Ескертулер (Бас интерфейске шығатын) | |
| warnings = [] | |
| if np.any(wind_speed > 45): warnings.append("🚨 **ҚАТТЫ ЖЕЛ:** Жел 45 км/сағ-тан асады. Мал бағуға қауіпті.") | |
| if np.any(temp_min < -20): warnings.append("❄️ **ӨТЕ ҚАТТЫ АЯЗ:** -20°C төмен. Жылытуды күшейтіңіз.") | |
| if np.any(np.isin(weather_code, [75, 85, 86])): warnings.append("🌨️ **ЫҚТИМАЛ ҚАЛЫҢ ҚАР:** Қалың қар күтілуде. Жолдарға назар аударыңыз.") | |
| if np.any(precip_sum > 10): warnings.append("💧 **СУ ТАСҚЫНЫ ҚАУПІ:** Жауын-шашын күшті. Су басу қаупі бар.") | |
| warning_message = "✅ Қауіпсіздік ескертулері жоқ. Ауа райы тұрақты." if not warnings else "⚠️ **МАҢЫЗДЫ ҚАУІПСІЗДІК ЕСКЕРТУЛЕРІ:**\n- " + "\n- ".join(warnings) | |
| # 4.1.2. 🧠 Қазақша Болжам/Талдау | |
| analysis = [] | |
| if np.any(temp_max > 15): analysis.append("Алдағы күндері **күн жылы** болады.") | |
| if np.any(np.isin(weather_code, [0, 1])): analysis.append("Көп күндері **күн ашық** болады.") | |
| analysis_text = "✨ **Апталық Болжам Талдауы:**\n- " + ("\n- ".join(analysis) if analysis else "Жалпы алғанда ауа райы айтарлықтай өзгеріссіз.") | |
| return warning_message, df, analysis_text | |
| except Exception as e: | |
| return f"❌ Ауа райы деректерін алу қатесі: {e}", pd.DataFrame(), "Талдау қолжетімсіз." | |
| # 4.2. ML Жіктеу (Өзгеріссіз) | |
| def classify_image(image, task): | |
| if (task in ["animal", "plant"] and not ANIMAL_PLANT_AVAILABLE) or (task == "trash" and not TRASH_AVAILABLE): | |
| return "❌ Суретті жіктеу моделі іске қосылмады. Серверді қайта жүктеңіз немесе 'requirements' тексеріңіз." | |
| try: | |
| model, model_name = ( | |
| (trash_model, "EfficientNet B0 (5.3M)") if task == "trash" | |
| else (animal_plant_model, "ShuffleNet V2 (1.3M)") | |
| ) | |
| input_tensor = transform_common(image).unsqueeze(0).to(DEVICE) | |
| with torch.no_grad(): | |
| outputs = model(input_tensor) | |
| _, predicted = torch.max(outputs.data, 1) | |
| predicted_index = predicted.item() | |
| predicted_kz_label = KZ_LABELS.get(predicted_index, f"Белгісіз Код #{predicted_index}") | |
| if task == "trash": type_kz = "Қоқыс түрі" | |
| elif task == "animal": type_kz = "Мал Ауруы" | |
| else: type_kz = "Өсімдік Түрі / Ауруы" | |
| kz_response = f"**{type_kz}** болжамды нәтиже:\nБолжам: **{predicted_kz_label}**.\n\n" | |
| kz_response += f"✅ **Қолданылған Жеңіл Модель:** {model_name}.\n" | |
| kz_response += "❗ **Ескерту:** Бұл модельдер жалпы деректерде оқытылған. Дәл диагноз үшін **жергілікті маманға** жүгініңіз." | |
| return kz_response | |
| except Exception as e: | |
| return f"❌ Суретті жіктеу қатесі: {e}" | |
| # 4.3. Уақытты жаңарту (Әр минут сайын) | |
| def get_current_time(): | |
| try: | |
| tz = pytz.timezone(TIMEZONE) | |
| now = datetime.now(tz) | |
| return now.strftime("⌚ %H:%M:%S (%d.%m.%Y)") | |
| except Exception: | |
| return "⌚ Уақыт дерегі қолжетімсіз" | |
| # Қосымша іске қосылғанда деректерді алдын ала жүктеу | |
| initial_warning, initial_df, initial_analysis = get_weather_data() | |
| # --- 5. Ғажап Интерфейс (Gradio) --- | |
| # Әдемі, қарапайым және түсінікті тақырыпты таңдаймыз | |
| with gr.Blocks(title="Quantum FINAL: Баян-Өлгий AI", theme=gr.themes.Soft()) as demo: | |
| current_time_display = gr.Textbox(label=f"Баян-Өлгий Уақыты", value=get_current_time(), interactive=False, container=False) | |
| # 5.1. Басты HTML блок (Қарапайым және таза дизайн) | |
| header_html = gr.HTML( | |
| f""" | |
| <div style="text-align: center; padding: 10px; background-color: #4CAF50; color: white; border-radius: 10px;"> | |
| <h1 style="margin: 0;">⚛️ QUANTUM FINAL: Баян-Өлгий AI Кеңесшісі ⛰️</h1> | |
| </div> | |
| <div style="margin: 15px 0; padding: 10px; border: 2px solid {'#FF5733' if 'ҚАУІПСІЗДІК' in initial_warning else '#33FF57'}; border-radius: 5px; background-color: #f0f0f0;"> | |
| <h3 style="margin: 0; color: #333;">{initial_warning.split(':')[0]}</h3> | |
| <p style="white-space: pre-wrap; margin: 5px 0 0 0; color: #555;">{initial_warning.split(':')[1] if len(initial_warning.split(':')) > 1 else initial_warning}</p> | |
| </div> | |
| """ | |
| ) | |
| with gr.Tabs(): | |
| # --- 1. Ауа Райы & Карта --- | |
| with gr.TabItem("🌤️ Ауа Райы, Талдау & Карта"): | |
| gr.Markdown(f"### Баян-Өлгий үшін ең сенімді 7 күндік болжам") | |
| # Толық деректер кестесі | |
| gr.DataFrame( | |
| value=initial_df, | |
| headers=list(initial_df.columns), | |
| row_count="dynamic", | |
| interactive=False, | |
| label="Ауа Райының Толық Деректері (Жел, Қар, Аяз)", | |
| wrap=True, | |
| type="pandas" | |
| ) | |
| # Қазақша Болжам/Талдауды көрсету | |
| gr.Markdown("### 🧠 Quantum Талдауы (Қазақша)") | |
| gr.Markdown(initial_analysis) | |
| gr.Markdown("### 🗺️ Баян-Өлгий Картасы") | |
| gr.HTML(f""" | |
| <iframe | |
| width="100%" height="300" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" | |
| src="http://maps.google.com/maps?q=48.97,89.97&z=10&output=embed0{BAYAN_ULGII_LAT},{BAYAN_ULGII_LON}&z=10&output=embed"> | |
| </iframe> | |
| """) | |
| # --- 2. ML Қолданбалары (Мамандандырылған Болжамдар) --- | |
| with gr.TabItem("🔬 ML Болжамдары (Өсімдік, Мал, Қоқыс)"): | |
| gr.Markdown("### 🔬 Мамандандырылған Модельдермен Талдау (Қазақша)") | |
| with gr.Row(): | |
| # Мал Ауруын Анықтау | |
| with gr.Column(): | |
| gr.Markdown("#### 🐑 Мал Ауруын Анықтау (ShuffleNet V2)") | |
| input_image_animal = gr.Image(type="pil", label="Мал суретін жүктеу") | |
| output_text_animal = gr.Textbox(label="БОЛЖАМДЫ НӘТИЖЕ", interactive=False) | |
| classify_btn_animal = gr.Button("Ауруды Анықтау") | |
| classify_btn_animal.click(fn=lambda img: classify_image(img, task="animal"), inputs=input_image_animal, outputs=output_text_animal) | |
| # Өсімдік Түрін/Ауруын Анықтау | |
| with gr.Column(): | |
| gr.Markdown("#### 🌱 Өсімдік Түрін/Ауруын Анықтау (ShuffleNet V2)") | |
| input_image_plant = gr.Image(type="pil", label="Өсімдік суретін жүктеу") | |
| output_text_plant = gr.Textbox(label="БОЛЖАМДЫ НӘТИЖЕ", interactive=False) | |
| classify_btn_plant = gr.Button("Түрін/Ауруын Анықтау") | |
| classify_btn_plant.click(fn=lambda img: classify_image(img, task="plant"), inputs=input_image_plant, outputs=output_text_plant) | |
| gr.Markdown("---") | |
| # Қоқыс Түрін Анықтау | |
| gr.Markdown("#### 🗑️ Қоқыс Түрін Анықтау (EfficientNet B0)") | |
| with gr.Row(): | |
| input_image_trash = gr.Image(type="pil", label="Қоқыс суретін жүктеу") | |
| output_text_trash = gr.Textbox(label="БОЛЖАМДЫ НӘТИЖЕ", interactive=False) | |
| classify_btn_trash = gr.Button("Түрін Анықтау") | |
| classify_btn_trash.click(fn=lambda img: classify_image(img, task="trash"), inputs=input_image_trash, outputs=output_text_trash) | |
| # --- 3. Анықтамалық Сөздік --- | |
| with gr.TabItem("📚 Анықтамалық Сөздік"): | |
| gr.Markdown("### 📚 Ауылшаруашылық Терминдері") | |
| gr.Markdown(""" | |
| * **Жайлау:** Жыл мезгіліне байланысты мал жайылатын жер. | |
| * **Қыстақ:** Қысқы уақытта малды ұстайтын жылы жер. | |
| * **Күйіс қайыру:** Малдың жеген шөбін қайта ауызға шығарып шайнауы. | |
| """) | |
| # Уақытты әр минут сайын жаңарту (Ауа райы емес, тек сағат) | |
| demo.load(get_current_time, None, current_time_display, every=60) | |
| demo.launch() |