106 lines
3.9 KiB
Python
106 lines
3.9 KiB
Python
"""Настройки весов в hardware_settings (симуляция, калибровка)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import platform
|
|
from typing import Any, Dict, Optional, Tuple
|
|
|
|
from app import db
|
|
from app.models import HardwareSetting
|
|
|
|
|
|
def _env_simulation_override() -> Optional[bool]:
|
|
raw = os.getenv("WESP_SIMULATION_MODE")
|
|
if raw is None or not str(raw).strip():
|
|
return None
|
|
return str(raw).strip().lower() in {"1", "true", "yes", "on"}
|
|
|
|
|
|
def is_scale_hardware_platform() -> bool:
|
|
"""
|
|
Целевая платформа для HX711: Linux на ARM (Raspberry Pi и аналоги).
|
|
На x86/macOS — False (без опроса датчика и без журнала ошибок).
|
|
WESP_FORCE_HX711=1|0 — принудительно для отладки.
|
|
"""
|
|
force = (os.getenv("WESP_FORCE_HX711") or "").strip().lower()
|
|
if force in {"1", "true", "yes", "on"}:
|
|
return True
|
|
if force in {"0", "false", "no", "off"}:
|
|
return False
|
|
if platform.system().lower() != "linux":
|
|
return False
|
|
machine = platform.machine().lower()
|
|
return "arm" in machine or "aarch64" in machine
|
|
|
|
|
|
def default_app_landing_path() -> str:
|
|
"""Куда вести после /starting и с корня / на этой машине."""
|
|
return "/scales" if is_scale_hardware_platform() else "/login"
|
|
|
|
|
|
def setup_complete_redirect(device_role: str | None) -> str:
|
|
"""Куда вести после завершения мастера настройки."""
|
|
role = (device_role or "").strip().lower()
|
|
if role == "client" and is_scale_hardware_platform():
|
|
return "/scales"
|
|
return "/login"
|
|
|
|
|
|
def default_simulation_mode_for_platform() -> bool:
|
|
"""
|
|
Стартовое значение simulation_mode для новой строки hardware_settings.
|
|
Везде выкл.; на dev (не ARM) весы работают только после включения симуляции в админке.
|
|
WESP_SIMULATION_MODE переопределяет платформенный дефолт.
|
|
"""
|
|
env = _env_simulation_override()
|
|
if env is not None:
|
|
return env
|
|
return False
|
|
|
|
|
|
def ensure_hardware_settings_row() -> HardwareSetting:
|
|
row = db.session.get(HardwareSetting, 1)
|
|
if row is None:
|
|
row = HardwareSetting(
|
|
id=1,
|
|
counts_per_kg=1.0,
|
|
tare_raw=0.0,
|
|
simulation_mode=default_simulation_mode_for_platform(),
|
|
simulation_weight_kg=0.0,
|
|
)
|
|
db.session.add(row)
|
|
db.session.commit()
|
|
return row
|
|
|
|
|
|
def hardware_settings_payload(row: Optional[HardwareSetting] = None) -> Dict[str, Any]:
|
|
row = row or ensure_hardware_settings_row()
|
|
return {
|
|
"simulation_mode": bool(row.simulation_mode),
|
|
"simulation_weight_kg": float(row.simulation_weight_kg or 0.0),
|
|
"counts_per_kg": float(row.counts_per_kg or 1.0),
|
|
"tare_raw": float(row.tare_raw or 0.0),
|
|
"platform_default_simulation": default_simulation_mode_for_platform(),
|
|
"platform_machine": platform.machine(),
|
|
"scale_hardware_platform": is_scale_hardware_platform(),
|
|
}
|
|
|
|
|
|
def set_simulation_mode(enabled: bool) -> Dict[str, Any]:
|
|
row = ensure_hardware_settings_row()
|
|
row.simulation_mode = bool(enabled)
|
|
db.session.commit()
|
|
return hardware_settings_payload(row)
|
|
|
|
|
|
def adjust_simulation_weight(delta_kg: int) -> Tuple[Dict[str, Any], int]:
|
|
row = ensure_hardware_settings_row()
|
|
if not row.simulation_mode:
|
|
raise ValueError("Симуляция выключена — включите её перед изменением веса")
|
|
current = int(round(float(row.simulation_weight_kg or 0.0)))
|
|
new_kg = max(0, current + int(delta_kg))
|
|
row.simulation_weight_kg = float(new_kg)
|
|
db.session.commit()
|
|
return hardware_settings_payload(row), new_kg
|