Curtain/cover motor controller as light. How to control it from HA?

I added the Sunricher SR-ZG9080A curtain motor controller to my Zigbee network with a Conbee II stick. In the Deconz app this device is recognized as a dimmable lamp, so it is in HA and Phoscon. In HA you can use the brightness slider to open, close and stop the cover:
brightness percentage 0-30: close
brightness percentage 31-70: stop
brightness percentage 71-100: open

I used a Template Cover to translate it to a Cover in HA:

cover:
  - platform: template
    covers:
      cover_pui:
        device_class: shutter
        friendly_name: 'Rolluik Schuifpui'
        open_cover:
          service : light.turn_on
          data:
            entity_id: light.rolluik_pui
            brightness_pct: 99
        close_cover:
          service : light.turn_on
          data:
            entity_id: light.rolluik_pui
            brightness_pct: 1
        stop_cover:
          service : light.turn_on
          data:
            entity_id: light.rolluik_pui
            brightness_pct: 50

This is working. I can open, close and stop the cover. The problem is, in HA I cannot see the position of the cover, nor I can move the cover to a specific position. This is because HA sees the cover controller as a light. Moving the cover to a specific position should be done in Zigbee cluster 0102 and is not part of the light clusters. In Deconz all information about position and the controls are available. I can move the cover to a specific position from the Deconz app. So it should be possible from HA. Can anyone tell me how I could control cluster 0102 from HA?

Cluster 0008 (Level Control) is actually brightness but is being used for up/down/stop. In this screenshot the attributes from cluster 0102 are shown. I want to control the “Go to lift percentage” and the “Read” function to get the current position from HA.

Surely this is an issue for the authors of deconz!

All the controls are actually available in Deconz. Isn’t there a possibility in HA to send controls for the 0102 cluster like it does for the 0008 cluster?

I found a solution. It’s here:

Final solution (also suitable for Philips Hue h2l-zbph-rs cover controller)

First edit the DDF for this device in Deconz. It should look like:

{
  "schema": "devcap1.schema.json",
  "manufacturername": "Sunricher",
  "modelid": "Motor Controller",
  "product": "SR-ZG9080A",
  "sleeper": false,
  "status": "Gold",
  "subdevices": [
    {
      "type": "$TYPE_WINDOW_COVERING_DEVICE",
      "restapi": "/lights",
      "uuid": [
        "$address.ext",
        "0x01"
      ],
      "items": [
        {
          "name": "attr/id"
        },
        {
          "name": "attr/lastannounced"
        },
        {
          "name": "attr/lastseen"
        },
        {
          "name": "attr/manufacturername"
        },
        {
          "name": "attr/modelid"
        },
        {
          "name": "attr/name"
        },
        {
          "name": "attr/swversion"
        },
        {
          "name": "attr/type"
        },
        {
          "name": "attr/uniqueid"
        },
        {
          "name": "state/lift",
          "refresh.interval": 60,
          "default": 0
        },
        {
          "name": "state/open",
          "parse": {
            "at": "0x0008",
            "cl": "0x0102",
            "ep": 0,
            "eval": "Item.val = Attr.val < 100",
            "fn": "zcl"
          }
        },
        {
          "name": "state/reachable"
        }
      ]
    }
  ],
  "bindings": [
    {
      "bind": "unicast",
      "src.ep": 1,
      "dst.ep": 1,
      "cl": "0x0102",
      "report": [
        {
          "at": "0x0008",
          "dt": "0x20",
          "min": 1,
          "max": 100,
          "change": "0x00000001"
        }
      ]
    }
  ]
}

For the Philips Hue h2l-zbph-rs use this one:

{
  "schema": "devcap1.schema.json",
  "manufacturername": "$MF_PHILIPS",
  "modelid": "H2L-ZBPH-RS",
  "product": "H2L-ZBPH-RS",
  "sleeper": false,
  "status": "Gold",
  "subdevices": [
    {
      "type": "$TYPE_WINDOW_COVERING_DEVICE",
      "restapi": "/lights",
      "uuid": [
        "$address.ext",
        "0x01"
      ],
      "items": [
        {
          "name": "attr/id"
        },
        {
          "name": "attr/lastannounced"
        },
        {
          "name": "attr/lastseen"
        },
        {
          "name": "attr/manufacturername"
        },
        {
          "name": "attr/modelid"
        },
        {
          "name": "attr/name"
        },
        {
          "name": "attr/swversion"
        },
        {
          "name": "attr/type"
        },
        {
          "name": "attr/uniqueid"
        },
        {
          "name": "state/lift",
          "refresh.interval": 60,
          "default": 0
        },
        {
          "name": "state/open",
          "parse": {
            "at": "0x0008",
            "cl": "0x0102",
            "ep": 0,
            "eval": "Item.val = Attr.val < 100",
            "fn": "zcl"
          }
        },
        {
          "name": "state/reachable"
        }
      ]
    }
  ],
  "bindings": [
    {
      "bind": "unicast",
      "src.ep": 1,
      "dst.ep": 1,
      "cl": "0x0102",
      "report": [
        {
          "at": "0x0008",
          "dt": "0x20",
          "min": 1,
          "max": 100,
          "change": "0x00000001"
        }
      ]
    }
  ]
}

By editing the DDF this way the cover is no longer treated as a light. Only thing is that the Sunricher/Philips cover controller uses 0% as completely closed and 100% for completely open. HA (and many other systems) use the other way around. You can invert this by putting some logic in the DDF, but then still the SET_POSITION will be inverted. in HA. This cannot be fixed in the DDF yet, so you have to use a cover template in HA to fix it:

cover:
  - platform: template
    covers:
      cover_inverted:
        device_class: shutter
        friendly_name: '<your friendly cover name>'
        position_template: "{{ 100 - (state_attr('cover.<your cover>', 'current_position') | int) }}"
        open_cover:
          service : cover.open_cover
          data:
            entity_id: cover.<your cover>
        close_cover:
          service : cover.close_cover
          data:
            entity_id: cover.<your cover>
        stop_cover:
          service : cover.stop_cover
          data:
            entity_id: cover.<your cover>
        set_cover_position:
          service: cover.set_cover_position
          data:
            entity_id: cover.<your cover>
            position: "{{ 100 - (position) }}"