# Path: controller/actor.py
# class PoupoolActor(pykka.ThreadingActor):
# 
#     def __init__(self):
#         super().__init__()
#         self._proxy = self.actor_ref.proxy()
#         self.__timer = None
# 
#     def on_failure(self, exception_type, exception_value, traceback):
#         # The actor is going to die
#         logger.fatal(exception_type, exception_value, traceback)
# 
#     def on_stop(self):
#         self.do_cancel()
# 
#     def get_actor(self, name):
#         fsm = pykka.ActorRegistry.get_by_class_name(name)
#         if fsm:
#             return fsm[0].proxy()
#         logger.critical("Actor %s not found!!!" % name)
#         return None
# 
#     def __do_cancel(self):
#         if self.__timer:
#             self.__timer.cancel()
#             self.__timer = None
# 
#     def do_cancel(self):
#         self.__do_cancel()
# 
#     def do_delay(self, delay, method, *args, **kwargs):
#         assert type(method) == str
#         assert delay >= 0
#         # Stop an already running timer
#         self.__do_cancel()
#         func = getattr(self._proxy, method)
#         if delay > 0:
#             self.__timer = Timer(delay, func.defer, *args, **kwargs)
#             self.__timer.start()
#         else:
#             func.defer(*args, **kwargs)


import logging
import statistics
import collections
from .actor import PoupoolActor
from datetime import timedelta
    def values(self):
        return self.__values

    def do_read(self):
        for sensor in self.__sensors:
            value = sensor.value
            if value is not None:
                self.__values[sensor.name].push(value)


class DisinfectionReader(BaseReader):

    DELAY_SECONDS = 60
    DURATION = timedelta(minutes=5)

    def __init__(self, sensors):
        samples = int(self.DURATION.total_seconds() // self.DELAY_SECONDS)
        super().__init__(sensors, samples)

    def get_ph(self):
        return self.values["ph"].mean()

    def get_orp(self):
        return self.values["orp"].mean()

    def do_read(self):
        super().do_read()
        self.do_delay(self.DELAY_SECONDS, self.do_read.__name__)



# Path: controller/actor.py
# class PoupoolActor(pykka.ThreadingActor):
# 
#     def __init__(self):
#         super().__init__()
#         self._proxy = self.actor_ref.proxy()
#         self.__timer = None
# 
#     def on_failure(self, exception_type, exception_value, traceback):
#         # The actor is going to die
#         logger.fatal(exception_type, exception_value, traceback)
# 
#     def on_stop(self):
#         self.do_cancel()
# 
#     def get_actor(self, name):
#         fsm = pykka.ActorRegistry.get_by_class_name(name)
#         if fsm:
#             return fsm[0].proxy()
#         logger.critical("Actor %s not found!!!" % name)
#         return None
# 
#     def __do_cancel(self):
#         if self.__timer:
#             self.__timer.cancel()
#             self.__timer = None
# 
#     def do_cancel(self):
#         self.__do_cancel()
# 
#     def do_delay(self, delay, method, *args, **kwargs):
#         assert type(method) == str
#         assert delay >= 0
#         # Stop an already running timer
#         self.__do_cancel()
#         func = getattr(self._proxy, method)
#         if delay > 0:
#             self.__timer = Timer(delay, func.defer, *args, **kwargs)
#             self.__timer.start()
#         else:
#             func.defer(*args, **kwargs)


# Path: controller/sensor.py
import logging
import statistics
import collections
from .actor import PoupoolActor
from datetime import timedelta

    def values(self):
        return self.__values

    def do_read(self):
        for sensor in self.__sensors:
            value = sensor.value
            if value is not None:
                self.__values[sensor.name].push(value)


class DisinfectionReader(BaseReader):

    DELAY_SECONDS = 60
    DURATION = timedelta(minutes=5)

    def __init__(self, sensors):
        samples = int(self.DURATION.total_seconds() // self.DELAY_SECONDS)
        super().__init__(sensors, samples)

    def get_ph(self):
        return self.values["ph"].mean()

    def get_orp(self):
        return self.values["orp"].mean()

    def do_read(self):
        super().do_read()
        self.do_delay(self.DELAY_SECONDS, self.do_read.__name__)



class DisinfectionWriter(PoupoolActor):