I found the only way to support smooth brightness change is work with MQTT. Also python is the way to avoid limitation of native scripting (see Python Scripts - Home Assistant to enable it).
Also to make life simplier I used special naming for devices to make them more or less self configurable. Only 5 button remote require helper variable to store current group of lams which it controls (see comment). Becouse of this maybe it can not be usefull as is for many, but IMHO it shows example how use the controls.
#
# PARAMETERS:
#
# topic - topic of the MQTT messages from zigbee2mqtt/+/action
# payload - payload of the messages
#
# Trigger which suply such parameters looks like this:
# alias: MQTT
# description: ''
# trigger:
# - platform: mqtt
# topic: zigbee2mqtt/+/action
# condition: []
# action:
# - service: python_script.mqtt_buttons
# data:
# topic: '{{ trigger.topic }}'
# payload: '{{ trigger.payload }}'
# mode: parallel
# max: 10
#
# DEVICES NAMING SCHEMA
#
# Lampls: lamp_XX, where XX number but theoretically can be any string, example:
# lamp_01
#
# Covers: shade_XX, where XX number but theoretically can be any string, example:
# shade_01
#
# Relay: switch_XX, where XX number but theoretically can be any string, example:
# swith_01
#
# Buttons:
#
# sw_XX_YY_ZZ... TRÅDFRI E1743 which control lamps, XX, YY, ZZ and so on are lamp
# endings above (points which lamps to control) examples:
#
# sw_25 sw_14_15 sw_26_27_28_33
#
# controls:
# on/off switch on/off lamps, long press change brightnes smoothly
#
# sc_XX_YY_ZZ... TRÅDFRI E1766 which controls covers, XX, YY, ZZ and so on are
# cover endings (points which covers to control) examples:
#
# sc_01 sc_02_03
#
# controls:
# open/close open or close covers
#
# st_XX_YY_ZZ... TRÅDFRI E1743 which control relays, XX, YY, ZZ and so on are
# relay endings (points which relays to control) examples:
#
# st_01 st_07_12
#
# controls:
# on/off switch on/off relays
#
# sb_A_B_C... TRÅDFRI E1524/E1810 which controls several groups of lamps,
# A, B, C and so on are groups of lamps ending devided by dash ('-'). examplea:
#
# sb_03-04_07-08-09_05-06_10_01-02
#
# (it controls 5 goups of lamps:
# 1) lamp_03 and lamp_04
# 2) lamp_07, lamp_08 and lamp_09
# 3) lamp_05 and lamp_06
# 4) lamp_10
# 5) lamp_01 and lamp_02 )
#
# controls:
# Left/right arrows switches between groups of lamps
# Toggle - switch on or off (toggle) each lamp in the group
# (if thay are out of sync it is your foult)
# short click on brightnes change brightness by steps
# long press on brightness change brightness smoothly
#
# helping input variable
# for functioning "sb" remote control you have to create helper with the
# same name (HA will change '-' with '_' but script takes it into account)
#
topic = data.get("topic")
payload = data.get("payload")
RESP= {'on' : '{"state":"ON"}',
'off' : '{"state":"OFF"}',
'brightness_move_up' : '{"brightness_move": 40}',
'brightness_move_down' : '{"brightness_move": -40}',
'brightness_stop' : '{"brightness_move": 0}',
'open' : '{"state":"OPEN"}',
'close' : '{"state":"CLOSE"}',
'toggle' : '{"state": "TOGGLE"}',
'brightness_up_hold' : '{"brightness_move": 40}',
'brightness_up_release' : '{"brightness_move": 0}',
'brightness_up_click' : '{"brightness_step": 40}',
'brightness_down_hold' : '{"brightness_move": -40}',
'brightness_down_release' : '{"brightness_move": 0}',
'brightness_down_click' : '{"brightness_step": -40}',
'arrow_right_click' : '+',
'arrow_left_click' : '-',
}
switch= topic.split('/')[1]
parts= switch.split('_')
sw= parts[0]
nums= parts[1:]
#logger.info("MQTT: %s %s %s %s", topic, payload, sw, nums)
if payload in RESP:
responce= RESP[payload]
if sw == 'sw':
# lamps
for num in nums:
lamp= 'zigbee2mqtt/lamp_' + num + '/set'
hass.services.call('mqtt', 'publish', {'topic' : lamp, 'payload' : responce, 'qos': 2}, False)
elif sw == 'sc':
# covers
for num in nums:
cover= 'zigbee2mqtt/shade_' + num + '/set'
hass.services.call('mqtt', 'publish', {'topic' : cover, 'payload' : responce, 'qos': 2}, False)
elif sw == 'sb':
# big button lamps
control_var= 'input_number.' + switch;
control_var= control_var.replace('-', '_')
logger.info("MQTT: Var %s", control_var)
control_num= int(float(hass.states.get(control_var).state))
if control_num < 0 or control_num >= len(nums):
control_num= 0;
hass.services.call('input_number','set_value', {'entity_id' : control_var , 'value' : 0}, False)
if responce == '+':
control_num = control_num + 1
if control_num >= len(nums):
control_num= 0
hass.services.call('input_number','set_value', {'entity_id' : control_var , 'value' : control_num}, False)
responce= '{"effect": "okay"}'
elif responce == '-':
if control_num == 0:
control_num= len(nums)
control_num = control_num - 1
hass.services.call('input_number','set_value', {'entity_id' : control_var , 'value' : control_num}, False)
responce= '{"effect": "okay"}'
nums= nums[control_num].split('-')
for num in nums:
lamp= 'zigbee2mqtt/lamp_' + num + '/set'
hass.services.call('mqtt', 'publish', {'topic' : lamp, 'payload' : responce, 'qos': 2}, False)
elif sw == 'st':
# switches
for num in nums:
switch= 'zigbee2mqtt/switch_' + num + '/set'
hass.services.call('mqtt', 'publish', {'topic' : switch, 'payload' : responce, 'qos': 2}, False)