Skip to content

Instantly share code, notes, and snippets.

@willwhui
Last active November 27, 2017 04:06
Show Gist options
  • Save willwhui/22e6ecc5aee88344d3a954962ef7c938 to your computer and use it in GitHub Desktop.
Save willwhui/22e6ecc5aee88344d3a954962ef7c938 to your computer and use it in GitHub Desktop.
在Hass上利用Chromecast state Event开关电视
@willwhui
Copy link
Author

willwhui commented Nov 23, 2017

电视机的状态:检查设备是否存在(通电联网为存在)

@willwhui
Copy link
Author

willwhui commented Nov 23, 2017

Device Tracker貌似是可用的方案(然而没有成功)

因为可以指定检测的时间间隔,所以可以做出比较及时的状态检测
首先要装个东西:

opkg update
opkg install luci-mod-rpc
/etc/init.d/uhttpd restart

然后在配置文件中写入:

- platform: luci
  host: 192.168.1.1   <---------------------必须是路由器的ip
  username: !secret openwrt_router_user_name
  password: !secret openwrt_router_password
  interval_seconds: 1
  consider_home: 1
  track_new_devices: yes

但是检测不出来:

 [homeassistant.components.device_tracker] Error setting up platform luci

搜索了一下,发现 https://community.home-assistant.io/t/openwrt-luci-device-tracker-need-more-specific-info-on-error/8717/4
里面遇到同样的问题,此帖楼主最后改用MQTT/Owntracks 和 Nmap搞定了。

@willwhui
Copy link
Author

willwhui commented Nov 23, 2017

nmap看起来蛮简单的( 但并没有成功)

https://home-assistant.io/components/device_tracker.nmap_tracker/

先安装必备组件:

$ sudo apt-get update
$ sudo apt-get install net-tools nmap

接着监控电视机:

- platform: nmap_tracker
  hosts: 192.168.1.206 # sky worth TV ip address
  home_interval: 60

成功了,出现了known_devices.yaml这个文件,里面有电视机的信息
在网页前端的state页面里面也可以看到它的id(后面需要用到)

但是总是显示在线(home),哪怕已经断电了

调整:

- platform: nmap_tracker
  hosts: 192.168.1.206 # sky worth TV ip address
  home_interval: 30
  consider_home: 30

上面这样的话,总是在线。
下面这样的话,只是在线1秒钟,然后就显示离线,哪怕实际上还在通电中

- platform: nmap_tracker
  hosts: 192.168.1.206 # sky worth TV ip address
  home_interval: 30
  consider_home: 1

@willwhui
Copy link
Author

willwhui commented Nov 24, 2017

使用ping(效果不太好,不及时)

https://home-assistant.io/components/device_tracker.ping/

device_tracker:
  - platform: ping
    hosts:
      hostone: 192.168.1.206

依然不能随着通电情况更新状态。

大概5~6分钟更新一次状态,看来是默认的“consider_home: 180”起了作用。

改成下面这样试试看

- platform: ping
  consider_home: 5 # 5秒后假设掉线
  hosts:
    skyworth_tv: 192.168.1.206

这样的话就是每5秒被判为掉线,然后很快启动扫描再次被判为在线。

再改成下面这样试试看

- platform: ping
  interval_seconds: 1 # 每隔1秒刷新一下
  consider_home: 5 # 5秒后假设掉线
  hosts:
    skyworth_tv: 192.168.1.206

貌似并没有多大改变,也许是探测时间太长?

再改成下面这样试试看

- platform: ping
  interval_seconds: 1 # 每隔1秒刷新一下
  consider_home: 5 # 5秒后假设掉线
  count: 1 # 只发一个包
  hosts:
    skyworth_tv: 192.168.1.206

貌似有所改善,但并不及时。

尝试 Ping (ICMP) Binary sensor(效果依然不好,基本上和ping是一个效果)

https://home-assistant.io/components/binary_sensor.ping/

@willwhui
Copy link
Author

willwhui commented Nov 24, 2017

再试试command line binary sensor (最终这个是好的)

https://home-assistant.io/components/binary_sensor.command_line/#check-rasplex
按照上述官方文档配置,十分简单:

