Files
site/WESP_REL/app/services/hardware/hx711_wrapper.py
T
2026-07-17 12:57:18 +03:00

75 lines
3.0 KiB
Python

import random
class HX711UnavailableError(RuntimeError):
"""Нет HX711 при выключенной симуляции или срыв чтения с датчика."""
class HX711Wrapper:
"""Minimal wrapper for HX711 access with simulation fallback."""
def __init__(self, simulation_mode: bool = False, dout_pin: int = 2, pd_sck_pin: int = 3):
self._sim_weight = 0.0
self._device = None
self._dout_pin = int(dout_pin)
self._pd_sck_pin = int(pd_sck_pin)
self.simulation_mode = False
self.apply_simulation_mode(simulation_mode)
def apply_simulation_mode(self, simulation_mode: bool) -> None:
"""Переключить симуляцию и при необходимости поднять/сбросить драйвер HX711."""
simulation_mode = bool(simulation_mode)
if simulation_mode == self.simulation_mode:
if simulation_mode or self._device is not None:
return
self.simulation_mode = simulation_mode
if simulation_mode:
self._device = None
return
self._ensure_device()
def _ensure_device(self) -> None:
if self._device is not None:
return
try:
from hx711 import HX711 # type: ignore[import-not-found]
self._device = HX711(dout_pin=self._dout_pin, pd_sck_pin=self._pd_sck_pin)
except Exception:
self._device = None
def read_weight_sample(self) -> float:
if self.simulation_mode:
self._sim_weight = max(0.0, self._sim_weight + random.uniform(-1.0, 2.5))
return self._sim_weight
if self._device is None:
raise HX711UnavailableError(
"HX711 недоступен: модуль не загрузился или датчик не инициализирован"
)
try:
return self._read_raw_mean(times=3)
except HX711UnavailableError:
raise
except Exception as exc:
raise HX711UnavailableError(f"Ошибка чтения HX711: {exc}") from exc
def _read_raw_mean(self, times: int = 3) -> float:
"""Среднее сырых отсчётов: tatobari (get_raw_data) или gandalf15 (get_raw_data_mean)."""
device = self._device
if device is None:
raise HX711UnavailableError(
"HX711 недоступен: модуль не загрузился или датчик не инициализирован"
)
if hasattr(device, "get_raw_data_mean"):
return float(device.get_raw_data_mean(times))
if hasattr(device, "get_raw_data"):
raw = device.get_raw_data(times=times)
if isinstance(raw, list):
if not raw:
return 0.0
return float(sum(raw) / len(raw))
return float(raw)
raise HX711UnavailableError(
"HX711: нет метода чтения (ожидается get_raw_data или get_raw_data_mean)"
)