def createDeviceObject(self, address, requestId, channel): """ Look up a device with a given address. """ self.getLogger().debug(f"Looking for device with address {address}") self.queue.put(Job( lambda: self._sendResponseEvent(channel, "kasa.Response", { "requestId":requestId, "data":Any("kasa.Device", self._createDeviceEvent(address, asyncio.run(Discover.discover_single(address)))), }) ))
def dev(request): """Device fixture. Provides a device (given --ip) or parametrized fixture for the supported devices. The initial update is called automatically before returning the device. """ file = request.param ip = request.config.getoption("--ip") if ip: d = asyncio.run(Discover.discover_single(ip)) asyncio.run(d.update()) if d.model in file: return d raise Exception("Unable to find type for %s" % ip) return get_device_for_file(file)
def cli(ctx, host, alias, target, debug, bulb, plug, strip): """A cli tool for controlling TP-Link smart home plugs.""" # noqa if debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) if ctx.invoked_subcommand == "discover": return if alias is not None and host is None: click.echo("Alias is given, using discovery to find host %s" % alias) host = find_host_from_alias(alias=alias, target=target) if host: click.echo(f"Found hostname is {host}") else: click.echo(f"No device with name {alias} found") return if host is None: click.echo("No host name given, trying discovery..") ctx.invoke(discover) return else: if not bulb and not plug and not strip: click.echo("No --strip nor --bulb nor --plug given, discovering..") dev = asyncio.run(Discover.discover_single(host)) elif bulb: dev = SmartBulb(host) elif plug: dev = SmartPlug(host) elif strip: dev = SmartStrip(host) else: click.echo( "Unable to detect type, use --strip or --bulb or --plug!") return ctx.obj = dev if ctx.invoked_subcommand is None: ctx.invoke(state)
def dev(request): """Device fixture. Provides a device (given --ip) or parametrized fixture for the supported devices. The initial update is called automatically before returning the device. """ file = request.param ip = request.config.getoption("--ip") if ip: d = asyncio.run(Discover.discover_single(ip)) asyncio.run(d.update()) if d.model in file: return d return def device_for_file(model): for d in STRIPS: if d in model: return SmartStrip for d in PLUGS: if d in model: return SmartPlug for d in BULBS: if d in model: return SmartBulb for d in DIMMERS: if d in model: return SmartDimmer raise Exception("Unable to find type for %s", model) with open(file) as f: sysinfo = json.load(f) model = basename(file) p = device_for_file(model)(host="123.123.123.123") p.protocol = FakeTransportProtocol(sysinfo) asyncio.run(p.update()) yield p
def dev(request): """Device fixture. Provides a device (given --ip) or parametrized fixture for the supported devices. The initial update is called automatically before returning the device. """ loop = asyncio.get_event_loop() file = request.param ip = request.config.getoption("--ip") if ip: d = loop.run_until_complete(Discover.discover_single(ip)) loop.run_until_complete(d.update()) print(d.model) if d.model in file: return d return def device_for_file(model): for d in STRIPS: if d in model: return SmartStrip for d in PLUGS: if d in model: return SmartPlug for d in BULBS: if d in model: return SmartBulb raise Exception("Unable to find type for %s", model) with open(file) as f: sysinfo = json.load(f) model = basename(file) params = {"host": "123.123.123.123", "cache_ttl": 0} p = device_for_file(model)(**params) p.protocol = FakeTransportProtocol(sysinfo) loop.run_until_complete(p.update()) yield p
async def main(discover_plugs=lambda: Discover.discover_single("192.168.0.11"), alarm=lambda s: print("ALARM", s), delay=True): # https://python-kasa.readthedocs.io/en/latest/smartplug.html # For some reason this doesn't work here, but works in the kasa cli program # devices_found = await Discover.discover(on_discovered=print_alias) # plugs_found = filter(lambda dev: dev.has_emeter, devices_found) log = logging.getLogger(__name__) try: plug_found = await discover_plugs() except SmartDeviceException as e: raise e # # if len(plugs_found == 0): # print("No plugs found") # exit(1) # # if len(plugs_found > 1): # print("More than one plug found") # exit(1) # # plug = plugs_found[0] plug = plug_found time_to_be_below_threshold = 60 # seconds time_in_range_now = False while True: if delay: time.sleep(1) time_in_range_then = time_in_range_now now = datetime.now() time_in_range_now = True # Elaborate check pending emeter_realtime = "<not set>" if time_in_range_now: if not time_in_range_then: power_currently_below_threshold = False power_threshold = 10 # Watts try: await plug.update() emeter_realtime = plug.emeter_realtime current_power = emeter_realtime.get("power") if current_power < power_threshold: if not power_currently_below_threshold: start_time_below_threshold = now power_currently_below_threshold = True seconds_below_threshold = ( now - start_time_below_threshold).total_seconds() if seconds_below_threshold > time_to_be_below_threshold: alarm(seconds_below_threshold) else: power_currently_below_threshold = False except SmartDeviceException as e: # For now we assume that network errors are transient. pass print(now, plug.alias, emeter_realtime)