Skip to content

如何开发新驱动

jiaomuwwl edited this page Jul 23, 2021 · 1 revision

En Zh

比如,我想让我名为”客厅插座“的插座在tuya v2中工作。

一、获取设备信息

首先,根据如何获取日志获取到日志,从日志中查找”客厅插座“,能获取到该设备的信息,如

{
      "active_time": 1623229189,
      "biz_type": 18,
      "category": "cz",
      "create_time": 1560491945,
      "icon": "smart/product_icon/cz.png",
      "id": "xxxxxxxxxxxxxxx",
      "ip": "xxxxxxxxxxxxxxx",
      "lat": "30.30286857361191",
      "local_key": "xxxxxxxx",
      "lon": "120.0639743842656",
      "model": "",
      "name": "Living room switch",
      "online": false,
      "owner_id": "34794909",
      "product_id": "yfemiswbgjhddhcf",
      "product_name": "Switch Product",
      "status": [
        {
          "code": "switch",
          "value": false
        },
        {
          "code": "countdown_1",
          "value": 0
        },
        {
          "code": "cur_current",
          "value": 0
        },
        {
          "code": "cur_power",
          "value": 0
        },
        {
          "code": "cur_voltage",
          "value": 2343
        }
      ],
      "sub": false,
      "time_zone": "+08:00",
      "uid": "ay1622097934070h5Mpi",
      "update_time": 1625101929,
      "uuid": "65015854bcddc21a9073"
    }

二、查找品类支持

2.1 涂鸦设备品类设备集

从中获取到 "category": "cz",得知我的插座在涂鸦定义的品类为 cz, 到涂鸦开发者网站查找 cz 品类对应设备集

2.2 Home Assistant支持Entities

根据我的插座,从Home Assistant Entities 中查找支持的Entity 模型,这里查找到SwitchEntity比较匹配我的插座设备。

三、驱动开发

根据选择的Home Assistant中SwitchEntity,我们在tuya_v2中新建switch.py文件。 新建 TUYA_SUPPORT_TYPE ,作为SwitchEntity 对应支持的涂鸦品类。

3.1 支持品类

由于我们需要支持 cz,所以在switch.py文件中编写

TUYA_SUPPORT_TYPE = {
    "kg",  # Switch
}

在const.py 的 TUYA_SUPPORT_HA_TYPE中确认SwitchEntity 对应的Home Assistant品类存在,如SwitchEntity 对应 switch,则需确认switch存在;如果不存在,则添加下。

TUYA_SUPPORT_HA_TYPE = [
    "switch",   
    "fan",
    "cover",
    "climate",
    "light",
    "sensor",
    "binary_sensor",
    "humidifier",
    "number",
    "vacuum"
]

3.2 设备注册逻辑

async def async_setup_entry(
    hass: HomeAssistant, _entry: ConfigEntry, async_add_entities
):
    """Set up tuya sensors dynamically through tuya discovery."""
    _LOGGER.info("switch init")

    hass.data[DOMAIN][TUYA_HA_TUYA_MAP].update({DEVICE_DOMAIN: TUYA_SUPPORT_TYPE})

    async def async_discover_device(dev_ids):
        """Discover and add a discovered tuya switch."""
        _LOGGER.info(f"switch add-> {dev_ids}")
        if not dev_ids:
            return
        entities = await hass.async_add_executor_job(_setup_entities, hass, dev_ids)
        hass.data[DOMAIN][TUYA_HA_DEVICES].extend(entities)
        async_add_entities(entities)

    async_dispatcher_connect(
        hass, TUYA_DISCOVERY_NEW.format(DEVICE_DOMAIN), async_discover_device
    )

    device_manager = hass.data[DOMAIN][TUYA_DEVICE_MANAGER]
    device_ids = []
    for (device_id, device) in device_manager.device_map.items():
        if device.category in TUYA_SUPPORT_TYPE:
            device_ids.append(device_id)
    await async_discover_device(device_ids)


def _setup_entities(hass, device_ids: list):
    """Set up Tuya Switch device."""
    device_manager = hass.data[DOMAIN][TUYA_DEVICE_MANAGER]
    entities = []
    for device_id in device_ids:
        device = device_manager.device_map[device_id]
        if device is None:
            continue

        for function in device.function:
            if function.startswith(DPCODE_SWITCH):
                entities.append(TuyaHaSwitch(device, device_manager, function))
                continue

    return entities

3.2 Properties

从Home Assistant Switch的Entity文档中可以查看到需要重写的Properties 参数为is_on。

作用为表示插座开关,查看插座对应涂鸦品类cz对应设备指令集得知dp code "switch"表示插座开关,并根据设备信息中status

"status": [
        {
          "code": "switch",
          "value": false
        },
        {
          "code": "countdown_1",
          "value": 0
        },
        {
          "code": "cur_current",
          "value": 0
        },
        {
          "code": "cur_power",
          "value": 0
        },
        {
          "code": "cur_voltage",
          "value": 2343
        }
      ]

得知该设备status中存在dp code "switch",因此 定义DPCODE_SWITCH作为开关dp code,重写方法is_on:

    @property
    def is_on(self) -> bool:
        """Return true if switch is on."""
        return self.tuya_device.status.get(self.dp_code, False)

3.3 Methods

从Home Assistant Switch的Entity文档中可以查看到需要重写的Methods

turn_on和turn_off,作用为实现插座开关动作,查看插座对应涂鸦品类cz对应设备指令集得知dp code "switch"用于插座开关动作,并从日志中获取设备的设备集信息

 "result": {
    "category": "cz",
    "functions": [
      {
        "code": "countdown_1",
        "type": "Integer",
        "values": "{\"unit\":\"s\",\"min\":0,\"max\":86400,\"scale\":0,\"step\":1}"
      },
      {
        "code": "switch",
        "type": "Boolean",
        "values": "{}"
      }
    ],
    "status": [
      {
        "code": "cur_voltage",
        "type": "Integer",
        "values": "{\"unit\":\"V\",\"min\":0,\"max\":2500,\"scale\":0,\"step\":1}"
      },
      {
        "code": "cur_current",
        "type": "Integer",
        "values": "{\"unit\":\"mA\",\"min\":0,\"max\":30000,\"scale\":0,\"step\":1}"
      },
      {
        "code": "switch",
        "type": "Boolean",
        "values": "{}"
      },
      {
        "code": "cur_power",
        "type": "Integer",
        "values": "{\"unit\":\"W\",\"min\":0,\"max\":50000,\"scale\":0,\"step\":1}"
      },
      {
        "code": "countdown_1",
        "type": "Integer",
        "values": "{\"unit\":\"s\",\"min\":0,\"max\":86400,\"scale\":0,\"step\":1}"
      }
    ]
  },
  "success": true,
  "t": 1625105881348
}

得知该设备functions中存在dp code "switch",因此 复用DPCODE_SWITCH,重写方法turn_on 和 turn_off

def turn_on(self, **kwargs: Any) -> None:
    """Turn the switch on."""
    self._send_command([{"code": self.dp_code, "value": True}])

def turn_off(self, **kwargs: Any) -> None:
    """Turn the device off."""
    self._send_command([{"code": self.dp_code, "value": False}])

3.4 调试

通过打开日志配合进行调试

四、参考代码

https://github.com/tuya/tuya-home-assistant/blob/master/custom_components/tuya_v2/switch.py

Clone this wiki locally