Tuya: New Device: Standing Desk

Hi,
I own a standing desk, that can be controlled with tuya smart, but is unsupported by the HA integration. I added the json with the device instruction info below. It would be amazing if we can get this working with HA.

Device Info JSON
{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2023.7.3",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.11.4",
    "docker": true,
    "arch": "aarch64",
    "timezone": "Europe/Berlin",
    "os_name": "Linux",
    "os_version": "6.1.21-v8",
    "supervisor": "2023.07.1",
    "host_os": "Home Assistant OS 10.3",
    "docker_version": "23.0.6",
    "chassis": "embedded",
    "run_as_root": true
  },
  "integration_manifest": {
    "domain": "tuya",
    "name": "Tuya",
    "codeowners": [
      "@Tuya",
      "@zlinoliver",
      "@frenck"
    ],
    "config_flow": true,
    "dependencies": [
      "ffmpeg"
    ],
    "dhcp": [
      {
        "macaddress": "105A17*"
      },
      {
        "macaddress": "10D561*"
      },
      {
        "macaddress": "1869D8*"
      },
      {
        "macaddress": "381F8D*"
      },
      {
        "macaddress": "508A06*"
      },
      {
        "macaddress": "68572D*"
      },
      {
        "macaddress": "708976*"
      },
      {
        "macaddress": "7CF666*"
      },
      {
        "macaddress": "84E342*"
      },
      {
        "macaddress": "D4A651*"
      },
      {
        "macaddress": "D81F12*"
      }
    ],
    "documentation": "https://www.home-assistant.io/integrations/tuya",
    "integration_type": "hub",
    "iot_class": "cloud_push",
    "loggers": [
      "tuya_iot"
    ],
    "requirements": [
      "tuya-iot-py-sdk==0.6.6"
    ],
    "is_built_in": true
  },
  "data": {
    "endpoint": "https://openapi.tuyaeu.com",
    "auth_type": 0,
    "country_code": "49",
    "app_type": "tuyaSmart",
    "mqtt_connected": true,
    "disabled_by": null,
    "disabled_polling": false,
    "name": "Standing Desk",
    "model": "",
    "category": "sjz",
    "product_id": "1wix0qshtb1gmgpn",
    "product_name": "Standing Desk",
    "online": true,
    "sub": false,
    "time_zone": "+02:00",
    "active_time": "2023-07-29T14:04:55+00:00",
    "create_time": "2023-07-29T14:04:55+00:00",
    "update_time": "2023-07-29T14:11:57+00:00",
    "function": {
      "child_lock": {
        "type": "Boolean",
        "value": {}
      },
      "unit_display": {
        "type": "Boolean",
        "value": {}
      },
      "reset_signal": {
        "type": "Boolean",
        "value": {}
      },
      "restore_user_set": {
        "type": "Boolean",
        "value": {}
      },
      "height_max": {
        "type": "Integer",
        "value": {
          "unit": "mm",
          "min": 500,
          "max": 2000,
          "scale": 0,
          "step": 1
        }
      },
      "height_min": {
        "type": "Integer",
        "value": {
          "unit": "mm",
          "min": 500,
          "max": 2000,
          "scale": 0,
          "step": 1
        }
      },
      "sensor_sensitive": {
        "type": "Integer",
        "value": {
          "unit": "",
          "min": 0,
          "max": 8,
          "scale": 0,
          "step": 1
        }
      },
      "up_i_sensitive": {
        "type": "Integer",
        "value": {
          "unit": "",
          "min": 0,
          "max": 8,
          "scale": 0,
          "step": 1
        }
      },
      "down_i_sensitive": {
        "type": "Integer",
        "value": {
          "unit": "",
          "min": 0,
          "max": 8,
          "scale": 0,
          "step": 1
        }
      },
      "desktop_thickness_cm": {
        "type": "Integer",
        "value": {
          "unit": "cm",
          "min": 0,
          "max": 120,
          "scale": 1,
          "step": 1
        }
      },
      "desktop_thickness_in": {
        "type": "Integer",
        "value": {
          "unit": "inch",
          "min": 0,
          "max": 20,
          "scale": 1,
          "step": 2
        }
      },
      "stand_height_set": {
        "type": "Integer",
        "value": {
          "unit": "mm",
          "min": 500,
          "max": 2000,
          "scale": 0,
          "step": 1
        }
      },
      "ss_time_set": {
        "type": "Raw",
        "value": {}
      },
      "move_up": {
        "type": "Boolean",
        "value": {}
      },
      "move_down": {
        "type": "Boolean",
        "value": {}
      },
      "memory_button": {
        "type": "Boolean",
        "value": {}
      },
      "memory_location": {
        "type": "Enum",
        "value": {
          "range": [
            "mem1",
            "mem2",
            "mem3",
            "mem4"
          ]
        }
      },
      "timing_remind_s_app": {
        "type": "Boolean",
        "value": {}
      },
      "timing_remind_s_dev": {
        "type": "Boolean",
        "value": {}
      },
      "timing_remind_signal": {
        "type": "Boolean",
        "value": {}
      }
    },
    "status_range": {
      "child_lock": {
        "type": "Boolean",
        "value": {}
      },
      "unit_display": {
        "type": "Boolean",
        "value": {}
      },
      "reset_signal": {
        "type": "Boolean",
        "value": {}
      },
      "restore_user_set": {
        "type": "Boolean",
        "value": {}
      },
      "height_max_limit": {
        "type": "Integer",
        "value": {
          "unit": "mm",
          "min": 500,
          "max": 2000,
          "scale": 0,
          "step": 1
        }
      },
      "height_min_limit": {
        "type": "Integer",
        "value": {
          "unit": "mm",
          "min": 500,
          "max": 2000,
          "scale": 0,
          "step": 1
        }
      },
      "height_max": {
        "type": "Integer",
        "value": {
          "unit": "mm",
          "min": 500,
          "max": 2000,
          "scale": 0,
          "step": 1
        }
      },
      "height_min": {
        "type": "Integer",
        "value": {
          "unit": "mm",
          "min": 500,
          "max": 2000,
          "scale": 0,
          "step": 1
        }
      },
      "sensor_sensitive": {
        "type": "Integer",
        "value": {
          "unit": "",
          "min": 0,
          "max": 8,
          "scale": 0,
          "step": 1
        }
      },
      "up_i_sensitive": {
        "type": "Integer",
        "value": {
          "unit": "",
          "min": 0,
          "max": 8,
          "scale": 0,
          "step": 1
        }
      },
      "down_i_sensitive": {
        "type": "Integer",
        "value": {
          "unit": "",
          "min": 0,
          "max": 8,
          "scale": 0,
          "step": 1
        }
      },
      "desktop_thickness_cm": {
        "type": "Integer",
        "value": {
          "unit": "cm",
          "min": 0,
          "max": 120,
          "scale": 1,
          "step": 1
        }
      },
      "desktop_thickness_in": {
        "type": "Integer",
        "value": {
          "unit": "inch",
          "min": 0,
          "max": 20,
          "scale": 1,
          "step": 2
        }
      },
      "stand_height_set": {
        "type": "Integer",
        "value": {
          "unit": "mm",
          "min": 500,
          "max": 2000,
          "scale": 0,
          "step": 1
        }
      },
      "ss_time_set": {
        "type": "Raw",
        "value": {}
      },
      "t_standing_min": {
        "type": "Integer",
        "value": {
          "unit": "min",
          "min": 0,
          "max": 1440,
          "scale": 0,
          "step": 1
        }
      },
      "t_stand_target_min": {
        "type": "Integer",
        "value": {
          "unit": "min",
          "min": 0,
          "max": 1440,
          "scale": 0,
          "step": 1
        }
      },
      "move_up": {
        "type": "Boolean",
        "value": {}
      },
      "move_down": {
        "type": "Boolean",
        "value": {}
      },
      "height_display": {
        "type": "Integer",
        "value": {
          "unit": "mm",
          "min": 500,
          "max": 2000,
          "scale": 0,
          "step": 1
        }
      },
      "memory_button": {
        "type": "Boolean",
        "value": {}
      },
      "memory_location": {
        "type": "Enum",
        "value": {
          "range": [
            "mem1",
            "mem2",
            "mem3",
            "mem4"
          ]
        }
      },
      "memory_height": {
        "type": "Raw",
        "value": {}
      },
      "fault_code_report": {
        "type": "Bitmap",
        "value": {
          "label": [
            "fault_code_1",
            "fault_code_2"
          ],
          "maxlen": 2
        }
      },
      "timing_remind_s_app": {
        "type": "Boolean",
        "value": {}
      },
      "timing_remind_s_dev": {
        "type": "Boolean",
        "value": {}
      },
      "timing_remind_signal": {
        "type": "Boolean",
        "value": {}
      },
      "ss_history_data1": {
        "type": "Raw",
        "value": {}
      },
      "ss_history_data2": {
        "type": "Raw",
        "value": {}
      },
      "ss_history_data3": {
        "type": "Raw",
        "value": {}
      },
      "ss_history_data4": {
        "type": "Raw",
        "value": {}
      }
    },
    "status": {
      "child_lock": true,
      "unit_display": false,
      "reset_signal": false,
      "restore_user_set": false,
      "height_max_limit": 1308,
      "height_min_limit": 648,
      "height_max": 1308,
      "height_min": 648,
      "sensor_sensitive": 4,
      "up_i_sensitive": 4,
      "down_i_sensitive": 4,
      "desktop_thickness_cm": 28,
      "desktop_thickness_in": 12,
      "stand_height_set": 900,
      "ss_time_set": "AC0AD38IAAseDQASAA==",
      "t_standing_min": 0,
      "t_stand_target_min": 135,
      "move_up": false,
      "move_down": false,
      "height_display": 740,
      "memory_button": false,
      "memory_location": "mem1",
      "memory_height": "AuQERAPSAuQ=",
      "fault_code_report": 0,
      "timing_remind_s_app": false,
      "timing_remind_s_dev": false,
      "timing_remind_signal": false,
      "ss_history_data1": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
      "ss_history_data2": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
      "ss_history_data3": "FwcBAAAAABcHAgAAAAAXBwMAAAAAFwcEAAAAABcHBQAAAAAXBwYAAAAAFwcHAAAAABcHCAAAAAAXBwkAAAAAFwcKAAAAABcHCwAAAAAXBwwAAAAAFwcNAAAAABcHDgAAAAAXBw8AAAAAFwcQAAAAABcHEQAAAAAXBxIAAAAAFwcTAAAAABcHFAAAAAAXBxUAAAAAFwcWAAAAABcHFwAAAAAXBxgAAAAAFwcZAAAAABcHGgAAAAAXBxsAAAAAFwccAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
      "ss_history_data4": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
    },
    "home_assistant": {
      "name": "Standing Desk",
      "name_by_user": null,
      "disabled": false,
      "disabled_by": null,
      "entities": []
    }
  }
}

