Esempio n. 1
0
	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)))),
			})
		))
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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
Esempio n. 5
0
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
Esempio n. 6
0
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)