diff --git a/CODEOWNERS b/CODEOWNERS
index c756cb383d473b445f8b69268b9bb71420ef4010..b86e09a6b7284b54b90faea3e3d67ce1185867db 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -52,6 +52,8 @@ homeassistant/components/cover/template.py @PhracturedBlue
 homeassistant/components/device_tracker/automatic.py @armills
 homeassistant/components/device_tracker/tile.py @bachya
 homeassistant/components/history_graph.py @andrey-git
+homeassistant/components/light/lifx.py @amelchio
+homeassistant/components/light/lifx_legacy.py @amelchio
 homeassistant/components/light/tplink.py @rytilahti
 homeassistant/components/light/yeelight.py @rytilahti
 homeassistant/components/lock/nello.py @pschmitt
@@ -65,6 +67,7 @@ homeassistant/components/media_player/sonos.py @amelchio
 homeassistant/components/media_player/xiaomi_tv.py @fattdev
 homeassistant/components/media_player/yamaha_musiccast.py @jalmeroth
 homeassistant/components/plant.py @ChristianKuehnel
+homeassistant/components/scene/lifx_cloud.py @amelchio
 homeassistant/components/sensor/airvisual.py @bachya
 homeassistant/components/sensor/filter.py @dgomes
 homeassistant/components/sensor/gearbest.py @HerrHofrat
diff --git a/homeassistant/components/light/lifx.py b/homeassistant/components/light/lifx.py
index cf5d6fef70425eebba10425152618ba87a1bb68f..bea39354e1b43a748f4304a6096d9a74fe66ab0e 100644
--- a/homeassistant/components/light/lifx.py
+++ b/homeassistant/components/light/lifx.py
@@ -167,9 +167,9 @@ async def async_setup_platform(hass,
     return True
 
 
-def lifx_features(device):
-    """Return a feature map for this device, or a default map if unknown."""
-    return aiolifx().products.features_map.get(device.product) or \
+def lifx_features(bulb):
+    """Return a feature map for this bulb, or a default map if unknown."""
+    return aiolifx().products.features_map.get(bulb.product) or \
         aiolifx().products.features_map.get(1)
 
 
@@ -256,7 +256,7 @@ class LIFXManager:
 
     async def start_effect(self, entities, service, **kwargs):
         """Start a light effect on entities."""
-        devices = [light.device for light in entities]
+        bulbs = [light.bulb for light in entities]
 
         if service == SERVICE_EFFECT_PULSE:
             effect = aiolifx_effects().EffectPulse(
@@ -266,7 +266,7 @@ class LIFXManager:
                 mode=kwargs.get(ATTR_MODE),
                 hsbk=find_hsbk(**kwargs),
             )
-            await self.effects_conductor.start(effect, devices)
+            await self.effects_conductor.start(effect, bulbs)
         elif service == SERVICE_EFFECT_COLORLOOP:
             preprocess_turn_on_alternatives(kwargs)
 
@@ -282,12 +282,12 @@ class LIFXManager:
                 transition=kwargs.get(ATTR_TRANSITION),
                 brightness=brightness,
             )
-            await self.effects_conductor.start(effect, devices)
+            await self.effects_conductor.start(effect, bulbs)
         elif service == SERVICE_EFFECT_STOP:
-            await self.effects_conductor.stop(devices)
+            await self.effects_conductor.stop(bulbs)
 
     def service_to_entities(self, service):