I used the iot platform to understand how the instructions work and I think for a start the following instruction might be the one with the most value:

[
  {
    "code": "memory_location",
    "value": "mem1"
  }
]

If this value is sent, the desk will then move to position 1 (predefined in app). There is also mem2, mem3 and mem4.
I believe four ‘simple’ buttons in HA would be enough, one for each position.

Of course, this desk can also be controlled like a cover:

  {
    "code": "move_up",
    "value": false
  },

or

  {
    "code": "move_down",
    "value": false
  },

If true is sent, the desk moves until again false is sent. However, this provides less value as a standing desk usually is not controlled like this (I of course always sit/stand at a predefined hight).

Good practice seems to be to wake the device before sending commands with (child lock is uses as an ‘energy saving thing’):

  {
    "code": "child_lock",
    "value": false
  }

Hi,

I finally got to your post, expecting to have a simillar desk (ergolutions) and the same problem. My research over the past few ours produced the exact same results.

Did you make any progress since summer? I am also looking for a way to integrate it into HA and HomeKit.

No progress yet by me

Hello,
If you’re still interested in having this supported, can you share the device with me and I’ll try to implement it in my custom integration (GitHub - azerty9971/xtend_tuya: eXtend Tuya's integration)
To share the device, from your SmartLife/Tuya app, share it with this account:
SmartLife: gg-106053160716494114782
Tuya: [email protected]

Thanks in advance,
Azerty