|
|
- """Squeezebox/Logitech Media server discovery."""
- import socket
-
- 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 = []
- 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 = '<broadcast>'
- 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
- if data.startswith(b'JSON', 1):
- 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()
|