- python模块目录:/srv/homeassistant/homeassistant_venv/lib/python3.6/site-packages/,后面用{python模块目录}代替。
解决过程记录
Step1
首先查看看HA日志,发现有错误信息:
ERROR (SyncWorker_8) [xiaomi_gateway] Unsupported device found! Please create an issue at https://github.com/Danielhiversen/PyXiaomiGateway/issues and provide the following data: {'cmd': 'read_rsp', 'model': 'sensor_86sw1',……
明显是说不支持sensor_86sw1的类型,还注意信息中的[xiaomi_gateway]说明是xiaomi_gateway模块。找到{python模块目录}/xiaomi_gateway/init.py,可以看到支持的设备类型是在device_types = {}中定义的,我们把sensor_86sw1、sensor_86sw2(双键开关)加进去。
……省略……
class XiaomiGateway(object):
……省略……
def _discover_devices(self):
……省略……
device_types = {
'sensor': ['sensor_ht', 'gateway', 'gateway.v3', 'weather',
'weather.v1', 'sensor_motion.aq2', 'acpartner.v3'],
'binary_sensor': ['magnet', 'sensor_magnet', 'sensor_magnet.aq2',
'motion', 'sensor_motion', 'sensor_motion.aq2',
'switch', 'sensor_switch', 'sensor_switch.aq2', 'sensor_switch.aq3',
'86sw1', 'sensor_86sw1.aq1', 'sensor_86sw1',
'86sw2', 'sensor_86sw2.aq1', 'sensor_86sw2',
'cube', 'sensor_cube', 'sensor_cube.aqgl01',
'smoke', 'sensor_smoke',
'natgas', 'sensor_natgas',
'sensor_wleak.aq1'],
'switch': ['plug',
'ctrl_neutral1', 'ctrl_neutral1.aq1',
'ctrl_neutral2', 'ctrl_neutral2.aq1',
'ctrl_ln1', 'ctrl_ln1.aq1',
'ctrl_ln2', 'ctrl_ln2.aq1',
'86plug', 'ctrl_86plug', 'ctrl_86plug.aq1'],
'light': ['gateway', 'gateway.v3'],
'cover': ['curtain'],
'lock': ['lock.aq1']}
……省略……
Step2
xiaomi_gateway模块只是完成把设备信息和网关关联起来,正式的创建设备是在{python模块目录}/homeassistant/components/binary_sensor/xiaomi_aqara.py中实现的。所以打开看里面代码可以看到无线开关是在elif model in ['86sw1', 'sensor_86sw1.aq1']、elif model in ['86sw2', 'sensor_86sw2.aq1']里面的,确是没有“sensor_86sw1”,那继续添加。
Tips:单键开关是实例化一个XiaomiButton的,双开关是实例化成三个XiaomiButton的(一个同时按双键触发)。
……省略……
def setup_platform(hass, config, add_devices, discovery_info=None):
……省略……
if model in ['motion', 'sensor_motion', 'sensor_motion.aq2']:
……省略……
elif model in ['86sw1', 'sensor_86sw1.aq1', 'sensor_86sw1']:
devices.append(XiaomiButton(device, 'Wall Switch', 'channel_0',
hass, gateway))
elif model in ['86sw2', 'sensor_86sw2.aq1', 'sensor_86sw1']:
devices.append(XiaomiButton(device, 'Wall Switch (Left)',
'channel_0', hass, gateway))
devices.append(XiaomiButton(device, 'Wall Switch (Right)',
'channel_1', hass, gateway))
devices.append(XiaomiButton(device, 'Wall Switch (Both)',
'dual_channel', hass, gateway))
……省略……
Step3
重启,HA可以成功识别出无线开关了。不过有个问题,点击按钮好像什么反应都没有,看回调方法中所执行的parse_data(),正常是会有click事件生成的。
……省略……
class XiaomiButton(XiaomiBinarySensor):
……省略……
def parse_data(self, data, raw_data):
……省略……
self._hass.bus.fire('click', {
'entity_id': self.entity_id,
'click_type': click_type
})
……省略……
Step4
看了下aqara的文档发现,无线开关的click_type是button_0、button_1,而不是channel_0、channel_1。那要把Step2的修改的代码恢复,新增sensor_86sw1、sensor_86sw2设备类型的处理代码。重启测试,日志有EVENT消息,可以正常使用了。
……省略……
elif model in ['86sw1', 'sensor_86sw1.aq1']:
devices.append(XiaomiButton(device, 'Wall Switch', 'channel_0',
hass, gateway))
elif model in ['sensor_86sw1']: #增加sensor_86sw1
devices.append(XiaomiButton(device, 'Wall Switch', 'button_0',
hass, gateway))
elif model in ['86sw2', 'sensor_86sw2.aq1']:
devices.append(XiaomiButton(device, 'Wall Switch (Left)',
'channel_0', hass, gateway))
devices.append(XiaomiButton(device, 'Wall Switch (Right)',
'channel_1', hass, gateway))
devices.append(XiaomiButton(device, 'Wall Switch (Both)',
'dual_channel', hass, gateway))
elif model in ['sensor_86sw2']: #增加sensor_86sw2
devices.append(XiaomiButton(device, 'Wall Switch (Left)',
'button_0', hass, gateway))
devices.append(XiaomiButton(device, 'Wall Switch (Right)',
'button_1', hass, gateway))
devices.append(XiaomiButton(device, 'Wall Switch (Both)',
'dual_channel', hass, gateway))
……省略……
小结
最后简单介绍下我所理解的网关工作流程吧,相关的工作是由{python模块目录}/homeassistant/components/xiaomi_aqara.py来完成的。