『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 1295|回复: 14

[基础教程] 手把手教你gateway3新设备的external converter编写!

[复制链接]

21

主题

525

帖子

3241

积分

论坛元老

Rank: 8Rank: 8

积分
3241
金钱
2716
HASS币
30
发表于 2024-9-4 16:38:44 | 显示全部楼层 |阅读模式
本帖最后由 wdmywm3 于 2024-9-4 17:00 编辑

前情提要。最近买了znsn家的oled半屏六键开关,当做家门口的无线开关来用。不为啥,就图它颜值,能够自定义文字,这样我万一要调整了还方便,不像那些激光打标的开关,如果要换文字,就得直接重做了。
而且比起用电池的无线开关,把有线开关当无线用,还能有背光来呈现状态反馈,比较直观。
结果一接入HA,顿时头都大了,miot auto能识别到6个开关,但是miot auto延迟大,而且哪怕是轮询,最小间隔也只能设置到1秒,延迟实在是有点太大了。

那么gateway3呢?

这玩意儿压根不识别!
众所周知,gateway3啥都好,就是更新慢,不过这也是没办法的事。
去搜了下,开关今年3月底才出,github上也没找到大佬写好的externel converter,那只能自己想办法弄了。
结果找了一大圈,发现具体的converter怎么写,github页面上很散碎,尽管还有很多教程,但一到具体部分,往往就是一句“参考类似的开关”就过去了。
可我不知道哪种才算类似啊!
没办法,只能打开gateway3的页面,翻它已经整合好的converter,再来来回回测试,费时一个晚上,终于给我搞定了。
由于内容很长,只能分成好几楼,不然发不出去。多图大流量警告,论坛带宽比较小,图片转圈要耐心等等
【PART A】
首先,我的开关是这个:znsn半屏Mesh六键开关
QQ20240904-144721.png
而我写好以后的converter如下,我们一行行来说
from custom_components.xiaomi_gateway3.core.devices import *

DEVICES = [{
    16854: ["ZNSN", "Mesh Six-Key Oled Wall Switch", "znsn.switch.oled6"],
    "spec": [
        BaseConv("channel_1", "switch", mi="2.p.1"),
        BaseConv("channel_2", "switch", mi="3.p.1"),
        BaseConv("channel_3", "switch", mi="4.p.1"),
        BaseConv("channel_4", "switch", mi="5.p.1"),
        BaseConv("channel_5", "switch", mi="13.p.1"),
        BaseConv("channel_6", "switch", mi="14.p.1"),

        MapConv("mode_1", "select", mi="2.p.6", map={0: "Normal", 1: "Linkage", 2: "Atom"}),  # config
        MapConv("mode_2", "select", mi="3.p.4", map={0: "Normal", 1: "Linkage", 2: "Atom"}),  # config
        MapConv("mode_3", "select", mi="4.p.4", map={0: "Normal", 1: "Linkage", 2: "Atom"}),  # config
        MapConv("mode_4", "select", mi="5.p.4", map={0: "Normal", 1: "Linkage", 2: "Atom"}),  # config
        MapConv("mode_5", "select", mi="13.p.2", map={0: "Scene", 1: "Wireless"}),  # config
        MapConv("mode_6", "select", mi="14.p.2", map={0: "Scene", 1: "Wireless"}),  # config

        MapConv("power_on_state_1", "select", mi="2.p.5", map={0: "Default", 1: "Off", 2: "On"}),  # config
        MapConv("power_on_state_2", "select", mi="3.p.3", map={0: "Default", 1: "Off", 2: "On"}),  # config
        MapConv("power_on_state_3", "select", mi="4.p.3", map={0: "Default", 1: "Off", 2: "On"}),  # config
        MapConv("power_on_state_4", "select", mi="5.p.3", map={0: "Default", 1: "Off", 2: "On"}),  # config

        BaseConv("action", "sensor"),
        MapConv("action", mi="6.e.1.p.2", map={1: BUTTON_1_SINGLE, 2: BUTTON_2_SINGLE, 3: BUTTON_3_SINGLE, 4: BUTTON_4_SINGLE, 5: "button_5_single", 6: "button_6_single"}),
    ],
}] + DEVICES

