本帖最后由 gujcong 于 2025-5-27 16:24 编辑
起因,卧室在以前装修的时候买了一个风扇灯,必须通过遥控器来开关风扇,无意间逛某宝发现,有支持接入米家的驱动可以通过蓝牙网关接入米家,二话不说,买回来就换上了,很顺利的就添加上了,在米家中控制很丝滑!
可是发现XiaomiGateway3中并不能识别这个设备,也无法控制,翻阅了XiaomiGateway3文档后发现,可以自己在配置文件目录中通过编写xiaomi_gateway3.py文件实现新设备的支持,于是开始折腾。
第一步,打开小米/米家产品库 - Xiaomi Miot Spec,通过设备型号查询到我们的设备(查看设备型号的方法,米家中进入设备,右上角三个点,选择产品百科,右上角分享,复制链接,出来的网址最后model=xxx就是我们的设备型号),这里面就能看见我们设备所有属性
第二步,在HA的config目录下新增xiaomi_gateway3.py文件,我们开始编写自定义converter,这里感谢大佬wdmywm3,这部分的内容参考了大佬《手把手教你gateway3新设备的external converter编写!》这篇文章,里面已经详细讲解各部分配置以及定义。
因为我主要是需要在ha中能控制灯和风扇,所以我只添加了Light和Fan的相关功能,原米家中还有些定时关闭的功能没有添加,毕竟这部分功能通过自动化能更好实现,编写好的代码如下:
from custom_components.xiaomi_gateway3.core.devices import *
DEVICES = [{
# pdid <厂商名称> <设备名称> <设备识别符>
15474: ["shhf", "智能调光风扇灯蓝牙版", "shhf.light.sflt11"],
"spec": [
BaseConv("light", "light", mi="2.p.1"),
BrightnessConv("brightness", mi="2.p.2", max=100),
ColorTempKelvin("color_temp", mi="2.p.3", mink=2700, maxk=6500),
MapConv("light_mode", "select", mi="2.p.4", map={0: "无", 1: "日光", 2: "月光", 3: "温馨", 4: "阅读", 5: "影院", 6: "电脑", 7: "会客", 8: "娱乐", 9: "儿童", 10: "办公", 11: "护眼"}),
BaseConv("fan", "switch", mi="11.p.1"),
BaseConv("wind_reverse", "switch", mi="11.p.12"),
MapConv("fan_level", "select", mi="11.p.2", map={1: "1", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 255: "auto"}),
]
}]+ DEVICES
第三步,重启HA后,进入GW3插件中发现已经可以正常显示出风扇和灯的实体了,并且也可以正常控制
但是控制起来还是有点麻烦,我们想要的方式是像其他接入的风扇一样,可以通过ui界面直接控制风扇的开关和风速、正反转的调整,如下图。查阅了GW3的文档后发现,GW3并不支持定义fan类型的实体,所以我们需要用到HA的template,来自己写一个fan类型的实体
第四步,查阅HA官方文档后,发现可以使用Template fan来自定义风扇实体,现在我们就需要在我们config目录下的configuration.yaml文件中,添加自定义风扇的配置,将GW3中的风扇开关、风扇正反转、风扇挡位实体整合成一个fan类型的风扇实体
fan:
- platform: template
fans:
bedroom_fan:
# 实体名称
friendly_name: Guest Bedroom Fan
# 实体唯一ID
unique_id: guest_bedroom_fan
# 风扇开关(on/off)定义
value_template: "{{ is_state('switch.84469391c0b8_fan', 'on') }}"
# 风扇正反转(forward/reverse)定义
direction_template: "{{ 'forward' if is_state('switch.84469391c0b8_wind_reverse', 'on') else 'reverse' }}"
# 风扇挡位设置
speed_count: 6
# 风扇挡位与HA百分比转换
percentage_template: >
{% if is_state('switch.84469391c0b8_fan', 'on') %}
{% if states('select.84469391c0b8_fan_level') == '1' %}
17
{% elif states('select.84469391c0b8_fan_level') == '2' %}
34
{% elif states('select.84469391c0b8_fan_level') == '3' %}
51
{% elif states('select.84469391c0b8_fan_level') == '4' %}
68
{% elif states('select.84469391c0b8_fan_level') == '5' %}
85
{% elif states('select.84469391c0b8_fan_level') == '6' %}
100
{% else %}
1
{% endif %}
{% else %}
0
{% endif %}
# 风扇打开调用实体服务
turn_on:
service: switch.turn_on
target:
entity_id: switch.84469391c0b8_fan
# 风扇关闭调用实体服务
turn_off:
service: switch.turn_off
target:
entity_id: switch.84469391c0b8_fan
# 风扇正反转(forward/reverse)调用实体服务
set_direction:
service: switch.turn_{{ 'on' if direction == 'forward' else 'off' }}
target:
entity_id: switch.84469391c0b8_wind_reverse
# 风扇挡位配置
set_percentage:
# 使用条件判断处理风速调整
- choose:
# 当百分比为0时关闭风扇
- conditions:
- condition: template
value_template: "{{ percentage == 0 }}"
sequence:
- service: switch.turn_off
target:
entity_id: switch.84469391c0b8_fan
# 当百分比非0时设置档位
- conditions:
- condition: template
value_template: "{{ percentage > 0 }}"
sequence:
# 设置对应档位
- service: select.select_option
target:
entity_id: select.84469391c0b8_fan_level
data:
option: >
{% if percentage == 1 %}
auto
{% elif percentage <= 17 %}
1
{% elif percentage <= 34 %}
2
{% elif percentage <= 51 %}
3
{% elif percentage <= 68 %}
4
{% elif percentage <= 85 %}
5
{% elif percentage <= 100 %}
6
{% endif %}
这里需要额外提一下set_percentage这块的配置,因为我们希望的操作,当风扇关闭时,通过UI界面滑动风速滑块,则自动打开风扇并且调整到对应挡位;当风速设置为0时,自动关闭风扇,但是set_percentage是中只能调用同一个实体的service,我们调整挡位,实际是调用GW3中select的实体,而关闭风扇则是调用switch实体,并且传参不同,所以这里我们需要使用到Template conditions来进行条件判断,在风扇不同的状态下调用不同的服务,具体可以看下我上面的配置!
最后,到这里已经完成了所有操作了!已经可以丝滑的在HA中操作原本不支持的风扇灯!使用我们自定义的风扇实体接入Homkit中也可以完美适配!
|