66
77import logging
88import requests
9+ import urllib3
10+ from urllib3 .exceptions import InsecureRequestWarning
911
10- from .const import CAST_TYPE_CHROMECAST
12+ from .const import CAST_TYPE_CHROMECAST , CAST_TYPES
1113from .discovery import get_info_from_service , get_host_from_service_info
1214
1315XML_NS_UPNP_DEVICE = "{urn:schemas-upnp-org:device-1-0}"
1416
15- FORMAT_BASE_URL = "http://{}:8008"
17+ FORMAT_BASE_URL_HTTP = "http://{}:8008"
18+ FORMAT_BASE_URL_HTTPS = "https://{}:8443"
1619
1720_LOGGER = logging .getLogger (__name__ )
1821
1922
20- def _get_status (host , services , zconf , path ):
23+ def _get_status (host , services , zconf , path , secure = False ):
2124 """
2225 :param host: Hostname or ip to fetch status from
2326 :type host: str
@@ -35,7 +38,12 @@ def _get_status(host, services, zconf, path):
3538
3639 headers = {"content-type" : "application/json" }
3740
38- req = requests .get (FORMAT_BASE_URL .format (host ) + path , headers = headers , timeout = 10 )
41+ if secure :
42+ url = FORMAT_BASE_URL_HTTPS .format (host ) + path
43+ else :
44+ url = FORMAT_BASE_URL_HTTP .format (host ) + path
45+ urllib3 .disable_warnings (category = InsecureRequestWarning )
46+ req = requests .get (url , headers = headers , timeout = 10 , verify = False )
3947
4048 req .raise_for_status ()
4149
@@ -60,17 +68,20 @@ def get_device_status(host, services=None, zconf=None):
6068 """
6169
6270 try :
63- status = _get_status (host , services , zconf , "/setup/eureka_info?options=detail" )
71+ status = _get_status (
72+ host , services , zconf , "/setup/eureka_info?options=detail" , secure = True
73+ )
6474
6575 friendly_name = status .get ("name" , "Unknown Chromecast" )
66- # model_name and manufacturer is no longer included in the response,
67- # mark as unknown
6876 model_name = "Unknown model name"
6977 manufacturer = "Unknown manufacturer"
78+ if "detail" in status :
79+ model_name = status ["detail" ].get ("model_name" , model_name )
80+ manufacturer = status ["detail" ].get ("manufacturer" , manufacturer )
7081
7182 udn = status .get ("ssdp_udn" , None )
7283
73- cast_type = CAST_TYPE_CHROMECAST
84+ cast_type = CAST_TYPES . get ( model_name . lower (), CAST_TYPE_CHROMECAST )
7485
7586 uuid = None
7687 if udn :
@@ -82,6 +93,49 @@ def get_device_status(host, services=None, zconf=None):
8293 return None
8394
8495
96+ def get_multizone_status (host , services = None , zconf = None ):
97+ """
98+ :param host: Hostname or ip to fetch status from
99+ :type host: str
100+ :return: The multizone status as a named tuple.
101+ :rtype: pychromecast.dial.MultizoneStatus or None
102+ """
103+
104+ try :
105+ status = _get_status (
106+ host , services , zconf , "/setup/eureka_info?params=multizone" , secure = True
107+ )
108+
109+ dynamic_groups = []
110+ if "multizone" in status and "dynamic_groups" in status ["multizone" ]:
111+ for group in status ["multizone" ]["dynamic_groups" ]:
112+ name = group .get ("name" , "Unknown group name" )
113+ udn = group .get ("uuid" , None )
114+ uuid = None
115+ if udn :
116+ uuid = UUID (udn .replace ("-" , "" ))
117+ dynamic_groups .append (MultizoneInfo (name , uuid ))
118+
119+ groups = []
120+ if "multizone" in status and "groups" in status ["multizone" ]:
121+ for group in status ["multizone" ]["groups" ]:
122+ name = group .get ("name" , "Unknown group name" )
123+ udn = group .get ("uuid" , None )
124+ uuid = None
125+ if udn :
126+ uuid = UUID (udn .replace ("-" , "" ))
127+ groups .append (MultizoneInfo (name , uuid ))
128+
129+ return MultizoneStatus (dynamic_groups , groups )
130+
131+ except (requests .exceptions .RequestException , OSError , ValueError ):
132+ return None
133+
134+
135+ MultizoneInfo = namedtuple ("MultizoneInfo" , ["friendly_name" , "uuid" ])
136+
137+ MultizoneStatus = namedtuple ("MultizoneStatus" , ["dynamic_groups" , "groups" ])
138+
85139DeviceStatus = namedtuple (
86140 "DeviceStatus" , ["friendly_name" , "model_name" , "manufacturer" , "uuid" , "cast_type" ]
87141)
0 commit comments