首先,米家蓝牙mesh设备,都会有个固定编号,就是上来的16854,每个产品都不同。
自己的产品用哪个编号,在spec页面,点击右侧的【规格】,再选择【使用说明】。
QQ20240904-145027.png
打开新页面后,查看这个页面的链接,就能从中找到产品编号,比如我这里就是16854。
QQ20240904-145129.png
后面的ZNSN就是品牌名,第二个是开关名称,第三个是型号,我这里就是znsn.switch.oled6。
接着spec部分,就是converter转换器的正体,也是最麻烦的部分。
转换器有很多类型,不过最常用的大概就几种,分别对应你设备的不同功能。
由于很多转换器其实是混用的,所以不能一概而论,我这里也只能以我的这个开关,讲一下最基础的几个用法。
同时写转换器的时候,也必须要打开开关的具体spec参数表:spec参数表
===============================================================================
BaseConv("channel_1", "switch", mi="2.p.1"),
BaseConv代表的是基础转换器,“channe_1”代表的是第一个开关,这个名称其实是随便的,你叫什么都可以。
"switch"代表的是它的类型,这里就是设置为开关switch,在ha里就会显示为一个开关,后面还会用到设置为传感器sensor的情况。
我这个开关有六个键,因此一共有6个switch类型的BaseConv。
mi="2.p.1"是最关键的部分,它告诉插件,究竟该去读取设备的哪个数值,我们来看图。
QQ20240904-150649.png
一个米家设备的每一个功能,都会有一个独立的siid,而我这个开关,第一个按键,它的siid就是2,因此开头就是2。
第二个按键,它的siid是3,因此开头就是3。
它的第五第六个按键,不知为何siid设置的是13和14,因此我这里必须设置成13和14,如果设置成6和7,就会造成错误。
其次是p,它的含义是“properties”属性,代表了让插件去读取siid为2的功能下的某项属性,比如说“开/关”状态,就是至于具体是哪项属性,就就是p.后面那个数字指定的。
每一项功能下,还有一个piid,每一个piid对应的就是一个属性。
QQ20240904-151612.png
譬如我这里,代表“开/关”状态的属性的piid是1,因此mi="2.p.1"的实际含义就是,读取siid为2的功能下,piid为1的这项属性的值
其他的5个开关也是同样的做法,到了这里保存好converter,重启HA,其实已经可以看到开关的6个实体出现在HA里,最基础的转换器就算是完成了。


评分

参与人数 14金钱 +133 收起 理由
凋零001 + 8 论坛有你更精彩!
louwu + 5 感谢楼主分享!
Jerrylee + 12
tangyali + 3
dscao + 20 感谢楼主分享!
grunner + 8
kei81131 + 8 论坛有你更精彩!
tianzhuang55 + 10 论坛有你更精彩!
隔壁的王叔叔 + 12 讲的好细啊,我学会了,谢谢
relliky + 12 大神666!建议加入精华!
louis_lee + 10 感谢楼主分享!
summ99111 + 8 感谢楼主分享!
mrtang + 5 厉害了word楼主!
mars.z + 12 非常牛,很详细,感谢分享

查看全部评分

回复

使用道具 举报

21

主题

525

帖子

3241

积分

论坛元老

Rank: 8Rank: 8

积分
3241
金钱
2716
HASS币
30
 楼主| 发表于 2024-9-4 16:42:12 | 显示全部楼层
