Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions ogscope/algorithms/plate_solve/centroid_quality.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ def _reject_dense_clusters(
return kept, removed, removed_pts


def _point_line_dist(points_yx: np.ndarray, p0: np.ndarray, p1: np.ndarray) -> np.ndarray:
def _point_line_dist(
points_yx: np.ndarray, p0: np.ndarray, p1: np.ndarray
) -> np.ndarray:
"""点到线段距离(像素)/ Distance from points to segment."""
# segment vector
vx = p1[1] - p0[1]
Expand Down Expand Up @@ -221,9 +223,11 @@ def filter_centroids_yx(
)

n1 = int(xy3.shape[0])
rejected_pts = np.concatenate(
[dense_removed, line_removed], axis=0
) if (dense_removed.size > 0 or line_removed.size > 0) else np.empty((0, 2), dtype=np.float64)
rejected_pts = (
np.concatenate([dense_removed, line_removed], axis=0)
if (dense_removed.size > 0 or line_removed.size > 0)
else np.empty((0, 2), dtype=np.float64)
)
quality: dict[str, Any] = {
"level": lv,
"flags": flags,
Expand Down
4 changes: 1 addition & 3 deletions ogscope/algorithms/plate_solve/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,7 @@ def solve(
sorted_stars = sorted(stars, key=lambda s: s.flux, reverse=True)
cyx = np.array([[s.y, s.x] for s in sorted_stars], dtype=np.float64)
overlay = (
_make_solve_overlay(
{}, cyx, None, (height, width), (height, width)
)
_make_solve_overlay({}, cyx, None, (height, width), (height, width))
if len(cyx) > 0
else None
)
Expand Down
4 changes: 3 additions & 1 deletion ogscope/config_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

ConfigFileScope = Literal["ogscope", "network", "both"]

_CATALOG_SECTIONS: tuple[tuple[str, str, str, ConfigFileScope, tuple[str, ...]], ...] = (
_CATALOG_SECTIONS: tuple[
tuple[str, str, str, ConfigFileScope, tuple[str, ...]], ...
] = (
(
"basic",
"基础",
Expand Down
46 changes: 31 additions & 15 deletions ogscope/core/application/core_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
stream_state_domain_service,
)
from ogscope.domain.system.services import system_info_service
from ogscope.platform.hardware_plane.runtime import get_hardware_plane_client
from ogscope.platform.hardware.wifi_switch import wifi_switch_service
from ogscope.platform.hardware_plane.runtime import get_hardware_plane_client


@dataclass(slots=True)
Expand Down Expand Up @@ -106,7 +106,9 @@ async def get_system_status(self) -> dict[str, Any]:
wifi_raw = wifi_switch_service.get_status()
hardware_client = get_hardware_plane_client()
hw_status_resp = await hardware_client.status_get()
hw_status_data = hw_status_resp.get("data", {}) if hw_status_resp.get("success") else {}
hw_status_data = (
hw_status_resp.get("data", {}) if hw_status_resp.get("success") else {}
)
camera_service_status = (
hw_status_data.get("services", {}).get("camera", {})
if isinstance(hw_status_data, dict)
Expand Down Expand Up @@ -150,15 +152,21 @@ async def get_system_status(self) -> dict[str, Any]:
"version": __version__,
"capabilities": capability_map(),
"hardware_plane": {
"started": bool(hw_status_data.get("started", False))
if isinstance(hw_status_data, dict)
else False,
"metrics": hw_status_data.get("metrics", {})
if isinstance(hw_status_data, dict)
else {},
"services": hw_status_data.get("services", {})
if isinstance(hw_status_data, dict)
else {},
"started": (
bool(hw_status_data.get("started", False))
if isinstance(hw_status_data, dict)
else False
),
"metrics": (
hw_status_data.get("metrics", {})
if isinstance(hw_status_data, dict)
else {}
),
"services": (
hw_status_data.get("services", {})
if isinstance(hw_status_data, dict)
else {}
),
},
"system": system,
"camera": {"success": True, **camera_status},
Expand All @@ -178,9 +186,15 @@ async def get_camera_status(self) -> dict[str, Any]:
status = await camera_domain_service.get_status()
normalized = self._normalize_camera_status(status)
if hp_camera:
normalized["connected"] = bool(hp_camera.get("connected", normalized["connected"]))
normalized["streaming"] = bool(hp_camera.get("streaming", normalized["streaming"]))
normalized["recording"] = bool(hp_camera.get("recording", normalized["recording"]))
normalized["connected"] = bool(
hp_camera.get("connected", normalized["connected"])
)
normalized["streaming"] = bool(
hp_camera.get("streaming", normalized["streaming"])
)
normalized["recording"] = bool(
hp_camera.get("recording", normalized["recording"])
)
return {"success": True, **normalized}

async def start_camera(self) -> dict[str, Any]:
Expand Down Expand Up @@ -222,7 +236,9 @@ async def tune_camera(self, payload: dict[str, Any]) -> dict[str, Any]:
applied["auto_exposure"] = bool(auto_exposure)

if payload.get("exposure_us") is not None:
await camera_domain_service.update_settings({"exposure": payload["exposure_us"]})
await camera_domain_service.update_settings(
{"exposure": payload["exposure_us"]}
)
applied["exposure_us"] = int(payload["exposure_us"])

if payload.get("analogue_gain") is not None:
Expand Down
1 change: 0 additions & 1 deletion ogscope/domain/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
"""
领域层聚合导出 / Domain layer package exports.
"""

1 change: 0 additions & 1 deletion ogscope/domain/analysis/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from ogscope.domain.analysis.services import analysis_domain_service

__all__ = ["analysis_domain_service"]

5 changes: 3 additions & 2 deletions ogscope/domain/analysis/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ def resolve_upload_file_response(path: Path) -> tuple[Path, str]:
return path, media or "application/octet-stream"

@staticmethod
def parse_frame_upload_payload(payload: str) -> tuple[dict[str, Any], dict[str, Any]]:
def parse_frame_upload_payload(
payload: str,
) -> tuple[dict[str, Any], dict[str, Any]]:
obj = json.loads(payload)
if not isinstance(obj, dict):
raise ValueError("payload 必须为 JSON 对象 / payload must be a JSON object")
Expand All @@ -51,4 +53,3 @@ def parse_frame_upload_payload(payload: str) -> tuple[dict[str, Any], dict[str,
analysis_domain_service = AnalysisDomainService()

__all__ = ["analysis_domain_service", "AnalysisDomainService"]

1 change: 0 additions & 1 deletion ogscope/domain/camera/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@
)

__all__ = ["DebugCameraService", "DebugFileService", "DebugPresetService"]

41 changes: 29 additions & 12 deletions ogscope/domain/camera/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
import time
from typing import Any

from fastapi import HTTPException
from fastapi.responses import Response
from starlette.requests import Request

from ogscope.platform.adapters.debug_services import get_debug_services_module
from ogscope.config import get_settings
from ogscope.domain.camera.stream_limiter import get_mjpeg_stream_limiter
from ogscope.platform.adapters.debug_services import get_debug_services_module

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -173,11 +172,15 @@ async def get_runtime_overrides():

@staticmethod
async def clear_runtime_overrides():
return await _debug_services_module().DebugCameraService.clear_runtime_overrides()
return (
await _debug_services_module().DebugCameraService.clear_runtime_overrides()
)

@staticmethod
async def apply_runtime_overrides_as_defaults():
return await _debug_services_module().DebugCameraService.apply_runtime_overrides_as_defaults()
return (
await _debug_services_module().DebugCameraService.apply_runtime_overrides_as_defaults()
)

@staticmethod
async def start_camera():
Expand Down Expand Up @@ -229,7 +232,9 @@ async def set_fps(fps: int):

@staticmethod
async def update_settings(settings: dict[str, Any]):
return await _debug_services_module().DebugCameraService.update_settings(settings)
return await _debug_services_module().DebugCameraService.update_settings(
settings
)

@staticmethod
async def set_auto_exposure_mode(enabled: bool):
Expand All @@ -251,19 +256,27 @@ async def get_image_quality():

@staticmethod
async def apply_night_mode_preset():
return await _debug_services_module().DebugCameraService.apply_night_mode_preset()
return (
await _debug_services_module().DebugCameraService.apply_night_mode_preset()
)

@staticmethod
async def save_current_settings_backup():
return await _debug_services_module().DebugCameraService.save_current_settings_backup()
return (
await _debug_services_module().DebugCameraService.save_current_settings_backup()
)

@staticmethod
async def restore_settings_backup():
return await _debug_services_module().DebugCameraService.restore_settings_backup()
return (
await _debug_services_module().DebugCameraService.restore_settings_backup()
)

@staticmethod
async def set_color_mode(color_mode: str):
return await _debug_services_module().DebugCameraService.set_color_mode(color_mode)
return await _debug_services_module().DebugCameraService.set_color_mode(
color_mode
)

@staticmethod
async def set_white_balance(mode: str, gain_r: float, gain_b: float):
Expand Down Expand Up @@ -307,11 +320,16 @@ async def save_preset(payload: dict[str, Any]):

@staticmethod
async def apply_preset(preset_name: str):
return await _debug_services_module().DebugPresetService.apply_preset(preset_name)
return await _debug_services_module().DebugPresetService.apply_preset(
preset_name
)

@staticmethod
async def delete_preset(preset_name: str):
return await _debug_services_module().DebugPresetService.delete_preset(preset_name)
return await _debug_services_module().DebugPresetService.delete_preset(
preset_name
)


__all__ = [
"DebugCameraService",
Expand All @@ -323,4 +341,3 @@ async def delete_preset(preset_name: str):
"file_domain_service",
"stream_state_domain_service",
]

1 change: 0 additions & 1 deletion ogscope/domain/camera/sidecar.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,3 @@ def merge_capture_sidecar_into_info(
if key not in capture_info:
capture_info[key] = value
info.update(capture_info)

1 change: 0 additions & 1 deletion ogscope/domain/camera/stream_limiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,3 @@ def get_mjpeg_stream_limiter() -> MjpegStreamLimiter:
if _limiter is None:
_limiter = MjpegStreamLimiter(get_settings().stream_max_mjpeg_clients)
return _limiter

1 change: 0 additions & 1 deletion ogscope/domain/camera/streaming.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,3 @@ async def frame_generator():
frame_generator(),
media_type=f"multipart/x-mixed-replace; boundary={boundary}",
)

1 change: 0 additions & 1 deletion ogscope/domain/network/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from ogscope.domain.network.services import wifi_domain_service

__all__ = ["wifi_domain_service"]

1 change: 0 additions & 1 deletion ogscope/domain/network/nmcli_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,4 +403,3 @@ async def _sta_rollback_loop() -> None:
raise
except Exception as e:
logger.error("STA 回滚失败 / Rollback to AP failed: {}", e)

19 changes: 13 additions & 6 deletions ogscope/domain/network/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import subprocess

from ogscope.config import get_settings
from ogscope.platform.hardware.wifi_switch import wifi_switch_service
from ogscope.domain.network import nmcli_services as net_impl
from ogscope.platform.hardware.wifi_switch import wifi_switch_service


class WifiDomainService:
Expand All @@ -27,7 +27,9 @@ def build_wifi_status() -> dict:
ap_connection = data.get("AP_CONNECTION", settings.wifi_ap_connection)
ap_ipv4 = data.get("AP_IPV4") or None
ap_url_hint = (
f"http://{settings.wifi_ap_url_host}:{settings.port}" if mode == "ap" else None
f"http://{settings.wifi_ap_url_host}:{settings.port}"
if mode == "ap"
else None
)
message = data.get("error")
suffix = settings.device_id_suffix or None
Expand Down Expand Up @@ -58,7 +60,9 @@ async def switch_mode(self, mode: str) -> dict:

async def scan_wifi(self):
settings = get_settings()
return await asyncio.to_thread(net_impl.nmcli_wifi_scan, settings.wifi_interface)
return await asyncio.to_thread(
net_impl.nmcli_wifi_scan, settings.wifi_interface
)

async def list_profiles(self):
settings = get_settings()
Expand All @@ -68,7 +72,9 @@ async def connect_sta(self, ssid: str, password: str) -> dict:
settings = get_settings()
if not wifi_switch_service.is_configured():
raise RuntimeError("wifi_not_configured")
await asyncio.to_thread(net_impl.nmcli_modify_sta_to_ssid, settings, ssid, password)
await asyncio.to_thread(
net_impl.nmcli_modify_sta_to_ssid, settings, ssid, password
)
await asyncio.to_thread(wifi_switch_service.switch, "sta")
net_impl.schedule_sta_rollback_watch()
return self.build_wifi_status()
Expand All @@ -83,7 +89,9 @@ async def activate_profile(self, connection_name: str) -> dict:
if name == settings.wifi_sta_connection:
await asyncio.to_thread(wifi_switch_service.switch, "sta")
else:
await asyncio.to_thread(net_impl.nm_down_if_exists, settings.wifi_ap_connection)
await asyncio.to_thread(
net_impl.nm_down_if_exists, settings.wifi_ap_connection
)
await asyncio.to_thread(net_impl.nmcli_activate_connection, settings, name)
net_impl.schedule_sta_rollback_watch()
return self.build_wifi_status()
Expand Down Expand Up @@ -115,4 +123,3 @@ async def activate_profile(self, connection_name: str) -> dict:
"TimeoutExpired",
"CalledProcessError",
]

1 change: 0 additions & 1 deletion ogscope/domain/shared/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,3 @@ def ensure_safe_basename(filename: str) -> str:
if "/" in safe_name or "\\" in safe_name:
raise ValueError("invalid filename")
return safe_name

1 change: 0 additions & 1 deletion ogscope/domain/system/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from ogscope.domain.system.services import system_info_service

__all__ = ["system_info_service"]

5 changes: 3 additions & 2 deletions ogscope/domain/system/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,9 @@ def read_systemd_logs(
rt = item.get("__REALTIME_TIMESTAMP")
try:
if rt is not None:
ts = dt.datetime.fromtimestamp(int(str(rt)) / 1_000_000, tz=dt.timezone.utc)
ts = dt.datetime.fromtimestamp(
int(str(rt)) / 1_000_000, tz=dt.timezone.utc
)
ts_iso = ts.isoformat()
except (ValueError, TypeError):
ts_iso = None
Expand Down Expand Up @@ -256,4 +258,3 @@ def _journal_priority_to_level(priority: str | int | None) -> str:
system_info_service = SystemInfoService()

__all__ = ["SystemInfoService", "system_info_service", "read_systemd_logs"]

1 change: 0 additions & 1 deletion ogscope/platform/adapters/debug_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@
def get_debug_services_module():
"""延迟加载调试实现模块 / Lazy load debug implementation module."""
return importlib.import_module("ogscope.web.api.debug.services")

Loading
Loading