-        """Return the known devices that a service call mentions."""
+        """Return the known entities that a service call mentions."""
         entity_ids = extract_entity_ids(self.hass, service)
         if entity_ids:
             entities = [entity for entity in self.entities.values()
@@ -298,50 +298,50 @@ class LIFXManager:
         return entities
 
     @callback
-    def register(self, device):
+    def register(self, bulb):
         """Handle aiolifx detected bulb."""
-        self.hass.async_add_job(self.register_new_device(device))
+        self.hass.async_add_job(self.register_new_bulb(bulb))
 
-    async def register_new_device(self, device):
+    async def register_new_bulb(self, bulb):
         """Handle newly detected bulb."""
-        if device.mac_addr in self.entities:
-            entity = self.entities[device.mac_addr]
+        if bulb.mac_addr in self.entities:
+            entity = self.entities[bulb.mac_addr]
             entity.registered = True
             _LOGGER.debug("%s register AGAIN", entity.who)
             await entity.update_hass()
         else:
-            _LOGGER.debug("%s register NEW", device.ip_addr)
+            _LOGGER.debug("%s register NEW", bulb.ip_addr)
 
             # Read initial state
             ack = AwaitAioLIFX().wait
-            color_resp = await ack(device.get_color)
+            color_resp = await ack(bulb.get_color)
             if color_resp:
-                version_resp = await ack(device.get_version)
+                version_resp = await ack(bulb.get_version)
 
             if color_resp is None or version_resp is None:
-                _LOGGER.error("Failed to initialize %s", device.ip_addr)
-                device.registered = False
+                _LOGGER.error("Failed to initialize %s", bulb.ip_addr)
+                bulb.registered = False
             else:
-                device.timeout = MESSAGE_TIMEOUT
-                device.retry_count = MESSAGE_RETRIES
-                device.unregister_timeout = UNAVAILABLE_GRACE
-
-                if lifx_features(device)["multizone"]:
-                    entity = LIFXStrip(device, self.effects_conductor)
-                elif lifx_features(device)["color"]:
-                    entity = LIFXColor(device, self.effects_conductor)
+                bulb.timeout = MESSAGE_TIMEOUT
+                bulb.retry_count = MESSAGE_RETRIES
+                bulb.unregister_timeout = UNAVAILABLE_GRACE
+
+                if lifx_features(bulb)["multizone"]:
+                    entity = LIFXStrip(bulb, self.effects_conductor)
+                elif lifx_features(bulb)["color"]:
+                    entity = LIFXColor(bulb, self.effects_conductor)
                 else:
-                    entity = LIFXWhite(device, self.effects_conductor)
+                    entity = LIFXWhite(bulb, self.effects_conductor)
 
                 _LOGGER.debug("%s register READY", entity.who)
-                self.entities[device.mac_addr] = entity
+                self.entities[bulb.mac_addr] = entity
                 self.async_add_entities([entity], True)
 
     @callback
-    def unregister(self, device):
+    def unregister(self, bulb):
         """Handle aiolifx disappearing bulbs."""
-        if device.mac_addr in self.entities:
-            entity = self.entities[device.mac_addr]
+        if bulb.mac_addr in self.entities:
+            entity = self.entities[bulb.mac_addr]
             _LOGGER.debug("%s unregister", entity.who)
             entity.registered = False
             self.hass.async_add_job(entity.async_update_ha_state())
@@ -352,20 +352,17 @@ class AwaitAioLIFX:
 
     def __init__(self):
         """Initialize the wrapper."""
-        self.device = None
         self.message = None
         self.event = asyncio.Event()
 
     @callback
-    def callback(self, device, message):
+    def callback(self, bulb, message):
         """Handle responses."""
-        self.device = device
         self.message = message
         self.event.set()
 
     async def wait(self, method):
         """Call an aiolifx method and wait for its response."""
-        self.device = None
         self.message = None
         self.event.clear()
         method(callb=self.callback)
@@ -387,9 +384,9 @@ def convert_16_to_8(value):
 class LIFXLight(Light):
     """Representation of a LIFX light."""
 
-    def __init__(self, device, effects_conductor):
+    def __init__(self, bulb, effects_conductor):
         """Initialize the light."""
-        self.light = device
+        self.bulb = bulb
         self.effects_conductor = effects_conductor
         self.registered = True
         self.postponed_update = None
@@ -397,34 +394,34 @@ class LIFXLight(Light):
 
     @property
     def available(self):
-        """Return the availability of the device."""
+        """Return the availability of the bulb."""
         return self.registered
 
     @property
     def unique_id(self):
         """Return a unique ID."""
-        return self.light.mac_addr
+        return self.bulb.mac_addr
 
     @property
     def name(self):
-        """Return the name of the device."""
-        return self.light.label
+        """Return the name of the bulb."""
+        return self.bulb.label
 
     @property
     def who(self):
-        """Return a string identifying the device."""
-        return "%s (%s)" % (self.light.ip_addr, self.name)
+        """Return a string identifying the bulb."""
+        return "%s (%s)" % (self.bulb.ip_addr, self.name)
 
     @property
     def min_mireds(self):
         """Return the coldest color_temp that this light supports."""
-        kelvin = lifx_features(self.light)['max_kelvin']
+        kelvin = lifx_features(self.bulb)['max_kelvin']
         return math.floor(color_util.color_temperature_kelvin_to_mired(kelvin))
 
     @property
     def max_mireds(self):
         """Return the warmest color_temp that this light supports."""
-        kelvin = lifx_features(self.light)['min_kelvin']
+        kelvin = lifx_features(self.bulb)['min_kelvin']
         return math.ceil(color_util.color_temperature_kelvin_to_mired(kelvin))
 
     @property
@@ -432,8 +429,8 @@ class LIFXLight(Light):
         """Flag supported features."""
         support = SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION | SUPPORT_EFFECT
 
-        device_features = lifx_features(self.light)
-        if device_features['min_kelvin'] != device_features['max_kelvin']:
+        bulb_features = lifx_features(self.bulb)
+        if bulb_features['min_kelvin'] != bulb_features['max_kelvin']:
             support |= SUPPORT_COLOR_TEMP
 
         return support
@@ -441,25 +438,25 @@ class LIFXLight(Light):
     @property
     def brightness(self):
         """Return the brightness of this light between 0..255."""
-        return convert_16_to_8(self.light.color[2])
+        return convert_16_to_8(self.bulb.color[2])
 
     @property
     def color_temp(self):
         """Return the color temperature."""
-        _, sat, _, kelvin = self.light.color
+        _, sat, _, kelvin = self.bulb.color
         if sat:
             return None
         return color_util.color_temperature_kelvin_to_mired(kelvin)
 
     @property
     def is_on(self):
-        """Return true if device is on."""
-        return self.light.power_level != 0
+        """Return true if light is on."""
+        return self.bulb.power_level != 0
 
     @property
     def effect(self):
         """Return the name of the currently running effect."""
-        effect = self.effects_conductor.effect(self.light)
+        effect = self.effects_conductor.effect(self.bulb)
         if effect:
             return 'lifx_effect_' + effect.name
         return None
@@ -485,19 +482,19 @@ class LIFXLight(Light):
                 util.dt.utcnow() + timedelta(milliseconds=when))
 
     async def async_turn_on(self, **kwargs):
