### Problem description
Switch is calibrated and working correctly up/down/st…op and even reporting correct state and position but go_to_lift_percentage function does not work
### Solution description
get the go_to_lift_percentage function working or a tool to send commands up/down and stop calculated based on the calibration time.
### Screenshots/Video
![image](https://github.com/zigpy/zha-device-handlers/assets/131381975/15b98ded-f5af-44ab-aeed-edabd173dd09) #2707
### Device signature
```
{
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.FullFunctionDevice|MainsPowered|RxOnWhenIdle|AllocateAddress: 142>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
"endpoints": {
"1": {
"profile_id": "0x0104",
"device_type": "0x0203",
"input_clusters": [
"0x0000",
"0x0004",
"0x0005",
"0x0006",
"0x0102",
"0xe001"
],
"output_clusters": [
"0x000a",
"0x0019"
]
},
"242": {
"profile_id": "0xa1e0",
"device_type": "0x0061",
"input_clusters": [],
"output_clusters": [
"0x0021"
]
}
},
"manufacturer": "_TZ3000_qa8s8vca",
"model": "TS130F",
"class": "ts130f.TuyaTS130ESTC"
}
```
### Diagnostic information
```
{
"home_assistant": {
"installation_type": "Home Assistant OS",
"version": "2023.11.1",
"dev": false,
"hassio": true,
"virtualenv": false,
"python_version": "3.11.6",
"docker": true,
"arch": "x86_64",
"timezone": "Europe/Paris",
"os_name": "Linux",
"os_version": "6.1.59",
"supervisor": "2023.10.1",
"host_os": "Home Assistant OS 11.1",
"docker_version": "24.0.6",
"chassis": "embedded",
"run_as_root": true
},
"custom_components": {
"zha_toolkit": {
"version": "v1.1.6",
"requirements": [
"pytz"
]
},
"localtuya": {
"version": "5.2.1",
"requirements": []
},
"dreame_vacuum": {
"version": "v2.0.0b6",
"requirements": [
"pillow",
"numpy",
"pybase64",
"requests",
"pycryptodome",
"python-miio",
"py-mini-racer",
"tzlocal"
]
},
"cover_time_based_synced": {
"version": "2.0.0",
"requirements": []
},
"hacs": {
"version": "1.33.0",
"requirements": [
"aiogithubapi>=22.10.1"
]
},
"landroid_cloud": {
"version": "3.1.0",
"requirements": [
"pyworxcloud==4.0.2"
]
}
},
"integration_manifest": {
"domain": "zha",
"name": "Zigbee Home Automation",
"after_dependencies": [
"onboarding",
"usb"
],
"codeowners": [
"@dmulcahey",
"@adminiuga",
"@puddly"
],
"config_flow": true,
"dependencies": [
"file_upload"
],
"documentation": "https://www.home-assistant.io/integrations/zha",
"iot_class": "local_polling",
"loggers": [
"aiosqlite",
"bellows",
"crccheck",
"pure_pcapy3",
"zhaquirks",
"zigpy",
"zigpy_deconz",
"zigpy_xbee",
"zigpy_zigate",
"zigpy_znp",
"universal_silabs_flasher"
],
"requirements": [
"bellows==0.36.8",
"pyserial==3.5",
"pyserial-asyncio==0.6",
"zha-quirks==0.0.106",
"zigpy-deconz==0.21.1",
"zigpy==0.59.0",
"zigpy-xbee==0.19.0",
"zigpy-zigate==0.11.0",
"zigpy-znp==0.11.6",
"universal-silabs-flasher==0.0.14",
"pyserial-asyncio-fast==0.11"
],
"usb": [
{
"vid": "10C4",
"pid": "EA60",
"description": "*2652*",
"known_devices": [
"slae.sh cc2652rb stick"
]
},
{
"vid": "1A86",
"pid": "55D4",
"description": "*sonoff*plus*",
"known_devices": [
"sonoff zigbee dongle plus v2"
]
},
{
"vid": "10C4",
"pid": "EA60",
"description": "*sonoff*plus*",
"known_devices": [
"sonoff zigbee dongle plus"
]
},
{
"vid": "10C4",
"pid": "EA60",
"description": "*tubeszb*",
"known_devices": [
"TubesZB Coordinator"
]
},
{
"vid": "1A86",
"pid": "7523",
"description": "*tubeszb*",
"known_devices": [
"TubesZB Coordinator"
]
},
{
"vid": "1A86",
"pid": "7523",
"description": "*zigstar*",
"known_devices": [
"ZigStar Coordinators"
]
},
{
"vid": "1CF1",
"pid": "0030",
"description": "*conbee*",
"known_devices": [
"Conbee II"
]
},
{
"vid": "10C4",
"pid": "8A2A",
"description": "*zigbee*",
"known_devices": [
"Nortek HUSBZB-1"
]
},
{
"vid": "0403",
"pid": "6015",
"description": "*zigate*",
"known_devices": [
"ZiGate+"
]
},
{
"vid": "10C4",
"pid": "EA60",
"description": "*zigate*",
"known_devices": [
"ZiGate"
]
},
{
"vid": "10C4",
"pid": "8B34",
"description": "*bv 2010/10*",
"known_devices": [
"Bitron Video AV2010/10"
]
}
],
"zeroconf": [
{
"type": "_esphomelib._tcp.local.",
"name": "tube*"
},
{
"type": "_zigate-zigbee-gateway._tcp.local.",
"name": "*zigate*"
},
{
"type": "_zigstar_gw._tcp.local.",
"name": "*zigstar*"
},
{
"type": "_uzg-01._tcp.local.",
"name": "uzg-01*"
},
{
"type": "_slzb-06._tcp.local.",
"name": "slzb-06*"
}
],
"is_built_in": true
},
"data": {
"ieee": "**REDACTED**",
"nwk": 4129,
"manufacturer": "_TZ3000_qa8s8vca",
"model": "TS130F",
"name": "_TZ3000_qa8s8vca TS130F",
"quirk_applied": true,
"quirk_class": "ts130f.TuyaTS130ESTC",
"quirk_id": null,
"manufacturer_code": 4417,
"power_source": "Mains",
"lqi": 212,
"rssi": -47,
"last_seen": "2023-11-07T14:15:58",
"available": true,
"device_type": "Router",
"signature": {
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.FullFunctionDevice|MainsPowered|RxOnWhenIdle|AllocateAddress: 142>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
"endpoints": {
"1": {
"profile_id": "0x0104",
"device_type": "0x0203",
"input_clusters": [
"0x0000",
"0x0004",
"0x0005",
"0x0006",
"0x0102",
"0xe001"
],
"output_clusters": [
"0x000a",
"0x0019"
]
},
"242": {
"profile_id": "0xa1e0",
"device_type": "0x0061",
"input_clusters": [],
"output_clusters": [
"0x0021"
]
}
},
"manufacturer": "_TZ3000_qa8s8vca",
"model": "TS130F"
},
"active_coordinator": false,
"entities": [
{
"entity_id": "cover.rollladen_buro_cover",
"name": "_TZ3000_qa8s8vca TS130F"
},
{
"entity_id": "switch.rollladen_buro_switch",
"name": "_TZ3000_qa8s8vca TS130F"
}
],
"neighbors": [],
"routes": [],
"endpoint_names": [
{
"name": "WINDOW_COVERING_CONTROLLER"
},
{
"name": "PROXY_BASIC"
}
],
"user_given_name": "Rollladen B\u00fcro",
"device_reg_id": "71d7a050aa03354d24de3aec06c8e182",
"area_id": "buro",
"cluster_details": {
"1": {
"device_type": {
"name": "WINDOW_COVERING_CONTROLLER",
"id": 515
},
"profile_id": 260,
"in_clusters": {
"0x0000": {
"endpoint_attribute": "basic",
"attributes": {
"0x0004": {
"attribute_name": "manufacturer",
"value": "_TZ3000_qa8s8vca"
},
"0x0005": {
"attribute_name": "model",
"value": "TS130F"
}
},
"unsupported_attributes": {}
},
"0x0004": {
"endpoint_attribute": "groups",
"attributes": {},
"unsupported_attributes": {}
},
"0x0005": {
"endpoint_attribute": "scenes",
"attributes": {},
"unsupported_attributes": {}
},
"0x0006": {
"endpoint_attribute": "on_off",
"attributes": {
"0x8001": {
"attribute_name": "backlight_mode",
"value": 0
}
},
"unsupported_attributes": {
"0x0000": {
"attribute_name": "on_off"
},
"0x4003": {
"attribute_name": "start_up_on_off"
}
}
},
"0x0102": {
"endpoint_attribute": "window_covering",
"attributes": {
"0xf001": {
"attribute_name": "calibration",
"value": 1
},
"0xf003": {
"attribute_name": "calibration_time",
"value": 210
},
"0x0008": {
"attribute_name": "current_position_lift_percentage",
"value": 0
},
"0x8000": {
"attribute_name": "motor_mode",
"value": 0
},
"0xf002": {
"attribute_name": "motor_reversal",
"value": 0
},
"0xf000": {
"attribute_name": "tuya_moving_state",
"value": 0
}
},
"unsupported_attributes": {
"0x0015": {
"attribute_name": "acceleration_time_lift"
},
"0x0009": {
"attribute_name": "current_position_tilt_percentage"
}
}
},
"0xe001": {
"endpoint_attribute": "tuya_external_switch_type",
"attributes": {},
"unsupported_attributes": {}
}
},
"out_clusters": {
"0x000a": {
"endpoint_attribute": "time",
"attributes": {},
"unsupported_attributes": {}
},
"0x0019": {
"endpoint_attribute": "ota",
"attributes": {},
"unsupported_attributes": {}
}
}
},
"242": {
"device_type": {
"name": "PROXY_BASIC",
"id": 97
},
"profile_id": 41440,
"in_clusters": {},
"out_clusters": {
"0x0021": {
"endpoint_attribute": "green_power",
"attributes": {},
"unsupported_attributes": {}
}
}
}
}
}
}
```
### Logs
### Custom quirk
```
"""Device handler for loratap TS130F smart curtain switch."""
from zigpy.profiles import zgp, zha
from zigpy.quirks import CustomCluster, CustomDevice
import zigpy.types as t
from zigpy.zcl.clusters.closures import WindowCovering
from zigpy.zcl.clusters.general import (
Basic,
GreenPowerProxy,
Groups,
OnOff,
Ota,
Scenes,
Time,
)
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODEL,
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.tuya import SwitchBackLight, TuyaZBExternalSwitchTypeCluster
ATTR_CURRENT_POSITION_LIFT_PERCENTAGE = 0x0008
CMD_GO_TO_LIFT_PERCENTAGE = 0x0005
class TuyaWithBacklightOnOffCluster(CustomCluster, OnOff):
"""Tuya Zigbee On Off cluster with extra attributes."""
attributes = OnOff.attributes.copy()
attributes.update({0x8001: ("backlight_mode", SwitchBackLight)})
class MotorMode(t.enum8):
"""Tuya motor mode enum."""
STRONG_MOTOR = 0x00
WEAK_MOTOR = 0x01
class TuyaCoveringCluster(CustomCluster, WindowCovering):
"""TuyaSmartCurtainWindowCoveringCluster: Allow to setup Window covering tuya devices."""
attributes = WindowCovering.attributes.copy()
attributes.update({0x8000: ("motor_mode", MotorMode)})
attributes.update({0xF000: ("tuya_moving_state", t.enum8)})
attributes.update({0xF001: ("calibration", t.enum8)})
attributes.update({0xF002: ("motor_reversal", t.enum8)})
attributes.update({0xF003: ("calibration_time", t.uint16_t)})
def _update_attribute(self, attrid, value):
if attrid == ATTR_CURRENT_POSITION_LIFT_PERCENTAGE:
# Invert the percentage value (cf https://github.com/dresden-elektronik/deconz-rest-plugin/issues/3757)
value = 100 - value
super()._update_attribute(attrid, value)
async def command(
self, command_id, *args, manufacturer=None, expect_reply=True, tsn=None
):
"""Override default command to invert percent lift value."""
if command_id == CMD_GO_TO_LIFT_PERCENTAGE:
percent = args[0]
# Invert the percentage value (cf https://github.com/dresden-elektronik/deconz-rest-plugin/issues/3757)
percent = 100 - percent
v = (percent,)
return await super().command(command_id, *v)
return await super().command(
command_id,
*args,
manufacturer=manufacturer,
expect_reply=expect_reply,
tsn=tsn,
)
class TuyaTS130FTI(CustomDevice):
"""Tuya smart curtain roller shutter Time In."""
signature = {
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=0x0202, device_version=1, input_clusters=[0, 4, 5, 6, 10, 0x0102], output_clusters=[25]))
MODEL: "TS130F",
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
Time.cluster_id,
OnOff.cluster_id,
WindowCovering.cluster_id,
],
OUTPUT_CLUSTERS: [Ota.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
Time.cluster_id,
TuyaWithBacklightOnOffCluster,
TuyaCoveringCluster,
],
OUTPUT_CLUSTERS: [Ota.cluster_id],
},
},
}
class TuyaZemismartTS130F(CustomDevice):
"""Tuya ZemiSmart smart curtain roller shutter."""
signature = {
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=0x0202, device_version=1, input_clusters=[0x0000, 0x0004, 0x0005, 0x0006, 0x0102], output_clusters=[0x000a, 0x0019]))
MODEL: "TS130F",
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
WindowCovering.cluster_id,
],
OUTPUT_CLUSTERS: [
Time.cluster_id,
Ota.cluster_id,
],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaWithBacklightOnOffCluster,
TuyaCoveringCluster,
],
OUTPUT_CLUSTERS: [
Time.cluster_id,
Ota.cluster_id,
],
},
},
}
class TuyaTS130FTOGP(CustomDevice):
"""Tuya Oxt smart curtain roller shutter."""
signature = {
MODEL: "TS130F",
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=0x0202
# device_version=1
# input_clusters=[0x0000, 0x0004, 0x0005, 0x0102]
# output_clusters=[0x000a, 0x0019]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
WindowCovering.cluster_id,
],
OUTPUT_CLUSTERS: [
Time.cluster_id,
Ota.cluster_id,
],
},
# <SimpleDescriptor endpoint=242 profile=41440 device_type=97
# input_clusters=[]
# output_clusters=[33]>
242: {
PROFILE_ID: zgp.PROFILE_ID,
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaCoveringCluster,
],
OUTPUT_CLUSTERS: [
Time.cluster_id,
Ota.cluster_id,
],
},
242: {
PROFILE_ID: zgp.PROFILE_ID,
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
class TuyaTS130FTI2(CustomDevice):
"""Tuya smart curtain roller shutter Time In."""
signature = {
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=0x0203, device_version=1, input_clusters=[0x0000, 0x0004, 0x0005, 0x0006, 0x0102], output_clusters=[0x000a, 0x0019]))
MODEL: "TS130F",
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_CONTROLLER,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
WindowCovering.cluster_id,
],
OUTPUT_CLUSTERS: [
Time.cluster_id,
Ota.cluster_id,
],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_CONTROLLER,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaWithBacklightOnOffCluster,
TuyaCoveringCluster,
],
OUTPUT_CLUSTERS: [
Time.cluster_id,
Ota.cluster_id,
],
},
},
}
class TuyaTS130FTO(CustomDevice):
"""Tuya smart curtain roller shutter Time Out."""
signature = {
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=0x0202, device_version=1, input_clusters=[0, 4, 5, 6, 10, 0x0102], output_clusters=[25]))
# This singnature is not correct is one copy of the first one and the cluster is not inline with the device.
MODEL: "TS130F",
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
WindowCovering.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaCoveringCluster,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
},
}
class TuyaTS130GP(CustomDevice):
"""Tuya ZemiSmart smart curtain roller shutter with Green Power."""
signature = {
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=0x0202, device_version=1, input_clusters=[0, 4, 5, 6, 0x0102], output_clusters=[0x000a, 0x0019]))
MODEL: "TS130F",
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
WindowCovering.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
242: {
# <SimpleDescriptor endpoint=242 profile=41440 device_type=97
# input_clusters=[]
# output_clusters=[33]
PROFILE_ID: zgp.PROFILE_ID,
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaWithBacklightOnOffCluster,
TuyaCoveringCluster,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
242: {
PROFILE_ID: zgp.PROFILE_ID,
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
class TuyaTS130Double_GP(CustomDevice):
"""Tuya double smart curtain roller shutter with Green Power."""
signature = {
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=0x0202, device_version=1, input_clusters=[0, 4, 5, 6, 0x0102], output_clusters=[0x000a, 0x0019]))
MODEL: "TS130F",
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
WindowCovering.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
2: {
# "profile_id": 260, "device_type": "0x0202",
# "in_clusters": ["0x0004","0x0005","0x0006","0x0102"],
# "out_clusters": []
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
WindowCovering.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
242: {
# <SimpleDescriptor endpoint=242 profile=41440 device_type=97
# input_clusters=[]
# output_clusters=[33]
PROFILE_ID: zgp.PROFILE_ID,
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaWithBacklightOnOffCluster,
TuyaCoveringCluster,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
TuyaWithBacklightOnOffCluster,
TuyaCoveringCluster,
],
OUTPUT_CLUSTERS: [],
},
242: {
PROFILE_ID: zgp.PROFILE_ID,
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
class TuyaTS130ESTC(CustomDevice):
"""Tuya ZigBee Curtain Switch Module with External Switch Type Cluster."""
signature = {
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=0x0202, device_version=1, input_clusters=[0x0000, 0x0004, 0x0005, 0x0006, 0x0102, 0xE001], output_clusters=[0x000a, 0x0019]))
MODEL: "TS130F",
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
WindowCovering.cluster_id,
TuyaZBExternalSwitchTypeCluster.cluster_id,
],
OUTPUT_CLUSTERS: [
Time.cluster_id,
Ota.cluster_id,
],
},
242: {
# <SimpleDescriptor endpoint=242 profile=41440 device_type=97
# input_clusters=[]
# output_clusters=[33]
PROFILE_ID: zgp.PROFILE_ID,
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_CONTROLLER,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaWithBacklightOnOffCluster,
TuyaCoveringCluster,
TuyaZBExternalSwitchTypeCluster,
],
OUTPUT_CLUSTERS: [
Time.cluster_id,
Ota.cluster_id,
],
},
242: {
PROFILE_ID: zgp.PROFILE_ID,
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
class TuyaTS130Double_GP_ESTC(CustomDevice):
"""Tuya double smart curtain roller shutter with Green Power and External Switch Type Cluster."""
signature = {
# SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=0x0202, device_version=1, input_clusters=[0, 4, 5, 6, 0x0102, 0xE001], output_clusters=[0x000a, 0x0019]))
MODEL: "TS130F",
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
WindowCovering.cluster_id,
TuyaZBExternalSwitchTypeCluster.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
2: {
# "profile_id": 260, "device_type": "0x0202",
# "in_clusters": ["0x0004","0x0005","0x0006","0x0102"],
# "out_clusters": []
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
WindowCovering.cluster_id,
TuyaZBExternalSwitchTypeCluster.cluster_id,
],
OUTPUT_CLUSTERS: [],
},
242: {
# <SimpleDescriptor endpoint=242 profile=41440 device_type=97
# input_clusters=[]
# output_clusters=[33]
PROFILE_ID: zgp.PROFILE_ID,
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Basic.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
TuyaWithBacklightOnOffCluster,
TuyaCoveringCluster,
TuyaZBExternalSwitchTypeCluster,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.WINDOW_COVERING_DEVICE,
INPUT_CLUSTERS: [
Groups.cluster_id,
Scenes.cluster_id,
TuyaWithBacklightOnOffCluster,
TuyaCoveringCluster,
TuyaZBExternalSwitchTypeCluster,
],
OUTPUT_CLUSTERS: [],
},
242: {
PROFILE_ID: zgp.PROFILE_ID,
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
```
### Additional information
I'm new to home assistant and managed it to got the local quirk working but I would say that's it.
I spent a lot of hours ready and searching for solutions but I didn't find the right thing.
If I try to send command: go_to_lift_percentage (id: 0x0005), I have a slider from with value from 0 to 255. But I got an error:
![image](https://github.com/zigpy/zha-device-handlers/assets/131381975/8fb07861-4e1e-4d4d-b9a3-b1c28ebe92ee)
![image](https://github.com/zigpy/zha-device-handlers/assets/131381975/134c8041-d637-4da6-8464-0ab2484478b8)
The return of the actual position in percent works, even if commanded via the physical buttons.
![image](https://github.com/zigpy/zha-device-handlers/assets/131381975/a9470cbb-0831-4b9a-98ba-886bf7ad38f1)
What about "time based cover synced", can that help me in my case? I tried to install it (adding to the configuration.yaml) but I don't know how to use it...
Hope someone can help me as it's the only zigbee roller shutter switch which has physical buttons which are superposed and not always backlight on and to a good price (I need 17 pieces). The light from other switches disturbs me in the night and to find the button without light with a glas touch panel is not so easy...
Thanks!