Spaces:
Sleeping
Sleeping
| import logging, sys, asyncio, random, json, requests, os | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| # ============================================================ | |
| # LOGGER SETUP | |
| # ============================================================ | |
| logger = logging.getLogger("ai_engine_dummy") | |
| logger.setLevel(logging.INFO) | |
| # Handler untuk tampil di console | |
| handler = logging.StreamHandler(sys.stdout) | |
| formatter = logging.Formatter("[%(asctime)s] %(levelname)s → %(message)s", "%H:%M:%S") | |
| handler.setFormatter(formatter) | |
| logger.addHandler(handler) | |
| # ============================================================ | |
| # HELPER FUNCTION (opsional untuk simulasi delay) | |
| # ============================================================ | |
| async def async_sleep_random(min_s=0.2, max_s=0.8): | |
| """ | |
| Helper untuk simulasi waktu inferensi secara acak. | |
| """ | |
| durasi = random.uniform(min_s, max_s) | |
| await asyncio.sleep(durasi) | |
| # ============================================================== | |
| # VALIDATION FUNCTION | |
| # ============================================================== | |
| def validate_input(required_parts_fields, station_id, cameras, parts, webhook_url): | |
| errors = [] | |
| # Validate station_id | |
| if not station_id or not str(station_id).strip(): | |
| errors.append("station_id is missing or empty") | |
| # Validate parts | |
| for field in required_parts_fields: | |
| if field not in parts or not str(parts[field]).strip(): | |
| errors.append(f"parts.{field} is missing or empty") | |
| # Validate cameras list | |
| if not isinstance(cameras, list) or len(cameras) == 0: | |
| errors.append("cameras must be a non-empty list") | |
| else: | |
| for index, cam in enumerate(cameras): | |
| if "camera_id" not in cam or not str(cam["camera_id"]).strip(): | |
| errors.append(f"camera[{index}].camera_id missing or empty") | |
| if "image_base64" not in cam or not str(cam["image_base64"]).strip(): | |
| errors.append(f"camera[{index}].image_base64 missing or empty") | |
| # if "rtsp_url" not in cam or not str(cam["rtsp_url"]).strip(): | |
| # errors.append(f"camera[{index}].rtsp_url missing or empty") | |
| # Validate webhook | |
| if not webhook_url or not webhook_url.startswith("http"): | |
| errors.append("webhook_url is invalid or missing") | |
| return errors | |
| # ============================================================ | |
| # HELPER | |
| # ============================================================ | |
| def _metadata(): | |
| """ | |
| load file metadata.json into json data | |
| """ | |
| path = Path("metadata/product.json") | |
| if not path.exists(): | |
| return {"status": "error", "message": "metadata.json not found"} | |
| with open(path, "r") as f: | |
| data = json.load(f) | |
| return data | |
| def _color_map(): | |
| path = Path("metadata/defect.json") | |
| if not path.exists(): | |
| return [] | |
| with open(path, "r") as f: | |
| return json.load(f) | |
| def model_by_id_metadata(part_id): | |
| """ | |
| part_id = "4" # id part / product | |
| get model_path from metadata by part_id | |
| """ | |
| metadata = _metadata() | |
| id_part = part_id | |
| item = next((x for x in metadata if x["id"] == id_part), None) | |
| model_path = item['model_path'] | |
| return model_path | |
| def model_by_pin_metadata(pin_api): | |
| """ | |
| pin_api = "JI4ACL-GCSBYHBK03" # PIN API from part / product | |
| get model_path from metadata by pin_api | |
| """ | |
| metadata = _metadata() | |
| pin_api = pin_api | |
| item = next((x for x in metadata if x["pin_api"] == pin_api), None) | |
| model_path = item['model_path'] | |
| return model_path | |
| def color_defect(defect_name): | |
| """ | |
| Return BGR tuple color for OpenCV bounding box. | |
| """ | |
| defect_name = defect_name.lower() | |
| data = _color_map() | |
| item = next((x for x in data if x["class"].lower() == defect_name), None) | |
| if item is None: | |
| return (0, 255, 0) # Default GREEN jika tidak ditemukan | |
| hex_color = item["color"].lstrip('#') | |
| r = int(hex_color[0:2], 16) | |
| g = int(hex_color[2:4], 16) | |
| b = int(hex_color[4:6], 16) | |
| return (b, g, r) # Convert to BGR | |
| def load_json(path): | |
| with open(path, "r") as f: | |
| return json.load(f) | |
| def start_detection(base_url, payload): | |
| return requests.post(f"{base_url}/start-detection", json=payload) | |
| def load_config(): | |
| load_dotenv() | |
| return os.getenv("BASE_URL"), os.getenv("WEBHOOK") |