def _resubscribe(self, url, sid=None): headers = {'TIMEOUT': 300} if sid is not None: headers['SID'] = sid else: host = get_ip_address() headers.update({ "CALLBACK": '<http://%s:8989>' % host, "NT": "upnp:event" }) response = requests.request(method="SUBSCRIBE", url=url, headers=headers) if response.status_code == 412 and sid: # Invalid subscription ID. Send an UNSUBSCRIBE for safety and # start over. requests.request(method='UNSUBSCRIBE', url=url, headers={'SID': sid}) return self._resubscribe(url) timeout = int( response.headers.get('timeout', '1801').replace('Second-', '')) sid = response.headers.get('sid', sid) gevent.spawn_later(timeout - 1, self._resubscribe, url, sid)
def __init__(self, mcast_ip='239.255.255.250', mcast_port=1900, bind=None): if bind is None: host = get_ip_address() if host.startswith('127.'): raise UPnPLoopbackException("Using %s as a callback IP for " "discovery will not be successful.") port = 54321 bind = '{0}:{1}'.format(host, port) self.bind = bind self.mcast_ip = mcast_ip self.mcast_port = mcast_port self.clients = {}
def __init__(self, mcast_ip='239.255.255.250', mcast_port=1900, bind=None): if bind is None: host = get_ip_address() if host.startswith('127.'): raise UPnPLoopbackException( "Using %s as a callback IP for " "discovery will not be successful.") port = 54321 bind = '{0}:{1}'.format(host, port) self.bind = bind self.mcast_ip = mcast_ip self.mcast_port = mcast_port self.clients = {}
def _resubscribe(self, url, sid=None): headers = {'TIMEOUT': 'Second-%d' % 1800} if sid is not None: headers['SID'] = sid else: host = get_ip_address() headers.update({ "CALLBACK": '<http://%s:8989>' % host, "NT": "upnp:event" }) response = requests_request(method="SUBSCRIBE", url=url, headers=headers) if response.status_code == 412 and sid: # Invalid subscription ID. Send an UNSUBSCRIBE for safety and # start over. requests_request(method='UNSUBSCRIBE', url=url, headers={'SID': sid}) return self._resubscribe(url) timeout = int(response.headers.get('timeout', '1801').replace( 'Second-', '')) sid = response.headers.get('sid', sid) gevent.spawn_later(int(timeout * 0.75), self._resubscribe, url, sid)
def mainloop(): #source_matcher = matcher(source) random_port = randint(54300, 54499) env = Environment(bind="%s:%d"%(get_ip_address(), random_port), with_cache=False) @receiver(devicefound) def found(sender, **kwargs): all_targets = [] for target in triggers.values(): if isinstance(target, list): all_targets.extend(target) else: all_targets.append(target) for key in (triggers.keys() + all_targets): if matcher(key)(sender.name): print "Found device:", sender.name @receiver(statechange) def something_happened(sender, **kwargs): print "Something happened with %s"%sender for key in triggers.keys(): if matcher(key)(sender.name): state = 1 if kwargs.get('state') else 0 print "{} state is {state}".format(sender.name, state=state) if isinstance(triggers[key], list): for target in triggers[key]: set_target_state(target, state) else: set_target_state(triggers[key], state) #this will intentionally not stop after it finds a first match so that we can use common prefixes to form groups def set_target_state(name, state): print "!!! Set '%s' State = %s"%(name, state) for switch_name in env.list_switches(): if matcher(name)(switch_name): print "Found a switch matching name %s" % name switch = env.get_switch(switch_name) switch.set_state(state) if len(env.list_bridges()) > 0: bridge = env.get_bridge(env.list_bridges()[0]) for light_name in bridge.bridge_get_lights(): if matcher(name)(light_name): print "telling target (via bridge) to set state to %s"%state light = bridge.bridge_get_lights()[light_name] bridge.light_set_state(light, state=state, dim=254 if state==1 else None) try: print "Starting..." env.start() #env.upnp.server env.discover(2) sock = env.upnp.server._socket sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) print "\t... discovering nearby devices" env.discover(10) print "Entering main loop" env.wait() except (KeyboardInterrupt, SystemExit): print "Goodbye!" sys.exit(0)