text: """Support for MySensors lights."""
  from homeassistant.components import mysensors
  from homeassistant.components.light import (
      ATTR_BRIGHTNESS, ATTR_HS_COLOR, ATTR_WHITE_VALUE, DOMAIN,
      SUPPORT_BRIGHTNESS, SUPPORT_COLOR, SUPPORT_WHITE_VALUE, Light)
  from homeassistant.const import STATE_OFF, STATE_ON
  from homeassistant.util.color import rgb_hex_to_rgb_list
  import homeassistant.util.color as color_util
  
  SUPPORT_MYSENSORS_RGBW = SUPPORT_COLOR | SUPPORT_WHITE_VALUE
  
  
  async def async_setup_platform(
          hass, config, async_add_entities, discovery_info=None):
      """Set up the mysensors platform for lights."""
      device_class_map = {
          'S_DIMMER': MySensorsLightDimmer,
          'S_RGB_LIGHT': MySensorsLightRGB,
          'S_RGBW_LIGHT': MySensorsLightRGBW,
      }
      mysensors.setup_mysensors_platform(
          hass, DOMAIN, discovery_info, device_class_map,
          async_add_entities=async_add_entities)
  
  
  class MySensorsLight(mysensors.device.MySensorsEntity, Light):
      """Representation of a MySensors Light child node."""
  
      def __init__(self, *args):
          """Initialize a MySensors Light."""
          super().__init__(*args)
          self._state = None
          self._brightness = None
          self._hs = None
          self._white = None
  
      @property
      def brightness(self):
          """Return the brightness of this light between 0..255."""
          return self._brightness
  
      @property
      def hs_color(self):
          """Return the hs color value [int, int]."""
          return self._hs
  
      @property
      def white_value(self):
          """Return the white value of this light between 0..255."""
          return self._white
  
      @property
      def assumed_state(self):
          """Return true if unable to access real state of entity."""
          return self.gateway.optimistic
  
      @property
      def is_on(self):
          """Return true if device is on."""
          return self._state
  
      def _turn_on_light(self):
          """Turn on light child device."""
          set_req = self.gateway.const.SetReq
  
          if self._state:
              return
          self.gateway.set_child_value(
              self.node_id, self.child_id, set_req.V_LIGHT, 1)
  
          if self.gateway.optimistic:
              # optimistically assume that light has changed state
              self._state = True
              self._values[set_req.V_LIGHT] = STATE_ON
  
      def _turn_on_dimmer(self, **kwargs):
          """Turn on dimmer child device."""
          set_req = self.gateway.const.SetReq
          brightness = self._brightness
  
          if ATTR_BRIGHTNESS not in kwargs or \
                  kwargs[ATTR_BRIGHTNESS] == self._brightness or \
                  set_req.V_DIMMER not in self._values:
              return
          brightness = kwargs[ATTR_BRIGHTNESS]
          percent = round(100 * brightness / 255)
          self.gateway.set_child_value(
              self.node_id, self.child_id, set_req.V_DIMMER, percent)
  
          if self.gateway.optimistic:
              # optimistically assume that light has changed state
              self._brightness = brightness
              self._values[set_req.V_DIMMER] = percent
  
      def _turn_on_rgb_and_w(self, hex_template, **kwargs):
          """Turn on RGB or RGBW child device."""
          rgb = list(color_util.color_hs_to_RGB(*self._hs))
          white = self._white
          hex_color = self._values.get(self.value_type)
          hs_color = kwargs.get(ATTR_HS_COLOR)
          if hs_color is not None:
              new_rgb = color_util.color_hs_to_RGB(*hs_color)
          else:
              new_rgb = None
          new_white = kwargs.get(ATTR_WHITE_VALUE)
  
          if new_rgb is None and new_white is None:
              return
          if new_rgb is not None:
              rgb = list(new_rgb)
          if hex_template == '%02x%02x%02x%02x':
              if new_white is not None:
                  rgb.append(new_white)
              else:
                  rgb.append(white)
          hex_color = hex_template % tuple(rgb)
          if len(rgb) > 3:
              white = rgb.pop()
          self.gateway.set_child_value(
              self.node_id, self.child_id, self.value_type, hex_color)
  
          if self.gateway.optimistic:
              # optimistically assume that light has changed state
              self._hs = color_util.color_RGB_to_hs(*rgb)
              self._white = white
              self._values[self.value_type] = hex_color
  
      async def async_turn_off(self, **kwargs):
          """Turn the device off."""
          value_type = self.gateway.const.SetReq.V_LIGHT
          self.gateway.set_child_value(
              self.node_id, self.child_id, value_type, 0)
          if self.gateway.optimistic:
              # optimistically assume that light has changed state
              self._state = False
              self._values[value_type] = STATE_OFF
              self.async_schedule_update_ha_state()
  
      def _async_update_light(self):
          """Update the controller with values from light child."""
          value_type = self.gateway.const.SetReq.V_LIGHT
          self._state = self._values[value_type] == STATE_ON
  
      def _async_update_dimmer(self):
          """Update the controller with values from dimmer child."""
          value_type = self.gateway.const.SetReq.V_DIMMER
          if value_type in self._values:
              self._brightness = round(255 * int(self._values[value_type]) / 100)
              if self._brightness == 0:
                  self._state = False
  
      def _async_update_rgb_or_w(self):
          """Update the controller with values from RGB or RGBW child."""
          value = self._values[self.value_type]
          color_list = rgb_hex_to_rgb_list(value)
          if len(color_list) > 3:
              self._white = color_list.pop()
          self._hs = color_util.color_RGB_to_hs(*color_list)
  
  
  class MySensorsLightDimmer(MySensorsLight):
      """Dimmer child class to MySensorsLight."""
  
      @property
      def supported_features(self):
          """Flag supported features."""
          return SUPPORT_BRIGHTNESS
  
      async def async_turn_on(self, **kwargs):
          """Turn the device on."""
          self._turn_on_light()
          self._turn_on_dimmer(**kwargs)
          if self.gateway.optimistic:
              self.async_schedule_update_ha_state()
  
      async def async_update(self):
          """Update the controller with the latest value from a sensor."""
          await super().async_update()
          self._async_update_light()
          self._async_update_dimmer()
  
  
  class MySensorsLightRGB(MySensorsLight):
      """RGB child class to MySensorsLight."""
  
      @property
      def supported_features(self):
          """Flag supported features."""
          set_req = self.gateway.const.SetReq
          if set_req.V_DIMMER in self._values:
              return SUPPORT_BRIGHTNESS | SUPPORT_COLOR
          return SUPPORT_COLOR
  
      async def async_turn_on(self, **kwargs):
          """Turn the device on."""
          self._turn_on_light()
          self._turn_on_dimmer(**kwargs)
          self._turn_on_rgb_and_w('%02x%02x%02x', **kwargs)
          if self.gateway.optimistic:
              self.async_schedule_update_ha_state()
  
      async def async_update(self):
          """Update the controller with the latest value from a sensor."""
          await super().async_update()
          self._async_update_light()
          self._async_update_dimmer()
          self._async_update_rgb_or_w()
  
  
  class MySensorsLightRGBW(MySensorsLightRGB):
      """RGBW child class to MySensorsLightRGB."""
  
      # pylint: disable=too-many-ancestors
  
      @property
      def supported_features(self):
          """Flag supported features."""
          set_req = self.gateway.const.SetReq
          if set_req.V_DIMMER in self._values:
              return SUPPORT_BRIGHTNESS | SUPPORT_MYSENSORS_RGBW
          return SUPPORT_MYSENSORS_RGBW
  
      async def async_turn_on(self, **kwargs):
          """Turn the device on."""
          self._turn_on_light()
          self._turn_on_dimmer(**kwargs)
          self._turn_on_rgb_and_w('%02x%02x%02x%02x', **kwargs)
          if self.gateway.optimistic:
              self.async_schedule_update_ha_state()
  