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

 找回密码
 立即注册
查看: 16648|回复: 37

[经验分享] 踩个鸿雁插排IHC8340B使用官方Broadlink插件的坑

[复制链接]

23

主题

302

帖子

2165

积分

论坛技术达人

积分
2165
金钱
1838
HASS币
110

活跃会员教程狂人

发表于 2018-6-3 00:08:06 | 显示全部楼层 |阅读模式
本帖最后由 cnk700i 于 2019-5-28 10:21 编辑

PS:本贴只有原因分析,改版插件下载移步至https://bbs.hassbian.com/thread-5200-1-1.html
Update:2018.08.15 更正一下Throttle其实是不带有定期更新功能的,只是限制调用频率。。。总结两种情况下会造成复位:
1、执行一次开关操作5s内执行另外一次开关操作。
2、HA的周期更新(会调用update())后5s内,刚好执行开关操作,也会造成复位。
另外:
1、switch默认SCAN_INTERVAL是30s。
2、插件作者设置TIME_BETWEEN_UPDATES的目的是为了减少通信请求:因为每次周期更新,每个插孔都会执行4次与排通信。


Update:2018.07.06 重新研究了C.S大的代码,发现之前的理解有误,C.S大是每次开、关也是立刻取排插的状态的,应该不存在排插反馈状态慢的问题,之前分析有误。于是又再研读代码,确认是由于BroadlinkMP1Switchl类的update方法用了Throttle原因导致:这个东西的作用是只规定时间内执行一次update并且只能执行一次,所以导致HA在开/关无法获取最新的状态。

所以解决办法就是把@Throttle(TIME_BETWEEN_UPDATES)删掉即可,这也是之前修改的代码有效的原因。。。官方组件更新时间是TIME_BETWEEN_UPDATES=5s,实际上HA已经有周期性的更新功能,配置文件通过scan_interval设置更新时间即可。

Update:2018.06.15 参考yeelight灯的代码,摸索增加了可用状态的判断。


趁着618活动入了中草已久的鸿雁插排IHC8340B玩玩,4个独立分控,wifi插线板比wifi插座划算多了。看论坛以前的帖子,用官方的broadlink MP1插件即可。到手之后用broadlink的易控APP设置好网络,按官网的配置指引配置好后,发现控制是可以控制了,不过有点诡异,点开关图标经常回复先前的状态,控制倒是正常。比如开关是“关”状态,点开之后插线板接通了,但HA的开关状态立刻切回“关”状态,等一会后状态就切回为“开”了。于是又是一番研究代码折腾,算是找到初步解决方法了。

一、测试环境

  • IHC8340B插线板,固件版本v10028

  • HA,版本0.70.1,Ubuntu 18.04直接安装

configuration.yaml

switch:        
  - platform: broadlink
    scan_interval: 15   #自动更新的间隔,默认30s
    host: 设备ip地址
    mac: '设备mac地址'
    type: mp1
    slots:
      slot_1: 'slot1'    #HA会实例化一个switch.slot1设备,这里不要用中文,否则HA实例化的设备名称是switch.x(x是数字),有一定随机性
      slot_2: 'slot2'
      slot_3: 'slot3'
      slot_4: 'slot4'

二、原因分析

处理的流程如下(个人理解,不一定准确)

1.web页面点击开关按钮,触发turn_on或turn_off service

2.通信、控制

3.设置开关状态并调用schedule_update_ha_state通告状态变更

4.通信查询状态并更新开关状态

#ha安装目录/homeassistant/components/switch/__init__.py
    #SwitchDevice类async def async_setup(hass, config)函数 部分代码
async def async_handle_switch_service(service):
    """Handle calls to the switch services."""
    target_switches = component.async_extract_from_service(service)

    update_tasks = []
    for switch in target_switches:
        if service.service == SERVICE_TURN_ON:
            await switch.async_turn_on()   #步骤1
        elif service.service == SERVICE_TOGGLE:
            await switch.async_toggle()
        else:
            await switch.async_turn_off()

        if not switch.should_poll:
            continue
        update_tasks.append(switch.async_update_ha_state(True)) #步骤4,后续会调用broadlink.py中update方法

    if update_tasks:
        await asyncio.wait(update_tasks, loop=hass.loop)

#ha安装目录/homeassistant/components/switch/broadlink.py
    #BroadlinkRMSwitch类 部分代码
        def turn_on(self, **kwargs):
    """Turn the device on."""
    if self._sendpacket(self._command_on):        #步骤2
        self._state = True                                        #步骤3
        self.schedule_update_ha_state()         #步骤3

        def turn_off(self, **kwargs):                        #流程同turn_on
    """Turn the device off."""
    if self._sendpacket(self._command_off): 
        self._state = False                                        
        self.schedule_update_ha_state()                

结论:由于步骤3、步骤4执行时间基本一致,导致步骤4去向插线板获取状态时,插线板返回的状态有一定的滞后性,导致开关状态复原,要等待一个scan_interval更新周期状态才会重新同步。

三、解决方案

步骤4查询插线板开关状态需要调用broadlink.py中BroadlinkMP1Slot类的update方法,所以在turn_on或者turn_off记录下点击开关的时间,然后在update方法中判断时间如果不超过3s则不执行update。

