-
Notifications
You must be signed in to change notification settings - Fork 26
/
airplay.py
141 lines (106 loc) · 3.9 KB
/
airplay.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""
Support for AirPlay.
Developed by Charley
"""
import logging
try:
from zeroconf import ServiceBrowser, ServiceStateChange, Zeroconf
except ImportError:
pass
import warnings
import time
import socket
import asyncio
from datetime import timedelta
# from airplay.const import (
# DOMAIN
# )
from homeassistant.helpers.event import async_track_point_in_utc_time
from homeassistant.const import EVENT_HOMEASSISTANT_START
import homeassistant.util.dt as dt_util
from homeassistant.core import callback
from homeassistant.helpers.discovery import load_platform
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=10)
REQUIREMENTS = ['zeroconf==0.20.0']
DOMAIN = 'airplay'
MEDIA_PLAYER_DOMAIN = 'airplayer'
@asyncio.coroutine
def async_setup(hass, config):
"""Set up the AirPlay component."""
_LOGGER.debug('Begin setup AirPlay')
ap = airplay()
regDevices = []
@asyncio.coroutine
def scan_devices(now):
devices = yield from hass.loop.run_in_executor(
None, ap.discover_MediaPlayer)
for device in devices:
isFind = False
address = device.get("address")
port = device.get("port")
for regDevice in regDevices:
regAddress = regDevice.get("address")
regPort = regDevice.get("port")
if regAddress == address and regPort == port:
isFind = True
if isFind == False:
regDevices.append(device)
load_platform(hass, "media_player", MEDIA_PLAYER_DOMAIN, device)
_LOGGER.debug("find device:%@", device)
async_track_point_in_utc_time(hass, scan_devices,
dt_util.utcnow() + SCAN_INTERVAL)
@callback
def schedule_first(event):
"""Schedule the first discovery when Home Assistant starts up."""
async_track_point_in_utc_time(hass, scan_devices, dt_util.utcnow())
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, schedule_first)
return True
class airplay:
def __init__(self):
pass
def remove_service(self, zeroconf, type, name):
print("Service %s removed" % (name,))
def add_service(self, zeroconf, type, name):
info = zeroconf.get_service_info(type, name)
print("Service %s added, service info: %s" % (name, info))
def discover_MediaPlayer(self, timeout=10, fast=False):
"""
find airPlay devices
"""
# this will be our list of devices
devices = []
# zeroconf will call this method when a device is found
def on_service_state_change(zeroconf, service_type, name, state_change):
if state_change is ServiceStateChange.Added:
info = zeroconf.get_service_info(service_type, name)
if info is None:
return
try:
name, _ = name.split('.', 1)
except ValueError:
pass
address = socket.inet_ntoa(info.address)
devices.append(
{
"name":name,
"address":address,
"port":info.port
}
)
elif state_change is ServiceStateChange.Removed :
pass
# search for AirPlay devices
try:
zeroconf = Zeroconf()
browser = ServiceBrowser(zeroconf, "_airplay._tcp.local.", handlers=[on_service_state_change]) # NOQA
except NameError:
warnings.warn(
'AirPlay.find() requires the zeroconf package but it could not be imported. '
'Install it if you wish to use this method. https://pypi.python.org/pypi/zeroconf',
stacklevel=2
)
return None
time.sleep(5)
zeroconf.close()
return devices