#!/usr/bin/env python # -*- coding: utf-8 -*- # from devices.base import base from devices.base import BATTERY_WARN_LEVEL from devices.base import warning import logging class tradfri_light(base): """ Communication (MQTT) tradfri_light { | "state": ["ON" / "OFF" / "TOGGLE"] | "linkquality": [0...255] lqi | "brightness": [0...254] | "color_mode": ["color_temp"] | "color_temp": ["coolest", "cool", "neutral", "warm", "warmest", 250...454] | "color_temp_startup": ["coolest", "cool", "neutral", "warm", "warmest", "previous", 250...454] | "update": [] | } +- get { | "state": "" | } +- set { "state": ["ON" / "OFF"] "brightness": [0...256] "color_temp": [250...454] "transition": [0...] seconds "brightness_move": [-X...0...X] X/s "brightness_step": [-X...0...X] "color_temp_move": [-X...0...X] X/s "color_temp_step": [-X...0...X] } """ KEY_LINKQUALITY = "linkquality" KEY_OUTPUT_0 = "state" KEY_BRIGHTNESS = "brightness" KEY_COLOR_TEMP = "color_temp" KEY_BRIGHTNESS_FADE = "brightness_move" # TX_TYPE = base.TX_DICT TX_FILTER_DATA_KEYS = [KEY_OUTPUT_0, KEY_BRIGHTNESS, KEY_COLOR_TEMP, KEY_BRIGHTNESS_FADE] # RX_KEYS = [KEY_LINKQUALITY, KEY_OUTPUT_0, KEY_BRIGHTNESS, KEY_COLOR_TEMP] RX_IGNORE_KEYS = ['update', 'color_mode', 'color_temp_startup'] RX_FILTER_DATA_KEYS = [KEY_OUTPUT_0, KEY_BRIGHTNESS, KEY_COLOR_TEMP] def __init__(self, mqtt_client, topic): super().__init__(mqtt_client, topic) def __device_to_instance_filter__(self, key, data): if key == self.KEY_BRIGHTNESS: return int(round((data - 1) * 100 / 253, 0)) elif key == self.KEY_COLOR_TEMP: return int(round((data - 250) * 10 / 204, 0)) return super().__device_to_instance_filter__(key, data) def __instance_to_device_filter__(self, key, data): if key == self.KEY_BRIGHTNESS: return int(round(data * 253 / 100 + 1, 0)) elif key == self.KEY_COLOR_TEMP: return int(round(data * 204 / 10 + 250, 0)) return super().__instance_to_device_filter__(key, data) # # RX # @property def output_0(self): """rv: [True, False]""" return self.get(self.KEY_OUTPUT_0, False) @property def linkquality(self): """rv: numeric value""" return self.get(self.KEY_LINKQUALITY, 0) @property def brightness(self): """rv: numeric value [0%, ..., 100%]""" return self.get(self.KEY_BRIGHTNESS, 0) @property def color_temp(self): """rv: numeric value [0, ..., 10]""" return self.get(self.KEY_COLOR_TEMP, 0) # # TX # def request_data(self, device=None, key=None, data=None): self.mqtt_client.send(self.topic + "/get", '{"%s": ""}' % self.KEY_OUTPUT_0) def set_output_0(self, state): """state: [True, False]""" self.send_command(self.KEY_OUTPUT_0, state) def set_output_0_mcb(self, device, key, data): self.logger.log(logging.INFO if data != self.output_0 else logging.DEBUG, "Changing output 0 to %s", str(data)) self.set_output_0(data) def toggle_output_0_mcb(self, device, key, data): self.logger.info("Toggeling output 0") self.set_output_0(not self.output_0) def set_brightness(self, brightness): """brightness: [0, ..., 100]""" self.send_command(self.KEY_BRIGHTNESS, brightness) def set_brightness_mcb(self, device, key, data): self.logger.log(logging.INFO if data != self.brightness else logging.DEBUG, "Changing brightness to %s", str(data)) self.set_brightness(data) def default_inc(self, speed=40): self.send_command(self.KEY_BRIGHTNESS_FADE, speed) def default_dec(self, speed=-40): self.default_inc(speed) def default_stop(self): self.default_inc(0) def set_color_temp(self, color_temp): """color_temp: [0, ..., 10]""" self.send_command(self.KEY_COLOR_TEMP, color_temp) def set_color_temp_mcb(self, device, key, data): self.logger.log(logging.INFO if data != self.color_temp else logging.DEBUG, "Changing color temperature to %s", str(data)) self.set_color_temp(data) def all_off(self): if self.output_0: self.set_output_0(False) class tradfri_button(base): """ Communication (MQTT) tradfri_button { "action": [ "arrow_left_click", "arrow_left_hold", "arrow_left_release", "arrow_right_click", "arrow_right_hold", "arrow_right_release", "brightness_down_click", "brightness_down_hold", "brightness_down_release", "brightness_up_click", "brightness_up_hold", "brightness_up_release", "toggle" ] "action_duration": [0...] s "battery": [0...100] % "linkquality": [0...255] lqi "update": [] } """ ACTION_TOGGLE = "toggle" ACTION_BRIGHTNESS_UP = "brightness_up_click" ACTION_BRIGHTNESS_DOWN = "brightness_down_click" ACTION_RIGHT = "arrow_right_click" ACTION_LEFT = "arrow_left_click" ACTION_BRIGHTNESS_UP_LONG = "brightness_up_hold" ACTION_BRIGHTNESS_UP_RELEASE = "brightness_up_release" ACTION_BRIGHTNESS_DOWN_LONG = "brightness_down_hold" ACTION_BRIGHTNESS_DOWN_RELEASE = "brightness_down_release" ACTION_RIGHT_LONG = "arrow_right_hold" ACTION_RIGHT_RELEASE = "arrow_right_release" ACTION_LEFT_LONG = "arrow_left_hold" ACTION_LEFT_RELEASE = "arrow_left_release" # KEY_LINKQUALITY = "linkquality" KEY_BATTERY = "battery" KEY_ACTION = "action" KEY_ACTION_DURATION = "action_duration" # RX_KEYS = [KEY_LINKQUALITY, KEY_BATTERY, KEY_ACTION] RX_IGNORE_KEYS = ['update', KEY_ACTION_DURATION] def __init__(self, mqtt_client, topic): super().__init__(mqtt_client, topic) # self.add_callback(self.KEY_BATTERY, None, self.__warning__, True) self.__battery_warning__ = False # # WARNING CALL # def __warning__(self, client, key, data): if data <= BATTERY_WARN_LEVEL: if not self.__battery_warning__: w = warning(self.topic, warning.TYPE_BATTERY_LOW, "Battery low (%.1f%%)", data) self.logger.warning(w) self.set(self.KEY_WARNING, w) else: self.__battery_warning__ = False # # RX # @property def action(self): """rv: action_txt""" return self.get(self.KEY_ACTION)