副作用就是点击操作后,如果3s内碰上定期更新周期,定期更新就不会执行了,不过影响不大,总比状态跳来跳去好。








评分

参与人数 1金钱 +20 收起 理由
+ 20 大神研究很细致,为你点赞!

查看全部评分

回复

使用道具 举报

123

主题

4626

帖子

1万

积分

管理员

囧死

Rank: 9Rank: 9Rank: 9

积分
16015
金钱
11304
HASS币
45
发表于 2018-6-3 00:39:41 | 显示全部楼层
官方插件确实有问题的,楼主分析的真是细致,不过大家普遍都不怎么用官方版,论坛CS大写了一个自定义组件,很完美,就是经常得随HA升级而修改:

具体看这里,2楼是最新修复版(比官方完美,响应很及时):

HA升级到0.69+博联broadlink MP1(或鸿雁)自改版插件修复

https://bbs.hassbian.com/thread-3724-1-1.html

回复

使用道具 举报

175

主题

2956

帖子

7555

积分

超级版主

我就是六神

Rank: 8Rank: 8

积分
7555
金钱
4574
HASS币
398

活跃会员教程狂人灌水之王

QQ
发表于 2018-6-3 01:43:28 | 显示全部楼层
原来是这样 楼主分析的很清楚
回复

使用道具 举报

123

主题

4626

帖子

1万

积分

管理员

囧死

Rank: 9Rank: 9Rank: 9

积分
16015
金钱
11304
HASS币
45
发表于 2018-6-3 01:51:25 | 显示全部楼层
楼主可以参考我发的那个自定义插件,修复一下官方代码,并提交给官方,这样大家就方便啦!
回复

使用道具 举报

23

主题

302

帖子

2165

积分

论坛技术达人

积分
2165
金钱
1838
HASS币
110

活跃会员教程狂人

 楼主| 发表于 2018-6-3 10:28:03 | 显示全部楼层
本帖最后由 cnk700i 于 2018-7-6 16:25 编辑
Jones 发表于 2018-6-3 00:39
官方插件确实有问题的,楼主分析的真是细致,不过大家普遍都不怎么用官方版,论坛CS大写了一个自定义组件, ...

之前就是看囧大你帖子了解到官方的组件有问题,不过想着是去年的帖子,或许官方组件有修复了,就先试试官方的组件,结果又被发现问题总想解决的强迫症推进坑了。

博客 https://ljr.im
回复

使用道具 举报

12

主题

545

帖子

2035

积分

金牌会员

Rank: 6Rank: 6

积分
2035
金钱
1490
HASS币
0
发表于 2018-6-3 11:10:10 来自手机 | 显示全部楼层
来看楼主show技术,对了618 还有优惠券吗?神秘连接在哪?打算再入手两个
回复

使用道具 举报

40

主题

3057

帖子

1万

积分

超级版主

Nero

Rank: 8Rank: 8

积分
11135
金钱
8028
HASS币
182
发表于 2018-6-3 11:29:49 | 显示全部楼层
cnk700i 发表于 2018-6-3 10:28
之前就是看囧大你帖子了解到官方的组件有问题,不过想着是去年的帖子,或许官方组件有修复了,就先试试官 ...

如果CS大的代码不影响官方的MP1,最好向HA官方提交个PR,把这个bug修了以后就方便多了。
Nero
回复

使用道具 举报

23

主题

302

帖子

2165

积分

论坛技术达人

积分
2165
金钱
1838
HASS币
110

活跃会员教程狂人

 楼主| 发表于 2018-6-3 11:30:52 | 显示全部楼层
潇洒哥er 发表于 2018-6-3 11:10
来看楼主show技术,对了618 还有优惠券吗?神秘连接在哪?打算再入手两个

1号的时候有199-100优惠券,优惠券随便领,不过很快就各种没货,我是普通的、电量的、USB的各入了一个。最低有做到普通的不到30一个,那才是神价啊。吐槽下里面的检验标志是2016年的,真是库存货。
博客 https://ljr.im
回复

使用道具 举报

23

主题

302

帖子

2165

积分

论坛技术达人

积分
2165
金钱
1838
HASS币
110

活跃会员教程狂人

 楼主| 发表于 2018-6-3 12:22:12 | 显示全部楼层
neroxps 发表于 2018-6-3 11:29
如果CS大的代码不影响官方的MP1,最好向HA官方提交个PR,把这个bug修了以后就方便多了。 ...

官方的broadlink.py组件里面是包含多个型号的,类和类的继承和CS大的代码差异比较大,合到一起有点困难。我现在是先把我的改动提了PR,也把问题反馈过去了(PS:希望别人能看懂我的花式英文)。
博客 https://ljr.im
回复

使用道具 举报

12

主题

545

帖子

2035

积分

金牌会员

Rank: 6Rank: 6

积分
2035
金钱
1490
HASS币
0
发表于 2018-6-3 12:43:08 来自手机 | 显示全部楼层
cnk700i 发表于 2018-6-3 11:30
1号的时候有199-100优惠券,优惠券随便领,不过很快就各种没货,我是普通的、电量的、USB的各入了一个。 ...

可惜错过了
回复

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-4-29 10:19 , Processed in 0.145339 second(s), 34 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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