-        """Turn the device on."""
+        """Turn the light on."""
         kwargs[ATTR_POWER] = True
         self.hass.async_add_job(self.set_state(**kwargs))
 
     async def async_turn_off(self, **kwargs):
-        """Turn the device off."""
+        """Turn the light off."""
         kwargs[ATTR_POWER] = False
         self.hass.async_add_job(self.set_state(**kwargs))
 
     async def set_state(self, **kwargs):
         """Set a color on the light and turn it on/off."""
         async with self.lock:
-            bulb = self.light
+            bulb = self.bulb
 
             await self.effects_conductor.stop([bulb])
 
@@ -544,13 +541,13 @@ class LIFXLight(Light):
         await self.update_during_transition(fade)
 
     async def set_power(self, ack, pwr, duration=0):
-        """Send a power change to the device."""
-        await ack(partial(self.light.set_power, pwr, duration=duration))
+        """Send a power change to the bulb."""
+        await ack(partial(self.bulb.set_power, pwr, duration=duration))
 
     async def set_color(self, ack, hsbk, kwargs, duration=0):
-        """Send a color change to the device."""
-        hsbk = merge_hsbk(self.light.color, hsbk)
-        await ack(partial(self.light.set_color, hsbk, duration=duration))
+        """Send a color change to the bulb."""
+        hsbk = merge_hsbk(self.bulb.color, hsbk)
+        await ack(partial(self.bulb.set_color, hsbk, duration=duration))
 
     async def default_effect(self, **kwargs):
         """Start an effect with default parameters."""
@@ -563,7 +560,7 @@ class LIFXLight(Light):
     async def async_update(self):
         """Update bulb status."""
         if self.available and not self.lock.locked():
-            await AwaitAioLIFX().wait(self.light.get_color)
+            await AwaitAioLIFX().wait(self.bulb.get_color)
 
 
 class LIFXWhite(LIFXLight):
@@ -600,7 +597,7 @@ class LIFXColor(LIFXLight):
     @property
     def hs_color(self):
         """Return the hs value."""
-        hue, sat, _, _ = self.light.color
+        hue, sat, _, _ = self.bulb.color
         hue = hue / 65535 * 360
         sat = sat / 65535 * 100
         return (hue, sat) if sat else None
@@ -610,8 +607,8 @@ class LIFXStrip(LIFXColor):
     """Representation of a LIFX light strip with multiple zones."""
 
     async def set_color(self, ack, hsbk, kwargs, duration=0):
-        """Send a color change to the device."""
-        bulb = self.light
+        """Send a color change to the bulb."""
+        bulb = self.bulb
         num_zones = len(bulb.color_zones)
 
         zones = kwargs.get(ATTR_ZONES)
@@ -659,7 +656,7 @@ class LIFXStrip(LIFXColor):
         while self.available and zone < top:
             # Each get_color_zones can update 8 zones at once
             resp = await AwaitAioLIFX().wait(partial(
-                self.light.get_color_zones,
+                self.bulb.get_color_zones,
                 start_index=zone))
             if resp:
                 zone += 8