【PART B】
接下来是MapConv("mode_1", "select", mi="2.p.6", map={0: "Normal", 1: "Linkage", 2: "Atom"}), 的部分
MapConv转换器的作用,当某个属性存在多个可能值的时候,用来标记对应值的具体含义。
我的六键开关,可以设置不同的开关模式,比如说常规模式,灵动模式,无线模式等等,对应的就是上图中piid为2和piid为6的两项属性。
其实正常情况下,直接用一个属性就行了,不知道znsn的程序员抽什么疯,非要把它分成两个属性,我暂时没有找到把它们拼起来的办法,不过问题也不大,一般这种模式设置一次,很少再去动,这个教程只要说明具体怎么用就行了。
另外一个很癫的是,其他几个按键的属性都是1234,就第一个按键不知道为啥是1256,znsn你的程序员吔屎了吗!
“mode_1”“channel_1”一样,属于自定义名称,随便设置。
“select”表示它在HA中显示为一个下拉框,让你可以进行选择。
QQ20240904-153033.png
mi="2.p.6"就如上面所说,它读取的是siid为2的功能下,piid为6的属性的值
map={0: "Normal", 1: "Linkage", 2: "Atom"}部分最重要。
由于设备实际上传递的不是灵动模式,常规模式,这些具体名称,而是一个个对应的数字,因此就要用一个map,相当于你查地图一样,来告诉ha,每一个数字具体代表什么含义。
比如我这个设备,在spec中规定的是
0 - Normal(常规)
1 - Linkage(联动)
2 - Atom(灵动)
所以就要在map的这个花括号里标注好,0是Normal,1是Linkage,2是Atom
MapConv("power_on_state_1", "select", mi="2.p.5", map={0: "Default", 1: "Off", 2: "On"}),  这几行的作用,是这是上电后的开关按键默认状态,和模式设置没有区别,就不细讲了。
到这里,保存好converter,重启一下ha,就能看到每个按键的模式选项,出现在了ha里
【题外话】如果这里把“select”改成“sensor”,其他不变,就会变成只显示你具体的按键模式,但无法在HA中直接更改
sensor常用于一些不需要更改的属性值。

回复

使用道具 举报

21

主题

525

帖子

3241

积分

论坛元老

Rank: 8Rank: 8

积分
3241
金钱
2716
HASS币
30
 楼主| 发表于 2024-9-4 16:45:10 | 显示全部楼层
本帖最后由 wdmywm3 于 2024-9-4 16:59 编辑

