Reorganize WNDB by responsibility and remove legacy scheme endpoints.\n\nRoute analysis and time-series access through project pools, preserve transactional realtime replacement, and refresh GIS materialized views after writes.\n\nAdd database architecture documentation, live pooling coverage, API contract updates, and executable container verification.\n\nBREAKING CHANGE: legacy scheme APIs and flat app.native.wndb module imports are removed.
57 lines
1.9 KiB
Python
57 lines
1.9 KiB
Python
from typing import Any
|
|
|
|
from psycopg import AsyncConnection
|
|
|
|
|
|
def _optional_text(value: Any) -> str | None:
|
|
return str(value).strip() if value is not None else None
|
|
|
|
|
|
def _optional_float(value: Any) -> float | None:
|
|
return float(value) if value is not None else None
|
|
|
|
|
|
def _optional_int(value: Any) -> int | None:
|
|
return int(value) if value is not None else None
|
|
|
|
|
|
class ScadaInfoRepository:
|
|
"""Read SCADA metadata from the current project's business database."""
|
|
|
|
@staticmethod
|
|
async def get_scadas(conn: AsyncConnection) -> list[dict[str, Any]]:
|
|
async with conn.cursor() as cur:
|
|
await cur.execute(
|
|
"""
|
|
SELECT id AS device_id,
|
|
device_type,
|
|
node_id,
|
|
link_id,
|
|
api_query_id,
|
|
transmission_mode,
|
|
transmission_frequency,
|
|
reliability,
|
|
x,
|
|
y
|
|
FROM gis.scada_devices
|
|
ORDER BY id
|
|
"""
|
|
)
|
|
records = await cur.fetchall()
|
|
|
|
return [
|
|
{
|
|
"device_id": str(record["device_id"]).strip(),
|
|
"device_type": str(record["device_type"]).strip().lower(),
|
|
"node_id": _optional_text(record["node_id"]),
|
|
"link_id": _optional_text(record["link_id"]),
|
|
"api_query_id": _optional_text(record["api_query_id"]),
|
|
"transmission_mode": record["transmission_mode"],
|
|
"transmission_frequency": record["transmission_frequency"],
|
|
"reliability": _optional_int(record["reliability"]),
|
|
"x": _optional_float(record["x"]),
|
|
"y": _optional_float(record["y"]),
|
|
}
|
|
for record in records
|
|
]
|