class PowerMeterApatorEC3Repeating: min_averaging_secs: float _power_meter: PowerMeterApatorEC3 _timer: RepeatTimer reading: Optional[PowerMeterReading] reading_ts: Optional[float] success: bool high: SingleCounter low: SingleCounter callbacks: List[Callable[[Optional[PowerMeterReading]], None]] def __init__(self, power_meter: PowerMeterApatorEC3, interval: float, min_averaging_secs: float): self.min_averaging_secs = min_averaging_secs self._power_meter = power_meter self._timer = RepeatTimer(interval, self._acquire) self.reading = None self.reading_ts = None self.success = False self.high = SingleCounter() self.low = SingleCounter() self.callbacks = [] def add_callback(self, callback: Callable[[Optional[PowerMeterReading]], None]): self.callbacks.append(callback) def start(self): if not self._timer.is_alive(): self._timer.start() def stop(self): self._timer.cancel() self._power_meter.close() def _acquire(self): try: ts = time.time() self.reading = self._power_meter.read() self.reading_ts = ts self._update_high_power() self._update_low_power() self.success = True except SerialException: self.success = False self._fire() def _update_low_power(self): self.low.update(self.reading.consumption_low_sum_kwh, self.reading_ts, self.min_averaging_secs, self.high) def _update_high_power(self): self.high.update(self.reading.consumption_high_sum_kwh, self.reading_ts, self.min_averaging_secs, self.low) def _fire(self): for callback in self.callbacks: callback(self.reading)