Add HS Color and/or XY Color support to light.mqtt template schema

As per official documentation MQTT Light - Home Assistant

HS Color and XY Color are not supported in the template schema for light.mqtt

My example use for this is to control a zigbee light connected to tasmota zigbee coordinator that does not respond to rgb command

See Tasmota Zigbee documentation: Zigbee - Tasmota

Tasmota supports color command using [x,y] coordinates or HueSat command

I am unable to use the default schema or json schema as being a zigbee light, there are no individual topics for hs, xy, rgb, brightness etc, this needs to be done via templating a JSON ZbSend command.

did you find a solution ?

I have the same problem and would like to publish something like this:

mosquitto_pub -h broker -t home/cmnd/tasmota_zigbee_xxx/ZbSend -m '{"Device":"0x1234", "Send":{"color":"30000,65534"}}'

Is there a solution?

I have just submitted a PR: [Add hs_command_template and xy_command_template to mqtt light default schema by orosam · Pull Request #84988 · home-assistant/core · GitHub].

If it gets merged, either “Color” or “HueSat” commands can be templated in the basic (default) schema.

Merged, it will be included in the next release. Once released, hs_command_topic and xy_command_topic options will be available for mqtt lights using the basic schema.

While testing, I could get a Tradfri light connected to my zbbridge work with a config something along these lines.
Note: this config assumes that the light has been named with something like ZbName 0x1234,My_Light.

-
  # This config requires the following options to be set on the Tasmota zbbridge:
  # ZbDeviceTopic 1
  # ZbNameTopic 1
  # ZbOmitDevice 1
  name: "My Color Zigbee Light"
  unique_id: "123456789abc-1"

  command_topic: "cmnd/my-zbbridge/ZbSend"
  on_command_type: first
  # NOTE: this MUST EXACTLY MATCH state_value_template below
  payload_on: '{ "Device": "My_Light", "Send": {"Power": 1} }'
  payload_off: '{ "Device": "My_Light", "Send": {"Power": 0} }'

  state_topic: "tele/my-zbbridge/My_Light/SENSOR"
  # This is ugly. Since HA compares the template output with payload_*, 
  # this template must generate the expected payload_on or payload_off.
  # Unfortunately, the basic schema has no command_template option (yet :-) ). 
  state_value_template: >-
    {%- set dev = "My_Light" -%}
    {%- set zb = value_json.ZbReceived | default(value_json.ZbInfo) | default({}) -%}
    {%- if zb.Power is defined -%}
    { "Device": "{{ dev }}", "Send": {"Power": {{ zb.Power }}} }
    {%- endif -%}

  brightness_scale: 254
  brightness_command_topic: "cmnd/my-zbbridge/ZbSend"
  brightness_command_template: '{ "Device": "My_Light", "Send": {"Dimmer": {{ value }} } }'
  brightness_state_topic: "tele/my-zbbridge/My_Light/SENSOR"
  brightness_value_template: >-
    {%- set zb = value_json.ZbReceived | default(value_json.ZbInfo) | default({}) -%}
    {{ zb.Dimmer | default }}

  xy_command_topic: "cmnd/my-zbbridge/ZbSend"
  xy_state_topic: "tele/my-zbbridge/My_Light/SENSOR"
  xy_command_template: '{ "Device": "My_Light", "Send": {"Color": "{{ [(x * 65536) | round | int, 65534] | min }},{{ [(y * 65536) | round | int, 65534] | min }}"} }'
  xy_value_template: >-
    {%- set zb = value_json.ZbReceived | default(value_json.ZbInfo) | default({}) -%}
    {%- if zb.X is defined and zb.Y is defined -%}
    {{  zb.X / 65536 }},{{ zb.Y / 65536 }}
    {%- endif -%}

  min_mireds: 250
  max_mireds: 454
  color_temp_command_topic: "cmnd/my-zbbridge/ZbSend"
  color_temp_command_template: '{ "Device": "My_Light", "Send": {"CT": {{value}}} }'
  color_temp_state_topic: "tele/my-zbbridge/My_Light/SENSOR"
  color_temp_value_template: >-
    {%- set zb = value_json.ZbReceived | default(value_json.ZbInfo) | default({}) -%}
    {{ zb.CT | default }}

  # Tasmota/HA: 0/hs, 1/xy, 2/color_temp
  color_mode_state_topic: "tele/my-zbbridge/My_Light/SENSOR"
  color_mode_value_template: >-
    {%- set zb = value_json.ZbReceived | default(value_json.ZbInfo) | default({}) -%}
    {%- if zb.ColorMode is defined -%}
    {%- set modemap = {0: "hs", 1: "xy", 2: "color_temp"} -%}
    {{ modemap[zb.ColorMode] | default }}
    {%- endif -%}