- platform: command_line
  name: "skyworth tv"
  command: ping -W 1 -c 1 192.168.1.206 > /dev/null 2>&1 && echo success || echo fail
  device_class: connectivity
  payload_on: "success"
  payload_off: "fail"
  scan_interval: 5 # 检测间隔

成功了:在前端可以看到多了一个sensor “skyworth tv”
并且效果很好,愿意的话,可以调整检测时间精确到1秒钟

而且看来可以利用这个command line模式做别的检测,good

@willwhui
Copy link
Author

连接智能红外遥控器(broadlink RM2)

官方文档中应该采用这个:Broadlink RM Switch
另一个“Broadlink RM2 and A1 sensor”仅用做传感器数据获取

官方文档理解起来有点困难。实际情况如下(其实都是按照文档来的):

首先,添加配置代码:

- platform: broadlink
  host: 192.168.31.196
  mac: !secret broadlink_rm2_switch_mac
  friendly_name: "broadlink rm2"

可选的参数都不用填。

然后,后台会出现这样的信息:

... [homeassistant.loader] Loaded switch.broadlink from homeassistant.components.switch.broadlink
... [homeassistant.components.switch] Setting up switch.broadlink
... [homeassistant.core] Bus:Handling <Event service_registered[L]: service=learn_command_192_168_31_196, domain=broadlink>
... [homeassistant.core] Bus:Handling <Event service_registered[L]: service=send_packet_192_168_31_196, domain=broadlink>
(上面的...是省略的重复的日期信息)

但是前端页面并不出现任何新的swith图标。
不过,此时已经可以在开发者工具的“服务”页面看到一个叫做"broadlink"的服务了,它的可用服务是

learn_command_192_168_31_196 (显然后面这些数字是broadlink的ip)
send_packet_192_168_31_196

这两个服务就是官方文档提到的需要用到的两个服务。

获取遥控器的控制代码

官方文档:

Choose Call Service from the Developer Tools. Choose the service broadlink/learn_command from the list of Available services: and hit CALL SERVICE. Press the button on your remote with in 20 seconds. The packet will be printed as a persistent notification in the States page of the web interface.

就如字面意思:
1、在service页面找到domain "broadlink",调用service "learn_command_192_168_31_196"
2、在20秒内按下电视遥控器的按键(我是按了power,因为我要开关机)
3、在state页面,搜索“packet”,可以看到梦寐以求的长串红外指令编码

然后按照文档增加配置内容成如下:

- platform: broadlink
  host: 192.168.31.196
  mac: !secret broadlink_rm2_switch_mac
  friendly_name: "broadlink rm2"
  switches:
    tv_skyworth:
      friendly_name: "Skyworth TV Power"
      command_on: !secret broadlink_rm2_switch_skywort_tv_on_packet # 为了保持整洁,我把红外线指令放到secret文件里面去了
      command_off: !secret broadlink_rm2_switch_skywort_tv_on_packet

重启hass

可以看到开关"Skyworth TV Power"出现在前端页面上了。

@willwhui
Copy link
Author

willwhui commented Nov 27, 2017

准备工作已做好,整理一下思路

trigger:
检查chromecast的状态,它是个mediaplayer
condition:
检查电视机的ip状态,它是个sensor
action:
向智能红外遥控器发送打开电视的指令,它是个switch

在配置文件中添加automation如下:

- alias: 'TV power on when Chromecast playing'
  trigger:
    - platform: state
      entity_id: media_player.living_room_tv
      from: 'off'
      to: 'idle' # start to play video. The next state change will be "idle to playing"
    - platform: state
      entity_id: media_player.living_room_tv
      from: 'off'
      to: 'playing' # maybe sometime state will directly be changed from "off" to "playing" ? i don't know
  condition:
    condition: state
    entity_id: binary_sensor.skyworth_tv
    state: 'off' # tv ip address not detected
  action:
    - service: media_player.media_pause # waiting for tv power on
      entity_id: media_player.living_room_tv
    - service: switch.turn_on
      entity_id: switch.skyworth_tv_power
    - delay: '00:00:30' # left some seconds for tv power on
    - service: media_player.media_play # continue playing
      entity_id: media_player.living_room_tv

这样就好了。
重启hass。
对google home说 “play movie on tv”,就可以自动启动电视了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment