diff --git a/homeassistant/components/light/lifx.py b/homeassistant/components/light/lifx.py new file mode 100644 index 00000000000..911262b75c9 --- /dev/null +++ b/homeassistant/components/light/lifx.py @@ -0,0 +1,648 @@ +""" +homeassistant.components.light.lifx +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LiFX platform that implements lights + +Configuration: + +light: + # platform name + platform: lifx + # optional server address + # only needed if using more than one network interface + # (omit if you are unsure) + server: 192.168.1.3 + # optional broadcast address, set to reach all LiFX bulbs + # (omit if you are unsure) + broadcast: 192.168.1.255 + +""" +# pylint: disable=missing-docstring + +import logging +import threading +import time +import queue +import socket +import io +import struct +import ipaddress +import colorsys + +from struct import pack +from enum import IntEnum +from homeassistant.helpers.event import track_time_change +from homeassistant.components.light import \ + (Light, ATTR_BRIGHTNESS, ATTR_RGB_COLOR, ATTR_COLOR_TEMP) + +_LOGGER = logging.getLogger(__name__) + +DEPENDENCIES = [] +REQUIREMENTS = [] + +CONF_SERVER = "server" # server address configuration item +CONF_BROADCAST = "broadcast" # broadcast address configuration item +RETRIES = 10 # number of packet send retries +DELAY = 0.05 # delay between retries +UDP_PORT = 56700 # udp port for listening socket +UDP_IP = "0.0.0.0" # address for listening socket +MAX_ACK_AGE = 1 # maximum ACK age in seconds +BUFFERSIZE = 1024 # socket buffer size +SHORT_MAX = 65535 # short int maximum +BYTE_MAX = 255 # byte maximum +SEQUENCE_BASE = 1 # packet sequence base +SEQUENCE_COUNT = 255 # packet sequence count + +HUE_MIN = 0 +HUE_MAX = 360 +SATURATION_MIN = 0 +SATURATION_MAX = 255 +BRIGHTNESS_MIN = 0 +BRIGHTNESS_MAX = 65535 +TEMP_MIN = 2500 +TEMP_MAX = 9000 +TEMP_MIN_HASS = 154 +TEMP_MAX_HASS = 500 + + +class PayloadType(IntEnum): + """ LIFX message payload types. """ + GETSERVICE = 2 + STATESERVICE = 3 + GETHOSTINFO = 12 + STATEHOSTINFO = 13 + GETHOSTFIRMWARE = 14 + STATEHOSTFIRMWARE = 15 + GETWIFIINFO = 16 + STATEWIFIINFO = 17 + GETWIFIFIRMWARE = 18 + STATEWIFIFIRMWARE = 19 + GETPOWER1 = 20 + SETPOWER1 = 21 + STATEPOWER1 = 22 + GETLABEL = 23 + SETLABEL = 24 + STATELABEL = 25 + GETVERSION = 32 + STATEVERSION = 33 + GETINFO = 34 + STATEINFO = 35 + ACKNOWLEDGEMENT = 45 + GETLOCATION = 48 + STATELOCATION = 50 + GETGROUP = 51 + STATEGROUP = 53 + ECHOREQUEST = 58 + ECHORESPONSE = 59 + GET = 101 + SETCOLOR = 102 + STATE = 107 + GETPOWER2 = 116 + SETPOWER2 = 117 + STATEPOWER2 = 118 + + +class Power(IntEnum): + """ LIFX power settings. """ + BULB_ON = 65535 + BULB_OFF = 0 + + +def gen_header(sequence, payloadtype): + """ Create LIFX packet header. """ + protocol = bytearray.fromhex("00 34") + source = bytearray.fromhex("42 52 4b 52") + target = bytearray.fromhex("00 00 00 00 00 00 00 00") + reserved1 = bytearray.fromhex("00 00 00 00 00 00") + sequence = pack("B", 3) + reserved2 = bytearray.fromhex("00 00 00 00 00 00 00 00") + packet_type = pack("