"""Tellstick device discovery.""" import socket from datetime import timedelta import logging 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 = [] 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 = (address,) + tuple(entry) entries.append(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()