diff --git a/netdisco/daikin.py b/netdisco/daikin.py deleted file mode 100644 index 014f1e29..00000000 --- a/netdisco/daikin.py +++ /dev/null @@ -1,103 +0,0 @@ -"""Daikin device discovery.""" -import socket - -from datetime import timedelta -from typing import Dict, List # noqa: F401 -from urllib.parse import unquote - -DISCOVERY_MSG = b"DAIKIN_UDP/common/basic_info" - -UDP_SRC_PORT = 30000 -UDP_DST_PORT = 30050 - -DISCOVERY_ADDRESS = '' -DISCOVERY_TIMEOUT = timedelta(seconds=2) - - -class Daikin: - """Base class to discover Daikin devices.""" - - def __init__(self): - """Initialize the Daikin discovery.""" - self.entries = [] # type: List[Dict[str, str]] - - def scan(self): - """Scan the network.""" - self.update() - - def all(self): - """Scan and return all found entries.""" - self.scan() - return self.entries - - def update(self): - """Scan network for Daikin devices.""" - entries = [] - - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.settimeout(DISCOVERY_TIMEOUT.seconds) - sock.bind(("", UDP_SRC_PORT)) - - try: - - sock.sendto(DISCOVERY_MSG, (DISCOVERY_ADDRESS, UDP_DST_PORT)) - - while True: - try: - data, (address, _) = sock.recvfrom(1024) - - entry = {x[0]: x[1] for x in ( - e.split('=', 1) - for e in data.decode("UTF-8").split(','))} - - # expecting product, mac, activation code, version - if 'ret' not in entry or entry['ret'] != 'OK': - # non-OK return on response - continue - - if 'mac' not in entry: - # no mac found for device" - continue - - if 'type' not in entry or entry['type'] != 'aircon': - # no mac found for device" - continue - - if 'name' in entry: - entry['name'] = unquote(entry['name']) - - # in case the device was not configured to have an id - # then use the mac address - if 'id' in entry and entry['id'] == '': - entry['id'] = entry['mac'] - - entries.append({ - 'id': entry['id'], - 'name': entry['name'], - 'ip': address, - 'mac': entry['mac'], - 'ver': entry['ver'], - }) - - except socket.timeout: - break - - finally: - sock.close() - - self.entries = entries - - -def main(): - """Test Daikin discovery.""" - from pprint import pprint - daikin = Daikin() - pprint("Scanning for Daikin devices..") - daikin.update() - pprint(daikin.entries) - - -if __name__ == "__main__": - main() diff --git a/netdisco/discoverables/apple_tv.py b/netdisco/discoverables/apple_tv.py deleted file mode 100644 index 02cb6429..00000000 --- a/netdisco/discoverables/apple_tv.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Discover Apple TV media players.""" -from . import MDNSDiscoverable -from ..const import ATTR_NAME, ATTR_PROPERTIES - - -class Discoverable(MDNSDiscoverable): - """Add support for Apple TV devices.""" - - def __init__(self, nd): - super(Discoverable, self).__init__(nd, '_appletv-v2._tcp.local.') - - def info_from_entry(self, entry): - """Returns most important info from mDNS entries.""" - info = super().info_from_entry(entry) - info[ATTR_NAME] = info[ATTR_PROPERTIES]['Name'].replace('\xa0', ' ') - return info diff --git a/netdisco/discoverables/arduino.py b/netdisco/discoverables/arduino.py deleted file mode 100644 index 013b6cc3..00000000 --- a/netdisco/discoverables/arduino.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Discover Arduino devices.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Arduino devices.""" - - def __init__(self, nd): - super(Discoverable, self).__init__(nd, '_arduino._tcp.local.') diff --git a/netdisco/discoverables/asus_router.py b/netdisco/discoverables/asus_router.py deleted file mode 100644 index 20de3a80..00000000 --- a/netdisco/discoverables/asus_router.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover ASUS routers.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering ASUS routers.""" - - def get_entries(self): - """Get all the ASUS uPnP entries.""" - return self.find_by_device_description({ - "manufacturer": "ASUSTeK Computer Inc.", - "deviceType": "urn:schemas-upnp-org:device:InternetGatewayDevice:1" - }) diff --git a/netdisco/discoverables/axis.py b/netdisco/discoverables/axis.py deleted file mode 100644 index c4278b18..00000000 --- a/netdisco/discoverables/axis.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Discover Axis devices.""" -from . import MDNSDiscoverable - -from ..const import ( - ATTR_HOST, ATTR_PORT, ATTR_HOSTNAME, ATTR_PROPERTIES) - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Axis devices.""" - - def info_from_entry(self, entry): - """Return most important info from mDNS entries.""" - properties = {} - - for key, value in entry.properties.items(): - if isinstance(value, bytes): - value = value.decode('utf-8') - properties[key.decode('utf-8')] = value - - return { - ATTR_HOST: self.ip_from_host(entry.server), - ATTR_PORT: entry.port, - ATTR_HOSTNAME: entry.server, - ATTR_PROPERTIES: properties, - } - - def __init__(self, nd): - """Initialize the Axis discovery.""" - super(Discoverable, self).__init__(nd, '_axis-video._tcp.local.') - - def ip_from_host(self, host): - """Attempt to return the ip address from an mDNS host. - - Return host if failed. - """ - ips = self.netdis.mdns.zeroconf.cache.entries_with_name(host.lower()) - - try: - return repr(ips[0]) if ips else host - except TypeError: - return host diff --git a/netdisco/discoverables/belkin_wemo.py b/netdisco/discoverables/belkin_wemo.py deleted file mode 100644 index 8f3a26ea..00000000 --- a/netdisco/discoverables/belkin_wemo.py +++ /dev/null @@ -1,19 +0,0 @@ -"""Discover Belkin Wemo devices.""" -from . import SSDPDiscoverable -from ..const import ATTR_MAC_ADDRESS - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Belkin WeMo platform devices.""" - - def info_from_entry(self, entry): - """Return most important info from a uPnP entry.""" - info = super().info_from_entry(entry) - device = entry.description['device'] - info[ATTR_MAC_ADDRESS] = device.get('macAddress', '') - return info - - def get_entries(self): - """Return all Belkin Wemo entries.""" - return self.find_by_device_description( - {'manufacturer': 'Belkin International Inc.'}) diff --git a/netdisco/discoverables/cambridgeaudio.py b/netdisco/discoverables/cambridgeaudio.py deleted file mode 100644 index 3538e480..00000000 --- a/netdisco/discoverables/cambridgeaudio.py +++ /dev/null @@ -1,13 +0,0 @@ -""" Discover Cambridge Audio StreamMagic devices. """ -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Cambridge Audio StreamMagic devices.""" - - def get_entries(self): - """Get all Cambridge Audio MediaRenderer uPnP entries.""" - return self.find_by_device_description({ - "manufacturer": "Cambridge Audio", - "deviceType": "urn:schemas-upnp-org:device:MediaRenderer:1" - }) diff --git a/netdisco/discoverables/canon_printer.py b/netdisco/discoverables/canon_printer.py deleted file mode 100644 index b005f617..00000000 --- a/netdisco/discoverables/canon_printer.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover Canon Printers""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Support for the discovery of Canon Printers""" - - def get_entries(self): - """Get all the Canon Printer uPnP entries.""" - return self.find_by_device_description({ - "manufacturer": "CANON INC.", - "deviceType": "urn:schemas-cipa-jp:device:DPSPrinter:1" - }) diff --git a/netdisco/discoverables/daikin.py b/netdisco/discoverables/daikin.py deleted file mode 100644 index b260fd40..00000000 --- a/netdisco/discoverables/daikin.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Discover Daikin devices.""" -from . import BaseDiscoverable - - -class Discoverable(BaseDiscoverable): - """Add support for discovering a Daikin device.""" - - def __init__(self, netdis): - """Initialize the Daikin discovery.""" - self._netdis = netdis - - def get_entries(self): - """Get all the Daikin details.""" - return self._netdis.daikin.entries diff --git a/netdisco/discoverables/deconz.py b/netdisco/discoverables/deconz.py deleted file mode 100644 index 0863cda7..00000000 --- a/netdisco/discoverables/deconz.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover deCONZ gateways.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering deCONZ Wireless Light Control gateways.""" - - def get_entries(self): - """Get all the deCONZ uPnP entries.""" - return self.find_by_device_description({ - "manufacturerURL": "http://www.dresden-elektronik.de", - "modelDescription": "dresden elektronik Wireless Light Control" - }) diff --git a/netdisco/discoverables/denonavr.py b/netdisco/discoverables/denonavr.py deleted file mode 100644 index d830aa66..00000000 --- a/netdisco/discoverables/denonavr.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Discover Denon AVR devices.""" -from urllib.parse import urlparse - -from . import SSDPDiscoverable -from ..const import ATTR_HOST - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Denon AVR devices.""" - - def get_entries(self): - """Get all Denon AVR uPnP entries.""" - return self.find_by_device_description({ - "manufacturer": "Denon", - "deviceType": "urn:schemas-upnp-org:device:MediaRenderer:1" - }) - - def info_from_entry(self, entry): - """Get most important info, which is name, model and host.""" - info = super().info_from_entry(entry) - info[ATTR_HOST] = urlparse( - entry.description['device']['presentationURL']).hostname - return info diff --git a/netdisco/discoverables/digitalstrom.py b/netdisco/discoverables/digitalstrom.py deleted file mode 100644 index ef1973ac..00000000 --- a/netdisco/discoverables/digitalstrom.py +++ /dev/null @@ -1,12 +0,0 @@ -"""Discover digitalSTROM server IP (dss-ip) devices.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering digitalSTROM server IP (dss-ip) devices.""" - - def __init__(self, nd): - super(Discoverable, self).__init__(nd, '_http._tcp.local.') - - def get_entries(self): - return self.find_by_device_name('dss-ip') diff --git a/netdisco/discoverables/directv.py b/netdisco/discoverables/directv.py deleted file mode 100644 index 7babd9cc..00000000 --- a/netdisco/discoverables/directv.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover DirecTV Receivers.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering DirecTV Receivers.""" - - def get_entries(self): - """Get all the DirecTV uPnP entries.""" - return self.find_by_device_description({ - "manufacturer": "DIRECTV", - "deviceType": "urn:schemas-upnp-org:device:MediaServer:1" - }) diff --git a/netdisco/discoverables/dlna_dmr.py b/netdisco/discoverables/dlna_dmr.py deleted file mode 100644 index bbc7fe6f..00000000 --- a/netdisco/discoverables/dlna_dmr.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover DLNA services.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering DLNA services.""" - - def get_entries(self): - """Get all the DLNA service uPnP entries.""" - return \ - self.find_by_st("urn:schemas-upnp-org:device:MediaRenderer:1") + \ - self.find_by_st("urn:schemas-upnp-org:device:MediaRenderer:2") + \ - self.find_by_st("urn:schemas-upnp-org:device:MediaRenderer:3") diff --git a/netdisco/discoverables/dlna_dms.py b/netdisco/discoverables/dlna_dms.py deleted file mode 100644 index eac38ecc..00000000 --- a/netdisco/discoverables/dlna_dms.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover DLNA services.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering DLNA services.""" - - def get_entries(self): - """Get all the DLNA service uPnP entries.""" - return self.find_by_st("urn:schemas-upnp-org:device:MediaServer:1") + \ - self.find_by_st("urn:schemas-upnp-org:device:MediaServer:2") + \ - self.find_by_st("urn:schemas-upnp-org:device:MediaServer:3") + \ - self.find_by_st("urn:schemas-upnp-org:device:MediaServer:4") diff --git a/netdisco/discoverables/esphome.py b/netdisco/discoverables/esphome.py deleted file mode 100644 index faeac976..00000000 --- a/netdisco/discoverables/esphome.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Discover ESPHome devices.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering ESPHome devices.""" - - def __init__(self, nd): - super().__init__(nd, '_esphomelib._tcp.local.') diff --git a/netdisco/discoverables/freebox.py b/netdisco/discoverables/freebox.py deleted file mode 100644 index 11bc5f88..00000000 --- a/netdisco/discoverables/freebox.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Discover Freebox routers.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Freebox routers.""" - - def __init__(self, nd): - """Initialize the Freebox discovery.""" - super(Discoverable, self).__init__(nd, '_fbx-api._tcp.local.') diff --git a/netdisco/discoverables/fritzbox.py b/netdisco/discoverables/fritzbox.py deleted file mode 100644 index 4b729f59..00000000 --- a/netdisco/discoverables/fritzbox.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Discover AVM FRITZ devices.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering AVM FRITZ devices.""" - - def get_entries(self): - """Get all AVM FRITZ entries.""" - return self.find_by_st("urn:schemas-upnp-org:device:fritzbox:1") diff --git a/netdisco/discoverables/google_cast.py b/netdisco/discoverables/google_cast.py deleted file mode 100644 index fb7d3730..00000000 --- a/netdisco/discoverables/google_cast.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Discover devices that implement the Google Cast platform.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Google Cast platform devices.""" - - def __init__(self, nd): - """Initialize the Cast discovery.""" - super(Discoverable, self).__init__(nd, '_googlecast._tcp.local.') diff --git a/netdisco/discoverables/harmony.py b/netdisco/discoverables/harmony.py deleted file mode 100644 index 19d97eb1..00000000 --- a/netdisco/discoverables/harmony.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover Harmony Hub remotes.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Harmony Hub remotes""" - - def get_entries(self): - """Get all the Harmony uPnP entries.""" - return self.find_by_device_description({ - "manufacturer": "Logitech", - "deviceType": "urn:myharmony-com:device:harmony:1" - }) diff --git a/netdisco/discoverables/hass_ios.py b/netdisco/discoverables/hass_ios.py deleted file mode 100644 index 84c1eaab..00000000 --- a/netdisco/discoverables/hass_ios.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Discover Home Assistant iOS app.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering the Home Assistant iOS app.""" - - def __init__(self, nd): - super(Discoverable, self).__init__(nd, '_hass-ios._tcp.local.') diff --git a/netdisco/discoverables/hass_mobile_app.py b/netdisco/discoverables/hass_mobile_app.py deleted file mode 100644 index 9d2c7cf7..00000000 --- a/netdisco/discoverables/hass_mobile_app.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Discover Home Assistant servers.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering mobile apps that support Home Assistant.""" - - def __init__(self, nd): - super(Discoverable, self).__init__(nd, '_hass-mobile-app._tcp.local.') diff --git a/netdisco/discoverables/heos.py b/netdisco/discoverables/heos.py deleted file mode 100644 index 5b6aa14b..00000000 --- a/netdisco/discoverables/heos.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Discover Heos devices.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering DLNA services.""" - - def get_entries(self): - """Get all the HEOS devices.""" - return self.find_by_st("urn:schemas-denon-com:device:ACT-Denon:1") diff --git a/netdisco/discoverables/hikvision.py b/netdisco/discoverables/hikvision.py deleted file mode 100644 index cf9372eb..00000000 --- a/netdisco/discoverables/hikvision.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover Hikvision cameras.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Hikvision cameras.""" - - def __init__(self, nd): - """Initialize Hikvision camera discovery.""" - super(Discoverable, self).__init__(nd, '_http._tcp.local.') - - def get_entries(self): - return self.find_by_device_name('HIKVISION') diff --git a/netdisco/discoverables/home_assistant.py b/netdisco/discoverables/home_assistant.py deleted file mode 100644 index 2b7828ef..00000000 --- a/netdisco/discoverables/home_assistant.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Discover Home Assistant servers.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Home Assistant instances.""" - - def __init__(self, nd): - super(Discoverable, self).__init__(nd, '_home-assistant._tcp.local.') diff --git a/netdisco/discoverables/homekit.py b/netdisco/discoverables/homekit.py deleted file mode 100644 index 690cb63f..00000000 --- a/netdisco/discoverables/homekit.py +++ /dev/null @@ -1,18 +0,0 @@ -"""Discover Homekit devices.""" -from . import MDNSDiscoverable - -from ..const import ATTR_NAME - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering HomeKit devices.""" - - def __init__(self, nd): - super(Discoverable, self).__init__(nd, '_hap._tcp.local.') - - def info_from_entry(self, entry): - info = super(Discoverable, self).info_from_entry(entry) - name = entry.name - name = name.replace('._hap._tcp.local.', '') - info[ATTR_NAME] = name - return info diff --git a/netdisco/discoverables/hp_printer.py b/netdisco/discoverables/hp_printer.py deleted file mode 100644 index b4c61313..00000000 --- a/netdisco/discoverables/hp_printer.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover HP Printers""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Support for the discovery of HP Printers""" - - def __init__(self, nd): - """Initialize the HP Printer discovery""" - super(Discoverable, self).__init__(nd, '_printer._tcp.local.') - - def get_entries(self): - return self.find_by_device_name('HP ') diff --git a/netdisco/discoverables/huawei_router.py b/netdisco/discoverables/huawei_router.py deleted file mode 100644 index 7f1bb3d5..00000000 --- a/netdisco/discoverables/huawei_router.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover Huawei routers.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Huawei routers.""" - - def get_entries(self): - """Get all the Huawei uPnP entries.""" - return self.find_by_device_description({ - "manufacturer": "Huawei Technologies Co., Ltd.", - "deviceType": "urn:schemas-upnp-org:device:InternetGatewayDevice:1" - }) diff --git a/netdisco/discoverables/igd.py b/netdisco/discoverables/igd.py deleted file mode 100644 index ba92c907..00000000 --- a/netdisco/discoverables/igd.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Discover IGD services.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering IGD services.""" - - def get_entries(self): - """Get all the IGD service uPnP entries.""" - return \ - self.find_by_st( - "urn:schemas-upnp-org:device:InternetGatewayDevice:1") + \ - self.find_by_st( - "urn:schemas-upnp-org:device:InternetGatewayDevice:2") diff --git a/netdisco/discoverables/ikea_tradfri.py b/netdisco/discoverables/ikea_tradfri.py deleted file mode 100644 index 9fa7c57e..00000000 --- a/netdisco/discoverables/ikea_tradfri.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Discover devices that implement the Ikea Tradfri platform.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Ikea Tradfri devices.""" - - def __init__(self, nd): - """Initialize the Cast discovery.""" - super(Discoverable, self).__init__(nd, '_coap._udp.local.') diff --git a/netdisco/discoverables/kodi.py b/netdisco/discoverables/kodi.py deleted file mode 100644 index 4de74dd0..00000000 --- a/netdisco/discoverables/kodi.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover Kodi servers.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Kodi.""" - - def __init__(self, nd): - """Initialize the Kodi discovery.""" - super(Discoverable, self).__init__(nd, '_http._tcp.local.') - - def get_entries(self): - return self.find_by_device_name('Kodi ') diff --git a/netdisco/discoverables/konnected.py b/netdisco/discoverables/konnected.py deleted file mode 100644 index 7057b177..00000000 --- a/netdisco/discoverables/konnected.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Discover Konnected Security devices.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Konnected Security devices.""" - - def get_entries(self): - """Return all Konnected entries.""" - return self.find_by_st('urn:schemas-konnected-io:device:Security:1') diff --git a/netdisco/discoverables/logitech_mediaserver.py b/netdisco/discoverables/logitech_mediaserver.py deleted file mode 100644 index d03b8fda..00000000 --- a/netdisco/discoverables/logitech_mediaserver.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Discover Logitech Media Server.""" -from . import BaseDiscoverable - - -class Discoverable(BaseDiscoverable): - """Add support for discovering Logitech Media Server.""" - - def __init__(self, netdis): - """Initialize Logitech Media Server discovery.""" - self.netdis = netdis - - def get_entries(self): - """Get all the Logitech Media Server details.""" - return self.netdis.lms.entries diff --git a/netdisco/discoverables/lutron.py b/netdisco/discoverables/lutron.py deleted file mode 100644 index b0c51d00..00000000 --- a/netdisco/discoverables/lutron.py +++ /dev/null @@ -1,11 +0,0 @@ -"""Discover Lutron Caseta Smart Bridge and Smart Bridge Pro devices.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Lutron Caseta Smart Bridge - and Smart Bridge Pro devices.""" - - def __init__(self, nd): - """Initialize the Lutron Smart Bridge discovery.""" - super(Discoverable, self).__init__(nd, '_lutron._tcp.local.') diff --git a/netdisco/discoverables/nanoleaf_aurora.py b/netdisco/discoverables/nanoleaf_aurora.py deleted file mode 100644 index 135d785a..00000000 --- a/netdisco/discoverables/nanoleaf_aurora.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Discover Nanoleaf Aurora devices.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Nanoleaf Aurora devices.""" - - def __init__(self, nd): - super(Discoverable, self).__init__(nd, '_nanoleafapi._tcp.local.') diff --git a/netdisco/discoverables/netgear_router.py b/netdisco/discoverables/netgear_router.py deleted file mode 100644 index d4409bd1..00000000 --- a/netdisco/discoverables/netgear_router.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover Netgear routers.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Netgear routers.""" - - def get_entries(self): - """Get all the Netgear uPnP entries.""" - return self.find_by_device_description({ - "manufacturer": "NETGEAR, Inc.", - "deviceType": "urn:schemas-upnp-org:device:InternetGatewayDevice:1" - }) diff --git a/netdisco/discoverables/octoprint.py b/netdisco/discoverables/octoprint.py deleted file mode 100644 index f6d10e07..00000000 --- a/netdisco/discoverables/octoprint.py +++ /dev/null @@ -1,12 +0,0 @@ -"""Discover OctoPrint Servers.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering OctoPrint servers.""" - - def get_entries(self): - """Get all the OctoPrint uPnP entries.""" - return self.find_by_device_description({ - "manufacturer": "The OctoPrint Project" - }) diff --git a/netdisco/discoverables/panasonic_viera.py b/netdisco/discoverables/panasonic_viera.py deleted file mode 100644 index 3f90271e..00000000 --- a/netdisco/discoverables/panasonic_viera.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Discover Panasonic Viera TV devices.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Viera TV devices.""" - - def get_entries(self): - """Get all the Viera TV device uPnP entries.""" - return self.find_by_st("urn:panasonic-com:service:p00NetworkControl:1") diff --git a/netdisco/discoverables/philips_hue.py b/netdisco/discoverables/philips_hue.py deleted file mode 100644 index 582fbc19..00000000 --- a/netdisco/discoverables/philips_hue.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Discover Philips Hue bridges.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Philips Hue bridges.""" - - def get_entries(self): - """Get all the Hue bridge uPnP entries.""" - return self.find_by_device_description({ - "manufacturer": "Royal Philips Electronics", - "manufacturerURL": "http://www.philips.com", - "modelNumber": ["929000226503", "BSB002"] - }) diff --git a/netdisco/discoverables/plex_mediaserver.py b/netdisco/discoverables/plex_mediaserver.py deleted file mode 100644 index 9eb427a4..00000000 --- a/netdisco/discoverables/plex_mediaserver.py +++ /dev/null @@ -1,21 +0,0 @@ -"""Discover PlexMediaServer.""" -from . import GDMDiscoverable -from ..const import ATTR_NAME, ATTR_HOST, ATTR_PORT, ATTR_URLBASE - - -class Discoverable(GDMDiscoverable): - """Add support for discovering Plex Media Server.""" - - def info_from_entry(self, entry): - """Return most important info from a GDM entry.""" - return { - ATTR_NAME: entry['data']['Name'], - ATTR_HOST: entry['from'][0], - ATTR_PORT: entry['data']['Port'], - ATTR_URLBASE: 'https://%s:%s' % (entry['from'][0], - entry['data']['Port']) - } - - def get_entries(self): - """Return all PMS entries.""" - return self.find_by_data({'Content-Type': 'plex/media-server'}) diff --git a/netdisco/discoverables/roku.py b/netdisco/discoverables/roku.py deleted file mode 100644 index 2cf7c4ee..00000000 --- a/netdisco/discoverables/roku.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Discover Roku players.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Roku media players.""" - - def get_entries(self): - """Get all the Roku entries.""" - return self.find_by_st("roku:ecp") diff --git a/netdisco/discoverables/samsung_printer.py b/netdisco/discoverables/samsung_printer.py deleted file mode 100644 index 04eb2c1f..00000000 --- a/netdisco/discoverables/samsung_printer.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Discover Samsung Printers""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Support for the discovery of Samsung Printers""" - - def get_entries(self): - """Get all the Samsung Printer uPnP entries.""" - return self.find_by_device_description({ - "manufacturer": "Samsung Electronics", - "deviceType": "urn:schemas-upnp-org:device:Printer:1" - }) diff --git a/netdisco/discoverables/samsung_tv.py b/netdisco/discoverables/samsung_tv.py deleted file mode 100644 index 4ad31bb3..00000000 --- a/netdisco/discoverables/samsung_tv.py +++ /dev/null @@ -1,25 +0,0 @@ -"""Discover Samsung Smart TV services.""" -from . import SSDPDiscoverable -from ..const import ATTR_NAME - -# For some models, Samsung forces a [TV] prefix to the user-specified name. -FORCED_NAME_PREFIX = '[TV]' - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Samsung Smart TV services.""" - - def get_entries(self): - """Get all the Samsung RemoteControlReceiver entries.""" - return self.find_by_st( - "urn:samsung.com:device:RemoteControlReceiver:1") - - def info_from_entry(self, entry): - """Get most important info, by default the description location.""" - info = super().info_from_entry(entry) - - # Strip the forced prefix, if present - if info[ATTR_NAME].startswith(FORCED_NAME_PREFIX): - info[ATTR_NAME] = info[ATTR_NAME][len(FORCED_NAME_PREFIX):].strip() - - return info diff --git a/netdisco/discoverables/sercomm.py b/netdisco/discoverables/sercomm.py deleted file mode 100644 index 870e34a5..00000000 --- a/netdisco/discoverables/sercomm.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -Discover Sercomm network cameras. -These are rebranded as iControl and many others, and are usually -distributed as part of an ADT or Comcast/Xfinity monitoring package. -https://github.com/edent/Sercomm-API -""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering camera services.""" - - def get_entries(self): - """Get all Sercomm iControl devices.""" - return self.find_by_device_description({'manufacturer': 'iControl'}) diff --git a/netdisco/discoverables/songpal.py b/netdisco/discoverables/songpal.py deleted file mode 100644 index 5eafe323..00000000 --- a/netdisco/discoverables/songpal.py +++ /dev/null @@ -1,57 +0,0 @@ -"""Discover Songpal devices.""" -import logging -from . import SSDPDiscoverable -from . import ATTR_PROPERTIES - - -class Discoverable(SSDPDiscoverable): - """Support for Songpal devices. - Supported devices: http://vssupport.sony.net/en_ww/device.html.""" - - def get_entries(self): - """Get all the Songpal devices.""" - devs = self.find_by_st( - "urn:schemas-sony-com:service:ScalarWebAPI:1") - - # At least some Bravia televisions use the same API for communication, - # but are handled by another platforms, so we filter them out here. - supported = [] - for dev in devs: - if 'device' in dev.description: - device = dev.description['device'] - scalarweb_info = device.get("X_ScalarWebAPI_DeviceInfo", None) - - if scalarweb_info: - services = scalarweb_info["X_ScalarWebAPI_ServiceList"] - service_types = services["X_ScalarWebAPI_ServiceType"] - # Sony Bravias offer videoScreen service, soundbars do not - if 'videoScreen' in service_types: - continue - - supported.append(dev) - - return supported - - def info_from_entry(self, entry): - """Get information for a device..""" - info = super().info_from_entry(entry) - - cached_descs = entry.DESCRIPTION_CACHE[entry.location] - - device_info_element = "X_ScalarWebAPI_DeviceInfo" - baseurl_element = "X_ScalarWebAPI_BaseURL" - device_element = "device" - if device_element in cached_descs and \ - device_info_element in cached_descs[device_element]: - scalarweb = cached_descs[device_element][device_info_element] - - properties = {"scalarwebapi": scalarweb} - if baseurl_element in scalarweb: - properties["endpoint"] = scalarweb[baseurl_element] - else: - logging.warning("Unable to find %s", baseurl_element) - info[ATTR_PROPERTIES] = properties - else: - logging.warning("Unable to find ScalarWeb element from desc.") - - return info diff --git a/netdisco/discoverables/sonos.py b/netdisco/discoverables/sonos.py deleted file mode 100644 index 29c96c09..00000000 --- a/netdisco/discoverables/sonos.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Discover Sonos devices.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Sonos devices.""" - - def get_entries(self): - """Get all the Sonos device uPnP entries.""" - return self.find_by_st("urn:schemas-upnp-org:device:ZonePlayer:1") diff --git a/netdisco/discoverables/spotify_connect.py b/netdisco/discoverables/spotify_connect.py deleted file mode 100644 index 6bdb0625..00000000 --- a/netdisco/discoverables/spotify_connect.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Discover devices that implement the Spotify Connect platform.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Spotify Connect service.""" - - def __init__(self, nd): - """Initialize the Cast discovery.""" - super(Discoverable, self).__init__(nd, '_spotify-connect._tcp.local.') diff --git a/netdisco/discoverables/tellstick.py b/netdisco/discoverables/tellstick.py deleted file mode 100644 index 727aa762..00000000 --- a/netdisco/discoverables/tellstick.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Discover Tellstick devices.""" -from . import BaseDiscoverable - - -class Discoverable(BaseDiscoverable): - """Add support for discovering a Tellstick device.""" - - def __init__(self, netdis): - """Initialize the Tellstick discovery.""" - self._netdis = netdis - - def get_entries(self): - """Get all the Tellstick details.""" - return self._netdis.tellstick.entries diff --git a/netdisco/discoverables/tivo_dvr.py b/netdisco/discoverables/tivo_dvr.py deleted file mode 100644 index 454cfe9a..00000000 --- a/netdisco/discoverables/tivo_dvr.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Discover TiVo DVR devices providing the TCP Remote Protocol.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering TiVo Remote Protocol service.""" - - def __init__(self, nd): - """Initialize the discovery. - - Yields a dictionary with hostname, host and port along with a - properties sub-dictionary with some device specific ids. - """ - super(Discoverable, self).__init__(nd, '_tivo-remote._tcp.local.') diff --git a/netdisco/discoverables/volumio.py b/netdisco/discoverables/volumio.py deleted file mode 100644 index a08b902c..00000000 --- a/netdisco/discoverables/volumio.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Discover Volumio servers.""" -from . import MDNSDiscoverable - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Volumio.""" - - def __init__(self, nd): - """Initialize the Volumio discovery.""" - super(Discoverable, self).__init__(nd, '_Volumio._tcp.local.') diff --git a/netdisco/discoverables/webos_tv.py b/netdisco/discoverables/webos_tv.py deleted file mode 100644 index 4328c60d..00000000 --- a/netdisco/discoverables/webos_tv.py +++ /dev/null @@ -1,15 +0,0 @@ -"""Discover LG WebOS TV devices.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering LG WebOS TV devices.""" - - def get_entries(self): - """Get all the LG WebOS TV device uPnP entries.""" - return self.find_by_device_description( - { - "deviceType": "urn:schemas-upnp-org:device:Basic:1", - "modelName": "LG Smart TV" - } - ) diff --git a/netdisco/discoverables/wink.py b/netdisco/discoverables/wink.py deleted file mode 100644 index 3678d60c..00000000 --- a/netdisco/discoverables/wink.py +++ /dev/null @@ -1,17 +0,0 @@ -"""Discover Wink hub devices.""" -from typing import List # noqa: F401 - -from . import SSDPDiscoverable -from ..ssdp import UPNPEntry # noqa: F401 - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Wink hub devices.""" - - def get_entries(self): - """Return all Wink entries.""" - results = [] # type: List[UPNPEntry] - results.extend(self.find_by_st('urn:wink-com:device:hub2:2')) - results.extend(self.find_by_st('urn:wink-com:device:hub:2')) - results.extend(self.find_by_st('urn:wink-com:device:relay:2')) - return results diff --git a/netdisco/discoverables/xbox_smartglass.py b/netdisco/discoverables/xbox_smartglass.py deleted file mode 100644 index 191ee7b9..00000000 --- a/netdisco/discoverables/xbox_smartglass.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Discover Xbox SmartGlass devices.""" -from . import BaseDiscoverable - - -class Discoverable(BaseDiscoverable): - """Add support for discovering a Xbox SmartGlass device.""" - - def __init__(self, netdis): - """Initialize the Xbox SmartGlass discovery.""" - self._netdis = netdis - - def get_entries(self): - """Get all the Xbox SmartGlass details.""" - return self._netdis.xbox_smartglass.entries diff --git a/netdisco/discoverables/xiaomi_gw.py b/netdisco/discoverables/xiaomi_gw.py deleted file mode 100644 index 5c9ab0d3..00000000 --- a/netdisco/discoverables/xiaomi_gw.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Discover Xiaomi Mi Home (aka Lumi) Gateways.""" -from . import MDNSDiscoverable -from ..const import ATTR_MAC_ADDRESS, ATTR_PROPERTIES - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Xiaomi Gateway""" - - def __init__(self, nd): - """Initialize the discovery.""" - super(Discoverable, self).__init__(nd, '_miio._udp.local.') - - def info_from_entry(self, entry): - """Return most important info from mDNS entries.""" - info = super().info_from_entry(entry) - - # Workaround of misparsing of mDNS properties. It's unclear - # whether it's bug in zeroconf module or in the Gateway, but - # returned properties look like: - # {b'poch': b'0:mac=286c07aaaaaa\x00'} instead of expected: - # {b'epoch': b'0', b'mac': '286c07aaaaaa'} - if "poch" in info[ATTR_PROPERTIES]: - misparsed = info[ATTR_PROPERTIES]["poch"] - misparsed = misparsed.rstrip("\0") - for val in misparsed.split(":"): - if val.startswith("mac="): - info[ATTR_MAC_ADDRESS] = val[len("mac="):] - - return info - - def get_entries(self): - """Return Xiaomi Gateway devices.""" - return self.find_by_device_name('lumi-gateway-') diff --git a/netdisco/discoverables/yeelight.py b/netdisco/discoverables/yeelight.py deleted file mode 100644 index 9a42c1b5..00000000 --- a/netdisco/discoverables/yeelight.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Discover Yeelight bulbs, based on Kodi discoverable.""" -from . import MDNSDiscoverable -from ..const import ATTR_DEVICE_TYPE - -DEVICE_NAME_PREFIX = 'yeelink-light-' - - -class Discoverable(MDNSDiscoverable): - """Add support for discovering Yeelight.""" - - def __init__(self, nd): - """Initialize the Yeelight discovery.""" - super(Discoverable, self).__init__(nd, '_miio._udp.local.') - - def info_from_entry(self, entry): - """Return most important info from mDNS entries.""" - info = super().info_from_entry(entry) - - # Example name: yeelink-light-ceiling4_mibt72799069._miio._udp.local. - info[ATTR_DEVICE_TYPE] = \ - entry.name.replace(DEVICE_NAME_PREFIX, '').split('_', 1)[0] - - return info - - def get_entries(self): - """ Return yeelight devices. """ - return self.find_by_device_name(DEVICE_NAME_PREFIX) diff --git a/netdisco/discoverables/ziggo_mediabox_xl.py b/netdisco/discoverables/ziggo_mediabox_xl.py deleted file mode 100644 index 57fcd506..00000000 --- a/netdisco/discoverables/ziggo_mediabox_xl.py +++ /dev/null @@ -1,12 +0,0 @@ -"""Discover Ziggo Mediabox XL devices.""" -from . import SSDPDiscoverable - - -class Discoverable(SSDPDiscoverable): - """Add support for discovering Ziggo Mediabox XL devices.""" - - def get_entries(self): - """Return all Ziggo (UPC) Mediabox XL entries.""" - return self.find_by_device_description( - {'modelDescription': 'UPC Hzn Gateway', - 'deviceType': 'urn:schemas-upnp-org:device:RemoteUIServer:2'}) diff --git a/netdisco/discovery.py b/netdisco/discovery.py index 22290022..b0b4b211 100644 --- a/netdisco/discovery.py +++ b/netdisco/discovery.py @@ -5,11 +5,6 @@ from .ssdp import SSDP from .mdns import MDNS -from .gdm import GDM -from .lms import LMS -from .tellstick import Tellstick -from .daikin import Daikin -from .smartglass import XboxSmartGlass _LOGGER = logging.getLogger(__name__) @@ -19,10 +14,6 @@ class NetworkDiscovery: mDNS scans in a background thread. SSDP scans in the foreground. - GDM scans in the foreground. - LMS scans in the foreground. - Tellstick scans in the foreground - Xbox One scans in the foreground start: is ready to scan scan: scan the network @@ -36,11 +27,6 @@ def __init__(self): self.mdns = None self.ssdp = None - self.gdm = None - self.lms = None - self.tellstick = None - self.daikin = None - self.xbox_smartglass = None self.is_discovering = False self.discoverables = None @@ -63,21 +49,6 @@ def scan(self, zeroconf_instance=None, suppress_mdns_types=None): self.ssdp = SSDP() self.ssdp.scan() - self.gdm = GDM() - self.gdm.scan() - - self.lms = LMS() - self.lms.scan() - - self.tellstick = Tellstick() - self.tellstick.scan() - - self.daikin = Daikin() - self.daikin.scan() - - self.xbox_smartglass = XboxSmartGlass() - self.xbox_smartglass.scan() - def stop(self): """Turn discovery off.""" if not self.is_discovering: @@ -87,11 +58,6 @@ def stop(self): # Not removing SSDP because it tracks state self.mdns = None - self.gdm = None - self.lms = None - self.tellstick = None - self.daikin = None - self.xbox_smartglass = None self.discoverables = None self.is_discovering = False @@ -139,15 +105,3 @@ def print_raw_data(self): print("") print("SSDP") pprint(self.ssdp.entries) - print("") - print("GDM") - pprint(self.gdm.entries) - print("") - print("LMS") - pprint(self.lms.entries) - print("") - print("Tellstick") - pprint(self.tellstick.entries) - print("") - print("Xbox SmartGlass") - pprint(self.xbox_smartglass.entries) diff --git a/netdisco/gdm.py b/netdisco/gdm.py deleted file mode 100644 index 75428b20..00000000 --- a/netdisco/gdm.py +++ /dev/null @@ -1,111 +0,0 @@ -""" -Support for discovery using GDM (Good Day Mate), multicast protocol by Plex. - -Inspired by - hippojay's plexGDM: - https://github.com/hippojay/script.plexbmc.helper/resources/lib/plexgdm.py - iBaa's PlexConnect: https://github.com/iBaa/PlexConnect/PlexAPI.py -""" -import socket -import struct -from typing import Any, Dict, List # noqa: F401 - - -class GDM: - """Base class to discover GDM services.""" - - def __init__(self): - self.entries = [] # type: List[Dict[str, Any]] - self.last_scan = None - - def scan(self): - """Scan the network.""" - self.update() - - def all(self): - """Return all found entries. - - Will scan for entries if not scanned recently. - """ - self.scan() - return list(self.entries) - - def find_by_content_type(self, value): - """Return a list of entries that match the content_type.""" - self.scan() - return [entry for entry in self.entries - if value in entry['data']['Content_Type']] - - def find_by_data(self, values): - """Return a list of entries that match the search parameters.""" - self.scan() - return [entry for entry in self.entries - if all(item in entry['data'].items() - for item in values.items())] - - def update(self): - """Scan for new GDM services. - - Example of the dict list assigned to self.entries by this function: - [{'data': { - 'Content-Type': 'plex/media-server', - 'Host': '53f4b5b6023d41182fe88a99b0e714ba.plex.direct', - 'Name': 'myfirstplexserver', - 'Port': '32400', - 'Resource-Identifier': '646ab0aa8a01c543e94ba975f6fd6efadc36b7', - 'Updated-At': '1444852697', - 'Version': '0.9.12.13.1464-4ccd2ca', - }, - 'from': ('10.10.10.100', 32414)}] - """ - - gdm_ip = '239.0.0.250' # multicast to PMS - gdm_port = 32414 - gdm_msg = 'M-SEARCH * HTTP/1.0'.encode('ascii') - gdm_timeout = 1 - - self.entries = [] - - # setup socket for discovery -> multicast message - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.settimeout(gdm_timeout) - - # Set the time-to-live for messages for local network - sock.setsockopt(socket.IPPROTO_IP, - socket.IP_MULTICAST_TTL, - struct.pack("B", gdm_timeout)) - - try: - # Send data to the multicast group - sock.sendto(gdm_msg, (gdm_ip, gdm_port)) - - # Look for responses from all recipients - while True: - try: - bdata, server = sock.recvfrom(1024) - data = bdata.decode('utf-8') - if '200 OK' in data.splitlines()[0]: - ddata = {k: v.strip() for (k, v) in ( - line.split(':') for line in - data.splitlines() if ':' in line)} - self.entries.append({'data': ddata, - 'from': server}) - except socket.timeout: - break - finally: - sock.close() - - -def main(): - """Test GDM discovery.""" - from pprint import pprint - - gdm = GDM() - - pprint("Scanning GDM...") - gdm.update() - pprint(gdm.entries) - - -if __name__ == "__main__": - main() diff --git a/netdisco/lms.py b/netdisco/lms.py deleted file mode 100644 index 71934c96..00000000 --- a/netdisco/lms.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Squeezebox/Logitech Media server discovery.""" -import socket -from typing import Dict, List, Union # noqa: F401 - -from .const import ATTR_HOST, ATTR_PORT - -DISCOVERY_PORT = 3483 -DEFAULT_DISCOVERY_TIMEOUT = 2 - - -class LMS: - """Base class to discover Logitech Media servers.""" - - def __init__(self): - """Initialize the Logitech discovery.""" - self.entries = [] # type: List[Dict[str, Union[str, int]]] - self.last_scan = None - - def scan(self): - """Scan the network.""" - self.update() - - def all(self): - """Scan and return all found entries.""" - self.scan() - return list(self.entries) - - def update(self): - """Scan network for Logitech Media Servers.""" - lms_ip = '' - lms_port = DISCOVERY_PORT - lms_msg = b"eJSON\0" - lms_timeout = DEFAULT_DISCOVERY_TIMEOUT - - entries = [] - - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - sock.settimeout(lms_timeout) - sock.bind(('', 0)) - - try: - sock.sendto(lms_msg, (lms_ip, lms_port)) - - while True: - try: - data, server = sock.recvfrom(1024) - if data.startswith(b'E'): - # Full response is EJSON\xYYXXXX - # Where YY is length of port string (ie 4) - # And XXXX is the web interface port (ie 9000) - port = None - # https://github.com/python/typeshed/pull/2696 - if data.startswith(b'JSON', 1): # type: ignore - length = data[5:6][0] - port = int(data[0-length:]) - entries.append({ - ATTR_HOST: server[0], - ATTR_PORT: port, - }) - except socket.timeout: - break - finally: - sock.close() - self.entries = entries - - -def main(): - """Test LMS discovery.""" - from pprint import pprint - - lms = LMS() - - pprint("Scanning for Logitech Media Servers...") - lms.update() - pprint(lms.entries) - - -if __name__ == "__main__": - main() diff --git a/netdisco/smartglass.py b/netdisco/smartglass.py deleted file mode 100644 index 0b534cfe..00000000 --- a/netdisco/smartglass.py +++ /dev/null @@ -1,159 +0,0 @@ -"""Xbox One SmartGlass device discovery.""" -import socket -import struct -import binascii -from datetime import timedelta -from typing import Any, Dict, List, Optional, Tuple # noqa: F401 - - -DISCOVERY_PORT = 5050 -DISCOVERY_ADDRESS_BCAST = '' -DISCOVERY_ADDRESS_MCAST = '239.255.255.250' -DISCOVERY_REQUEST = 0xDD00 -DISCOVERY_RESPONSE = 0xDD01 -DISCOVERY_TIMEOUT = timedelta(seconds=2) - -""" -SmartGlass Client type -XboxOne = 1 -Xbox360 = 2 -WindowsDesktop = 3 -WindowsStore = 4 -WindowsPhone = 5 -iPhone = 6 -iPad = 7 -Android = 8 -""" -DISCOVERY_CLIENT_TYPE = 4 - -_Response = Dict[str, Any] - - -class XboxSmartGlass: - """Base class to discover Xbox SmartGlass devices.""" - - def __init__(self): - """Initialize the Xbox SmartGlass discovery.""" - self.entries = [] # type: List[Tuple[str, Optional[_Response]]] - self._discovery_payload = self.discovery_packet() - - @staticmethod - def discovery_packet(): - """Assemble discovery payload.""" - version = 0 - flags = 0 - min_version = 0 - max_version = 2 - - payload = struct.pack( - '>IHHH', - flags, DISCOVERY_CLIENT_TYPE, min_version, max_version - ) - header = struct.pack( - '>HHH', - DISCOVERY_REQUEST, len(payload), version - ) - return header + payload - - @staticmethod - def parse_discovery_response(data): - """Parse console's discovery response.""" - pos = 0 - # Header - # pkt_type, payload_len, version = struct.unpack_from( - # '>HHH', - # data, pos - # ) - pos += 6 - # Payload - flags, type_, name_len = struct.unpack_from( - '>IHH', - data, pos - ) - pos += 8 - name = data[pos:pos + name_len] - pos += name_len + 1 # including null terminator - uuid_len = struct.unpack_from( - '>H', - data, pos - )[0] - pos += 2 - uuid = data[pos:pos + uuid_len] - pos += uuid_len + 1 # including null terminator - last_error, cert_len = struct.unpack_from( - '>IH', - data, pos - ) - pos += 6 - cert = data[pos:pos + cert_len] - - return { - 'device_type': type_, - 'flags': flags, - 'name': name.decode('utf-8'), - 'uuid': uuid.decode('utf-8'), - 'last_error': last_error, - 'certificate': binascii.hexlify(cert).decode('utf-8') - } - - def scan(self): - """Scan the network.""" - self.update() - - def all(self): - """Scan and return all found entries.""" - self.scan() - return self.entries - - @staticmethod - def verify_packet(data): - """Parse packet if it has correct magic""" - if len(data) < 2: - return None - - pkt_type = struct.unpack_from('>H', data)[0] - if pkt_type != DISCOVERY_RESPONSE: - return None - - return XboxSmartGlass.parse_discovery_response(data) - - def update(self): - """Scan network for Xbox SmartGlass devices.""" - entries = [] - - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.settimeout(DISCOVERY_TIMEOUT.seconds) - sock.sendto(self._discovery_payload, - (DISCOVERY_ADDRESS_BCAST, DISCOVERY_PORT)) - sock.sendto(self._discovery_payload, - (DISCOVERY_ADDRESS_MCAST, DISCOVERY_PORT)) - - while True: - try: - data, (address, _) = sock.recvfrom(1024) - - response = self.verify_packet(data) - if response: - entries.append((address, response)) - - except socket.timeout: - break - - self.entries = entries - - sock.close() - - -def main(): - """Test XboxOne discovery.""" - from pprint import pprint - xbsmartglass = XboxSmartGlass() - pprint("Scanning for Xbox One SmartGlass consoles devices..") - xbsmartglass.update() - pprint(xbsmartglass.entries) - - -if __name__ == "__main__": - main() diff --git a/netdisco/tellstick.py b/netdisco/tellstick.py deleted file mode 100644 index f5bd7bd0..00000000 --- a/netdisco/tellstick.py +++ /dev/null @@ -1,73 +0,0 @@ -"""Tellstick device discovery.""" -import socket -from datetime import timedelta -import logging -from typing import List, Tuple # noqa: F401 - - -DISCOVERY_PORT = 30303 -DISCOVERY_ADDRESS = '' -DISCOVERY_PAYLOAD = b"D" -DISCOVERY_TIMEOUT = timedelta(seconds=2) - - -class Tellstick: - """Base class to discover Tellstick devices.""" - - def __init__(self): - """Initialize the Tellstick discovery.""" - self.entries = [] # type: List[Tuple[str]] - - def scan(self): - """Scan the network.""" - self.update() - - def all(self): - """Scan and return all found entries.""" - self.scan() - return self.entries - - def update(self): - """Scan network for Tellstick devices.""" - entries = [] - - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.settimeout(DISCOVERY_TIMEOUT.seconds) - sock.sendto(DISCOVERY_PAYLOAD, (DISCOVERY_ADDRESS, DISCOVERY_PORT)) - - while True: - try: - data, (address, _) = sock.recvfrom(1024) - entry = data.decode("ascii").split(":") - # expecting product, mac, activation code, version - if len(entry) != 4: - continue - entry.insert(0, address) - entries.append(tuple(entry)) - - except socket.timeout: - break - except UnicodeDecodeError: - # Catch invalid responses - logging.getLogger(__name__).debug( - 'Ignoring invalid unicode response from %s', address) - continue - - self.entries = entries - - sock.close() - - -def main(): - """Test Tellstick discovery.""" - from pprint import pprint - tellstick = Tellstick() - pprint("Scanning for Tellstick devices..") - tellstick.update() - pprint(tellstick.entries) - - -if __name__ == "__main__": - main() diff --git a/setup.py b/setup.py index aaa380e0..acc282ca 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setup( name="netdisco", - version="2.9.0", + version="3.0.0", description="Discover devices on your local network", long_description=long_description, long_description_content_type="text/markdown",