Files
Northern-Thailand-Ping-Rive…/src/models.py
T
grabowski 9cac9c4d2a style: apply black/isort across the repo; make CI mypy advisory
The push-CI gates (black/isort/mypy) had never actually run before the
branch-trigger fix, and the codebase predates them. Formatting is now
black/isort clean repo-wide. mypy keeps running but non-blocking: 86
pre-existing errors are a separate cleanup, not a gate to hold hostage.
2026-08-10 15:57:00 +07:00

122 lines
3.2 KiB
Python

#!/usr/bin/env python3
"""
Data models for water monitoring system
"""
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Any, Dict, List, Optional
class DatabaseType(Enum):
SQLITE = "sqlite"
MYSQL = "mysql"
POSTGRESQL = "postgresql"
INFLUXDB = "influxdb"
VICTORIAMETRICS = "victoriametrics"
class StationStatus(Enum):
ACTIVE = "active"
INACTIVE = "inactive"
MAINTENANCE = "maintenance"
ERROR = "error"
@dataclass
class StationInfo:
"""Station information model"""
station_id: int
station_code: str
thai_name: str
english_name: str
latitude: Optional[float] = None
longitude: Optional[float] = None
geohash: Optional[str] = None
status: StationStatus = StationStatus.ACTIVE
@dataclass
class WaterMeasurement:
"""Water measurement data model"""
timestamp: datetime
station_info: StationInfo
water_level: float
discharge: float
water_level_unit: str = "m"
discharge_unit: str = "cms"
discharge_percent: Optional[float] = None
status: StationStatus = StationStatus.ACTIVE
def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary for database storage"""
return {
"timestamp": self.timestamp,
"station_id": self.station_info.station_id,
"station_code": self.station_info.station_code,
"station_name_en": self.station_info.english_name,
"station_name_th": self.station_info.thai_name,
"latitude": self.station_info.latitude,
"longitude": self.station_info.longitude,
"geohash": self.station_info.geohash,
"water_level": self.water_level,
"water_level_unit": self.water_level_unit,
"discharge": self.discharge,
"discharge_unit": self.discharge_unit,
"discharge_percent": self.discharge_percent,
"status": self.status.value,
}
@dataclass
class DatabaseConfig:
"""Database configuration model"""
db_type: DatabaseType
connection_string: Optional[str] = None
host: Optional[str] = None
port: Optional[int] = None
database: Optional[str] = None
username: Optional[str] = None
password: Optional[str] = None
additional_params: Dict[str, Any] = field(default_factory=dict)
@dataclass
class ScrapingResult:
"""Result of a scraping operation"""
success: bool
measurements_count: int
error_message: Optional[str] = None
timestamp: datetime = field(default_factory=datetime.now)
processing_time_seconds: Optional[float] = None
@dataclass
class StationCreateRequest:
"""Request model for creating a new station"""
station_code: str
thai_name: str
english_name: str
latitude: Optional[float] = None
longitude: Optional[float] = None
geohash: Optional[str] = None
status: StationStatus = StationStatus.ACTIVE
@dataclass
class StationUpdateRequest:
"""Request model for updating an existing station"""
thai_name: Optional[str] = None
english_name: Optional[str] = None
latitude: Optional[float] = None
longitude: Optional[float] = None
geohash: Optional[str] = None
status: Optional[StationStatus] = None