【PART C】
最后,最麻烦的部分来了。
当一个开关按键,被转换为无线开关后,它尽管依旧具有on和off的开关状态,但实际上我们很多时候真正需要的,是它的单击、双击、长按等“事件”。
当然了,具体支持哪些事件,还要看厂商的设计,我这个开关转无线之后,就只支持单击事件,并没有另外两种事件,不过这里拿来作为参考足够了。
而实际上,在设备的spec信息中,这些“事件”属于一个单独的功能。
QQ20240904-154602.png
比如我的开关,它的这些事件,就单独有一个siid为6的“switch sensor”功能,在这个功能下,它的具体属性piid为2。
(为什么这里是莫名其妙从2开始,ZNSN程序员你到底在发什么癫??
BaseConv("action", "sensor"),
MapConv("action", mi="6.e.1.p.2", map={1: BUTTON_1_SINGLE, 2: BUTTON_2_SINGLE, 3: BUTTON_3_SINGLE, 4: BUTTON_4_SINGLE, 5: "button_5_single", 6: "button_6_single"}),
其中BaseConv("action", "sensor"),部分,和最初的开关一样,它定义了一个基础转换器,自定义名称为“action”,类型为“sensor”
MapConv转换器,名称依旧是“action”,代表的是依旧给上面的转换器赋值,而不是另开一个新的转换器。
好了,最迷惑的部分来了。
相信很多人第一次看到转换器文件的时候都会疑惑——
6.p.2好理解,6.e.1.p.2是个什么鬼???
e是哪来的??
为什么e我写多少都不对??
我找到的几乎所有教程,都没有提这玩意儿到底是啥,以及应该怎么判断,并且设备的spec参数列表里,也完全没有这东西!
一直到我昨晚随手点进了这里……
QQ20240904-155535.png
这玩意儿居然是个超链接,你丫藏得够深的啊!
点进去以后乍一看眼睛都要花了,不过不要紧,勾一下左上角的【美观输出】,它就能变成可阅读的格式了
QQ20240904-155649.png
然后通过关键词,一路往下找,找到了这里
QQ20240904-155840.png
上面的红框里,就是我们6.p.2的属性
而下面的红框里,还显示了一个真正的events事件!
p代表的是properties属性,e代表的是events事件。
在这里,这个事件叫做“click”,也就是单击事件,而对应的编号则是1。
(有些设备的events事件直接设置了四位数,所以才会看到e.1012之类的奇怪数字,厂商拍脑子定的,没办法)
因此6.e.1.p.2的真正含义是:
siid为6,eiid为1,piid为2
翻译过来就是,当eiid=1,也即单击事件发生时,看piid=2的属性是多少,来判断究竟是哪个开关进行了单击
后面的map={1: BUTTON_1_SINGLE, 2: BUTTON_2_SINGLE, 3: BUTTON_3_SINGLE, 4: BUTTON_4_SINGLE, 5: "button_5_single", 6: "button_6_single"}部分,
就是根据6.e.1.p.2所获得的数值,来判断究竟是哪种事件
值得一提的是,gateway3自己原生支持的单击事件只有四个,因此前面的1: BUTTON_1_SINGLE不用加引号,而后面的5: "button_5_single", 6: "button_6_single"需要加引号,不然会报错(好像是这样)
到这里,保存converter,重启ha,一个显示具体事件的传感器也出现在ha里了!

回复

使用道具 举报

21

主题

525

帖子

3241

积分

论坛元老

Rank: 8Rank: 8

积分
3241
金钱
2716
HASS币
30
 楼主| 发表于 2024-9-4 16:50:24 | 显示全部楼层
本帖最后由 wdmywm3 于 2024-9-4 16:56 编辑

【PART D】
结语
我随便找了个gateway3已经正式支持的开关
QQ20240904-162019.png
QQ20240904-161135.png
QQ20240904-161629.png
这里就可以看到,它的event事件是四位数的,1012代表单击,1013代表双击,1014代表长按
而其他的一些传感器属性,也可以参考上面的办法来写转换器
QQ20240904-164821.png
比如说最常见的电量,在这里就是siid=2,piid=1003
综合起来就是:
BaseConv("battery", "sensor", mi="2.p.1003"),
而有些传感器的数字需要换算的,则使用MathConv这个转换器
比如说我随便找的一条
MathConv("distance", "sensor", mi="2.p.6", multiply=0.01),
这是子擎人体存在传感器下的一个距离参数
设备实际传给你的数字单位是厘米,你如果想要显示为米,那就加上一个系数,也就是multiply=0.01
除了这些转换器外,gateway3还有很多其他转换器,比如说亮度转换器BrightnessConv,色温转换器ColorTempKelvin
如下,这是两个可以调色温的智能灯
QQ20240904-164952.png
另外,转换器的类型,除了“switch”“sensor”之外,也有很多,比如说“binary_sensor”,“number”等
就好比“number”在HA中显示为一个可以拖动的条条,用来设置一些数值
不过这些都很复杂了,需要根据具体设备来调整,但知道了具体的参数怎么看,converter看起来就简单很多了,大部分功能也可以实现了。

回复

使用道具 举报

0

主题

43

帖子

308

积分

中级会员

Rank: 3Rank: 3

积分
308
金钱
265
HASS币
0
发表于 2024-9-4 17:19:08 | 显示全部楼层
有点厉害了。
回复

使用道具 举报

3

主题

99

帖子

1230

积分

金牌会员

Rank: 6Rank: 6

积分
1230
金钱
1131
HASS币
0
发表于 2024-9-4 18:00:13 来自手机 | 显示全部楼层
太棒了
回复

使用道具 举报

3

主题

80

帖子

777

积分

高级会员

Rank: 4

积分
777
金钱
697
HASS币
0
发表于 2024-9-4 18:14:44 | 显示全部楼层
楼主讲的详细
回复

使用道具 举报

0

主题

18

帖子

336

积分

中级会员

Rank: 3Rank: 3

积分
336
金钱
318
HASS币
0
发表于 2024-9-4 19:11:20 | 显示全部楼层
好,小白友好贴
回复

使用道具 举报

18

主题

591

帖子

4344

积分

元老级技术达人

积分
4344
金钱
3718
HASS币
182
发表于 2024-9-4 21:16:48 | 显示全部楼层
感谢经验分享,xiaomigateway3 git项目上这部分介绍基本上没咋介绍。正好前几天我也折腾来着,对于其他大部分类型来说直接+converter就行,climate类型需要额外再修改代码,否则无法识别。

回复

使用道具 举报

3

主题

99

帖子

1230

积分

金牌会员

Rank: 6Rank: 6

积分
1230
金钱
1131
HASS币
0
发表于 2024-9-5 09:38:24 | 显示全部楼层
感谢!之前糊里糊涂的改了几个converter,不知其所以然,楼主这篇透彻!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-12-28 01:29 , Processed in 0.084018 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表