예제 #1
0
class TurnSlowlyStatic(AbstractMessage):
    def __init__(self):
        super().__init__()
        self.topic = settings.Mqtt.TOPIC + settings.Messages.TURN_SLOWLY_STATIC
        self.light_controller = LightController()

    def _parse_payload(self, payload):
        self._logger.debug('Executing Turn Slowly Static message')
        color = payload.get(settings.Messages.COLOR, None)
        if color is None:
            error_msg = f'Couln\'t read state, color or time span from ' \
                        f'message {payload}'
            self._logger.error(error_msg)
            raise IncorrectPayloadException(error_msg)

        color = utils.color_message_to_tuple(color)
        brightness = payload.get(settings.Messages.BRIGHTNESS, max(color))
        time_span = payload.get(settings.Messages.TIME_SPAN, 10)

        return color, brightness, time_span

    def execute(self, payload: Dict[str, Any]):
        color, brightness, time_span = self._parse_payload(payload)
        self.light_controller.state_on()
        action = ChangeColorAction(color, brightness, time_span)

        self.light_controller.add_action(action)
예제 #2
0
class ChangeColorAction(LightAction):
    def __init__(self, color, brightness, time_span):
        self.light_controller = LightController()
        super().__init__(method=None)
        self.color: Tuple[int, int, int] = color
        self.brightness = brightness
        self.time_span = time_span

    def _calculate_steps(self, time_span):
        steps = int(time_span * 1000 / settings.Lights.SLOW_CHANGE_WAIT_MS)
        steps = max(steps, settings.Lights.MIN_STEPS)
        return steps

    def _calculate_color_changes(self, color, time_span):
        current_colors = self.light_controller.read_colors()
        steps = self._calculate_steps(time_span)

        leds_colors = utils.create_colors_change_table(
            current_colors, [color] * len(current_colors), steps)
        self._logger.debug(f'Changing leds of colors {current_colors} '
                           f'to {color} in {steps} steps')
        color_sets = list(zip(*leds_colors))
        return color_sets

    def calculate_brightness_changes(self, brightness, time_span):
        steps = self._calculate_steps(time_span)
        current_brightness = self.light_controller.read_brightness()
        brightness_changes = utils.create_value_change_table(
            current_brightness, brightness, steps)

        return brightness_changes

    def evaluate_payload(self, payload) -> bool:
        """
        Check if payload is at least type {'state': 'ON'}
        :raises: IncorrectPayloadException if state has wrong value
        """
        has_state = utils.message_has_state(payload)

        if not has_state:
            return False

        state_off = payload[settings.Messages.STATE] == settings.Messages.OFF

        return state_off

    def execute(self):
        """
        Add multiple light color actions into light_controller
        """
        color_sets = self._calculate_color_changes(self.color, self.time_span)
        brightness_changes = self.calculate_brightness_changes(
            self.brightness, self.time_span)
        wait_time = self.time_span / len(color_sets)

        for color_set, brightness in zip(color_sets, brightness_changes):
            action = LightAction(
                self.light_controller.turn_into_colors_and_wait,
                args=[color_set, brightness, wait_time])
            self.light_controller.add_action(action)
예제 #3
0
class SetBrightness(LightAction):
    def __init__(self):
        self.light_controller = LightController()
        super().__init__(method=self.light_controller.set_brightness)
        self._payload = None

    def evaluate_payload(self, payload: Dict[str, Any]) -> bool:
        """
        Check if payload is type {'state': 'ON', 'brightness': int}
        :raises: IncorrectPayloadException if state or brightness have wrong
        value
        """
        has_state = utils.message_has_state(payload)
        has_brightness = utils.message_has_brightness(payload)
        keys = payload.keys()

        if not has_state or not has_brightness or len(keys) > 2:
            return False

        if payload[settings.Messages.STATE] == settings.Messages.ON:
            self._payload = payload
            self.arguments = [payload.get(settings.Messages.BRIGHTNESS)]
            return True

        return False

    def execute(self):
        self.light_controller.state_on()
        super().execute()
