def detect_devices(): # Uses ssdp to return a list of Sky boxes on the network. Uses the netdisco package to do the discovery. ssdp_entries = scan() # initialise dictionary for founfd Sky devices found_entries = {} address_regex = re.compile(r'https*://([\w\.]*):([0-9]+)/.*', re.X) type_regex = re.compile(r'.*:(\w*Sky\w*):.*', re.X) for entry in ssdp_entries: # is it a sky device st = entry.st if "schemas-nds-com" in st and "Sky" in st: m = address_regex.match(entry.location) addr = m.group(1) m = type_regex.match(st) type = m.group(1) this_remote = found_entries.get(addr, SkyRemote(addr)) this_remote.addSDPEntry(type, entry) found_entries[addr] = this_remote return found_entries.values()
def discover(timeout=5): """ Convenience method to discover UPnP devices on the network. Returns a list of `upnp.Device` instances. Any invalid servers are silently ignored. """ devices = {} for entry in scan(timeout): if entry.location in devices: continue try: devices[entry.location] = Device(entry.location) except Exception as exc: log = _getLogger("ssdp") log.error('Error \'%s\' for %s', exc, entry.location) return list(devices.values())
def discoverSSDP(self, timeout=5): upnp_ports = [None] * len(self._urns) upnp_paths = [None] * len(self._urns) for entry in scan(timeout): if entry.location.startswith('http://{}'.format( self._config['host'])): for i in range(len(self._urns)): if entry.st == self._urns[i]: upnp_ports[i] = int( entry.location.split(':')[2].split('/')[0]) upnp_paths[i] = self.getPathFromUrlSsdp( entry.location, i) if None not in upnp_paths: for i in range(len(self._urns)): _LOGGER.info( '{} uPNP service detected in http://{}{}'.format( self._urns[i].split(':')[3], entry.location.split('/')[2], upnp_paths[i])) return tuple(upnp_ports), tuple(upnp_paths) return None, None
def discover_upnp(username=None): from netdisco.ssdp import scan PHILIPS = 'Royal Philips Electronics' BRIDGE_MODELS = ['929000226503', 'BSB002'] hue_bridges = [] res = scan() for h in res: _LOGGER.info('Check {}'.format(h)) device_info = h.description.get('device', None) if device_info: manufacturer = device_info.get('manufacturer', None) model = device_info.get('modelNumber', None) if manufacturer == PHILIPS and model in BRIDGE_MODELS: url = h.description['URLBase'] if url not in hue_bridges: hue_bridges.append(url) else: _LOGGER.error('Missing device info') return [Bridge.from_url(x, username) for x in hue_bridges]
def update(self): """Get the latest player details from the device.""" import upnpclient from netdisco.ssdp import scan if self._slave_mode: return True if self._upnp_device is None: for entry in scan(UPNP_TIMEOUT): try: if upnpclient.Device(entry.location).friendly_name == \ self._name: self._upnp_device = upnpclient.Device(entry.location) break except requests.exceptions.HTTPError: pass self._lpapi.call('GET', 'getPlayerStatus') player_api_result = self._lpapi.data if player_api_result is None: self._media_title = 'Unable to connect to device' return True try: player_status = json.loads(player_api_result) except ValueError: _LOGGER.warning("REST result could not be parsed as JSON") _LOGGER.debug("Erroneous JSON: %s", player_api_result) player_status = None if isinstance(player_status, dict): self._lpapi.call('GET', 'getStatus') device_api_result = self._lpapi.data try: device_status = json.loads(device_api_result) except ValueError: _LOGGER.warning("REST result could not be parsed as JSON") _LOGGER.debug("Erroneous JSON: %s", device_api_result) if isinstance(device_status, dict): self._wifi_channel = device_status['WifiChannel'] self._ssid = \ binascii.hexlify(device_status['ssid'].encode('utf-8')) self._ssid = self._ssid.decode() # Update variables that changes during playback of a track. self._volume = player_status['vol'] self._muted = player_status['mute'] self._seek_position = int(int(player_status['curpos']) / 1000) self._position_updated_at = utcnow() self._media_uri = str(bytearray.fromhex( player_status['iuri']).decode()) self._state = { 'stop': STATE_PAUSED, 'play': STATE_PLAYING, 'pause': STATE_PAUSED, }.get(player_status['status'], STATE_UNKNOWN) self._source = SOURCES_MAP.get(player_status['mode'], 'WiFi') self._sound_mode = SOUND_MODES.get(player_status['eq']) self._shuffle = True if player_status['loop'] == '2' else False self._playing_spotify = bool(player_status['mode'] == '31') if self._is_playing_new_track(player_status): # Only do some things when a new track is playing. if self._playing_spotify or player_status['totlen'] == '0': self._update_via_upnp() else: self._update_from_id3() if self._lfmapi is not None and\ self._media_title is not None: self._get_lastfm_coverart() else: self._media_image_url = None self._duration = int(int(player_status['totlen']) / 1000) else: _LOGGER.warning("JSON result was not a dictionary") # Get multiroom slave information self._lpapi.call('GET', 'multiroom:getSlaveList') slave_list = self._lpapi.data try: slave_list = json.loads(slave_list) except ValueError: _LOGGER.warning("REST result could not be parsed as JSON") _LOGGER.debug("Erroneous JSON: %s", slave_list) self._slave_list = [] if isinstance(slave_list, dict): if int(slave_list['slaves']) > 0: slave_list = slave_list['slave_list'] for slave in slave_list: device = self.hass.data[DATA_LINKPLAY].get(slave['name'], None) if device: self._slave_list.append(device) device.set_master(self) device.set_slave_mode(True) device.set_media_title("Slave mode") device.set_media_artist(self.name) device.set_volume(slave['volume']) device.set_muted(slave['mute']) device.set_state(self.state) device.set_slave_ip(slave['ip']) device.set_seek_position(self.media_position) device.set_duration(self.media_duration) device.set_position_updated_at( self.media_position_updated_at) device.set_source(self._source) device.set_sound_mode(self._sound_mode) else: _LOGGER.warning("JSON result was not a dictionary") return True
def _run_ssdp_scans(): _LOGGER.debug("Scanning") # Run 3 times as packets can get lost return itertools.chain.from_iterable([ssdp.scan() for _ in range(3)])