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)" )