예제 #4
0
class SetColor(LightAction):
    def __init__(self):
        self.light_controller = LightController()
        super().__init__(method=self.light_controller.turn_static_color)
        self._color: Optional[Tuple[int, int, int]] = None
        self._brightness: Optional[int] = None

    def evaluate_payload(self, payload: Dict[str, Any]) -> bool:
        """
        Check if payload is type
        {
            'state': 'ON',
            'color': {'r': int, 'g': int, 'b': int}
        }
        :raises: IncorrectPayloadException if state, brightness or color have
        wrong value
        """
        has_state = utils.message_has_state(payload)
        has_color = utils.message_has_color(payload)

        if not has_state or not has_color:
            return False
        if sum([has_state, has_color]) != 2:
            return False
        if payload[settings.Messages.STATE] == settings.Messages.OFF:
            return False

        self._logger.debug('Received payload that fits to set color action')
        color = payload.get(settings.Messages.COLOR)

        self._color = utils.color_message_to_tuple(color)
        self._brightness = self.light_controller.get_brightness()
        self._logger.debug(f'Received color: {self._color} and brightness: '
                           f'{self._brightness}')
        return True

    def execute(self):
        self.light_controller.state_on()
        if not self._color:
            raise ValueError('Color not set. Run evaluate_payload before '
                             'calling execute')
        if not self._brightness:
            self._brightness = max(self._color)

        self.arguments = [self._color, self._brightness]
        super().execute()
예제 #5
0
class TurnStatic(AbstractMessage):
    def __init__(self):
        super().__init__()
        self.topic = settings.Mqtt.TOPIC + settings.Messages.TURN_STATIC
        self.light_controller = LightController()

    def create_action(self, payload):
        for action in ACTIONS:
            if action.evaluate_payload(payload):
                return action

        return None

    def execute(self, payload: Dict[str, Any]):
        self._logger.debug(f'Executing TurnStatic message with payload '
                           f'{payload}')
        action = self.create_action(payload)
        if not action:
            msg = f'Turn static message has unexpected payload: {payload}'
            raise IncorrectPayloadException(msg)

        self.light_controller.add_action(action)
예제 #6
0
 def __init__(self, color, brightness, time_span):
     self.light_controller = LightController()
     super().__init__(method=None)
     self.color: Tuple[int, int, int] = color
     self.brightness = brightness
     self.time_span = time_span
예제 #7
0
 def __init__(self):
     self.light_controller = LightController()
     super().__init__(method=self.light_controller.turn_off,
                      priority=settings.Actions.TURN_OFF_PRIORITY)
예제 #8
0
 def __init__(self):
     super().__init__()
     self.topic = settings.Mqtt.TOPIC + settings.Messages.TURN_STATIC
     self.light_controller = LightController()
예제 #9
0
 def __init__(self):
     self.light_controller = LightController()
     super().__init__(method=self.light_controller.turn_on)
예제 #10
0
from lights.light_controller.light_controller import LightController
from lights.messages.message_manager import MessageManager, MESSAGES
from lights.mqtt_client.mqtt_client import MQTTClient

if __name__ == '__main__':
    now = datetime.now()
    dt_string = now.strftime("%Y_%m_%d__%H_%M_%S")

    logging.basicConfig(filename=f'/home/pi/projects/lights/logs/{dt_string}.log',
                        filemode='a',
                        format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
                        datefmt='%H:%M:%S',
                        level=logging.DEBUG)

    logging.info('Starting lights controller')
    light_controller = LightController()
    light_controller.start()

    logging.info('Starting mqtt client')
    client = MQTTClient([msg.topic for msg in MESSAGES])
    client.connect()

    logging.info('Starting message manager')
    message_manager = MessageManager(client.message_queue, client.publish)
    light_controller.update_publish_method(message_manager.publish)
    message_manager.start()

    try:
        client.loop_forever()
    except KeyboardInterrupt:
        light_controller.stop()
예제 #11
0
 def __init__(self):
     self.light_controller = LightController()
     super().__init__(method=self.light_controller.set_brightness)
     self._payload = None
예제 #12
0
 def __init__(self):
     self.light_controller = LightController()
     super().__init__(method=self.light_controller.turn_static_color)
     self._color: Optional[Tuple[int, int, int]] = None
     self._brightness: Optional[int] = None