translated to russian

This commit is contained in:
ayzen
2025-10-15 17:29:15 +03:00
parent 85ac55cf1e
commit 99200aad83
3 changed files with 56 additions and 56 deletions

View File

@ -65,13 +65,13 @@ class BScanProcessor(BaseProcessor):
return [ return [
UIParameter( UIParameter(
name="open_air", name="open_air",
label="Open Air Reference", label="Референс открытого воздуха",
type="toggle", type="toggle",
value=cfg["open_air"], value=cfg["open_air"],
), ),
UIParameter( UIParameter(
name="axis", name="axis",
label="Axis", label="Ось",
type="select", type="select",
value=cfg["axis"], value=cfg["axis"],
options={"choices": ["real", "abs", "phase"]}, options={"choices": ["real", "abs", "phase"]},
@ -85,45 +85,45 @@ class BScanProcessor(BaseProcessor):
# ), # ),
UIParameter( UIParameter(
name="cut", name="cut",
label="Cut (m)", label="Отсечка (м)",
type="slider", type="slider",
value=cfg["cut"], value=cfg["cut"],
options={"min": 0.0, "max": 2.0, "step": 0.001, "dtype": "float"}, options={"min": 0.0, "max": 2.0, "step": 0.001, "dtype": "float"},
), ),
UIParameter( UIParameter(
name="max", name="max",
label="Max Depth (m)", label="Макс. глубина (м)",
type="slider", type="slider",
value=cfg["max"], value=cfg["max"],
options={"min": 0.1, "max": 5.0, "step": 0.1, "dtype": "float"}, options={"min": 0.1, "max": 5.0, "step": 0.1, "dtype": "float"},
), ),
UIParameter( UIParameter(
name="gain", name="gain",
label="Gain Factor", label="Коэф. усиления",
type="slider", type="slider",
value=cfg["gain"], value=cfg["gain"],
options={"min": 0.0, "max": 3.0, "step": 0.1, "dtype": "float"}, options={"min": 0.0, "max": 3.0, "step": 0.1, "dtype": "float"},
), ),
UIParameter( UIParameter(
name="start_freq", name="start_freq",
label="Start Frequency (MHz)", label="Нач. частота (МГц)",
type="slider", type="slider",
value=cfg["start_freq"], value=cfg["start_freq"],
options={"min": 100.0, "max": 8800.0, "step": 10.0, "dtype": "float"}, options={"min": 100.0, "max": 8800.0, "step": 10.0, "dtype": "float"},
), ),
UIParameter( UIParameter(
name="stop_freq", name="stop_freq",
label="Stop Frequency (MHz)", label="Кон. частота (МГц)",
type="slider", type="slider",
value=cfg["stop_freq"], value=cfg["stop_freq"],
options={"min": 100.0, "max": 8800.0, "step": 10.0, "dtype": "float"}, options={"min": 100.0, "max": 8800.0, "step": 10.0, "dtype": "float"},
), ),
UIParameter( UIParameter(
name="clear_history", name="clear_history",
label="Clear Plot History", label="Очистить историю",
type="button", type="button",
value=False, value=False,
options={"action": "Clear accumulated plot history"}, options={"action": "Очистить накопленную историю графика"},
), ),
] ]
@ -258,10 +258,10 @@ class BScanProcessor(BaseProcessor):
return { return {
"data": [], "data": [],
"layout": { "layout": {
"title": "B-Scan Analysis - Error", "title": "B-Scan анализ - Ошибка",
"annotations": [ "annotations": [
{ {
"text": f"Error: {processed_data['error']}", "text": f"Ошибка: {processed_data['error']}",
"x": 0.5, "x": 0.5,
"y": 0.5, "y": 0.5,
"xref": "paper", "xref": "paper",
@ -280,9 +280,9 @@ class BScanProcessor(BaseProcessor):
return { return {
"data": [], "data": [],
"layout": { "layout": {
"title": "B-Scan Analysis - No Data", "title": "B-Scan анализ - Нет данных",
"xaxis": {"title": "Sweep Number"}, "xaxis": {"title": "Номер развертки"},
"yaxis": {"title": "Depth (m)"}, "yaxis": {"title": "Глубина (м)"},
"template": "plotly_dark", "template": "plotly_dark",
}, },
} }
@ -316,11 +316,11 @@ class BScanProcessor(BaseProcessor):
"y": y_coords, "y": y_coords,
"z": z_values, "z": z_values,
"colorscale": colorscale, "colorscale": colorscale,
"colorbar": {"title": "Amplitude"}, "colorbar": {"title": "Амплитуда"},
"hovertemplate": ( "hovertemplate": (
"Sweep: %{x}<br>" "Развертка: %{x}<br>"
"Depth: %{y:.3f} m<br>" "Глубина: %{y:.3f} м<br>"
"Amplitude: %{z:.3f}<br>" "Амплитуда: %{z:.3f}<br>"
"<extra></extra>" "<extra></extra>"
), ),
**heatmap_kwargs, **heatmap_kwargs,
@ -328,28 +328,28 @@ class BScanProcessor(BaseProcessor):
freq_start, freq_stop = processed_data.get("frequency_range", [0.0, 0.0]) freq_start, freq_stop = processed_data.get("frequency_range", [0.0, 0.0])
config_info = ( config_info = (
f"Freq: {freq_start/1e6:.1f}-{freq_stop/1e6:.1f} MHz | " f"Частота: {freq_start/1e6:.1f}-{freq_stop/1e6:.1f} МГц | "
f"Gain: {self._config['gain']:.1f} | " f"Усиление: {self._config['gain']:.1f} | "
f"Cut: {self._config['cut']:.3f} m | " f"Отсечка: {self._config['cut']:.3f} м | "
f"Max: {self._config['max']:.1f} m | " f"Макс глубина: {self._config['max']:.1f} м | "
f"Axis: {self._config['axis']} | " f"Ось: {self._config['axis']} | "
f"Sweeps: {len(history)}" f"Разверток: {len(history)}"
) )
if processed_data.get("reference_used", False): if processed_data.get("reference_used", False):
config_info += " | Open Air: ON" config_info += " | Открытый воздух: ВКЛ"
# if self._config["data_limitation"]: # if self._config["data_limitation"]:
# config_info += f" | Limit: {self._config['data_limitation']}" # config_info += f" | Limit: {self._config['data_limitation']}"
layout = { layout = {
"title": f"B-Scan Heatmap - {config_info}", "title": f"B-Scan тепловая карта - {config_info}",
"xaxis": {"title": "Sweep Number", "side": "bottom"}, "xaxis": {"title": "Номер развертки", "side": "bottom"},
"yaxis": {"title": "Depth (m)", "autorange": "reversed"}, "yaxis": {"title": "Глубина (м)", "autorange": "reversed"},
"hovermode": "closest", "hovermode": "closest",
"height": 546, "height": 546,
"template": "plotly_dark", "template": "plotly_dark",
"margin": {"t": 40, "r": 50, "b": 110, "l": 50}, "margin": {"t": 40, "r": 50, "b": 110, "l": 50},
"autosize": True "autosize": True
} }

View File

@ -137,7 +137,7 @@ class MagnitudeProcessor(BaseProcessor):
"y": mags_db, "y": mags_db,
"type": "scatter", "type": "scatter",
"mode": "lines", "mode": "lines",
"name": f"|{parameter_type}| Magnitude", "name": f"|{parameter_type}| Амплитуда",
"line": {"color": magnitude_color, "width": 2}, "line": {"color": magnitude_color, "width": 2},
"yaxis": "y", "yaxis": "y",
}) })
@ -149,15 +149,15 @@ class MagnitudeProcessor(BaseProcessor):
"y": phases_deg, "y": phases_deg,
"type": "scatter", "type": "scatter",
"mode": "lines", "mode": "lines",
"name": f"{parameter_type} Phase", "name": f"{parameter_type} Фаза",
"line": {"color": phase_color, "width": 2}, "line": {"color": phase_color, "width": 2},
"yaxis": "y2" if show_magnitude else "y", "yaxis": "y2" if show_magnitude else "y",
}) })
# Layout configuration # Layout configuration
layout = { layout = {
"title": f"{parameter_type} Response", "title": f"Отклик {parameter_type}",
"xaxis": {"title": "Frequency (GHz)", "showgrid": True}, "xaxis": {"title": "Частота (ГГц)", "showgrid": True},
"hovermode": "x unified", "hovermode": "x unified",
"showlegend": True, "showlegend": True,
} }
@ -165,7 +165,7 @@ class MagnitudeProcessor(BaseProcessor):
# Configure y-axis based on what's shown # Configure y-axis based on what's shown
if show_magnitude: if show_magnitude:
y_axis_config = { y_axis_config = {
"title": "Magnitude (dB)", "title": "Амплитуда (дБ)",
"showgrid": True, "showgrid": True,
"side": "left", "side": "left",
"titlefont": {"color": magnitude_color}, "titlefont": {"color": magnitude_color},
@ -183,7 +183,7 @@ class MagnitudeProcessor(BaseProcessor):
if show_magnitude: if show_magnitude:
# Phase on second axis (radians converted to degrees, but displayed as -π to π) # Phase on second axis (radians converted to degrees, but displayed as -π to π)
layout["yaxis2"] = { layout["yaxis2"] = {
"title": "Phase (rad)", "title": "Фаза (рад)",
"overlaying": "y", "overlaying": "y",
"side": "right", "side": "right",
"showgrid": False, "showgrid": False,
@ -194,7 +194,7 @@ class MagnitudeProcessor(BaseProcessor):
else: else:
# Phase on primary axis if magnitude is hidden # Phase on primary axis if magnitude is hidden
layout["yaxis"] = { layout["yaxis"] = {
"title": "Phase (rad)", "title": "Фаза (рад)",
"showgrid": True, "showgrid": True,
"side": "left", "side": "left",
"range": [-180, 180], # -π to π in degrees "range": [-180, 180], # -π to π in degrees
@ -218,32 +218,32 @@ class MagnitudeProcessor(BaseProcessor):
return [ return [
UIParameter( UIParameter(
name="show_magnitude", name="show_magnitude",
label="Show Magnitude", label="Показать амплитуду",
type="toggle", type="toggle",
value=self._config.get("show_magnitude", True), value=self._config.get("show_magnitude", True),
), ),
UIParameter( UIParameter(
name="show_phase", name="show_phase",
label="Show Phase", label="Показать фазу",
type="toggle", type="toggle",
value=self._config.get("show_phase", False), value=self._config.get("show_phase", False),
), ),
UIParameter( UIParameter(
name="autoscale", name="autoscale",
label="Autoscale Y Axis", label="Автомасштаб оси Y",
type="toggle", type="toggle",
value=self._config.get("autoscale", False), value=self._config.get("autoscale", False),
), ),
UIParameter( UIParameter(
name="y_min", name="y_min",
label="Y Axis Min (dB)", label="Мин. ось Y (дБ)",
type="slider", type="slider",
value=self._config.get("y_min", -80), value=self._config.get("y_min", -80),
options={"min": -80, "max": 20, "step": 5, "dtype": "int"}, options={"min": -80, "max": 20, "step": 5, "dtype": "int"},
), ),
UIParameter( UIParameter(
name="y_max", name="y_max",
label="Y Axis Max (dB)", label="Макс. ось Y (дБ)",
type="slider", type="slider",
value=self._config.get("y_max", 10), value=self._config.get("y_max", 10),
options={"min": -20, "max": 40, "step": 5, "dtype": "int"}, options={"min": -20, "max": 40, "step": 5, "dtype": "int"},

View File

@ -105,19 +105,19 @@ class ProcessorWebSocketHandler:
elif mtype == "get_processor_state": elif mtype == "get_processor_state":
await self._handle_get_processor_state(websocket, message) await self._handle_get_processor_state(websocket, message)
else: else:
await self._send_error(websocket, f"Unknown message type: {mtype!r}") await self._send_error(websocket, f"Неизвестный тип сообщения: {mtype!r}")
except json.JSONDecodeError as json_error: except json.JSONDecodeError as json_error:
logger.error("JSON decode error", raw_data=data[:200], error=str(json_error)) logger.error("JSON decode error", raw_data=data[:200], error=str(json_error))
await self._send_error( await self._send_error(
websocket, websocket,
"Invalid JSON format", "Неверный формат JSON",
details=f"JSON parse error: {json_error}", details=f"Ошибка парсинга JSON: {json_error}",
source="websocket_handler", source="websocket_handler",
raw_data=data[:200] if len(data) <= 200 else f"{data[:200]}..." raw_data=data[:200] if len(data) <= 200 else f"{data[:200]}..."
) )
except Exception as exc: # noqa: BLE001 except Exception as exc: # noqa: BLE001
logger.error("Error handling websocket message") logger.error("Error handling websocket message")
await self._send_error(websocket, f"Internal error: {exc}") await self._send_error(websocket, f"Внутренняя ошибка: {exc}")
# --------------------------------------------------------------------- # # --------------------------------------------------------------------- #
# Client commands # Client commands
@ -130,7 +130,7 @@ class ProcessorWebSocketHandler:
config_updates = message.get("config_updates") config_updates = message.get("config_updates")
if not processor_id: if not processor_id:
await self._send_error(websocket, "processor_id is required") await self._send_error(websocket, "Требуется processor_id")
return return
try: try:
@ -138,10 +138,10 @@ class ProcessorWebSocketHandler:
if result: if result:
await websocket.send_text(json.dumps(self._result_to_message(processor_id, result))) await websocket.send_text(json.dumps(self._result_to_message(processor_id, result)))
else: else:
await self._send_error(websocket, f"No result from processor {processor_id}") await self._send_error(websocket, f"Нет результата от процессора {processor_id}")
except Exception as exc: # noqa: BLE001 except Exception as exc: # noqa: BLE001
logger.error("Recalculation failed") logger.error("Recalculation failed")
await self._send_error(websocket, f"Recalculation failed: {exc}") await self._send_error(websocket, f"Пересчёт не удался: {exc}")
async def _handle_get_history(self, websocket: WebSocket, message: dict[str, Any]) -> None: async def _handle_get_history(self, websocket: WebSocket, message: dict[str, Any]) -> None:
""" """
@ -151,7 +151,7 @@ class ProcessorWebSocketHandler:
limit = int(message.get("limit", 10)) limit = int(message.get("limit", 10))
if not processor_id: if not processor_id:
await self._send_error(websocket, "processor_id is required") await self._send_error(websocket, "Требуется processor_id")
return return
try: try:
@ -172,7 +172,7 @@ class ProcessorWebSocketHandler:
await websocket.send_text(json.dumps(response)) await websocket.send_text(json.dumps(response))
except Exception as exc: # noqa: BLE001 except Exception as exc: # noqa: BLE001
logger.error("Error getting history") logger.error("Error getting history")
await self._send_error(websocket, f"Error getting history: {exc}") await self._send_error(websocket, f"Ошибка получения истории: {exc}")
async def _handle_load_history(self, websocket: WebSocket, message: dict[str, Any]) -> None: async def _handle_load_history(self, websocket: WebSocket, message: dict[str, Any]) -> None:
""" """
@ -182,11 +182,11 @@ class ProcessorWebSocketHandler:
history_data = message.get("history_data") history_data = message.get("history_data")
if not processor_id: if not processor_id:
await self._send_error(websocket, "processor_id is required") await self._send_error(websocket, "Требуется processor_id")
return return
if not history_data or not isinstance(history_data, list): if not history_data or not isinstance(history_data, list):
await self._send_error(websocket, "history_data (list) is required") await self._send_error(websocket, "Требуется history_data (список)")
return return
try: try:
@ -194,10 +194,10 @@ class ProcessorWebSocketHandler:
if result: if result:
await websocket.send_text(json.dumps(self._result_to_message(processor_id, result))) await websocket.send_text(json.dumps(self._result_to_message(processor_id, result)))
else: else:
await self._send_error(websocket, f"No result from processor {processor_id} after loading history") await self._send_error(websocket, f"Нет результата от процессора {processor_id} после загрузки истории")
except Exception as exc: # noqa: BLE001 except Exception as exc: # noqa: BLE001
logger.error("History load failed", processor_id=processor_id, error=repr(exc)) logger.error("History load failed", processor_id=processor_id, error=repr(exc))
await self._send_error(websocket, f"History load failed: {exc}") await self._send_error(websocket, f"Загрузка истории не удалась: {exc}")
async def _handle_get_processor_state(self, websocket: WebSocket, message: dict[str, Any]) -> None: async def _handle_get_processor_state(self, websocket: WebSocket, message: dict[str, Any]) -> None:
""" """
@ -209,7 +209,7 @@ class ProcessorWebSocketHandler:
processor_id = message.get("processor_id") processor_id = message.get("processor_id")
if not processor_id: if not processor_id:
await self._send_error(websocket, "processor_id is required") await self._send_error(websocket, "Требуется processor_id")
return return
try: try:
@ -217,7 +217,7 @@ class ProcessorWebSocketHandler:
await websocket.send_text(json.dumps(response)) await websocket.send_text(json.dumps(response))
except Exception as exc: # noqa: BLE001 except Exception as exc: # noqa: BLE001
logger.error("Error getting processor state", processor_id=processor_id, error=repr(exc)) logger.error("Error getting processor state", processor_id=processor_id, error=repr(exc))
await self._send_error(websocket, f"Error getting processor state: {exc}") await self._send_error(websocket, f"Ошибка получения состояния процессора: {exc}")
def _result_to_message(self, processor_id: str, result: ProcessedResult) -> dict[str, Any]: def _result_to_message(self, processor_id: str, result: ProcessedResult) -> dict[str, Any]:
""" """