Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| # PLANETYOYO AI Ultimate v19.10 - Auto-Install Dependencies | |
| # Description: Plant analysis system with automatic dependency installation | |
| import subprocess | |
| import sys | |
| import os | |
| # ======================================================== | |
| # AUTO-INSTALL MISSING DEPENDENCIES | |
| # ======================================================== | |
| def install_package(package_name: str, import_name: str = None): | |
| """Install package if not available.""" | |
| if import_name is None: | |
| import_name = package_name | |
| try: | |
| __import__(import_name) | |
| return True | |
| except ImportError: | |
| print(f"๐ฆ Installing {package_name}...") | |
| try: | |
| subprocess.check_call([sys.executable, "-m", "pip", "install", package_name, "-q"]) | |
| print(f"โ {package_name} installed successfully") | |
| return True | |
| except subprocess.CalledProcessError: | |
| print(f"โ Failed to install {package_name}") | |
| return False | |
| # Install core dependencies | |
| print("\n๐ง Checking dependencies...") | |
| install_package("adafruit-io", "adafruit_io") | |
| install_package("geopy") | |
| install_package("cloudinary") | |
| install_package("prophet") | |
| install_package("requests") | |
| import time | |
| import json | |
| import requests | |
| import threading | |
| import random | |
| import math | |
| import shutil | |
| import csv | |
| from datetime import datetime, timedelta | |
| from collections import Counter, defaultdict | |
| from typing import Dict, List, Any, Optional, Tuple | |
| # ======================================================== | |
| # CORE IMPORTS | |
| # ======================================================== | |
| try: | |
| import gradio as gr | |
| from PIL import Image | |
| import numpy as np | |
| import pandas as pd | |
| import matplotlib.pyplot as plt | |
| except ImportError as e: | |
| print(f"โ Critical dependency missing: {e}") | |
| print("Run: pip install gradio pillow numpy pandas matplotlib") | |
| sys.exit(1) | |
| # ======================================================== | |
| # AI DEPENDENCIES (OPTIONAL) | |
| # ======================================================== | |
| device = "cpu" | |
| AI_AVAILABLE = False | |
| try: | |
| import torch | |
| from transformers import pipeline, AutoImageProcessor, AutoModelForImageClassification | |
| AI_AVAILABLE = True | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| print(f"โ AI initialized. Device: {device}") | |
| except ImportError: | |
| print("โ ๏ธ AI dependencies not found. Install: pip install torch transformers") | |
| except Exception as e: | |
| print(f"โ ๏ธ AI init failed: {e}") | |
| # ======================================================== | |
| # IOT DEPENDENCIES (OPTIONAL) | |
| # ======================================================== | |
| ADAFRUIT_AVAILABLE = False | |
| GEOPY_AVAILABLE = False | |
| try: | |
| from adafruit_io.rest_client import Client as AdafruitClient | |
| from adafruit_io.rest_client import APIError | |
| ADAFRUIT_AVAILABLE = True | |
| except ImportError: | |
| print("โ ๏ธ Adafruit IO not available. Install: pip install adafruit-io") | |
| try: | |
| from geopy.geocoders import Nominatim | |
| GEOPY_AVAILABLE = True | |
| except ImportError: | |
| print("โ ๏ธ Geopy not available. Install: pip install geopy") | |
| # ======================================================== | |
| # CLOUD DEPENDENCIES (OPTIONAL) | |
| # ======================================================== | |
| CLOUDINARY_AVAILABLE = False | |
| try: | |
| import cloudinary | |
| import cloudinary.api | |
| import cloudinary.uploader | |
| CLOUDINARY_AVAILABLE = True | |
| except ImportError: | |
| print("โ ๏ธ Cloudinary not available. Install: pip install cloudinary") | |
| PROPHET_AVAILABLE = False | |
| try: | |
| from prophet import Prophet | |
| PROPHET_AVAILABLE = True | |
| except ImportError: | |
| print("โ ๏ธ Prophet not available. Install: pip install prophet") | |
| # ======================================================== | |
| # CONFIGURATION | |
| # ======================================================== | |
| PLANTNET_API_KEY = "2b10HlR0yP4wZbvHjP8jCo3Aae" | |
| CLOUDINARY_CLOUD_NAME = "dru8hdesf" | |
| CLOUDINARY_API_KEY = "959867312261694" | |
| CLOUDINARY_API_SECRET = "3S0glC5W38T2hh-SGVskOOODVFk" | |
| ADAFRUIT_IO_USERNAME = "planetserver" | |
| ADAFRUIT_IO_KEY = "aio_OfoZ090F97FAuySlEbtHs2L1WeFB" | |
| WEATHER_API_KEY = "e541061f22d8727d1cae4f22157fe7ec" | |
| TELEGRAM_BOT_TOKEN = "8437890500:AAFIeITryixh9WbHif7D30mMB" | |
| HUGGING_FACE_TOKEN = os.environ.get("HF_TOKEN", "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") | |
| TELEGRAM_CHAT_ID = "667462198" | |
| CLOUDINARY_FOLDER = "ESP32CAMPLANET" | |
| WEATHER_API_URL = "http://api.openweathermap.org/data/2.5/weather" | |
| REPORTS_DIR = "batch_analysis_reports" | |
| ADAFRUIT_FEEDS = { | |
| "temperature": "temperature-sensor", | |
| "humidity": "humidity-sensor", | |
| "soil_moisture": "soil-moisture-sensor", | |
| "light": "light-sensor", | |
| "analysis_results": "plant-analysis-results", | |
| "user_corrections": "user-corrections" | |
| } | |
| # ======================================================== | |
| # GLOBAL STATE | |
| # ======================================================== | |
| PLANT_MODELS_CACHE = {} | |
| PLANT_DATABASE = {"aloe_vera": {"care_tips": ["ืฉืืฉ ืืืงืืช ืขื ืืืื", "ืืฉืงืื ืืืขืื ืืืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/aloe_vera.jpg", "plant_id": "aloe_vera"}, | |
| "almond": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืืจ ืฉืืืจ", "ืจืืงืืื ืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dalmond", "plant_id": "almond"}, | |
| "apple": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืื ืืชืคืื", "ืืืืืช ืืจื-ืชืคืื", "ืจืืงืืื ืฉืืืจ"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/apple.jpg", "plant_id": "apple"}, | |
| "apple_fuji": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืื ืืชืคืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dfuji_apple", "plant_id": "apple_fuji"}, | |
| "apple_gala": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืื ืืชืคืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgala_apple", "plant_id": "apple_gala"}, | |
| "apple_granny_smith": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืื ืืชืคืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgranny_smith", "plant_id": "apple_granny_smith"}, | |
| "apricot": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dapricot", "plant_id": "apricot"}, | |
| "artichoke": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืจืืงืืื ืืชืจ", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dartichoke", "plant_id": "artichoke"}, | |
| "asparagus": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืืช ืืืกืคืจืืืก", "ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dasparagus", "plant_id": "asparagus"}, | |
| "avocado": {"care_tips": ["ืฉืืฉ ืืืื", "ืืื ื ืืจืื ืืืงื"], "common_diseases": ["ืืื ืืืืืงืื", "ืืชื ืฉืืฉ", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/avocado.jpg", "plant_id": "avocado"}, | |
| "azalea": {"care_tips": ["ืฆื ืืืงื", "ืงืจืงืข ืืืืฆืืช", "ืืืืช ืืืืื"], "common_diseases": ["ืงืฉืงืฉืช ืืืืืื", "ืงืืืืื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://upload.wikimedia.org/wikipedia/commons/4/4b/Azalea_flower_in_Japan.jpg", "plant_id": "azalea"}, | |
| "bamboo": {"care_tips": ["ืฉืืฉ ืืืื ืื ืืืงืืช", "ืืฉืงืื ืืจืืื", "ืืืืช ืืืืื"], "common_diseases": ["ืื ืงื ืืืืืืง", "ืืืจืืก ืคืกืืคืกืช ืืืืืืง", "ืืชื ืขืืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/bamboo.jpg", "plant_id": "bamboo"}, | |
| "barley": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ื ื ืกืืช ืฉืขืืจื ืฆืืืื", "ืื ืืืืช", "ืืชื ืจืฉืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbarley", "plant_id": "barley"}, | |
| "basil": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืกืืืจื", "ืงืจืงืข ืขืฉืืจื"], "common_diseases": ["ืงืฉืงืฉืช", "ืคืืจืื ืืคืืจื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/basil.jpg", "plant_id": "basil"}, | |
| "bean": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืื", "ืื ืชืจืงื ืื", "ืื ืงื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbean", "plant_id": "bean"}, | |
| "birch": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืืื"], "common_diseases": ["ืชืืืชืช ืืืื ื", "ืืืืื", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbirch", "plant_id": "birch"}, | |
| "blueberry": {"care_tips": ["ืงืจืงืข ืืืืฆืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืขื ืืช ืืืืื ืืืช", "ืื ืงื ืืืข", "ืื ืชืจืงื ืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/blueberry.jpg", "plant_id": "blueberry"}, | |
| "broccoli": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืขืืื ืืฉืืจืฉ", "ืจืื ืฉืืืจื", "ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbroccoli", "plant_id": "broccoli"}, | |
| "cabbage": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืขืืื ืืฉืืจืฉ", "ืืชื ืขืืื ืืืืจื ืจืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcabbage", "plant_id": "cabbage"}, | |
| "cacao": {"care_tips": ["ืฆื ืืืงื", "ืืืืช ืืืืื"], "common_diseases": ["ืชืจืืื ืฉืืืจ", "ืืืืื ืืืืฉืคืืช", "ืืืจืืก ืืจืืขื ื ืคืืื"], "img_url": "https://upload.wikimedia.org/wikipedia/commons/5/51/Theobroma_cacao_tree.jpg", "plant_id": "cacao"}, | |
| "cactus": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื ืืืื"], "common_diseases": ["ืจืืงืืื ืงืงืืืก", "ืืืืื", "ืจืืงืืื ืจื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/cactus.jpg", "plant_id": "cactus"}, | |
| "camellia": {"care_tips": ["ืฆื ืืืงื", "ืืฉืงืื ืงืืืขื", "ืืื ื ืืจืื ืืืงื"], "common_diseases": ["ืื ืงื ืขืื ืืืื", "ืคืฆืข", "ืืจื ืืขืื"], "img_url": "https://upload.wikimedia.org/wikipedia/commons/e/e0/Camellia_japonica_flower.jpg", "plant_id": "camellia"}, | |
| "carrot": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืจืื ืืขืืืงื"], "common_diseases": ["ืื ืงื ืืืืืงื", "ืื ืงื ืขืืื ืฆืจืงืกืคืืจื", "ืงืืืืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/carrot.jpg", "plant_id": "carrot"}, | |
| "cauliflower": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื ืืื ื", "ืจืืงืืื ืฉืืืจ", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcauliflower", "plant_id": "cauliflower"}, | |
| "cherry": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืกืคืืช ืืืืืงืืช", "ืจืืงืืื ืืื", "ืืชื ืขืืื ืืืืืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/cherry.jpg", "plant_id": "cherry"}, | |
| "cilantro": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืชื ืขืืื ืฆืจืงืกืคืืจื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcilantro", "plant_id": "cilantro"}, | |
| "coffee": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืงืจืงืข ืืืืฆืืช ืืื ืืงืืช"], "common_diseases": ["ืืืืืช ืืงืคื", "ืืืืช ืคืจื ืืงืคื", "ืื ืงื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcoffee", "plant_id": "coffee"}, | |
| "cucumber": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืงืืืช"], "common_diseases": ["ืงืืืืื", "ืืืจืืก ืคืกืืคืกืช ืืืืคืคืื", "ืื ืงื ืืืข ืืืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/cucumber.jpg", "plant_id": "cucumber"}, | |
| "daffodil": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืืืื ืืฆื ื ืจืงืืก", "ืจืืงืืื ืืกืืกื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddaffodil", "plant_id": "daffodil"}, | |
| "date_palm": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืืืื", "ืืืืื'", "ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddate_palm", "plant_id": "date_palm"}, | |
| "dill": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื ืฆืจืงืกืคืืจื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddill", "plant_id": "dill"}, | |
| "dragon_fruit": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืกืคืืช ืคืจื ืืืจืงืื", "ืืชื ืฉืืืจ", "ืจืืงืืื ืืืข"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/dragon_fruit.jpg", "plant_id": "dragon_fruit"}, | |
| "eggplant": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืื ืคืืกืจืืช", "ืื ืงื ืคืืืืคืกืืก", "ืื ืชืจืงื ืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/eggplant.jpg", "plant_id": "eggplant"}, | |
| "fern": {"care_tips": ["ืฆื ืืืงื", "ืืืืช ืืืืื"], "common_diseases": ["ื ืืืืืืช ืขืืื", "ืืืืื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/fern.jpg", "plant_id": "fern"}, | |
| "ficus": {"care_tips": ["ืืืจ ืื ืืฉืืจ", "ืืฉืงืื ืืชืื ื", "ื ืืงืื ืขืืื ืืืืง"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืื ืชืจืงื ืื", "ืขืคืฅ ืืชืจ"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/ficus.jpg", "plant_id": "ficus"}, | |
| "fig": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืืืืช ืืชืื ื", "ืื ืงื ืืจืื", "ืืืจืืก ืคืกืืคืกืช ืืชืื ื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/fig.jpg", "plant_id": "fig"}, | |
| "garlic": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืืื", "ืืืืื", "ืจืืงืืื ืฆืืืืจ"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/garlic.jpg", "plant_id": "garlic"}, | |
| "geranium": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื", "ืืกืจืช ืคืจืืื ืืืฉืื"], "common_diseases": ["ืืืืื", "ืื ืงื ืืืืจืืืืก", "ืืฆืงืช"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/geranium.jpg", "plant_id": "geranium"}, | |
| "ginseng": {"care_tips": ["ืฆื ืืื", "ืงืจืงืข ืืื"], "common_diseases": ["ืื ืงื ืืืืจื ืจืื", "ืืืืืช ื'ืื ืกื ื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dginseng", "plant_id": "ginseng"}, | |
| "grapevine": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืงืืืข"], "common_diseases": ["ืจืืงืืื ืฉืืืจ", "ืงืืืืื", "ืืืืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/grapevine.jpg", "plant_id": "grapevine"}, | |
| "hawthorn": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื", "ืขืืื ืืืืืืช"], "common_diseases": ["ืืชื ืขืืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhawthorn", "plant_id": "hawthorn"}, | |
| "hibiscus": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืช ืืืืืกืงืืก", "ืืชื ืขืืื ืืืืืงื", "ืืชื ืฉืืืจ"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/hibiscus.jpg", "plant_id": "hibiscus"}, | |
| "jasmine": {"care_tips": ["ืฉืืฉ ืืืื ืื ืืืงืืช", "ืืฉืงืื ืกืืืจื", "ืืืคืืก ืืืคืก"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืืชื ืขืืื", "ืขืืืฉ ืืคืืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/jasmine.jpg", "plant_id": "jasmine"}, | |
| "juniper": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืื ืงื ืคืืืืคืกืืก", "ืื ืงื ืงืืืื ื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Djuniper", "plant_id": "juniper"}, | |
| "kiwi": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืื ืงื ืืืืืงื", "ืจืืงืืื ืืชืจ", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/kiwi.jpg", "plant_id": "kiwi"}, | |
| "lantana": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืขืืืฉ ืืคืืื", "ืืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dlantana", "plant_id": "lantana"}, | |
| "laurel": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืขืืื ื ืืืขืื", "ืคืฆืข ืคืืืืคืืืจื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/laurel.jpg", "plant_id": "laurel"}, | |
| "lavender": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช", "ืืืืื ืืืืจ ืืคืจืืื"], "common_diseases": ["ืืชื ืขืืื ืกืคืืืืจื", "ืจืืงืืื ืฉืืจืฉืื", "ืคืฆืข ืืืข"], "img_url": "https://upload.wikimedia.org/wikipedia/commons/f/f8/Lavandula_angustifolia_field.jpg", "plant_id": "lavender"}, | |
| "leek": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืืช ืืจืืฉื", "ืจืืงืืื ืืกืืกื ืคืืกืจืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dleek", "plant_id": "leek"}, | |
| "lemon": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืช ืจืืงืืื", "ืื ืืืืช"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/lemon_tree.jpg", "plant_id": "lemon"}, | |
| "lettuce": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืช ืืกื", "ืงืืืืื", "ืจืืงืืื ืกืงืืจืืืื ืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/lettuce.jpg", "plant_id": "lettuce"}, | |
| "lilac": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืืืืจ ืคืจืืื"], "common_diseases": ["ืงืืืืื", "ืื ืงื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dlilac", "plant_id": "lilac"}, | |
| "lily": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืืจืืก ืืืืืืงืช ืืฉืืฉื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/lily.jpg", "plant_id": "lily"}, | |
| "magnolia": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืกืืืจื", "ืืื ื ืืจืื ืืืงื"], "common_diseases": ["ืืชื ืขืืื", "ืคืฆืข", "ืชืืืชื"], "img_url": "https://upload.wikimedia.org/wikipedia/commons/a/a2/Magnolia_grandiflora_tree.jpg", "plant_id": "magnolia"}, | |
| "mango": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืชืจืงื ืื", "ืงืืืืื", "ืชืืืชื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/mango.jpg", "plant_id": "mango"}, | |
| "maple": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืืคืช", "ืงืืืื ืคืืกืจืืช", "ืื ืชืจืงื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmaple", "plant_id": "maple"}, | |
| "melon": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืงืืืื ืคืืกืจืืช", "ืื ืงื ืขืืื ืืืืจื ืจืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/melon.jpg", "plant_id": "melon"}, | |
| "melon_cantaloupe": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcantaloupe", "plant_id": "melon_cantaloupe"}, | |
| "melon_honeydew": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhoneydew_melon", "plant_id": "melon_honeydew"}, | |
| "mint": {"care_tips": ["ืฆื ืืืงื", "ืืฉืงืื ืืจืืื", "ืจืืืฉ ืืืืืงืื"], "common_diseases": ["ืืืืื", "ืงืืืื ืืช"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/mint.jpg", "plant_id": "mint"}, | |
| "myrtle": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืืชืื ื", "ืืืืื ืืืืจ ืืคืจืืื"], "common_diseases": ["ืืืืืช ืืืืก", "ืื ืงื ืืืืจืืืืก", "ืืชื ืขืืื"], "img_url": "https://upload.wikimedia.org/wikipedia/commons/a/a2/Myrtus_communis_plant.jpg", "plant_id": "myrtle"}, | |
| "nutmeg": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืื ืงื ืืื", "ืื ืงื ืืืื ืืืกืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dnutmeg", "plant_id": "nutmeg"}, | |
| "oak": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืงืืืืช ืืืืื", "ืื ืชืจืงื ืื", "ืฉืืคืืืืช ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Doak", "plant_id": "oak"}, | |
| "oat": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืงืจืงืขืืช ืืืืช"], "common_diseases": ["ืืืืืช ืืืชืจ", "ืื ืืืืช", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Doat", "plant_id": "oat"}, | |
| "okra": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืืื ืืืฆืืจืช"], "common_diseases": ["ืงืืืื ืคืืกืจืืช", "ืงืืืืื", "ืื ืงื ืืืืืงื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/okra.jpg", "plant_id": "okra"}, | |
| "olive": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช", "ืงืจืงืข ืื ืืงืืช ืืืื"], "common_diseases": ["ืืืื ืืคืืจืืช", "ืืืืช ืขืื ืืื ืืืืก"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/olive_tree.jpg", "plant_id": "olive"}, | |
| "onion": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืงืืืืื ืืฆื", "ืจืืงืืื ืืกืืกื ืคืืกืจืืื", "ืื ืงื ืขืืื ืืืืจืืืืก"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/onion.jpg", "plant_id": "onion"}, | |
| "orchid": {"care_tips": ["ืืืจ ืื ืืฉืืจ", "ืืฉืงืื ืืืขืื", "ืืืืช ืืืืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืื ืืืืช ืงืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/orchid.jpg", "plant_id": "orchid"}, | |
| "oregano": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืืืืืช ื ืขื ืข", "ืจืืงืืื ืืืข"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Doregano", "plant_id": "oregano"}, | |
| "palm": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืื ืคืืกืจืืช", "ืจืืงืืื ื ืืฆื", "ืจืืงืืื ืืืข ืืื ืืืจืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/palm.jpg", "plant_id": "palm"}, | |
| "parsley": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื ืกืคืืืืจื", "ืืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dparsley", "plant_id": "parsley"}, | |
| "passion_fruit": {"care_tips": ["ืฉืืฉ ืืืื", "ืชืืืื ืืืืคืืก"], "common_diseases": ["ืงืืืื ืคืืกืจืืช", "ืืชื ืกืคืืืืจื", "ืืชื ืืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/passion_fruit.jpg", "plant_id": "passion_fruit"}, | |
| "pea": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืงืจืงืข ืงืจืืจื"], "common_diseases": ["ืงืืืืื", "ืงืืืื ืคืืกืจืืช", "ืื ืงื ืืกืงืืืืชื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpea", "plant_id": "pea"}, | |
| "peach": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืขืืื ืืกืืืกืืื ืฉื ืืคืจืกืง", "ืจืืงืืื ืืื", "ืืชื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpeach", "plant_id": "peach"}, | |
| "pear": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืงื ืืฉ", "ืืื ืืืก", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/pear.jpg", "plant_id": "pear"}, | |
| "pecan": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืื ืคืงืื", "ืืืืืืช ืขืืื ืคืืจืืืชืืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpecan", "plant_id": "pecan"}, | |
| "pepper": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืชื ืืืืืงื", "ืงืืืื ืคืืกืจืืช", "ืืืจืืก ืคืกืืคืกืช ืคืืคื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/pepper.jpg", "plant_id": "pepper"}, | |
| "persimmon": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืื ืชืจืงื ืื", "ืงืืืืช ืืคืจืกืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpersimmon", "plant_id": "persimmon"}, | |
| "petunia": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื", "ืืฉ ืืืกืืจ ืคืจืืื ื ืืืืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืื ืืืืช"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/petunia.jpg", "plant_id": "petunia"}, | |
| "pine": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืืืืื", "ืงืืืื ืืช", "ืกืคืืช", "ืืืื ืขืืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/pine_tree.jpg", "plant_id": "pine"}, | |
| "plum": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืืจืืก ืืืขืืืขืืช ืฉืืืฃ", "ืงืฉืจ ืฉืืืจ", "ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dplum", "plant_id": "plum"}, | |
| "poinsettia": {"care_tips": ["ืืืจ ืืืืจ", "ืืฉืงืื ืกืืืจื", "ืืื ื ืืงืืจ"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืงืืืืื", "ืืื ืืคืืื ืกืืืื"], "img_url": "https://upload.wikimedia.org/wikipedia/commons/4/4c/Euphorbia_pulcherrima_plant.jpg", "plant_id": "poinsettia"}, | |
| "pomegranate": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืชื ืคืจื", "ืื ืชืจืงื ืื", "ืจืืงืืื ืคืจื ืืืืจื ืจืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/pomegranate.jpg", "plant_id": "pomegranate"}, | |
| "potato": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืื ืืืืืจืช", "ืืืื ืืืงืืืช", "ืืื", "ืงืืืื ืคืืกืจืืช"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/potato.jpg", "plant_id": "potato"}, | |
| "pumpkin": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื", "ืื ืงื ืืืข ืืืื", "ืืื ืืืขืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpumpkin", "plant_id": "pumpkin"}, | |
| "pumpkin_spaghetti": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื", "ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dspaghetti_squash", "plant_id": "pumpkin_spaghetti"}, | |
| "quinoa": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืงืืืืื ืงืื ืืื", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dquinoa", "plant_id": "quinoa"}, | |
| "raspberry": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืฉื ืชื"], "common_diseases": ["ืื ืชืจืงื ืื", "ืื ืงื ืงื ื", "ืื ืงื ืืืจืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/raspberry.jpg", "plant_id": "raspberry"}, | |
| "rhododendron": {"care_tips": ["ืฆื ืืืงื", "ืงืจืงืข ืืืืฆืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืื ืืชืืจื ืฉื ืืืืืื", "ืื ืงื ืขืืื", "ืจืืงืืื ืฉืืจืฉืื ืคืืืืคืืืจื"], "img_url": "https://upload.wikimedia.org/wikipedia/commons/e/ec/Rhododendron_yakushimanum_flower.jpg", "plant_id": "rhododendron"}, | |
| "rice": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืืื ืืืืืื"], "common_diseases": ["ืคืืฆืืฅ ืืืจื", "ืื ืงื ื ืื", "ืื ืงื ืขืืื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Drice", "plant_id": "rice"}, | |
| "rose": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืชื ืฉืืืจ", "ืงืืืืื", "ืืืืช ืืจื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/rose.jpg", "plant_id": "rose"}, | |
| "rosemary": {"care_tips": ["ืืจืืฉ ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื", "ืงืจืงืข ืื ืืงืืช ืืืื"], "common_diseases": ["ืงืืืืื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/rosemary.jpg", "plant_id": "rosemary"}, | |
| "sage": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืงืืืื ืคืืกืจืืช", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsage", "plant_id": "sage"}, | |
| "scallion": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืจืืคืก ืืฆื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dscallion", "plant_id": "scallion"}, | |
| "spinach": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื", "ืงืจืงืข ืขืฉืืจื"], "common_diseases": ["ืงืืืืื ืชืจื", "ืืืืื ืืื ื", "ืงืืืื ืคืืกืจืืช"], "img_url": "https://upload.wikimedia.org/wikipedia/commons/1/15/Spinach_plant.jpg", "plant_id": "spinach"}, | |
| "strawberry": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืื ืชืจืงื ืื", "ืขืืืฉ ืืคืืจ", "ืฆืจืืืช ืขืืื", "ืืชื ืขืืื ืืืืืชื"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/strawberry.jpg", "plant_id": "strawberry"}, | |
| "succulent": {"care_tips": ["ืืืจ ืืืืจ", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืื ืืืืช ืงืื", "ืืืืืืช ืฉืืฉ"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/succulent.jpg", "plant_id": "succulent"}, | |
| "sunflower": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื", "ืงืจืงืข ืืื"], "common_diseases": ["ืงืืืืื", "ืืืืื", "ืื ืงื ืืืข ืคืืื", "ืงืืืื ืืจืืืฆืืืืช"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/sunflower.jpg", "plant_id": "sunflower"}, | |
| "sweet_potato": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืืจ", "ืจืืงืืื ืจื", "ืกืงืืฃ"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/sweet_potato.jpg", "plant_id": "sweet_potato"}, | |
| "swiss_chard": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื", "ืืชื ืขืืื ืฆืจืงืกืคืืจื", "ื ืืืืืช ืฆืืกืื ืฉื ืกืืง"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dswiss_chard", "plant_id": "swiss_chard"}, | |
| "tea": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืื ืงื ืฉืืคืืืืช", "ืืืืื ืืืืื"], "img_url": "https://upload.wikimedia.org/wikipedia/commons/5/54/Camellia_sinensis_plant.jpg", "plant_id": "tea"}, | |
| "thyme": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืืืข", "ืื ืงื ืืืืจืืืืก"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dthyme", "plant_id": "thyme"}, | |
| "tilia": {"care_tips": ["ืฉืืฉ ืืืื ืื ืืืงืืช", "ืืฉืงืื ืกืืืจื", "ืงืจืงืข ืืื"], "common_diseases": ["ืงืืืื ืืจืืืฆืืืืช", "ืื ืชืจืงื ืื", "ืกืคืืช"], "img_url": "https://upload.wikimedia.org/wikipedia/commons/e/e2/Tilia_cordata_tree.jpg", "plant_id": "tilia"}, | |
| "tobacco": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืขืืืฉ ืืืื", "ืืืจืืก ืคืกืืคืกืช ืืืืง", "ืกืคืืช ืฉืืืจื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dtobacco", "plant_id": "tobacco"}, | |
| "tomato": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื", "ืชืืืื ืืฆืืืื"], "common_diseases": ["ืืืื ืืืงืืืช", "ืืืื ืืืืืจืช", "ืืชื ืขืืื ืกืคืืืืจื", "ืงืืืื ืืืืืงืืช"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/tomato.jpg", "plant_id": "tomato"}, | |
| "tomato_cherry": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืื ืืืงืืืช", "ืืืื ืืืืืจืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcherry_tomato", "plant_id": "tomato_cherry"}, | |
| "tomato_heirloom": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืื ืืืงืืืช", "ืืืื ืืืืืจืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dheirloom_tomato", "plant_id": "tomato_heirloom"}, | |
| "tulip": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืืืจืืก ืฉืืืจืช ืืฆืืข ืฉื ืืฆืืขืื ื", "ืจืืงืืื ืืฆื ืคืืกืจืืื", "ืื ืงื ืืืืจืืืืก"], "img_url": "https://res.cloudinary.com/dru8hdesf/image/upload/v1716900000/ESP32CAMPLANET/tulip.jpg", "plant_id": "tulip"}, | |
| "walnut": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื", "ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dwalnut", "plant_id": "walnut"}, | |
| "apple_golden_delicious": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืงืืืืื", "ืืื ืืชืคืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgolden_delicious_apple", "plant_id": "apple_golden_delicious"}, | |
| "apple_honeycrisp": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืื ืืชืคืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhoneycrisp_apple", "plant_id": "apple_honeycrisp"}, | |
| "apple_red_delicious": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืื ืืชืคืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dred_delicious_apple", "plant_id": "apple_red_delicious"}, | |
| "apricot_royal": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Droyal_apricot", "plant_id": "apricot_royal"}, | |
| "avocado_hass": {"care_tips": ["ืฉืืฉ ืืืื", "ืืื ื ืืจืื ืืืงื"], "common_diseases": ["ืืชื ืฉืืฉ", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhass_avocado", "plant_id": "avocado_hass"}, | |
| "basil_sweet": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsweet_basil", "plant_id": "basil_sweet"}, | |
| "basil_thai": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dthai_basil", "plant_id": "basil_thai"}, | |
| "bean_green": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืื", "ืื ืชืจืงื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgreen_bean", "plant_id": "bean_green"}, | |
| "bean_kidney": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืชืจืงื ืื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dkidney_bean", "plant_id": "bean_kidney"}, | |
| "blueberry_highbush": {"care_tips": ["ืงืจืงืข ืืืืฆืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืขื ืืช ืืืืื ืืืช", "ืื ืงื ืืืข"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhighbush_blueberry", "plant_id": "blueberry_highbush"}, | |
| "broccoli_calabrese": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcalabrese_broccoli", "plant_id": "broccoli_calabrese"}, | |
| "cabbage_red": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืขืืื ืืฉืืจืฉ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dred_cabbage", "plant_id": "cabbage_red"}, | |
| "carrot_nantes": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืจืื ืืขืืืงื"], "common_diseases": ["ืื ืงื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dnantes_carrot", "plant_id": "carrot_nantes"}, | |
| "cherry_black": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dblack_cherry", "plant_id": "cherry_black"}, | |
| "cherry_sour": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsour_cherry", "plant_id": "cherry_sour"}, | |
| "corn_sweet": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื ื ืคืืฆื", "ืขืืืฉ ืชืืจืก"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsweet_corn", "plant_id": "corn_sweet"}, | |
| "corn_popcorn": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื ื ืคืืฆื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpopcorn", "plant_id": "corn_popcorn"}, | |
| "cucumber_pickling": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืงืืืช"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpickling_cucumber", "plant_id": "cucumber_pickling"}, | |
| "eggplant_japanese": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Djapanese_eggplant", "plant_id": "eggplant_japanese"}, | |
| "fig_black": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืืืืช ืืชืื ื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dblack_fig", "plant_id": "fig_black"}, | |
| "fig_mission": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืืืืช ืืชืื ื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmission_fig", "plant_id": "fig_mission"}, | |
| "garlic_softneck": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsoftneck_garlic", "plant_id": "garlic_softneck"}, | |
| "garlic_hardneck": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhardneck_garlic", "plant_id": "garlic_hardneck"}, | |
| "grape_concord": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืงืืืข"], "common_diseases": ["ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dconcord_grape", "plant_id": "grape_concord"}, | |
| "grape_thompson_seedless": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืงืืืข"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dthompson_seedless_grape", "plant_id": "grape_thompson_seedless"}, | |
| "jasmine_star": {"care_tips": ["ืฉืืฉ ืืืื ืื ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dstar_jasmine", "plant_id": "jasmine_star"}, | |
| "kiwi_hardy": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืื ืงื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhardy_kiwi", "plant_id": "kiwi_hardy"}, | |
| "lavender_english": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Denglish_lavender", "plant_id": "lavender_english"}, | |
| "lemon_meyer": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืช ืจืืงืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmeyer_lemon", "plant_id": "lemon_meyer"}, | |
| "lettuce_romaine": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื", "ืจืืงืืื ืกืงืืจืืืื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dromaine_lettuce", "plant_id": "lettuce_romaine"}, | |
| "lettuce_iceberg": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Diceberg_lettuce", "plant_id": "lettuce_iceberg"}, | |
| "mint_peppermint": {"care_tips": ["ืฆื ืืืงื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpeppermint", "plant_id": "mint_peppermint"}, | |
| "mint_spearmint": {"care_tips": ["ืฆื ืืืงื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dspearmint", "plant_id": "mint_spearmint"}, | |
| "oak_white": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืงืืืืช ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dwhite_oak", "plant_id": "oak_white"}, | |
| "oak_red": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืงืืืืช ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dred_oak", "plant_id": "oak_red"}, | |
| "olive_black": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืืื ืืคืืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dblack_olive", "plant_id": "olive_black"}, | |
| "onion_red": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืืกืืกื ืคืืกืจืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dred_onion", "plant_id": "onion_red"}, | |
| "onion_sweet": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืงืืืืื ืืฆื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsweet_onion", "plant_id": "onion_sweet"}, | |
| "parsley_flat_leaf": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dflat_leaf_parsley", "plant_id": "parsley_flat_leaf"}, | |
| "peach_nectarine": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dnectarine", "plant_id": "peach_nectarine"}, | |
| "pear_anjo": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืงื ืืฉ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Danjo_pear", "plant_id": "pear_anjo"}, | |
| "pepper_bell": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืชื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbell_pepper", "plant_id": "pepper_bell"}, | |
| "pepper_jalapeno": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Djalapeno_pepper", "plant_id": "pepper_jalapeno"}, | |
| "plum_damson": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืงืฉืจ ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddamson_plum", "plant_id": "plum_damson"}, | |
| "potato_russet": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืื", "ืืืื ืืืืืจืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Drusset_potato", "plant_id": "potato_russet"}, | |
| "potato_yukon_gold": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dyukon_gold_potato", "plant_id": "potato_yukon_gold"}, | |
| "pumpkin_jack_o_lantern": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Djack_o_lantern_pumpkin", "plant_id": "pumpkin_jack_o_lantern"}, | |
| "raspberry_black": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืฉื ืชื"], "common_diseases": ["ืื ืชืจืงื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dblack_raspberry", "plant_id": "raspberry_black"}, | |
| "rose_hybrid_tea": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืชื ืฉืืืจ", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhybrid_tea_rose", "plant_id": "rose_hybrid_tea"}, | |
| "sage_common": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcommon_sage", "plant_id": "sage_common"}, | |
| "spinach_savoy": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื ืชืจื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsavoy_spinach", "plant_id": "spinach_savoy"}, | |
| "strawberry_everbearing": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืขืืืฉ ืืคืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Deverbearing_strawberry", "plant_id": "strawberry_everbearing"}, | |
| "sweet_potato_jewel": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Djewel_sweet_potato", "plant_id": "sweet_potato_jewel"}, | |
| "tomato_roma": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืื ืืืงืืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Droma_tomato", "plant_id": "tomato_roma"}, | |
| "tomato_beefsteak": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืื ืืืืืจืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbeefsteak_tomato", "plant_id": "tomato_beefsteak"}, | |
| "tulip_darwin_hybrid": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืืฆื ืคืืกืจืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddarwin_hybrid_tulip", "plant_id": "tulip_darwin_hybrid"}, | |
| "walnut_black": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dblack_walnut", "plant_id": "walnut_black"}, | |
| "watermelon": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืงืืืืื", "ืืชื ืขืืื", "ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dwatermelon", "plant_id": "watermelon"}, | |
| "watermelon_sugar_baby": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsugar_baby_watermelon", "plant_id": "watermelon_sugar_baby"}, | |
| "zucchini": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืืืจืืก ืคืกืืคืกืช ืืืืขืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dzucchini", "plant_id": "zucchini"}, | |
| "zucchini_black_beauty": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dblack_beauty_zucchini", "plant_id": "zucchini_black_beauty"}, | |
| "arborvitae": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืขืืื", "ืงืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Darborvitae", "plant_id": "arborvitae"}, | |
| "banana": {"care_tips": ["ืฉืืฉ ืืืื", "ืืงืืื ืืจืืคื", "ืงืจืงืข ืืื"], "common_diseases": ["ืงืืืืช ืคื ืื", "ืืชื ืกืืืืืืงื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbanana", "plant_id": "banana"}, | |
| "beech": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืงืจืงืข ืืื ืืื ืืงืืช"], "common_diseases": ["ืืืืช ืืืื ื ืืืจืืงืืืช", "ืืืืช ืืืื ื ืืืจืืคืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbeech", "plant_id": "beech"}, | |
| "beet": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbeet", "plant_id": "beet"}, | |
| "bok_choy": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืงืจืงืข ืืื"], "common_diseases": ["ืืืขืืื ืฉืืจืฉ", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbok_choy", "plant_id": "bok_choy"}, | |
| "cauliflower_romanesco": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื ืืื ื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dromanesco_cauliflower", "plant_id": "cauliflower_romanesco"}, | |
| "celery": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืชื ืขืืื ืืืงืื", "ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcelery", "plant_id": "celery"}, | |
| "chamomile": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืงืืืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dchamomile", "plant_id": "chamomile"}, | |
| "chive": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืกืืกื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dchive", "plant_id": "chive"}, | |
| "collard_greens": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืขืืื ืฉืืจืฉ", "ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcollard_greens", "plant_id": "collard_greens"}, | |
| "corn_indian": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื ื ืคืืฆื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dindian_corn", "plant_id": "corn_indian"}, | |
| "cranberry": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืืืืฆืืช", "ืืฉืงืื ืงืืืขื"], "common_diseases": ["ืงืืืื ืคืืกืจืืช", "ืจืืงืืื ืคืืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcranberry", "plant_id": "cranberry"}, | |
| "currant": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcurrant", "plant_id": "currant"}, | |
| "elderberry": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื", "ืจืืงืืื ืคืืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Delderberry", "plant_id": "elderberry"}, | |
| "endive": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dendive", "plant_id": "endive"}, | |
| "fennel": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dfennel", "plant_id": "fennel"}, | |
| "foxglove": {"care_tips": ["ืฆื ืืืงื", "ืงืจืงืข ืืื"], "common_diseases": ["ืืชื ืขืืื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dfoxglove", "plant_id": "foxglove"}, | |
| "gardenia": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืงืจืงืข ืืืืฆืืช", "ืืืืช ืืืืื"], "common_diseases": ["ืืชื ืฉืืืจ", "ืขืืืฉ ืืคืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgardenia", "plant_id": "gardenia"}, | |
| "ginger": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dginger", "plant_id": "ginger"}, | |
| "gooseberry": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgooseberry", "plant_id": "gooseberry"}, | |
| "hazelnut": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืงืคืื", "ืจืืงืืื ืขืฅ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhazelnut", "plant_id": "hazelnut"}, | |
| "honeysuckle": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืคืฆืขืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhoneysuckle", "plant_id": "honeysuckle"}, | |
| "iris": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืจื ืืืืืงื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Diris", "plant_id": "iris"}, | |
| "kohlrabi": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืขืืื ืฉืืจืฉ", "ืืืืื ืืื ื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dkohlrabi", "plant_id": "kohlrabi"}, | |
| "lemon_lime": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืช ืจืืงืืื", "ืื ืืืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dlemon_lime", "plant_id": "lemon_lime"}, | |
| "lettuce_butterhead": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbutterhead_lettuce", "plant_id": "lettuce_butterhead"}, | |
| "lettuce_leaf": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dleaf_lettuce", "plant_id": "lettuce_leaf"}, | |
| "lime": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืชืจ", "ืืชื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dlime", "plant_id": "lime"}, | |
| "mandarin": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืจ ืฉืืืจ", "ืขืืืฉ ืืคืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmandarin", "plant_id": "mandarin"}, | |
| "marigold": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmarigold", "plant_id": "marigold"}, | |
| "oat_rolled": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืงืจืงืขืืช ืืืืช"], "common_diseases": ["ืืืืืช ืืืชืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Drolled_oat", "plant_id": "oat_rolled"}, | |
| "olive_green": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืืื ืืคืืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgreen_olive", "plant_id": "olive_green"}, | |
| "onion_white": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืืกืืกื ืคืืกืจืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dwhite_onion", "plant_id": "onion_white"}, | |
| "orange": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืชืจ", "ืืืืช ืจืืงืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dorange", "plant_id": "orange"}, | |
| "orange_navel": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืชืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dnavel_orange", "plant_id": "orange_navel"}, | |
| "orange_valencia": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืชืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dvalencia_orange", "plant_id": "orange_valencia"}, | |
| "papaya": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช ืืืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืืืจืืก ืืืขืช ืคืกืืคืกืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpapaya", "plant_id": "papaya"}, | |
| "parsley_curly": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcurly_parsley", "plant_id": "parsley_curly"}, | |
| "peach_white": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dwhite_peach", "plant_id": "peach_white"}, | |
| "pecan_paper_shell": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืื ืคืงืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpaper_shell_pecan", "plant_id": "pecan_paper_shell"}, | |
| "pepper_cayenne": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืชื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcayenne_pepper", "plant_id": "pepper_cayenne"}, | |
| "pepper_habanero": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhabanero_pepper", "plant_id": "pepper_habanero"}, | |
| "pepper_poblano": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืืจืืก ืคืกืืคืกืช ืคืืคื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpoblano_pepper", "plant_id": "pepper_poblano"}, | |
| "pistachio": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืื", "ืจืืงืืื ืคืืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpistachio", "plant_id": "pistachio"}, | |
| "potato_red": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dred_potato", "plant_id": "potato_red"}, | |
| "pumpkin_pie": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpie_pumpkin", "plant_id": "pumpkin_pie"}, | |
| "quince": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืงื ืืฉ", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dquince", "plant_id": "quince"}, | |
| "rose_floribunda": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืชื ืฉืืืจ", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dfloribunda_rose", "plant_id": "rose_floribunda"}, | |
| "safflower": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืืืื", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsafflower", "plant_id": "safflower"}, | |
| "shallot": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืืืืื", "ืจืืงืืื ืฆืืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dshallot", "plant_id": "shallot"}, | |
| "sorghum": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืขืืืฉ ืจืืฉ", "ืืืืื", "ืงืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsorghum", "plant_id": "sorghum"}, | |
| "soybean": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืื", "ืจืืงืืื ืืืข"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsoybean", "plant_id": "soybean"}, | |
| "spinach_new_zealand": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืื ืืื ื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dnew_zealand_spinach", "plant_id": "spinach_new_zealand"}, | |
| "squash_butternut": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื", "ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbutternut_squash", "plant_id": "squash_butternut"}, | |
| "strawberry_alpine": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืขืืืฉ ืืคืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dalpine_strawberry", "plant_id": "strawberry_alpine"}, | |
| "sunflower_confection": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dconfection_sunflower", "plant_id": "sunflower_confection"}, | |
| "thyme_lemon": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dlemon_thyme", "plant_id": "thyme_lemon"}, | |
| "tomato_grape": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืื ืืืงืืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgrape_tomato", "plant_id": "tomato_grape"}, | |
| "turnip": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืื ืืื ื", "ืืืขืืื ืฉืืจืฉ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dturnip", "plant_id": "turnip"}, | |
| "vanilla": {"care_tips": ["ืฆื ืืืงื", "ืืืืช ืืืืื"], "common_diseases": ["ืจืืงืืื ืืืข", "ืื ืชืจืงื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dvanilla", "plant_id": "vanilla"}, | |
| "watermelon_seeded": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dseeded_watermelon", "plant_id": "watermelon_seeded"}, | |
| "wheat": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืืืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dwheat", "plant_id": "wheat"}, | |
| "zucchini_yellow_squash": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dyellow_squash", "plant_id": "zucchini_yellow_squash"}, | |
| "alyssum": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dalyssum", "plant_id": "alyssum"}, | |
| "anemone": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืงืจืงืข ืืื"], "common_diseases": ["ืืืืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Danemone", "plant_id": "anemone"}, | |
| "apple_pink_lady": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืื ืืชืคืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpink_lady_apple", "plant_id": "apple_pink_lady"}, | |
| "artemisia": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dartemisia", "plant_id": "artemisia"}, | |
| "azalea_mollis": {"care_tips": ["ืฆื ืืืงื", "ืงืจืงืข ืืืืฆืืช"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmollis_azalea", "plant_id": "azalea_mollis"}, | |
| "balsam": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืจืืงืืื ืืืข"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbalsam", "plant_id": "balsam"}, | |
| "basil_lemon": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dlemon_basil", "plant_id": "basil_lemon"}, | |
| "blackberry": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืฉื ืชื"], "common_diseases": ["ืื ืชืจืงื ืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dblackberry", "plant_id": "blackberry"}, | |
| "boxwood": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืงืืืื ืคืืกืจืืช", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dboxwood", "plant_id": "boxwood"}, | |
| "canna": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื", "ืืืจืืก ืคืกืืคืกืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcanna", "plant_id": "canna"}, | |
| "carnation": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืืืื", "ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcarnation", "plant_id": "carnation"}, | |
| "cherry_bing": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbing_cherry", "plant_id": "cherry_bing"}, | |
| "chrysanthemum": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dchrysanthemum", "plant_id": "chrysanthemum"}, | |
| "clematis": {"care_tips": ["ืฉืืฉ ืืืื ืื ืืืงืืช", "ืงืจืงืข ืงืจืืจื"], "common_diseases": ["ืงืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dclematis", "plant_id": "clematis"}, | |
| "crocus": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืืฆื", "ืืืจืืก"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcrocus", "plant_id": "crocus"}, | |
| "dahlia": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืืืจืืก ืคืกืืคืกืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddahlia", "plant_id": "dahlia"}, | |
| "daisy": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddaisy", "plant_id": "daisy"}, | |
| "dogwood": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืชืจืงื ืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddogwood", "plant_id": "dogwood"}, | |
| "echinacea": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืชื ืขืืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dechinacea", "plant_id": "echinacea"}, | |
| "eucalyptus": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืืืื", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Deucalyptus", "plant_id": "eucalyptus"}, | |
| "forsythia": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืืชืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dforsythia", "plant_id": "forsythia"}, | |
| "geranium_zonal": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dzonal_geranium", "plant_id": "geranium_zonal"}, | |
| "ginger_butterfly": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbutterfly_ginger", "plant_id": "ginger_butterfly"}, | |
| "gladiolus": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืืืืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgladiolus", "plant_id": "gladiolus"}, | |
| "grape_cabernet_sauvignon": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืงืืืข"], "common_diseases": ["ืงืืืืื", "ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcabernet_sauvignon", "plant_id": "grape_cabernet_sauvignon"}, | |
| "holly": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dholly", "plant_id": "holly"}, | |
| "hydrangea": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืชื ืขืืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhydrangea", "plant_id": "hydrangea"}, | |
| "iris_bearded": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืจื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbearded_iris", "plant_id": "iris_bearded"}, | |
| "kiwi_golden": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืื ืงื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgolden_kiwi", "plant_id": "kiwi_golden"}, | |
| "lemon_eureka": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืช ืจืืงืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Deureka_lemon", "plant_id": "lemon_eureka"}, | |
| "lettuce_leaf_red": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dred_leaf_lettuce", "plant_id": "lettuce_leaf_red"}, | |
| "lilac_common": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืืืืจ ืคืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcommon_lilac", "plant_id": "lilac_common"}, | |
| "lily_asiatic": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืืจืืก ืืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dasiatic_lily", "plant_id": "lily_asiatic"}, | |
| "lily_oriental": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืืจืืก ืืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Doriental_lily", "plant_id": "lily_oriental"}, | |
| "linden": {"care_tips": ["ืฉืืฉ ืืืื ืื ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืื ืืจืืืฆืืืืช", "ืื ืชืจืงื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dlinden", "plant_id": "linden"}, | |
| "mango_ataulfo": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืชืจืงื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dataulfo_mango", "plant_id": "mango_ataulfo"}, | |
| "marjoram": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmarjoram", "plant_id": "marjoram"}, | |
| "melaleuca": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmelaleuca", "plant_id": "melaleuca"}, | |
| "mint_chocolate": {"care_tips": ["ืฆื ืืืงื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dchocolate_mint", "plant_id": "mint_chocolate"}, | |
| "morning_glory": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืชื ืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmorning_glory", "plant_id": "morning_glory"}, | |
| "nasturtium": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืืืจืืก ืคืกืืคืกืช", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dnasturtium", "plant_id": "nasturtium"}, | |
| "oak_pin": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืงืืืืช ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpin_oak", "plant_id": "oak_pin"}, | |
| "oregano_greek": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืืืืื ื ืขื ืข"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgreek_oregano", "plant_id": "oregano_greek"}, | |
| "pansy": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpansy", "plant_id": "pansy"}, | |
| "passion_fruit_purple": {"care_tips": ["ืฉืืฉ ืืืื", "ืชืืืื ืืืืคืืก"], "common_diseases": ["ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpurple_passion_fruit", "plant_id": "passion_fruit_purple"}, | |
| "pear_bartlett": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืงื ืืฉ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbartlett_pear", "plant_id": "pear_bartlett"}, | |
| "pecan_elliott": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืื ืคืงืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Delliott_pecan", "plant_id": "pecan_elliott"}, | |
| "pepper_chili": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืืจืืก ืคืกืืคืกืช ืคืืคื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dchili_pepper", "plant_id": "pepper_chili"}, | |
| "pine_scots": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dscots_pine", "plant_id": "pine_scots"}, | |
| "pomegranate_wonderful": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืชื ืคืจื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dwonderful_pomegranate", "plant_id": "pomegranate_wonderful"}, | |
| "potato_sweet": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsweet_potato", "plant_id": "potato_sweet"}, | |
| "pumpkin_mini": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmini_pumpkin", "plant_id": "pumpkin_mini"}, | |
| "radish": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืขืืื ืฉืืจืฉ", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dradish", "plant_id": "radish"}, | |
| "rhubarb": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืชืจ", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Drhubarb", "plant_id": "rhubarb"}, | |
| "rose_climbing": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืชื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dclimbing_rose", "plant_id": "rose_climbing"}, | |
| "sage_purple": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpurple_sage", "plant_id": "sage_purple"}, | |
| "squash_acorn": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dacorn_squash", "plant_id": "squash_acorn"}, | |
| "strawberry_june_bearing": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืขืืืฉ ืืคืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Djune_bearing_strawberry", "plant_id": "strawberry_june_bearing"}, | |
| "thyme_creeping": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcreeping_thyme", "plant_id": "thyme_creeping"}, | |
| "tomato_san_marzano": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืื ืืืงืืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsan_marzano_tomato", "plant_id": "tomato_san_marzano"}, | |
| "tulip_parrot": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืืืจืืก ืฉืืืจืช ืืฆืืข"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dparrot_tulip", "plant_id": "tulip_parrot"}, | |
| "valerian": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืืื"], "common_diseases": ["ืืืืื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dvalerian", "plant_id": "valerian"}, | |
| "walnut_english": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Denglish_walnut", "plant_id": "walnut_english"}, | |
| "water_lily": {"care_tips": ["ืฉืืฉ ืืืื", "ืืื ืืชืืงืื"], "common_diseases": ["ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dwater_lily", "plant_id": "water_lily"}, | |
| "yarrow": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dyarrow", "plant_id": "yarrow"}, | |
| "yucca": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืชื ืขืืื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dyucca", "plant_id": "yucca"}, | |
| "agapanthus": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืจืืงืืื ืืชืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dagapanthus", "plant_id": "agapanthus"}, | |
| "anise": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Danise", "plant_id": "anise"}, | |
| "aralia": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Daralia", "plant_id": "aralia"}, | |
| "artichoke_globe": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืจืืงืืื ืืชืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dglobe_artichoke", "plant_id": "artichoke_globe"}, | |
| "aster": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Daster", "plant_id": "aster"}, | |
| "asparagus_fern": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dasparagus_fern", "plant_id": "asparagus_fern"}, | |
| "borage": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dborage", "plant_id": "borage"}, | |
| "broccoli_raab": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbroccoli_raab", "plant_id": "broccoli_raab"}, | |
| "cabbage_napa": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืขืืื ืฉืืจืฉ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dnapa_cabbage", "plant_id": "cabbage_napa"}, | |
| "caladium": {"care_tips": ["ืฆื ืืื", "ืืืืช ืืืืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcaladium", "plant_id": "caladium"}, | |
| "camphor": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcamphor", "plant_id": "camphor"}, | |
| "celosia": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืจืืงืืื ืืืข"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcelosia", "plant_id": "celosia"}, | |
| "chive_garlic": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืกืืกื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgarlic_chive", "plant_id": "chive_garlic"}, | |
| "citronella": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcitronella", "plant_id": "citronella"}, | |
| "cranesbill": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcranesbill", "plant_id": "cranesbill"}, | |
| "creeping_myrtle": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcreeping_myrtle", "plant_id": "creeping_myrtle"}, | |
| "daffodil_jonquil": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืืกืืกื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Djonquil_daffodil", "plant_id": "daffodil_jonquil"}, | |
| "daisy_shasta": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dshasta_daisy", "plant_id": "daisy_shasta"}, | |
| "dandelion": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืืืื ืืื ื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddandelion", "plant_id": "dandelion"}, | |
| "dianthus": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืืืื", "ืจืืงืืื ืืชืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddianthus", "plant_id": "dianthus"}, | |
| "dracaena": {"care_tips": ["ืืืจ ืื ืืฉืืจ", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืชื ืขืืื", "ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddracaena", "plant_id": "dracaena"}, | |
| "echinacea_purpurea": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dechinacea_purpurea", "plant_id": "echinacea_purpurea"}, | |
| "feverfew": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dfeverfew", "plant_id": "feverfew"}, | |
| "gardenia_cape_jasmine": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืงืจืงืข ืืืืฆืืช"], "common_diseases": ["ืืชื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcape_jasmine_gardenia", "plant_id": "gardenia_cape_jasmine"}, | |
| "goldenrod": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืงืืืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgoldenrod", "plant_id": "goldenrod"}, | |
| "gooseberry_jostaberry": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Djostaberry", "plant_id": "gooseberry_jostaberry"}, | |
| "grape_chardonnay": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืงืืืข"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dchardonnay_grape", "plant_id": "grape_chardonnay"}, | |
| "holly_american": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Damerican_holly", "plant_id": "holly_american"}, | |
| "honeysuckle_vine": {"care_tips": ["ืฉืืฉ ืืืื ืื ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhoneysuckle_vine", "plant_id": "honeysuckle_vine"}, | |
| "hyssop": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืืืืื", "ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhyssop", "plant_id": "hyssop"}, | |
| "iris_dutch": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืืฆื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddutch_iris", "plant_id": "iris_dutch"}, | |
| "kale": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืขืืื ืฉืืจืฉ", "ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dkale", "plant_id": "kale"}, | |
| "kiwi_fuzzy": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืจืืงืืื ืืชืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dfuzzy_kiwi", "plant_id": "kiwi_fuzzy"}, | |
| "lavender_french": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dfrench_lavender", "plant_id": "lavender_french"}, | |
| "lemon_pink_eureka": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืช ืจืืงืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpink_eureka_lemon", "plant_id": "lemon_pink_eureka"}, | |
| "lettuce_bibb": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbibb_lettuce", "plant_id": "lettuce_bibb"}, | |
| "magnolia_star": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dstar_magnolia", "plant_id": "magnolia_star"}, | |
| "mango_kent": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืชืจืงื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dkent_mango", "plant_id": "mango_kent"}, | |
| "maple_sugar": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืืคืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsugar_maple", "plant_id": "maple_sugar"}, | |
| "melon_galia": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgalia_melon", "plant_id": "melon_galia"}, | |
| "mint_apple": {"care_tips": ["ืฆื ืืืงื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dapple_mint", "plant_id": "mint_apple"}, | |
| "myrtle_crape": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcrape_myrtle", "plant_id": "myrtle_crape"}, | |
| "narcissus": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืืฆื", "ืืืจืืก"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dnarcissus", "plant_id": "narcissus"}, | |
| "oak_live": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืงืืืืช ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dlive_oak", "plant_id": "oak_live"}, | |
| "orange_blood": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืชืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dblood_orange", "plant_id": "orange_blood"}, | |
| "paprika": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืชื ืืืืืงื", "ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpaprika", "plant_id": "paprika"}, | |
| "parsley_italian": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ditalian_parsley", "plant_id": "parsley_italian"}, | |
| "peach_flat": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dflat_peach", "plant_id": "peach_flat"}, | |
| "pecan_cheyenne": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืื ืคืงืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcheyenne_pecan", "plant_id": "pecan_cheyenne"}, | |
| "pepper_ghost": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dghost_pepper", "plant_id": "pepper_ghost"}, | |
| "petunia_wave": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dwave_petunia", "plant_id": "petunia_wave"}, | |
| "pine_eastern_white": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืืืื", "ืงืืืื ืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Deastern_white_pine", "plant_id": "pine_eastern_white"}, | |
| "plum_japanese": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Djapanese_plum", "plant_id": "plum_japanese"}, | |
| "pomegranate_pink": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืชื ืคืจื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpink_pomegranate", "plant_id": "pomegranate_pink"}, | |
| "potato_fingerling": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dfingerling_potato", "plant_id": "potato_fingerling"}, | |
| "pumpkin_sugar": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsugar_pumpkin", "plant_id": "pumpkin_sugar"}, | |
| "quinoa_red": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dred_quinoa", "plant_id": "quinoa_red"}, | |
| "raspberry_red": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืฉื ืชื"], "common_diseases": ["ืื ืชืจืงื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dred_raspberry", "plant_id": "raspberry_red"}, | |
| "rose_miniature": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืชื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dminiature_rose", "plant_id": "rose_miniature"}, | |
| "rosemary_prostrate": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dprostrate_rosemary", "plant_id": "rosemary_prostrate"}, | |
| "saffron_crocus": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืืฆื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsaffron_crocus", "plant_id": "saffron_crocus"}, | |
| "spinach_perpetual": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื ืชืจื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dperpetual_spinach", "plant_id": "spinach_perpetual"}, | |
| "squash_spaghetti": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื", "ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dspaghetti_squash", "plant_id": "squash_spaghetti"}, | |
| "sunflower_tall": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dtall_sunflower", "plant_id": "sunflower_tall"}, | |
| "sweet_potato_purple": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpurple_sweet_potato", "plant_id": "sweet_potato_purple"}, | |
| "thyme_common": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืืืข"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcommon_thyme", "plant_id": "thyme_common"}, | |
| "tomato_brandywine": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืื ืืืืืจืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbrandywine_tomato", "plant_id": "tomato_brandywine"}, | |
| "verbena": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืงืืืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dverbena", "plant_id": "verbena"}, | |
| "wheat_durum": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddurum_wheat", "plant_id": "wheat_durum"}, | |
| "zinnia": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dzinnia", "plant_id": "zinnia"}, | |
| "anemone_coronaria": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืงืจืงืข ืืื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Danemone_coronaria", "plant_id": "anemone_coronaria"}, | |
| "apple_honeycrisp": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืื ืืชืคืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhoneycrisp_apple", "plant_id": "apple_honeycrisp"}, | |
| "apple_macintosh": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืืื ืืชืคืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmacintosh_apple", "plant_id": "apple_macintosh"}, | |
| "avocado_reed": {"care_tips": ["ืฉืืฉ ืืืื", "ืืื ื ืืจืื ืืืงื"], "common_diseases": ["ืืชื ืฉืืฉ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dreed_avocado", "plant_id": "avocado_reed"}, | |
| "basil_genovese": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgenovese_basil", "plant_id": "basil_genovese"}, | |
| "bean_lima": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dlima_bean", "plant_id": "bean_lima"}, | |
| "bean_snap": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืชืจืงื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsnap_bean", "plant_id": "bean_snap"}, | |
| "beet_sugar": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsugar_beet", "plant_id": "beet_sugar"}, | |
| "bellflower": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbellflower", "plant_id": "bellflower"}, | |
| "cabbage_savoy": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืขืืื ืฉืืจืฉ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsavoy_cabbage", "plant_id": "cabbage_savoy"}, | |
| "calla_lily": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืจืืงืืื ืจื", "ืืืจืืก"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcalla_lily", "plant_id": "calla_lily"}, | |
| "camellia_sinensis": {"care_tips": ["ืฆื ืืืงื", "ืืฉืงืื ืงืืืขื"], "common_diseases": ["ืื ืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcamellia_sinensis", "plant_id": "camellia_sinensis"}, | |
| "cannabis": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืขืืืฉ ืืคืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcannabis", "plant_id": "cannabis"}, | |
| "castor_bean": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcastor_bean", "plant_id": "castor_bean"}, | |
| "cherry_rainier": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Drainier_cherry", "plant_id": "cherry_rainier"}, | |
| "chrysanthemum_garden": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgarden_chrysanthemum", "plant_id": "chrysanthemum_garden"}, | |
| "coleus": {"care_tips": ["ืฆื ืืืงื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcoleus", "plant_id": "coleus"}, | |
| "corn_dent": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืืืื ื ืคืืฆื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddent_corn", "plant_id": "corn_dent"}, | |
| "cranberry_american": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืืืืฆืืช"], "common_diseases": ["ืจืืงืืื ืคืืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Damerican_cranberry", "plant_id": "cranberry_american"}, | |
| "cucumber_english": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืงืืืช"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Denglish_cucumber", "plant_id": "cucumber_english"}, | |
| "daisy_gerbera": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgerbera_daisy", "plant_id": "daisy_gerbera"}, | |
| "date_palm_deglet_noor": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddeglet_noor_date_palm", "plant_id": "date_palm_deglet_noor"}, | |
| "delphinium": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืงืืืืื", "ืจืืงืืื ืืชืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddelphinium", "plant_id": "delphinium"}, | |
| "dogwood_flowering": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืชืจืงื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dflowering_dogwood", "plant_id": "dogwood_flowering"}, | |
| "fern_maidenhair": {"care_tips": ["ืฆื ืืื", "ืืืืช ืืืืื"], "common_diseases": ["ื ืืืืืืช ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmaidenhair_fern", "plant_id": "fern_maidenhair"}, | |
| "ficus_lyrata": {"care_tips": ["ืืืจ ืื ืืฉืืจ", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dficus_lyrata", "plant_id": "ficus_lyrata"}, | |
| "garlic_elephant": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Delephant_garlic", "plant_id": "garlic_elephant"}, | |
| "grape_merlot": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืงืืืข"], "common_diseases": ["ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmerlot_grape", "plant_id": "grape_merlot"}, | |
| "hazelnut_filbert": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืงืคืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dfilbert_hazelnut", "plant_id": "hazelnut_filbert"}, | |
| "hibiscus_syriacus": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืช ืืืืืกืงืืก"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhibiscus_syriacus", "plant_id": "hibiscus_syriacus"}, | |
| "hollyhock": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dhollyhock", "plant_id": "hollyhock"}, | |
| "hydrangea_oakleaf": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Doakleaf_hydrangea", "plant_id": "hydrangea_oakleaf"}, | |
| "iris_siberian": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืจื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsiberian_iris", "plant_id": "iris_siberian"}, | |
| "kale_lacinato": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืขืืื ืฉืืจืฉ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dlacinato_kale", "plant_id": "kale_lacinato"}, | |
| "kiwi_arctic_beauty": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืื ืงื ืืืืืงื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Darctic_beauty_kiwi", "plant_id": "kiwi_arctic_beauty"}, | |
| "lemon_ponzu": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืืช ืจืืงืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dponzu_lemon", "plant_id": "lemon_ponzu"}, | |
| "lettuce_mesclun": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmesclun_lettuce", "plant_id": "lettuce_mesclun"}, | |
| "lilac_dwarf": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืืืืจ ืคืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddwarf_lilac", "plant_id": "lilac_dwarf"}, | |
| "magnolia_southern": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืฆื ืืืงื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsouthern_magnolia", "plant_id": "magnolia_southern"}, | |
| "maple_japanese": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืื ืืจืืืฆืืืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Djapanese_maple", "plant_id": "maple_japanese"}, | |
| "melissa": {"care_tips": ["ืฉืืฉ ืืืื ืขื ืืืงืืช", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื", "ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmelissa", "plant_id": "melissa"}, | |
| "mint_catnip": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dcatnip_mint", "plant_id": "mint_catnip"}, | |
| "oak_bur": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืงืืืืช ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbur_oak", "plant_id": "oak_bur"}, | |
| "orange_mandarin": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืชืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmandarin_orange", "plant_id": "orange_mandarin"}, | |
| "papaya_solo": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsolo_papaya", "plant_id": "papaya_solo"}, | |
| "pea_sugar_snap": {"care_tips": ["ืฉืืฉ ืืืงืืช", "ืงืจืงืข ืงืจืืจื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsugar_snap_pea", "plant_id": "pea_sugar_snap"}, | |
| "peach_donut": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddonut_peach", "plant_id": "peach_donut"}, | |
| "pepper_banana": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืืจืืก ืคืกืืคืกืช ืคืืคื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbanana_pepper", "plant_id": "pepper_banana"}, | |
| "petunia_super_tunia": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsuper_tunia_petunia", "plant_id": "petunia_super_tunia"}, | |
| "pine_loblolly": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dloblolly_pine", "plant_id": "pine_loblolly"}, | |
| "plum_greengage": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืื ืื ืืช"], "common_diseases": ["ืจืืงืืื ืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dgreengage_plum", "plant_id": "plum_greengage"}, | |
| "pomegranate_kazake": {"care_tips": ["ืฉืืฉ ืืืื", "ืขืืื ืืืฆืืจืช"], "common_diseases": ["ืืชื ืคืจื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dkazake_pomegranate", "plant_id": "pomegranate_kazake"}, | |
| "potato_sweet_red": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dred_sweet_potato", "plant_id": "potato_sweet_red"}, | |
| "pumpkin_blue_hubbard": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dblue_hubbard_pumpkin", "plant_id": "pumpkin_blue_hubbard"}, | |
| "quince_orange": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืื ืงื ืืฉ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dorange_quince", "plant_id": "quince_orange"}, | |
| "raspberry_black_cap": {"care_tips": ["ืฉืืฉ ืืืื", "ืืืืื ืฉื ืชื"], "common_diseases": ["ืื ืชืจืงื ืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dblack_cap_raspberry", "plant_id": "raspberry_black_cap"}, | |
| "rhododendron_pjm": {"care_tips": ["ืฆื ืืืงื", "ืงืจืงืข ืืืืฆืืช"], "common_diseases": ["ืืชื ืขืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpjm_rhododendron", "plant_id": "rhododendron_pjm"}, | |
| "rice_basmati": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืืื ืืืืืื"], "common_diseases": ["ืคืืฆืืฅ ืืืจื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbasmati_rice", "plant_id": "rice_basmati"}, | |
| "rose_knockout": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืขืืืงื"], "common_diseases": ["ืืชื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dknockout_rose", "plant_id": "rose_knockout"}, | |
| "rosemary_tuscan_blue": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dtuscan_blue_rosemary", "plant_id": "rosemary_tuscan_blue"}, | |
| "sage_tri_color": {"care_tips": ["ืฉืืฉ ืืืื", "ืงืจืงืข ืื ืืงืืช"], "common_diseases": ["ืงืืืื ืคืืกืจืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dtri_color_sage", "plant_id": "sage_tri_color"}, | |
| "spinach_malabar": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dmalabar_spinach", "plant_id": "spinach_malabar"}, | |
| "squash_pattypan": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dpattypan_squash", "plant_id": "squash_pattypan"}, | |
| "strawberry_dayneutral": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืจืืื"], "common_diseases": ["ืขืืืฉ ืืคืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Ddayneutral_strawberry", "plant_id": "strawberry_dayneutral"}, | |
| "sweet_potato_beauregard": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืจืืงืืื ืฉืืืจ"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dbeauregard_sweet_potato", "plant_id": "sweet_potato_beauregard"}, | |
| "thyme_silver": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืฉืืจืฉืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dsilver_thyme", "plant_id": "thyme_silver"}, | |
| "tomato_amish_paste": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืกืืืจื"], "common_diseases": ["ืืืื ืืืงืืืช"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Damish_paste_tomato", "plant_id": "tomato_amish_paste"}, | |
| "tulip_triumph": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืืขืื"], "common_diseases": ["ืจืืงืืื ืืฆื ืคืืกืจืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dtriumph_tulip", "plant_id": "tulip_triumph"}, | |
| "vanilla_planifolia": {"care_tips": ["ืฆื ืืืงื", "ืืืืช ืืืืื"], "common_diseases": ["ืจืืงืืื ืืืข"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dvanilla_planifolia", "plant_id": "vanilla_planifolia"}, | |
| "verbena_perennial": {"care_tips": ["ืฉืืฉ ืืืื", "ืืฉืงืื ืืชืื ื"], "common_diseases": ["ืงืืืืื"], "img_url": "https://www.google.com/searchq=https://placehold.co/600x400/000000/FFFFFF%3Ftext%3Dperennial_verbena", "plant_id": "verbena_perennial"} | |
| } | |
| MODEL_WEIGHTS = {} | |
| last_analysis_details: Optional[Dict] = None | |
| # Keywords to filter from both Species AND Health | |
| # Keywords that generally refer to non-plant objects, environment, or general concepts. | |
| NON_PLANT_KEYWORDS = [ | |
| 'pot', 'label', 'background', 'hand', 'unhealthy', 'unknown', 'drop', | |
| 'daisy', 'nursery', 'glasshouse', 'cliff', 'picket', 'fence', 'vase', | |
| 'barrow', 'garden cart', 'lawn cart', 'wheelbarrow', 'fire screen', | |
| 'fireguard', 'castle', 'viaduct', 'watering can', 'shovel', 'trowel', | |
| 'rake', 'hoe', 'pruner', 'shears', 'mower', 'sprayer', 'trellis', | |
| 'stake', 'wire cage', 'planter box', 'raised bed', 'compost bin', | |
| 'garden hose', 'gloves', 'boots', 'bird bath', 'gnome', 'bench', | |
| 'patio furniture', 'fountain', 'scarecrow', 'sun dial', 'seeder', | |
| 'sundial', 'deck', 'porch', 'balcony', 'shed', 'greenhouse', 'pergola', | |
| 'arbor', 'gazebo', 'wall', 'brick', 'stone', 'pavement', 'concrete', | |
| 'dirt', 'soil', 'sand', 'gravel', 'sky', 'clouds', 'sunshine', | |
| 'shadow', 'mountain', 'river', 'lake', 'stream', 'pathway', 'walkway', | |
| 'door', 'window', 'roof', 'chimney', 'lamp post', 'street light', | |
| 'human', 'animal', 'insect', 'bird', 'cat', 'dog', 'man', 'woman', | |
| 'child', 'texture', 'pattern', 'color', 'blur', 'pixel', 'reflection', | |
| 'water droplet', 'rain', 'snow', 'frost', 'dew', 'person', 'tool', | |
| 'equipment', 'appliance', 'flower', 'tree', 'bush', 'shrub', 'weed', | |
| 'grass', 'leaf', 'stem', 'root' | |
| ] | |
| # NEW: Disease/condition keywords - only these are allowed in Health predictions (Expanded List) | |
| DISEASE_KEYWORDS = [ | |
| 'disease', 'healthy', 'unhealthy', 'sickness', 'infection', 'pathogen', | |
| 'syndrome', 'disorder', 'malaise', 'decline', 'symptom', 'sign', | |
| 'mortality', 'morbidity', 'prevention', 'cure', 'treatment', 'blight', | |
| 'rust', 'rot', 'mold', 'mildew', 'wilt', 'spot', 'scab', 'canker', | |
| 'lesion', 'necrosis', 'chlorosis', 'mosaic', 'virus', 'bacterial', | |
| 'fungal', 'oomycete', 'viroid', 'phytoplasma', 'nematode', 'mycoplasma', | |
| 'parasite', 'saprophyte', 'obligate', 'facultative', 'systemic', | |
| 'localized', 'dieback', 'galls', 'tumors', 'pustules', 'ooze', | |
| 'exudate', 'stunting', 'dwarfing', 'etiolation', 'deformation', | |
| 'distortion', 'yellowing', 'browning', 'blackening', 'whitening', | |
| 'reddening', 'bronzing', 'margin', 'veinal', 'interveinal', 'hole', | |
| 'tear', 'chewing', 'mining', 'pest', 'insect', 'mite', 'aphid', | |
| 'thrips', 'whitefly', 'scale', 'mealybug', 'caterpillar', 'grub', | |
| 'borer', 'leafhopper', 'spider', 'snail', 'slug', 'weevil', 'locust', | |
| 'earwig', 'cutworm', 'armyworm', 'fungus gnat', 'webbing', 'gall former', | |
| 'powdery', 'downy', 'anthracnose', 'septoria', 'phytophthora', | |
| 'fusarium', 'verticillium', 'pythium', 'botrytis', 'alternaria', | |
| 'cercospora', 'xanthomonas', 'pseudomonas', 'erwinia', 'agrobacterium', | |
| 'rhizoctonia', 'sclerotinia', 'plasmopara', 'peronospora', 'unCinula', | |
| 'oidium', 'taphrina', 'meloidogyne', 'deficiency', 'toxicity', | |
| 'nutritional', 'nitrogen', 'phosphorus', 'potassium', 'iron', | |
| 'magnesium', 'calcium', 'sulfur', 'manganese', 'zinc', 'copper', | |
| 'boron', 'molybdenum', 'over-fertilization', 'salt burn', 'pH imbalance', | |
| 'stress', 'damage', 'drought', 'waterlogging', 'overwatering', | |
| 'underwatering', 'heat', 'cold', 'frost', 'sun', 'burn', 'scald', | |
| 'windburn', 'hail', 'lightning', 'mechanical', 'chemical', 'herbicide', | |
| 'air pollution', 'ozone', 'acid rain', 'transplant shock', 'girdling', | |
| 'lodging', 'edema', 'early', 'late', 'leaf', 'stem', 'root', | |
| 'flower', 'fruit', 'bud', 'twig', 'branch', 'trunk', 'crown', | |
| 'vascular', 'xylem', 'phloem', 'black', 'brown', 'yellow', 'white', | |
| 'gray', 'grey' | |
| ] | |
| # Plant names to filter from Health predictions (Extremely common ones) | |
| PLANT_NAMES_TO_FILTER = [ | |
| 'tomato', 'potato', 'apple', 'grape', 'corn', 'wheat', 'rice', 'pepper', | |
| 'strawberry', 'raspberry', 'blueberry', 'cherry', 'peach', 'rose', 'oak', | |
| 'pine', 'maple', 'bean', 'pea', 'cucumber', 'lettuce', 'cabbage', 'carrot', | |
| 'onion', 'garlic', 'spinach', 'broccoli', 'cauliflower', 'squash', | |
| 'pumpkin', 'zucchini', 'eggplant', 'sweet potato', 'sugar beet', | |
| 'soybean', 'alfalfa', 'oat', 'barley', 'rye', 'millet', 'canola', | |
| 'cotton', 'tobacco', 'sunflower', 'artichoke', 'asparagus', 'celery', | |
| 'radish', 'turnip', 'kohlrabi', 'blackberry', 'cranberry', 'currant', | |
| 'gooseberry', 'fig', 'kiwi', 'pomegranate', 'pear', 'plum', 'apricot', | |
| 'lemon', 'orange', 'lime', 'grapefruit', 'mandarin', 'avocado', 'mango', | |
| 'banana', 'coconut', 'olive', 'almond', 'walnut', 'pecan', 'date', | |
| 'persimmon', 'cedar', 'fir', 'spruce', 'willow', 'birch', 'beech', 'elm', | |
| 'ash', 'sycamore', 'poplar', 'eucalyptus', 'redwood', 'magnolia', | |
| 'dogwood', 'holly', 'linden', 'hickory', 'tulip', 'daffodil', 'lily', | |
| 'iris', 'zinnia', 'marigold', 'petunia', 'geranium', 'chrysanthemum', | |
| 'orchid', 'hydrangea', 'azalea', 'rhododendron', 'carnation', | |
| 'gardenia', 'jasmine', 'lavender', 'peony', 'dahlia', 'begonia', | |
| 'cyclamen', 'pothos', 'fern', 'ivy', 'succulent', 'cactus' | |
| ] | |
| # ======================================================== | |
| # CURATED AI MODELS - USER WILL INSERT THEIR MODELS | |
| # ======================================================== | |
| PLANT_AI_MODELS = { #// ============ TIER 1: Core Species & Taxonomy Experts ============ | |
| "PlantNet-Species-Expert": { | |
| "model_id": "google/vit-large-patch16-224-in21k", | |
| "specialty": "Species|Taxonomy", | |
| "reliability": 0.95, | |
| "priority": 1, | |
| "description": "Elite model for botanical species identification" | |
| }, | |
| "PlantCLEF-Advanced": { | |
| "model_id": "microsoft/swinv2-base-patch4-window12to16-192to256-22kto1k-ft", | |
| "specialty": "Species|Wild Flora", | |
| "reliability": 0.93, | |
| "priority": 2, | |
| "description": "Specialized in wild and cultivated plant species" | |
| }, | |
| "Flora-Vision-v2": { | |
| "model_id": "facebook/deit-base-distilled-patch16-224", | |
| "specialty": "Species|Garden|Agricultural", | |
| "reliability": 0.91, | |
| "priority": 3, | |
| "description": "Optimized for garden and agricultural plants" | |
| }, | |
| "Plant-ViT-Base": { | |
| "model_id": "google/vit-base-patch16-224-in21k", | |
| "specialty": "Species|General Flora", | |
| "reliability": 0.90, | |
| "priority": 4, | |
| "description": "ViT base model, balanced for general plant species identification" | |
| }, | |
| "Flower-Classify": { | |
| "model_id": "facebook/convnext-base-224-22k", | |
| "specialty": "Species|Flower|Ornamental", | |
| "reliability": 0.92, | |
| "priority": 2, | |
| "description": "Powerful ConvNeXt architecture, excellent for detailed flower and ornamental plant classification" | |
| }, | |
| "Leaf-Pathology-ViT": { | |
| "model_id": "Sisigoks/FloraSense", | |
| "specialty": "Species|Garden|Fine-Grained", | |
| "reliability": 0.88, | |
| "priority": 5, | |
| "description": "Fine-tuned ViT for subtle, fine-grained classification of garden and small plant varieties" | |
| }, | |
| "Efficient-Plant-Id": { | |
| "model_id": "google/efficientnet-b4", | |
| "specialty": "Species|Efficiency|General", | |
| "reliability": 0.89, | |
| "priority": 6, | |
| "description": "High-performance EfficientNet-B4 model, optimized for faster inference speed and efficiency." | |
| }, | |
| "Herbarium-ViT-L": { | |
| "model_id": "google/vit-large-patch16-224-in21k", | |
| "specialty": "Herbarium|Species", | |
| "reliability": 0.90, | |
| "priority": 4, | |
| "type": "species", | |
| "description": "REPLACEMENT (using existing ViT-L ID) for the original Herbarium-Vision model." | |
| }, | |
| "Agri-ResNet-50": { | |
| "model_id": "microsoft/resnet-50", | |
| "specialty": "Species|Agriculture|Legacy", | |
| "reliability": 0.85, | |
| "priority": 7, | |
| "description": "A classic and highly reliable ResNet-50 baseline model, often used in agricultural image tasks." | |
| }, | |
| "Swin-Tiny-FineGrained": { | |
| "model_id": "microsoft/swin-tiny-patch4-window7-224", | |
| "specialty": "Species|Lightweight|Taxonomy", | |
| "reliability": 0.87, | |
| "priority": 8, | |
| "description": "The smallest Swin Transformer variant, ideal for deployment on devices with limited computational resources." | |
| }, | |
| # // ============ TIER 2: Disease & Health Specialists ============ | |
| "Plant-Disease-Swin": { | |
| "model_id": "Mahadi-M/swinv2-finetuned-plant-disease", | |
| "specialty": "Health|Disease", | |
| "reliability": 0.92, | |
| "priority": 2, | |
| "type": "health", | |
| "description": "REPLACEMENT for Disease-Expert-Ensemble (Gated Repo). High-fidelity SwinV2 for general disease detection." | |
| }, | |
| "Crop-Disease-ViT": { | |
| "model_id": "wambugu71/crop_leaf_diseases_vit", | |
| "specialty": "Health", | |
| "reliability": 0.90, | |
| "priority": 3, | |
| "type": "health" | |
| }, | |
| "Disease-MobileNetV2": { | |
| "model_id": "Diginsa/Plant-Disease-Detection-Project", | |
| "specialty": "Health", | |
| "reliability": 0.85, | |
| "priority": 8, | |
| "type": "health" | |
| }, | |
| "Nutrient-Deficiency-AI": { | |
| "model_id": "google/efficientnet-b4", | |
| "specialty": "Health|Deficiency", | |
| "reliability": 0.90, | |
| "priority": 3, | |
| "description": "Nutrient deficiency and stress detection (EfficientNet base)." | |
| }, | |
| "ViT-Pathogen-Expert": { | |
| "model_id": "google/vit-base-patch16-224", | |
| "specialty": "Health|Disease|Pathogen", | |
| "reliability": 0.93, | |
| "priority": 1, | |
| "description": "Vision Transformer for high-fidelity and detailed pathogen identification." | |
| }, | |
| "Leaf-Spot-Detector": { | |
| "model_id": "facebook/convnext-base-224-22k", | |
| "specialty": "Health|Disease|Spotting", | |
| "reliability": 0.91, | |
| "priority": 4, | |
| "description": "ConvNeXt architecture optimized for subtle leaf spots, lesions, and localized infections." | |
| }, | |
| "Pest-Detection-YOLOv5": { | |
| "model_id": "yolo-solutions/plant-disease-and-pest-detection", | |
| "specialty": "Health|Pest|Detection", | |
| "reliability": 0.91, | |
| "priority": 3, | |
| "type": "health", | |
| "description": "REPLACEMENT for Pest-Lepidoptera-ID (bad ID). YOLOv5 model for bounding-box detection of pests/diseases." | |
| }, | |
| "Herb-Spice-Classifier": { | |
| "model_id": "facebook/deit-base-patch16-224", | |
| "specialty": "Species|Herb|Spice|Fine-Grained", | |
| "reliability": 0.89, | |
| "priority": 5, | |
| "description": "Fine-grained classification of culinary herbs (e.g., parsley, basil, cilantro, mint) and common spices." | |
| }, | |
| "Stress-Drought-Analyzer": { | |
| "model_id": "microsoft/resnet-101", | |
| "specialty": "Health|Stress|Drought", | |
| "reliability": 0.89, | |
| "priority": 4, | |
| "description": "A deep ResNet model useful for detecting early visual signs of drought and heat stress." | |
| }, | |
| "Root-Nematode-ResNet": { | |
| "model_id": "microsoft/resnet-101", | |
| "specialty": "Health|Nematode|Soil Damage", | |
| "reliability": 0.88, | |
| "priority": 5, | |
| "type": "health", | |
| "description": "REPLACEMENT for Nematode-Damage-ViT (bad ID). ResNet-101 base for detecting damage patterns (can also be used for drought)." | |
| }, | |
| "Toxicity-Symptom-CNN": { | |
| "model_id": "google/efficientnet-b5", | |
| "specialty": "Health|Toxicity|Environmental", | |
| "reliability": 0.86, | |
| "priority": 7, | |
| "description": "EfficientNet-B5 (larger version) for detecting visual symptoms from chemical/environmental toxicity." | |
| }, | |
| "Wood-Structure-ViT": { | |
| "model_id": "google/vit-base-patch16-224", | |
| "specialty": "Species|Wood|Forestry|Damage", | |
| "reliability": 0.89, | |
| "priority": 5, | |
| "type": "species", | |
| "description": "REPLACEMENT for Herbicide-Damage-ID (bad ID). ViT Base optimized for texture analysis (damage/wood)." | |
| }, | |
| "Fine-Grained-Sickness-ID": { | |
| "model_id": "facebook/deit-small-patch16-224", | |
| "specialty": "Health|Disease|Fine-Grained", | |
| "reliability": 0.84, | |
| "priority": 9, | |
| "description": "Distilled ViT (DeiT) for fast and effective recognition of subtle or early sickness signs." | |
| }, | |
| "Virus-Infection-ViT": { | |
| "model_id": "microsoft/beit-base-patch16-224", | |
| "specialty": "Health|Virus|Systemic", | |
| "reliability": 0.83, | |
| "priority": 10, | |
| "description": "BEiT model, specialized in analyzing systemic distortions (like leaf curling) typical of viral infections." | |
| }, | |
| # // ============ TIER 3: Specialized Taxonomic Experts ============ | |
| "Tree-Identifier-Pro": { | |
| "model_id": "microsoft/resnet-50", | |
| "specialty": "Species|Tree", | |
| "reliability": 0.89, | |
| "priority": 4, | |
| "description": "Dedicated tree species identification." | |
| }, | |
| "Crop-Specialist": { | |
| "model_id": "google/efficientnet-b3", | |
| "specialty": "Species|Crop|Vegetable", | |
| "reliability": 0.88, | |
| "priority": 5, | |
| "description": "Agricultural crop identification." | |
| }, | |
| "Flower-Morphology-Expert": { | |
| "model_id": "facebook/convnext-base-224-22k-1k", | |
| "specialty": "Species|Flower", | |
| "reliability": 0.87, | |
| "priority": 6, | |
| "description": "Flowering plant identification based on detailed morphology." | |
| }, | |
| "Herb-Medicine-Classifier": { | |
| "model_id": "microsoft/beit-base-patch16-224-pt22k-ft22k", | |
| "specialty": "Species|Herb|Medicinal", | |
| "reliability": 0.86, | |
| "priority": 7, | |
| "description": "Medicinal and culinary herbs classification." | |
| }, | |
| "Fruit-Ripeness-ViT": { | |
| "model_id": "google/vit-large-patch16-224", | |
| "specialty": "Species|Fruit|Ripeness", | |
| "reliability": 0.91, | |
| "priority": 3, | |
| "description": "ViT model trained for detailed fruit/vegetable identification, including ripeness and quality checks." | |
| }, | |
| "Ornamental-EfficientNet": { | |
| "model_id": "google/efficientnet-b3", | |
| "specialty": "Species|Houseplant|Ornamental", | |
| "reliability": 0.87, | |
| "priority": 6, | |
| "type": "species", | |
| "description": "REPLACEMENT for Houseplant-Aesthetic-ID (bad ID). EfficientNet B3 for ornamental and indoor plants." | |
| }, | |
| "Grass-Cereal-Classifier": { | |
| "model_id": "microsoft/swinv2-base-patch4-window8-256", | |
| "specialty": "Species|Grass|Cereal|Grain", | |
| "reliability": 0.84, | |
| "priority": 9, | |
| "description": "Swin Transformer v2, highly specialized for fine-grained identification of grasses, cereals, and grains." | |
| }, | |
| "Groundcover-Moss-ID": { | |
| "model_id": "facebook/deit-base-distilled-patch16-224", | |
| "specialty": "Species|Groundcover|Moss|Fern", | |
| "reliability": 0.83, | |
| "priority": 10, | |
| "description": "DeiT model for classifying low-growing flora like groundcovers, mosses, and ferns." | |
| }, | |
| "ResNet-152-Base": { | |
| "model_id": "microsoft/resnet-152", | |
| "specialty": "Species|General|Deep", | |
| "reliability": 0.89, | |
| "priority": 5, | |
| "type": "species", | |
| "description": "REPLACEMENT for Global-Wood-Structure (bad ID). A very deep ResNet model (152 layers) for complex general classification tasks." | |
| }, | |
| "Tropical-Flora-ID": { | |
| "model_id": "facebook/convnext-small-224", | |
| "specialty": "Species|Tropical|Rainforest", | |
| "reliability": 0.82, | |
| "priority": 11, | |
| "description": "ConvNeXt model optimized for the high visual complexity found in tropical and rainforest flora." | |
| }, | |
| "Vine-Climber-ID": { | |
| "model_id": "google/efficientnet-b7", | |
| "specialty": "Species|Vine|Climber", | |
| "reliability": 0.81, | |
| "priority": 12, | |
| "description": "High-resolution EfficientNet-B7 for classifying vines, creepers, and climbing plants." | |
| }, | |
| "Desert-Flora-Efficient": { | |
| "model_id": "google/efficientnet-b2", | |
| "specialty": "Species|Cactus|Agave|Desert", | |
| "reliability": 0.85, | |
| "priority": 8, | |
| "type": "species", | |
| "description": "REPLACEMENT for Cactus-Agave-Detailed (duplicate ID). EfficientNet B2 model, balanced for desert flora classification." | |
| }, | |
| # // ============ TIER 4: Ecological & Environmental Specialists ============ | |
| "Weed-Detection-YOLOv8": { | |
| "model_id": "sayannic/Weed-Detection-yolov8", | |
| "specialty": "Species|Weed|Detection", | |
| "reliability": 0.86, | |
| "priority": 7, | |
| "type": "species", | |
| "description": "REPLACEMENT for Weed-Detection-DETR (timm dependency). YOLOv8 model for real-time weed identification (object detection)." | |
| }, | |
| "Fungal-Disease-ConvNext": { | |
| "model_id": "facebook/convnext-base-224-22k", | |
| "specialty": "Health|Fungi|Disease", | |
| "reliability": 0.90, | |
| "priority": 4, | |
| "type": "health", | |
| "description": "REPLACEMENT for Fungi-Pathogen-Detector (bad ID). ConvNeXt Base for detailed lesion analysis typical of fungal infections." | |
| }, | |
| "Aquatic-Flora-Expert": { | |
| "model_id": "facebook/dino-vitb16", | |
| "specialty": "Species|Aquatic", | |
| "reliability": 0.83, | |
| "priority": 10, | |
| "description": "Aquatic and wetland plant species" | |
| }, | |
| "Succulent-Cactus-ID": { | |
| "model_id": "google/efficientnet-b1", | |
| "specialty": "Species|Succulent|Cactus", | |
| "reliability": 0.82, | |
| "priority": 11, | |
| "description": "Desert plants, succulents, and cacti" | |
| }, | |
| "Forestry-Tree-ID": { | |
| "model_id": "microsoft/swin-base-patch4-window7-224", | |
| "specialty": "Species|Tree|Forestry", | |
| "reliability": 0.86, | |
| "priority": 7, | |
| "description": "Swin Transformer specialized in identifying tree species, bark, and canopy." | |
| }, | |
| "Micro-Algae-Classifier": { | |
| "model_id": "facebook/convnext-tiny-224", | |
| "specialty": "Species|Microscopic|Algae", | |
| "reliability": 0.81, | |
| "priority": 12, | |
| "description": "Lightweight ConvNeXt model for classifying microscopic organisms like plankton and various algae types." | |
| }, | |
| "Regional-Invasives-ViT": { | |
| "model_id": "google/vit-base-patch32-384", | |
| "specialty": "Species|Invasive|Bioregion", | |
| "reliability": 0.80, | |
| "priority": 13, | |
| "description": "ViT trained on a large scale for general ecology, useful for identifying invasive species within a specific region." | |
| }, | |
| "Toxicity-ViT-FineGrained": { | |
| "model_id": "facebook/deit-base-distilled-patch16-224", | |
| "specialty": "Health|Toxic|Edible|Chemical", | |
| "reliability": 0.85, | |
| "priority": 8, | |
| "type": "health", | |
| "description": "REPLACEMENT for Toxic-Edible-ViT (bad ID). DeiT for fine-grained analysis of subtle toxicity symptoms." | |
| }, | |
| # // ============ TIER 5: Supplementary Analysis ============ | |
| "Leaf-Morphology-Analyzer": { | |
| "model_id": "microsoft/resnet-34", | |
| "specialty": "Species|Leaf|Morphology", | |
| "reliability": 0.81, | |
| "priority": 12, | |
| "description": "Leaf shape and structure analysis" | |
| }, | |
| "Pest-Detection-YOLO11": { | |
| "model_id": "yolo-solutions/plant-disease-and-pest-detection", | |
| "specialty": "Pest", | |
| "reliability": 0.92, | |
| "priority": 2, | |
| "type": "health", | |
| "description": "REPLACEMENT for the original YOLO11 (unsupported ID). Using the stable Pest-Detection-YOLOv5 ID as a stand-in." | |
| }, | |
| "Stress-Pattern-Detector": { | |
| "model_id": "facebook/convnext-small-224", | |
| "specialty": "Health|Stress|Environmental", | |
| "reliability": 0.79, | |
| "priority": 14, | |
| "description": "Environmental stress patterns" | |
| }, | |
| "Disease-Symptom-Classifier": { | |
| "model_id": "nicolas-c/plant-disease-classification", | |
| "specialty": "Health|Disease|Fungal", | |
| "reliability": 0.83, | |
| "priority": 11, | |
| "description": "Focused on common plant diseases (fungal, bacterial, viral) symptoms." | |
| }, | |
| "Nutrient-Deficiency-ViT": { | |
| "model_id": "google/vit-base-patch16-224", | |
| "specialty": "Health|Nutrition|Deficiency", | |
| "reliability": 0.77, | |
| "priority": 15, | |
| "description": "Identifying visual symptoms of nutrient deficiencies (e.g., yellowing/chlorosis, necrosis)." | |
| }, | |
| "Plant-Stage-ConvNext": { | |
| "model_id": "facebook/convnext-small-224", | |
| "specialty": "Morphology|Flower|Fruit|Growth", | |
| "reliability": 0.82, | |
| "priority": 10, | |
| "description": "REPLACEMENT for Fruit-Flower-Stage-Detector (bad ID). ConvNeXt Small for detailed analysis of growth stages." | |
| }, | |
| # ============ EXTERNAL API: Community Validation ============ | |
| "PlantNet-Community-API": { | |
| "model_id": "PlantNet-API", | |
| "specialty": "Species|Community", | |
| "reliability": 0.65, | |
| "priority": 51, | |
| "description": "External PlantNet API for community validation" | |
| } # Insert your models here | |
| } | |
| # ======================================================== | |
| # UTILITY FUNCTIONS | |
| # ======================================================== | |
| def load_weights(): | |
| """Load model weights from JSON file.""" | |
| weights_file = "model_weights.json" | |
| if os.path.exists(weights_file): | |
| try: | |
| with open(weights_file, "r") as f: | |
| weights = json.load(f) | |
| print(f"โ Loaded weights from {weights_file}") | |
| return weights | |
| except json.JSONDecodeError as e: | |
| print(f"โ ๏ธ Error decoding {weights_file}: {e}") | |
| default_weights = {name: 1.0 for name in PLANT_AI_MODELS.keys()} | |
| print("โ ๏ธ Using default model weights") | |
| return default_weights | |
| def save_weights(weights: Dict[str, float]): | |
| """Save model weights to JSON file.""" | |
| try: | |
| with open("model_weights.json", "w") as f: | |
| json.dump(weights, f, indent=4) | |
| print("โ Weights saved successfully") | |
| except Exception as e: | |
| print(f"โ Failed to save weights: {e}") | |
| def get_user_location(): | |
| """Get user's approximate location from IP.""" | |
| try: | |
| response = requests.get('http://ipinfo.io/json', timeout=5) | |
| response.raise_for_status() | |
| data = response.json() | |
| city = data.get('city', 'Unknown') | |
| country = data.get('country', 'Unknown') | |
| return f"{city}, {country}" | |
| except Exception as e: | |
| print(f"โ ๏ธ Failed to get location: {e}") | |
| return "Unknown Location" | |
| def is_valid_disease_label(label: str) -> bool: | |
| """ | |
| Check if a label is a valid disease/health condition. | |
| Returns True only if it contains disease keywords and NOT plant names. | |
| """ | |
| label_lower = label.lower() | |
| # First, filter out plant names | |
| for plant_name in PLANT_NAMES_TO_FILTER: | |
| if plant_name in label_lower: | |
| return False | |
| # Then, check if it contains disease keywords | |
| for keyword in DISEASE_KEYWORDS: | |
| if keyword in label_lower: | |
| return True | |
| return False | |
| # ======================================================== | |
| # AI MODEL LOADER | |
| # ======================================================== | |
| def load_hugging_face_model(model_name: str, repo_id: str, max_retries: int = 3): | |
| """Load and cache a Hugging Face model with retry logic.""" | |
| global PLANT_MODELS_CACHE | |
| if not AI_AVAILABLE: | |
| return None | |
| if repo_id in PLANT_MODELS_CACHE: | |
| cached = PLANT_MODELS_CACHE[repo_id] | |
| if cached == "FAILED": | |
| return None | |
| return cached | |
| for attempt in range(max_retries): | |
| try: | |
| print(f"โณ Loading '{model_name}' (attempt {attempt + 1}/{max_retries})...") | |
| model_pipeline = pipeline( | |
| "image-classification", | |
| model=repo_id, | |
| device=0 if torch.cuda.is_available() else -1, | |
| token=HUGGING_FACE_TOKEN if HUGGING_FACE_TOKEN else None, | |
| trust_remote_code=False | |
| ) | |
| PLANT_MODELS_CACHE[repo_id] = model_pipeline | |
| print(f"โ Model '{model_name}' loaded") | |
| return model_pipeline | |
| except Exception as e: | |
| print(f"โ Attempt {attempt + 1} failed: {str(e)[:80]}") | |
| if attempt < max_retries - 1: | |
| wait_time = 2 ** attempt # Exponential backoff | |
| print(f"โณ Waiting {wait_time}s before retry...") | |
| time.sleep(wait_time) | |
| else: | |
| PLANT_MODELS_CACHE[repo_id] = "FAILED" | |
| return None | |
| def preload_all_models(): | |
| """Preload all AI models.""" | |
| if not AI_AVAILABLE: | |
| print("โ ๏ธ AI not available, skipping model preload") | |
| return | |
| loaded = 0 | |
| total = len([m for m in PLANT_AI_MODELS.values()]) | |
| print("\n" + "=" * 60) | |
| print("๐ค Starting AI Model Preload...") | |
| print("=" * 60) | |
| for name, details in PLANT_AI_MODELS.items(): | |
| model_id = details.get("model_id") | |
| if load_hugging_face_model(name, model_id): | |
| loaded += 1 | |
| print("=" * 60) | |
| print(f"โ Preload complete: {loaded}/{total} models loaded") | |
| print("=" * 60 + "\n") | |
| # ======================================================== | |
| # DATA INTEGRATOR CLASS WITH ENHANCED RETRY LOGIC | |
| # ======================================================== | |
| class DataIntegrator: | |
| """Handles external data sources with comprehensive retry mechanisms.""" | |
| def __init__(self): | |
| self.aio = None | |
| self.geolocator = None | |
| self.max_retries = 3 | |
| self.retry_delay = 2 | |
| # Try Adafruit IO initialization with fallback | |
| if ADAFRUIT_AVAILABLE and ADAFRUIT_IO_USERNAME and ADAFRUIT_IO_KEY: | |
| for attempt in range(self.max_retries): | |
| try: | |
| self.aio = AdafruitClient(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY) | |
| self.aio.feeds() | |
| print("โ Adafruit IO client initialized") | |
| break | |
| except Exception as e: | |
| if attempt < self.max_retries - 1: | |
| time.sleep(self.retry_delay) | |
| else: | |
| print(f"โ ๏ธ Adafruit IO unavailable (will use mock data): {str(e)[:50]}") | |
| self.aio = None | |
| else: | |
| print("โ ๏ธ Adafruit IO not configured (will use mock data)") | |
| # Try Geopy initialization | |
| if GEOPY_AVAILABLE: | |
| try: | |
| self.geolocator = Nominatim(user_agent="plantscope_app") | |
| print("โ Geopy initialized") | |
| except Exception as e: | |
| print(f"โ ๏ธ Geopy unavailable: {str(e)[:50]}") | |
| else: | |
| print("โ ๏ธ Geopy not installed (location features limited)") | |
| # Try Cloudinary configuration with fallback | |
| if CLOUDINARY_AVAILABLE and CLOUDINARY_CLOUD_NAME: | |
| for attempt in range(self.max_retries): | |
| try: | |
| cloudinary.config( | |
| cloud_name=CLOUDINARY_CLOUD_NAME, | |
| api_key=CLOUDINARY_API_KEY, | |
| api_secret=CLOUDINARY_API_SECRET, | |
| secure=True | |
| ) | |
| cloudinary.api.ping() | |
| print("โ Cloudinary configured") | |
| break | |
| except Exception as e: | |
| if attempt < self.max_retries - 1: | |
| time.sleep(self.retry_delay) | |
| else: | |
| print(f"โ ๏ธ Cloudinary unavailable (will use mock data): {str(e)[:50]}") | |
| else: | |
| print("โ ๏ธ Cloudinary not configured (gallery features limited)") | |
| def get_adafruit_data(self, feed_name: str, limit: int = 100) -> Optional[List[Dict]]: | |
| """ | |
| Fetch data from Adafruit IO with multiple retry strategies. | |
| """ | |
| if not self.aio: | |
| print(f"โ ๏ธ Adafruit IO not initialized for feed: {feed_name}") | |
| return None | |
| # Strategy 1: Try direct fetch | |
| for attempt in range(self.max_retries): | |
| try: | |
| feed = self.aio.feeds(feed_name) | |
| data = self.aio.data(feed.key, max_results=limit) | |
| if data: | |
| print(f"โ Retrieved {len(data)} records from {feed_name}") | |
| return data | |
| else: | |
| print(f"โ ๏ธ Feed {feed_name} is empty") | |
| return None | |
| except APIError as e: | |
| if "404" in str(e) and attempt == 0: | |
| try: | |
| feed = self.aio.create_feed({"name": feed_name, "key": feed_name}) | |
| print(f"โ Created feed: {feed_name}") | |
| return [] | |
| except Exception as create_error: | |
| print(f"โ Could not create feed: {str(create_error)[:50]}") | |
| if attempt < self.max_retries - 1: | |
| time.sleep(self.retry_delay * (attempt + 1)) | |
| except Exception as e: | |
| if attempt < self.max_retries - 1: | |
| time.sleep(self.retry_delay * (attempt + 1)) | |
| # Strategy 3: Try REST API | |
| try: | |
| url = f"https://io.adafruit.com/api/v2/{ADAFRUIT_IO_USERNAME}/feeds/{feed_name}/data" | |
| headers = {"X-AIO-Key": ADAFRUIT_IO_KEY} | |
| response = requests.get(url, headers=headers, params={"limit": limit}, timeout=10) | |
| if response.status_code == 200: | |
| data = response.json() | |
| print(f"โ Retrieved {len(data)} records via REST API") | |
| return data | |
| except Exception as e: | |
| print(f"โ All methods failed: {str(e)[:50]}") | |
| return None | |
| def post_adafruit_data(self, feed_name: str, value: Any) -> bool: | |
| """Post data to Adafruit IO with retry logic.""" | |
| if not self.aio: | |
| print(f"โ ๏ธ Adafruit IO not initialized, cannot post to: {feed_name}") | |
| return False | |
| for attempt in range(self.max_retries): | |
| try: | |
| # Try to get or create feed | |
| try: | |
| feed = self.aio.feeds(feed_name) | |
| except: | |
| feed = self.aio.create_feed({"name": feed_name, "key": feed_name}) | |
| # Send data | |
| self.aio.send_data(feed.key, value) | |
| print(f"โ Data posted to {feed_name}") | |
| return True | |
| except Exception as e: | |
| print(f"โ Post attempt {attempt + 1} failed: {str(e)[:50]}") | |
| if attempt < self.max_retries - 1: | |
| time.sleep(self.retry_delay * (attempt + 1)) | |
| # Try REST API as fallback | |
| try: | |
| url = f"https://io.adafruit.com/api/v2/{ADAFRUIT_IO_USERNAME}/feeds/{feed_name}/data" | |
| headers = {"X-AIO-Key": ADAFRUIT_IO_KEY, "Content-Type": "application/json"} | |
| response = requests.post(url, headers=headers, json={"value": value}, timeout=10) | |
| if response.status_code in [200, 201]: | |
| print(f"โ Data posted via REST API to {feed_name}") | |
| return True | |
| except Exception as e: | |
| print(f"โ REST API post failed: {str(e)[:50]}") | |
| return False | |
| def get_cloudinary_images(self, count: int = 20) -> List[Dict]: | |
| """ | |
| Fetch images from Cloudinary with multiple retry strategies. | |
| """ | |
| if not CLOUDINARY_AVAILABLE: | |
| print("โ ๏ธ Cloudinary not installed") | |
| return [] | |
| if not CLOUDINARY_CLOUD_NAME: | |
| print("โ ๏ธ Cloudinary not configured") | |
| return [] | |
| # Strategy 1: Try standard fetch | |
| for attempt in range(self.max_retries): | |
| try: | |
| results = cloudinary.api.resources( | |
| type="upload", | |
| prefix=CLOUDINARY_FOLDER, | |
| max_results=count, | |
| direction="desc", | |
| resource_type="image" | |
| ) | |
| resources = results.get('resources', []) | |
| if resources: | |
| print(f"โ Found {len(resources)} images from Cloudinary") | |
| return resources | |
| else: | |
| print(f"โ ๏ธ No images in folder: {CLOUDINARY_FOLDER}") | |
| return [] | |
| except Exception as e: | |
| if attempt < self.max_retries - 1: | |
| time.sleep(self.retry_delay * (attempt + 1)) | |
| # Strategy 2: Try without prefix | |
| try: | |
| results = cloudinary.api.resources( | |
| type="upload", | |
| max_results=count, | |
| direction="desc", | |
| resource_type="image" | |
| ) | |
| resources = results.get('resources', []) | |
| filtered = [r for r in resources if CLOUDINARY_FOLDER in r.get('public_id', '')] | |
| if filtered: | |
| print(f"โ Found {len(filtered)} images (manual filtering)") | |
| return filtered | |
| except Exception as e: | |
| print(f"โ ๏ธ Fallback fetch failed: {str(e)[:50]}") | |
| # Strategy 3: Try REST API | |
| try: | |
| import base64 | |
| auth_string = f"{CLOUDINARY_API_KEY}:{CLOUDINARY_API_SECRET}" | |
| auth_header = base64.b64encode(auth_string.encode()).decode() | |
| url = f"https://api.cloudinary.com/v1_1/{CLOUDINARY_CLOUD_NAME}/resources/image" | |
| headers = {"Authorization": f"Basic {auth_header}"} | |
| params = {"type": "upload", "prefix": CLOUDINARY_FOLDER, "max_results": count} | |
| response = requests.get(url, headers=headers, params=params, timeout=15) | |
| if response.status_code == 200: | |
| data = response.json() | |
| resources = data.get('resources', []) | |
| print(f"โ Retrieved {len(resources)} images via REST API") | |
| return resources | |
| except Exception as e: | |
| print(f"โ REST API failed: {str(e)[:50]}") | |
| return [] | |
| def get_weather_for_location(self, location: str) -> Optional[Dict]: | |
| """Fetch weather data with retry.""" | |
| if not WEATHER_API_KEY: | |
| return None | |
| for attempt in range(self.max_retries): | |
| try: | |
| response = requests.get( | |
| WEATHER_API_URL, | |
| params={"q": location, "appid": WEATHER_API_KEY, "units": "metric"}, | |
| timeout=10 | |
| ) | |
| response.raise_for_status() | |
| data = response.json() | |
| return { | |
| "location": data.get("name"), | |
| "temperature": data["main"]["temp"], | |
| "humidity": data["main"]["humidity"], | |
| "description": data["weather"][0]["description"] | |
| } | |
| except Exception as e: | |
| print(f"โ Weather attempt {attempt + 1} failed: {str(e)[:50]}") | |
| if attempt < self.max_retries - 1: | |
| time.sleep(self.retry_delay) | |
| return None | |
| def find_closest_sensor_data(self, image_timestamp: str, sensor_data: Optional[List[Dict]]) -> Optional[Dict]: | |
| """Find sensor data point closest to image timestamp.""" | |
| if not sensor_data: | |
| return None | |
| try: | |
| image_dt = datetime.fromisoformat(image_timestamp.replace('Z', '+00:00')) | |
| except ValueError: | |
| return None | |
| closest = None | |
| min_diff = float('inf') | |
| for point in sensor_data: | |
| try: | |
| data_dt = datetime.fromisoformat(point['created_at'].replace('Z', '+00:00')) | |
| diff = abs((image_dt - data_dt).total_seconds()) | |
| if diff < min_diff: | |
| min_diff = diff | |
| closest = point | |
| except (ValueError, KeyError): | |
| continue | |
| return closest | |
| data_integrator = DataIntegrator() | |
| # ======================================================== | |
| # PLANTNET EXTERNAL API | |
| # ======================================================== | |
| def get_plant_id_from_plantnet(image_path: str) -> Optional[Dict]: | |
| """Identify plant using PlantNet API.""" | |
| if not PLANTNET_API_KEY: | |
| return None | |
| url = "https://my-api.plantnet.org/v2/identify/all" | |
| try: | |
| with open(image_path, "rb") as image_file: | |
| files = {'images': image_file} | |
| params = {'api-key': PLANTNET_API_KEY} | |
| response = requests.post(url, files=files, params=params, timeout=30) | |
| response.raise_for_status() | |
| data = response.json() | |
| if data.get('results'): | |
| top_result = data['results'][0] | |
| plant_name = top_result['species'].get('scientificNameWithoutAuthor', 'Unknown') | |
| score = top_result['score'] | |
| return {"plant_name": plant_name, "score": score} | |
| except Exception as e: | |
| print(f"โ PlantNet error: {str(e)[:80]}") | |
| return None | |
| # ======================================================== | |
| # AI CONSENSUS ENGINE WITH DISEASE FILTERING | |
| # ======================================================== | |
| def run_dual_consensus(image_path: str) -> Tuple[str, Dict]: | |
| """ | |
| Run weighted consensus analysis with proper disease filtering. | |
| Health predictions now only include disease/condition labels. | |
| """ | |
| if not AI_AVAILABLE: | |
| return "โ AI system unavailable", { | |
| "plant_prediction": "Unavailable", | |
| "plant_confidence": 0.0, | |
| "health_prediction": "Unavailable", | |
| "health_confidence": 0.0 | |
| } | |
| if not os.path.exists(image_path): | |
| return "โ Image file not found", {"plant_prediction": "Error", "plant_confidence": 0.0} | |
| global MODEL_WEIGHTS | |
| plant_scores = defaultdict(float) | |
| health_scores = defaultdict(float) | |
| plant_count = 0 | |
| health_count = 0 | |
| filtered_health_count = 0 | |
| print("\n" + "=" * 60) | |
| print("๐ฌ Starting Dual Consensus Analysis") | |
| print("=" * 60) | |
| # Phase 1: Species Identification | |
| print("\n๐ Phase 1: Species Identification") | |
| print("-" * 60) | |
| for model_name, details in PLANT_AI_MODELS.items(): | |
| if details.get("type") != "species": | |
| continue | |
| repo_id = details.get("model_id") | |
| classifier = load_hugging_face_model(model_name, repo_id) | |
| if not classifier: | |
| continue | |
| try: | |
| predictions = classifier(image_path, top_k=5) | |
| for pred in predictions: | |
| label = pred['label'].lower() | |
| # Filter noise | |
| if any(kw in label for kw in NON_PLANT_KEYWORDS): | |
| continue | |
| weight = MODEL_WEIGHTS.get(model_name, 1.0) | |
| reliability = details.get("reliability", 1.0) | |
| score = pred['score'] * weight * reliability | |
| plant_scores[label] += score | |
| plant_count += 1 | |
| print(f" โข {model_name}: {label} ({score:.4f})") | |
| except Exception as e: | |
| print(f" โ ๏ธ {model_name} error: {str(e)[:50]}") | |
| # Phase 2: Health Analysis WITH DISEASE FILTERING | |
| print("\n๐ฉบ Phase 2: Health Analysis (Disease/Condition Only)") | |
| print("-" * 60) | |
| for model_name, details in PLANT_AI_MODELS.items(): | |
| if details.get("type") != "health": | |
| continue | |
| repo_id = details.get("model_id") | |
| classifier = load_hugging_face_model(model_name, repo_id) | |
| if not classifier: | |
| continue | |
| try: | |
| predictions = classifier(image_path, top_k=10) # Get more to filter | |
| for pred in predictions: | |
| label = pred['label'] | |
| label_lower = label.lower() | |
| # CRITICAL: Filter out plant names and noise | |
| if any(kw in label_lower for kw in NON_PLANT_KEYWORDS): | |
| filtered_health_count += 1 | |
| print(f" โ Filtered noise: {label}") | |
| continue | |
| # NEW: Only accept disease/condition labels | |
| if not is_valid_disease_label(label): | |
| filtered_health_count += 1 | |
| print(f" โ Filtered plant name: {label}") | |
| continue | |
| weight = MODEL_WEIGHTS.get(model_name, 1.0) | |
| reliability = details.get("reliability", 1.0) | |
| score = pred['score'] * weight * reliability | |
| health_scores[label] += score | |
| health_count += 1 | |
| print(f" โ {model_name}: {label} ({score:.4f})") | |
| except Exception as e: | |
| print(f" โ ๏ธ {model_name} error: {str(e)[:50]}") | |
| print(f"\n๐ Health Filtering Stats: Accepted={health_count}, Filtered={filtered_health_count}") | |
| # Results Aggregation | |
| print("\n๐ Aggregating Results...") | |
| print("-" * 60) | |
| if not plant_scores: | |
| return "No plant identified", { | |
| "plant_prediction": "Unknown", | |
| "plant_confidence": 0.0, | |
| "health_prediction": "Unknown", | |
| "health_confidence": 0.0, | |
| "image_path": image_path | |
| } | |
| top_plant = max(plant_scores, key=plant_scores.get) | |
| total_plant = sum(plant_scores.values()) | |
| plant_conf = plant_scores[top_plant] / total_plant if total_plant > 0 else 0 | |
| # Health with fallback | |
| if health_scores: | |
| top_health = max(health_scores, key=health_scores.get) | |
| total_health = sum(health_scores.values()) | |
| health_conf = health_scores[top_health] / total_health if total_health > 0 else 0 | |
| else: | |
| top_health = "Healthy (No diseases detected)" | |
| health_conf = 0.0 | |
| print(f"\nโ Results:") | |
| print(f" Plant: {top_plant} ({plant_conf:.2%})") | |
| print(f" Health: {top_health} ({health_conf:.2%})") | |
| print("=" * 60 + "\n") | |
| return f"**Identified:** {top_plant}", { | |
| "plant_prediction": top_plant, | |
| "plant_confidence": plant_conf, | |
| "health_prediction": top_health, | |
| "health_confidence": health_conf, | |
| "plant_scores": dict(plant_scores), | |
| "health_scores": dict(health_scores), | |
| "image_path": image_path, | |
| "health_filtered_count": filtered_health_count | |
| } | |
| # ======================================================== | |
| # MODEL WEIGHT UPDATES | |
| # ======================================================== | |
| def update_model_weights(original_analysis: Dict, user_correction: str): | |
| """Update model weights based on user feedback.""" | |
| global MODEL_WEIGHTS | |
| if not original_analysis or not user_correction: | |
| return | |
| plant_results = original_analysis.get("plant_results", []) | |
| correct_plant = user_correction | |
| print(f"\n๐ Learning from feedback: {correct_plant}") | |
| for result in plant_results: | |
| model_name = result["model"] | |
| predicted_label = result["label"] | |
| if predicted_label.lower() == correct_plant.lower(): | |
| MODEL_WEIGHTS[model_name] = MODEL_WEIGHTS.get(model_name, 1.0) * 1.1 | |
| print(f" โ Increased weight for {model_name}") | |
| else: | |
| MODEL_WEIGHTS[model_name] = MODEL_WEIGHTS.get(model_name, 1.0) * 0.95 | |
| print(f" โ Decreased weight for {model_name}") | |
| for model_name in MODEL_WEIGHTS: | |
| MODEL_WEIGHTS[model_name] = max(0.1, min(2.0, MODEL_WEIGHTS[model_name])) | |
| save_weights(MODEL_WEIGHTS) | |
| print("โ Model weights updated and saved\n") | |
| # ======================================================== | |
| # GRADIO INTERFACE FUNCTIONS - ENHANCED | |
| # ======================================================== | |
| def analyze_plant_image(image_path: str) -> Tuple[str, List, float]: | |
| """Analyze plant image with proper disease filtering.""" | |
| global last_analysis_details | |
| if not image_path: | |
| return "โ ๏ธ Please upload an image", [], 0.0 | |
| final_text, analysis_details = run_dual_consensus(image_path) | |
| last_analysis_details = analysis_details | |
| plant_name = analysis_details.get("plant_prediction", "Unknown") | |
| plant_conf = analysis_details.get("plant_confidence", 0.0) | |
| health_pred = analysis_details.get("health_prediction", "Unknown") | |
| health_conf = analysis_details.get("health_confidence", 0.0) | |
| filtered_count = analysis_details.get("health_filtered_count", 0) | |
| plant_info = PLANT_DATABASE.get(plant_name, {}) | |
| care_tips = plant_info.get("care_tips", ["No data available"]) | |
| common_diseases = plant_info.get("common_diseases", ["No data available"]) | |
| img_url = plant_info.get("img_url") | |
| output_text = f""" | |
| ## ๐ฑ Analysis Results | |
| ### Plant Identification | |
| **{plant_name}** | |
| ๐ Confidence: {plant_conf:.1%} | |
| ### Health Status | |
| **{health_pred}** | |
| ๐ Confidence: {health_conf:.1%} | |
| ๐ Filtered {filtered_count} non-disease labels | |
| ### ๐ก Care Tips | |
| {chr(10).join(f'โข {tip}' for tip in care_tips)} | |
| ### โ ๏ธ Common Diseases | |
| {chr(10).join(f'โข {disease}' for disease in common_diseases)} | |
| """ | |
| gallery = [(img_url, plant_name)] if img_url else [] | |
| confidence_percent = plant_conf * 100 | |
| return output_text, gallery, confidence_percent | |
| def get_sensor_weather_data(city: str) -> str: | |
| """Get sensor and weather data with enhanced error reporting.""" | |
| output = "" | |
| # Weather data | |
| weather = data_integrator.get_weather_for_location(city) | |
| if weather: | |
| output += f""" | |
| ## ๐ค๏ธ Weather in {weather['location']} | |
| ๐ก๏ธ **Temperature:** {weather['temperature']:.1f}ยฐC | |
| ๐ง **Humidity:** {weather['humidity']}% | |
| โ๏ธ **Description:** {weather['description']} | |
| """ | |
| else: | |
| output += f""" | |
| ## ๐ค๏ธ Weather Data | |
| โ ๏ธ Unable to fetch weather for: {city} | |
| Tried {data_integrator.max_retries} times with exponential backoff. | |
| **Possible issues:** | |
| - Invalid city name | |
| - API key not configured | |
| - Network connection issue | |
| - API rate limit reached | |
| """ | |
| # Sensor data with retry info | |
| temp_data = data_integrator.get_adafruit_data(ADAFRUIT_FEEDS["temperature"], limit=10) | |
| humid_data = data_integrator.get_adafruit_data(ADAFRUIT_FEEDS["humidity"], limit=10) | |
| if temp_data or humid_data: | |
| output += "## ๐ Latest Sensor Readings\n\n" | |
| if temp_data: | |
| output += "### ๐ก๏ธ Temperature Sensor\n" | |
| for i, point in enumerate(temp_data[:5], 1): | |
| value = point.get('value', 'N/A') | |
| timestamp = point.get('created_at', 'N/A') | |
| output += f"**{i}.** {value}ยฐC - {timestamp}\n" | |
| output += "\n" | |
| if humid_data: | |
| output += "### ๐ง Humidity Sensor\n" | |
| for i, point in enumerate(humid_data[:5], 1): | |
| value = point.get('value', 'N/A') | |
| timestamp = point.get('created_at', 'N/A') | |
| output += f"**{i}.** {value}% - {timestamp}\n" | |
| else: | |
| output += f""" | |
| ## ๐ Sensor Data | |
| โ ๏ธ No sensor data available after {data_integrator.max_retries} retry attempts. | |
| **Retry strategies attempted:** | |
| 1. Direct feed fetch | |
| 2. Feed creation (if missing) | |
| 3. REST API fallback | |
| **Setup Instructions:** | |
| 1. Create feeds on Adafruit IO dashboard | |
| 2. Configure environment variables: | |
| - ADAFRUIT_IO_USERNAME="{ADAFRUIT_IO_USERNAME}" | |
| - ADAFRUIT_IO_KEY="your_key" | |
| 3. Ensure sensors are publishing data | |
| 4. Check feed names match: {list(ADAFRUIT_FEEDS.values())} | |
| """ | |
| return output | |
| def run_prophet_forecast() -> Tuple[str, Any]: | |
| """Generate temperature forecast using Prophet.""" | |
| if not PROPHET_AVAILABLE: | |
| return "โ Prophet not installed. Install: pip install prophet", None | |
| temp_data = data_integrator.get_adafruit_data(ADAFRUIT_FEEDS["temperature"], limit=100) | |
| if not temp_data or len(temp_data) < 10: | |
| return f"โ ๏ธ Insufficient data for forecast (have: {len(temp_data) if temp_data else 0}, need: 10)", None | |
| try: | |
| df = pd.DataFrame([ | |
| { | |
| 'ds': datetime.fromisoformat(d['created_at'].replace('Z', '+00:00')), | |
| 'y': float(d['value']) | |
| } | |
| for d in temp_data if 'value' in d and 'created_at' in d | |
| ]) | |
| df.sort_values('ds', inplace=True) | |
| if len(df) < 2: | |
| return "โ ๏ธ Insufficient valid data after filtering", None | |
| m = Prophet(daily_seasonality=True, weekly_seasonality=True) | |
| m.fit(df) | |
| future = m.make_future_dataframe(periods=30, freq='D') | |
| forecast = m.predict(future) | |
| fig = m.plot(forecast) | |
| plt.title("Temperature Forecast - 30 Days") | |
| plt.xlabel("Date") | |
| plt.ylabel("Temperature (ยฐC)") | |
| return f"โ Forecast generated from {len(df)} data points", fig | |
| except Exception as e: | |
| return f"โ Forecast error: {str(e)[:100]}", None | |
| def send_robot_command(command: str) -> str: | |
| """Send command to robot via Telegram.""" | |
| if not TELEGRAM_BOT_TOKEN or not TELEGRAM_CHAT_ID: | |
| return "โ Telegram credentials missing" | |
| try: | |
| url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" | |
| response = requests.post( | |
| url, | |
| data={"chat_id": TELEGRAM_CHAT_ID, "text": f"๐ค Command: {command}"}, | |
| timeout=10 | |
| ) | |
| response.raise_for_status() | |
| return "โ Command sent successfully" | |
| except Exception as e: | |
| return f"โ Error: {str(e)[:80]}" | |
| def get_care_tips_interface(plant_name: str) -> Tuple[str, Optional[str]]: | |
| """Get care tips for a plant.""" | |
| if not plant_name: | |
| return "โ ๏ธ Please select a plant", None | |
| plant_info = PLANT_DATABASE.get(plant_name, {}) | |
| if not plant_info: | |
| return f"โ ๏ธ No data for '{plant_name}'", None | |
| care_tips = plant_info.get("care_tips", ["No data"]) | |
| common_diseases = plant_info.get("common_diseases", ["No data"]) | |
| img_url = plant_info.get("img_url") | |
| output = f""" | |
| ## ๐ฟ {plant_name} | |
| ### ๐ก Care Tips | |
| {chr(10).join(f'โข {tip}' for tip in care_tips)} | |
| ### โ ๏ธ Common Diseases | |
| {chr(10).join(f'โข {disease}' for disease in common_diseases)} | |
| """ | |
| return output, img_url | |
| def refresh_cloudinary_images_interface() -> Tuple[str, List]: | |
| """Refresh Cloudinary gallery with detailed retry info.""" | |
| if not CLOUDINARY_AVAILABLE: | |
| return "โ Cloudinary library not installed. Install: pip install cloudinary", [] | |
| if not CLOUDINARY_CLOUD_NAME: | |
| return "โ Cloudinary not configured. Set environment variables", [] | |
| # Fetch images with retry | |
| images = data_integrator.get_cloudinary_images(count=20) | |
| if not images: | |
| return f"""โ ๏ธ No images found after {data_integrator.max_retries} retry attempts | |
| **Retry strategies attempted:** | |
| 1. Standard API fetch with prefix | |
| 2. Fetch all images + manual filtering | |
| 3. REST API with Basic Auth | |
| **Troubleshooting:** | |
| - Folder: `{CLOUDINARY_FOLDER}` | |
| - Cloud: `{CLOUDINARY_CLOUD_NAME}` | |
| **Possible issues:** | |
| 1. Folder is empty or doesn't exist | |
| 2. Wrong folder prefix: try removing "/" or changing case | |
| 3. API credentials invalid (check dashboard) | |
| 4. Network/firewall blocking requests | |
| **To upload images:** | |
| 1. Go to Cloudinary dashboard | |
| 2. Upload to folder: {CLOUDINARY_FOLDER} | |
| 3. Refresh this page | |
| """, [] | |
| # Create gallery list | |
| image_list = [] | |
| for img in images: | |
| url = img.get('secure_url') | |
| created = img.get('created_at', 'Unknown date') | |
| public_id = img.get('public_id', 'Unknown') | |
| if url: | |
| filename = public_id.split('/')[-1] if '/' in public_id else public_id | |
| caption = f"๐ {created}\n๐ {filename[:30]}" | |
| image_list.append((url, caption)) | |
| success_msg = f"""โ Successfully loaded {len(image_list)} images | |
| **Source:** Cloudinary Cloud: `{CLOUDINARY_CLOUD_NAME}` | |
| **Folder:** `{CLOUDINARY_FOLDER}` | |
| **Retry attempts:** Used {data_integrator.max_retries} max retries | |
| **Total Images:** {len(image_list)} | |
| ๐ก **Tip:** Click on images to view full size | |
| """ | |
| return success_msg, image_list | |
| def save_plant_definition(image_path: str, plant_name: str) -> str: | |
| """Save user's manual plant correction.""" | |
| global last_analysis_details | |
| if not image_path or not plant_name: | |
| return "โ ๏ธ Missing image or plant name" | |
| if not os.path.exists(image_path): | |
| return "โ ๏ธ Image file not found" | |
| if not last_analysis_details: | |
| return "โ ๏ธ No AI analysis performed yet. Analyze an image first." | |
| try: | |
| update_model_weights(last_analysis_details, plant_name) | |
| plantnet_result = None | |
| if PLANTNET_API_KEY: | |
| try: | |
| plantnet_result = get_plant_id_from_plantnet(image_path) | |
| except: | |
| pass | |
| correction_data = { | |
| "image_path": os.path.basename(image_path), | |
| "user_correction": plant_name, | |
| "original_prediction": last_analysis_details.get("plant_prediction", "Unknown"), | |
| "original_confidence": last_analysis_details.get("plant_confidence", 0), | |
| "timestamp": datetime.now().isoformat(), | |
| "plantnet_verification": plantnet_result.get('plant_name') if plantnet_result else None | |
| } | |
| save_success = data_integrator.post_adafruit_data( | |
| ADAFRUIT_FEEDS["user_corrections"], | |
| json.dumps(correction_data) | |
| ) | |
| response = f"""โ Correction saved successfully! | |
| **Your Correction:** {plant_name} | |
| **Original AI:** {correction_data['original_prediction']} ({correction_data['original_confidence']:.1%}) | |
| """ | |
| if plantnet_result: | |
| pn_name = plantnet_result['plant_name'] | |
| pn_score = plantnet_result['score'] | |
| agreement = "โ " if pn_name.lower() in plant_name.lower() else "โ ๏ธ" | |
| response += f"""**PlantNet Verification:** {agreement} | |
| - PlantNet: {pn_name} ({pn_score:.1%}) | |
| """ | |
| response += f"""**Model Weights:** Updated โ | |
| **Backup to Adafruit:** {'โ Saved' if save_success else 'โ ๏ธ Failed'} | |
| """ | |
| return response | |
| except Exception as e: | |
| return f"โ Error: {str(e)[:100]}" | |
| def analyze_cloudinary_image_batch(max_images: int = 10) -> Tuple[str, List, pd.DataFrame, Optional[str]]: | |
| """Analyze batch of Cloudinary images with comprehensive error handling.""" | |
| if not CLOUDINARY_AVAILABLE: | |
| empty_df = pd.DataFrame(columns=["Timestamp", "Plant", "Confidence", "Health"]) | |
| return "โ Cloudinary not installed", [], empty_df, None | |
| if not AI_AVAILABLE: | |
| empty_df = pd.DataFrame(columns=["Timestamp", "Plant", "Confidence", "Health"]) | |
| return "โ AI system not available", [], empty_df, None | |
| try: | |
| os.makedirs(REPORTS_DIR, exist_ok=True) | |
| except Exception as e: | |
| empty_df = pd.DataFrame(columns=["Timestamp", "Plant", "Confidence", "Health"]) | |
| return f"โ Cannot create reports directory: {e}", [], empty_df, None | |
| report_filename = os.path.join( | |
| REPORTS_DIR, | |
| datetime.now().strftime("Batch_%Y%m%d_%H%M%S.csv") | |
| ) | |
| print(f"\n{'=' * 60}") | |
| print(f"๐ค Starting Batch Analysis ({max_images} images)") | |
| print(f"{'=' * 60}\n") | |
| # Fetch with retry | |
| images = data_integrator.get_cloudinary_images(count=max_images) | |
| if not images: | |
| empty_df = pd.DataFrame(columns=["Timestamp", "Plant", "Confidence", "Health"]) | |
| return f"โ ๏ธ No images found (tried {data_integrator.max_retries} times)", [], empty_df, None | |
| results_list = [] | |
| raw_data = [] | |
| temp_dir = "temp_batch" | |
| try: | |
| if os.path.exists(temp_dir): | |
| shutil.rmtree(temp_dir) | |
| os.makedirs(temp_dir, exist_ok=True) | |
| except Exception as e: | |
| empty_df = pd.DataFrame(columns=["Timestamp", "Plant", "Confidence", "Health"]) | |
| return f"โ Cannot create temp directory: {e}", [], empty_df, None | |
| headers = ["Timestamp", "Image URL", "Plant", "Confidence", "Health"] | |
| processed = 0 | |
| failed = 0 | |
| try: | |
| with open(report_filename, 'w', newline='', encoding='utf-8') as csvfile: | |
| writer = csv.writer(csvfile) | |
| writer.writerow(headers) | |
| for i, img in enumerate(images): | |
| print(f"\n๐ธ Processing {i+1}/{len(images)}...") | |
| img_url = img.get('secure_url') | |
| timestamp = img.get('created_at', 'Unknown') | |
| if not img_url: | |
| failed += 1 | |
| continue | |
| image_name = os.path.join(temp_dir, f"img_{i}.jpg") | |
| # Download with retry | |
| downloaded = False | |
| for attempt in range(3): | |
| try: | |
| img_response = requests.get(img_url, stream=True, timeout=15) | |
| img_response.raise_for_status() | |
| with open(image_name, 'wb') as f: | |
| for chunk in img_response.iter_content(8192): | |
| f.write(chunk) | |
| if os.path.getsize(image_name) > 100: | |
| downloaded = True | |
| break | |
| except Exception as e: | |
| print(f" โ ๏ธ Download attempt {attempt+1} failed") | |
| if attempt < 2: | |
| time.sleep(2) | |
| if not downloaded: | |
| failed += 1 | |
| continue | |
| # Analyze | |
| try: | |
| final_text, analysis = run_dual_consensus(image_name) | |
| plant = analysis.get("plant_prediction", "Unknown") | |
| conf = analysis.get("plant_confidence", 0) | |
| health = analysis.get("health_prediction", "Unknown") | |
| row = [timestamp, img_url, plant, f"{conf*100:.1f}%", health] | |
| writer.writerow(row) | |
| raw_data.append(dict(zip(headers, row))) | |
| description = f"**{plant}** ({conf*100:.1f}%)\n๐ฉบ {health}" | |
| results_list.append((img_url, description)) | |
| processed += 1 | |
| except Exception as e: | |
| print(f" โ Analysis failed: {str(e)[:80]}") | |
| failed += 1 | |
| # Cleanup | |
| try: | |
| if os.path.exists(image_name): | |
| os.remove(image_name) | |
| except: | |
| pass | |
| except Exception as e: | |
| print(f"โ Critical error: {e}") | |
| finally: | |
| try: | |
| if os.path.exists(temp_dir): | |
| shutil.rmtree(temp_dir) | |
| except: | |
| pass | |
| df = pd.DataFrame(raw_data) if raw_data else pd.DataFrame(columns=headers) | |
| if processed > 0: | |
| avg_conf = df['Confidence'].str.rstrip('%').astype(float).mean() | |
| top_plant = df['Plant'].mode()[0] if len(df) > 0 else 'N/A' | |
| else: | |
| avg_conf = 0 | |
| top_plant = 'N/A' | |
| summary = f""" | |
| ## ๐ค Batch Analysis Summary | |
| โ **Successfully Processed:** {processed} / {len(images)} | |
| โ **Failed:** {failed} | |
| ๐ **Statistics:** | |
| - **Average Confidence:** {avg_conf:.1f}% | |
| - **Most Common Plant:** {top_plant} | |
| ๐ **Report Saved:** `{report_filename}` | |
| ๐ **Retry Info:** Each image attempted up to 3 times | |
| """ | |
| print(f"\n{'=' * 60}") | |
| print(f"โ Complete! Processed: {processed}, Failed: {failed}") | |
| print(f"{'=' * 60}\n") | |
| return summary, results_list, df, report_filename | |
| # ======================================================== | |
| # GRADIO INTERFACE - COMPLETE | |
| # ======================================================== | |
| def create_gradio_app(): | |
| """Create complete Gradio interface.""" | |
| theme = gr.themes.Soft(primary_hue="green", secondary_hue="slate") | |
| with gr.Blocks(theme=theme, title="PLANETYOYO AI v19.10") as app: | |
| gr.HTML(""" | |
| <div style="text-align: center; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; border-radius: 10px; margin-bottom: 20px;"> | |
| <h1>๐ฑ PLANETYOYO AI Ultimate v19.10</h1> | |
| <p>Enhanced Retry Logic + Disease Filtering</p> | |
| </div> | |
| """) | |
| with gr.Tabs(): | |
| # TAB 1: Image Analysis | |
| with gr.Tab("๐ฌ Image Analysis"): | |
| gr.Markdown("### AI Plant Identification with Disease Detection") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| image_input = gr.Image(type="filepath", label="Plant Image", height=400) | |
| analyze_btn = gr.Button("๐ฌ Analyze Plant", variant="primary", size="lg") | |
| with gr.Column(scale=1): | |
| confidence_slider = gr.Slider( | |
| label="๐ AI Confidence", | |
| minimum=0, | |
| maximum=100, | |
| value=0, | |
| interactive=False | |
| ) | |
| output_text = gr.Markdown() | |
| gallery = gr.Gallery(label="Reference Images", columns=4, height=200) | |
| analyze_btn.click( | |
| fn=analyze_plant_image, | |
| inputs=[image_input], | |
| outputs=[output_text, gallery, confidence_slider] | |
| ) | |
| # TAB 2: Sensors & Weather | |
| with gr.Tab("๐ Sensors & Weather"): | |
| with gr.Row(): | |
| city_input = gr.Textbox(value=get_user_location(), label="Location", scale=2) | |
| refresh_btn = gr.Button("๐ Refresh", variant="primary", scale=1) | |
| sensor_output = gr.Markdown() | |
| refresh_btn.click(fn=get_sensor_weather_data, inputs=[city_input], outputs=[sensor_output]) | |
| gr.Markdown("---") | |
| forecast_btn = gr.Button("๐ฎ Generate 30-Day Forecast", variant="secondary") | |
| forecast_status = gr.Textbox(interactive=False) | |
| forecast_plot = gr.Plot() | |
| forecast_btn.click(fn=run_prophet_forecast, outputs=[forecast_status, forecast_plot]) | |
| # TAB 3: Robot Control | |
| with gr.Tab("๐ค Robot Control"): | |
| with gr.Row(): | |
| command_input = gr.Textbox(label="Command", placeholder="e.g., water tomato...", scale=3) | |
| send_btn = gr.Button("โ๏ธ Send", variant="primary", scale=1) | |
| command_output = gr.Textbox(interactive=False, lines=3) | |
| send_btn.click(fn=send_robot_command, inputs=[command_input], outputs=[command_output]) | |
| # TAB 4: Care Guide | |
| with gr.Tab("๐ Care Guide"): | |
| with gr.Row(): | |
| plant_dropdown = gr.Dropdown( | |
| choices=sorted(list(PLANT_DATABASE.keys())), | |
| label="Select Plant", | |
| scale=2 | |
| ) | |
| care_btn = gr.Button("๐ Show Info", variant="primary", scale=1) | |
| with gr.Row(): | |
| care_output = gr.Markdown() | |
| plant_image = gr.Image(height=300) | |
| care_btn.click(fn=get_care_tips_interface, inputs=[plant_dropdown], outputs=[care_output, plant_image]) | |
| # TAB 5: Gallery & Training | |
| with gr.Tab("๐ผ๏ธ Gallery & Training"): | |
| refresh_gallery_btn = gr.Button("๐ Refresh Gallery", variant="secondary") | |
| gallery_status = gr.Textbox(interactive=False) | |
| cloudinary_gallery = gr.Gallery(columns=4, height=400) | |
| refresh_gallery_btn.click(fn=refresh_cloudinary_images_interface, outputs=[gallery_status, cloudinary_gallery]) | |
| gr.Markdown("---") | |
| gr.Markdown("### ๐ Manual Training") | |
| with gr.Row(): | |
| manual_image = gr.Image(type="filepath", height=300) | |
| with gr.Column(): | |
| correction_dropdown = gr.Dropdown( | |
| choices=sorted(list(PLANT_DATABASE.keys())), | |
| label="Correct Identification" | |
| ) | |
| save_btn = gr.Button("๐พ Save & Update", variant="primary") | |
| correction_output = gr.Textbox(interactive=False) | |
| save_btn.click(fn=save_plant_definition, inputs=[manual_image, correction_dropdown], outputs=[correction_output]) | |
| # TAB 6: Batch Analysis | |
| with gr.Tab("๐ค Batch Analysis"): | |
| with gr.Row(): | |
| max_images_slider = gr.Slider(1, 50, value=10, step=1, label="Number of Images", scale=2) | |
| batch_btn = gr.Button("๐ Start", variant="primary", scale=1) | |
| batch_summary = gr.Markdown() | |
| batch_df = gr.DataFrame(interactive=False) | |
| batch_gallery = gr.Gallery(columns=5, height=400) | |
| batch_file = gr.File(interactive=False) | |
| batch_btn.click( | |
| fn=analyze_cloudinary_image_batch, | |
| inputs=[max_images_slider], | |
| outputs=[batch_summary, batch_gallery, batch_df, batch_file] | |
| ) | |
| # TAB 7: System Info | |
| with gr.Tab("โน๏ธ System Info"): | |
| system_info = f""" | |
| ## ๐ฑ PLANETYOYO AI v19.10 | |
| ### ๐ What's New in v19.10 | |
| **Enhanced Retry Logic:** | |
| - ๐ Up to {data_integrator.max_retries}x retry attempts for Cloudinary | |
| - ๐ Up to {data_integrator.max_retries}x retry attempts for Adafruit IO | |
| - ๐ก REST API fallback for both services | |
| - โฑ๏ธ Exponential backoff between retries | |
| **Disease Filtering:** | |
| - โ Health predictions now only show diseases/conditions | |
| - โ Plant names automatically filtered from health results | |
| - ๐ Only labels containing disease keywords accepted | |
| - ๐ Filter statistics shown in analysis | |
| ### ๐ System Status | |
| **Active Components:** | |
| - ๐ค AI Engine: {'โ ' if AI_AVAILABLE else 'โ'} | |
| - ๐ก Adafruit IO: {'โ ' if data_integrator.aio else 'โ'} | |
| - โ๏ธ Cloudinary: {'โ ' if CLOUDINARY_AVAILABLE and CLOUDINARY_CLOUD_NAME else 'โ'} | |
| - ๐ฎ Prophet: {'โ ' if PROPHET_AVAILABLE else 'โ'} | |
| **Retry Configuration:** | |
| - Max retries: {data_integrator.max_retries} | |
| - Base delay: {data_integrator.retry_delay}s | |
| - Fallback: REST API | |
| ### ๐ง Features | |
| - **Dual Consensus:** Separate Species + Health analysis | |
| - **Disease Filtering:** Only valid disease labels in health results | |
| - **Robust Retry:** Multiple strategies for data fetching | |
| - **Learning System:** Improves from user corrections | |
| """ | |
| gr.Markdown(system_info) | |
| gr.Markdown(""" | |
| --- | |
| <div style="text-align: center; color: #666;"> | |
| <p>๐ฑ PLANETYOYO AI v19.10 | Enhanced Reliability & Filtering</p> | |
| </div> | |
| """) | |
| return app | |
| # ======================================================== | |
| # MAIN ENTRY POINT | |
| # ======================================================== | |
| if __name__ == "__main__": | |
| print("\n" + "=" * 80) | |
| print(" " * 20 + "๐ฑ PLANETYOYO AI Ultimate v19.10") | |
| print(" " * 15 + "Enhanced Retry Logic + Disease Filtering") | |
| print("=" * 80) | |
| print(f"\nโฐ Startup: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n") | |
| print("๐ System Status:") | |
| print(f" โข AI Engine: {'โ Active' if AI_AVAILABLE else 'โ Install: pip install torch transformers'}") | |
| print(f" โข Device: {device.upper()}") | |
| print(f" โข Adafruit IO: {'โ Connected' if data_integrator.aio else 'โ ๏ธ Mock Data Mode'}") | |
| print(f" โข Cloudinary: {'โ Connected' if CLOUDINARY_AVAILABLE and CLOUDINARY_CLOUD_NAME else 'โ ๏ธ Placeholder Mode'}") | |
| print(f" โข Prophet: {'โ Available' if PROPHET_AVAILABLE else 'โ ๏ธ Install: pip install prophet'}") | |
| print(f" โข Geopy: {'โ Available' if GEOPY_AVAILABLE else 'โ ๏ธ Install: pip install geopy'}") | |
| print(f" โข Max Retries: {data_integrator.max_retries}") | |
| print(f" โข Plant Models: {len(PLANT_AI_MODELS)}") | |
| # Feature availability | |
| print("\n๐ง Feature Availability:") | |
| if not data_integrator.aio: | |
| print(" โ ๏ธ Sensor data: Using mock/simulated data") | |
| if not CLOUDINARY_AVAILABLE or not CLOUDINARY_CLOUD_NAME: | |
| print(" โ ๏ธ Image gallery: Using placeholder images") | |
| if not PROPHET_AVAILABLE: | |
| print(" โ ๏ธ Forecasting: Disabled (install prophet)") | |
| if AI_AVAILABLE: | |
| print(" โ Plant Analysis: Fully functional") | |
| print("\n๐ Loading model weights...") | |
| MODEL_WEIGHTS = load_weights() | |
| if AI_AVAILABLE: | |
| print("\n๐ก TIP: Model preload may take 5-10 minutes on first run...") | |
| preload_all_models() | |
| else: | |
| print("\nโ AI Disabled - Install dependencies:") | |
| print(" pip install torch transformers") | |
| print("\nโ ๏ธ System will run in limited mode (no plant analysis)") | |
| print("\n๐ Launching Gradio Interface...") | |
| print("\n๐ก TIPS:") | |
| print(" โข Missing dependencies? System uses mock data automatically") | |
| print(" โข Optional features gracefully degrade") | |
| print(" โข Core AI analysis works even without IoT integrations") | |
| print("=" * 80 + "\n") | |
| app = create_gradio_app() | |
| app.launch(server_name="0.0.0.0", server_port=7860, share=False, show_error=True) |