Exemplo n.º 1
0
def discover_devices():

    devices = yield from Discover.discover()

    plugs = []

    for key, device in devices.items():

        try:
            if not has_resource(device.alias):
                if isinstance(device, SmartStrip):
                    for strip_child in device.children:
                        try:
                            plug = KasaPlug(strip_child.alias,
                                            device_name=strip_child.alias,
                                            device=strip_child,
                                            parent=device)
                            plugs.append(plug)
                        except ResourceNameAlreadyTaken:
                            pass

                else:
                    try:
                        plugs.append(
                            KasaPlug(device.alias,
                                     device_name=device.alias,
                                     device=device))
                    except ResourceNameAlreadyTaken:
                        pass
        except SmartDeviceException:
            print("SmartDeviceException with {}".format(
                device.host))
            continue

    return plugs
Exemplo n.º 2
0
def get_kasa_plug(alias):
    devices = Discover.discover()

    for key, device in devices.items():

        if device.alias == alias:
            return device
Exemplo n.º 3
0
 def discover_bulbs(self, bulb_one_name, bulb_two_name):
     bulbs = []
     found_devices = asyncio.run(Discover.discover())
     ip_addresses = [item for item in found_devices]
     for count, device in enumerate(found_devices.values()):
         if device.is_bulb:
             bulbs.append(ip_addresses[count])
     return bulbs
Exemplo n.º 4
0
def setup_device_info():
    devices = asyncio.run(Discover.discover())
    for addr, dev in devices.items():
        asyncio.run(dev.update())
        if dev.alias == device_name:
            print("Found device")
            f = open("device-ip.txt", "a")
            f.write(addr)
            f.close()
Exemplo n.º 5
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)))),
			})
		))
def discoverPlug():
    print("trying to discover plug")
    d = asyncio.run(Discover.discover())

    if len(d) != 0:
        for addr, dev in d.items():
            asyncio.run(dev.update())
            if dev.is_plug:
                return dev
    print("couldn't find the plug")
    return None
Exemplo n.º 7
0
def get_switch(switch_name: str):
    found_devices = asyncio.run(Discover.discover())
    device = [
        dev for addr, dev in found_devices.items() if dev.alias == switch_name
    ]
    if len(device) != 1:
        if switch_name not in [s['alias'] for s in SWITCHES]:
            raise ValueError("Invalid Name")
        s = [s for s in SWITCHES if s['alias'] == switch_name][0]
        switch = SmartPlug(s['ip'])
        asyncio.run(switch.update())
        return switch
    return device[0]
Exemplo n.º 8
0
def rediscover():
    devices = asyncio.run(Discover.discover())

    formattedDevices = {'devices': []}

    for addr, dev in devices.items():
        asyncio.run(dev.update())

        formattedDevices['devices'].append({
            'name': dev.alias,
            # 'host': dev.host,
            'address': addr,
            'state': dev.is_on,
            'sysinfo': dev.sys_info
        })
Exemplo n.º 9
0
def find_host_from_alias(alias,
                         target="255.255.255.255",
                         timeout=1,
                         attempts=3):
    """Discover a device identified by its alias."""
    host = None
    click.echo("Trying to discover %s using %s attempts of %s seconds" %
               (alias, attempts, timeout))
    for attempt in range(1, attempts):
        click.echo(f"Attempt {attempt} of {attempts}")
        found_devs = Discover.discover(target=target, timeout=timeout).items()
        for ip, dev in found_devs:
            if dev.alias.lower() == alias.lower():
                host = dev.host
                return host
    return None
Exemplo n.º 10
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)
Exemplo n.º 11
0
def discover(detectedLights):
    logging.debug('Kasa discovery started')
    devices: dict = asyncio.run(Discover.discover(target="192.168.0.255"))

    for device in list(devices.keys()):
        x: KL430LightStrip = devices[device]
        asyncio.run(x.update())

        if x.model.startswith("KL430"):
            ip = device
            name = x.alias
            for x in range(1, 4):
                lightName = name
                protocol_cfg = {"ip": ip, "id": name, "light_nr": x, "model": "KL430", }
                protocol_cfg["points_capable"] = 7
                detectedLights.append({"protocol": "tpkasa", "name": lightName, "modelid": "LCX002",
                                       "protocol_cfg": protocol_cfg})
Exemplo n.º 12
0
def discover(ctx, timeout, discover_only, dump_raw):
    """Discover devices in the network."""
    target = ctx.parent.params["target"]
    click.echo("Discovering devices for %s seconds" % timeout)
    found_devs = asyncio.run(
        Discover.discover(target=target, timeout=timeout, return_raw=dump_raw))
    if not discover_only:
        for ip, dev in found_devs.items():
            asyncio.run(dev.update())
            if dump_raw:
                click.echo(dev)
                continue
            ctx.obj = dev
            ctx.invoke(state)
            print()

    return found_devs
Exemplo n.º 13
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)
Exemplo n.º 14
0
def create_device_from_ip_or_scan(ip, device_name):
    """Tries to create a kasa SmartDevice object either from a given IP address
    or by scanning the network."""
    device = None
    if ip:
        try:
            device = SmartPlug(ip)
            asyncio.run(device.update())
        except exceptions.SmartDeviceException:
            print(
                "Unable to connect to device at provided IP. Attempting scan.")

    # If unable to create device from ip, or ip is not given, scan the network.
    if not device:
        devices = asyncio.run(Discover.discover())
        for _, dev in devices.items():
            if dev.alias == device_name:
                asyncio.run(dev.update())
                device = dev

    return device
Exemplo n.º 15
0
    def __init__(self, channels, logger=None):
        """ Initializes connection to all TP Kasa smart plugs in the network.

        :channels: list of channels accessaable via this smart plug interface
        """

        # Instantiate log.
        self.log = LogHandler(logger=logger)

        self.channels = channels

        # Discover smart plugs.
        self.found_devices = asyncio.run(Discover.discover())

        # Store aliases of found devices.
        self.found_device_aliases = [
            dev.alias for dev in self.found_devices.values()
        ]

        self.log.info(
            f"Discovered {len(self.found_device_aliases)} smart plugs.")
Exemplo n.º 16
0
 def discover(self):
     LOGGER.info(
         f"start: {self.poly.network_interface['broadcast']} timout=10 discovery_packets=10"
     )
     self.devm = {}
     devices = asyncio.run(
         Discover.discover(timeout=10,
                           discovery_packets=10,
                           target=self.poly.network_interface['broadcast'],
                           on_discovered=self.discover_add_device))
     # make sure all we know about are added in case they didn't respond this time.
     for mac in self.polyConfig['customParams']:
         if not self.smac(mac) in self.devm:
             cfg = self.get_device_cfg(mac)
             if cfg is not None:
                 LOGGER.warning(
                     f"Adding previously known device that didn't respond to discover: {cfg}"
                 )
                 self.add_node(cfg=cfg)
     self.discover_done = True
     LOGGER.info("done")
Exemplo n.º 17
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
Exemplo n.º 18
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
Exemplo n.º 19
0
def dump_discover(ctx, scrub):
    """Dump discovery information.

    Useful for dumping into a file to be added to the test suite.
    """
    target = ctx.parent.params["target"]
    keys_to_scrub = [
        "deviceId",
        "fwId",
        "hwId",
        "oemId",
        "mac",
        "latitude_i",
        "longitude_i",
        "latitude",
        "longitude",
    ]
    devs = asyncio.run(Discover.discover(target=target, return_raw=True))
    if scrub:
        click.echo("Scrubbing personal data before writing")
    for dev in devs.values():
        if scrub:
            for key in keys_to_scrub:
                if key in dev["system"]["get_sysinfo"]:
                    val = dev["system"]["get_sysinfo"][key]
                    if key in ["latitude_i", "longitude_i"]:
                        val = 0
                    else:
                        val = re.sub("\w", "0", val)
                    dev["system"]["get_sysinfo"][key] = val

        model = dev["system"]["get_sysinfo"]["model"]
        hw_version = dev["system"]["get_sysinfo"]["hw_ver"]
        save_to = f"{model}_{hw_version}.json"
        click.echo("Saving info to %s" % save_to)
        with open(save_to, "w") as f:
            json.dump(dev, f, sort_keys=True, indent=4)
            f.write("\n")
Exemplo n.º 20
0
 def discover(self):
     devices = asyncio.run(Discover.discover())
     for addr,dev in devices.items():
         asyncio.run(dev.update())
         devices.update({addr:dev})
     devices = self.sortdevices(devices)
     for addr, dev in devices.items():
         if dev.is_plug:
             asyncio.run(dev.update())
             notexisting = False
             if not self.plugs.get(addr,False):
                 notexisting = True
             plug = self.plugs.get(addr,SmartPlug(addr))
             is_on = False
             powerupdate = False
             if not notexisting:
                 is_on = plug.is_on
                 if plug.model.startswith("HS110"):
                     powerupdate = True
             asyncio.run(plug.update())
             if notexisting or powerupdate or is_on != plug.is_on:
                 self.updateview.append(addr)
             self.plugs.update({addr:plug})
Exemplo n.º 21
0
async def test_type_detection_plug(dev: SmartDevice):
    d = Discover._get_device_class(dev.protocol.discovery_data)("localhost")
    assert d.is_plug
    assert d.device_type == DeviceType.Plug
Exemplo n.º 22
0
 def discover(self):
     self.bulbs = [
         dev for dev in asyncio.run(Discover.discover()).values()
         if dev.is_bulb
     ]
Exemplo n.º 23
0
from flask import Flask, render_template, redirect, request
from kasa import SmartPlug, Discover
import asyncio

app = Flask(__name__)

devices = asyncio.run(Discover.discover())


def rediscover():
    devices = asyncio.run(Discover.discover())

    formattedDevices = {'devices': []}

    for addr, dev in devices.items():
        asyncio.run(dev.update())

        formattedDevices['devices'].append({
            'name': dev.alias,
            # 'host': dev.host,
            'address': addr,
            'state': dev.is_on,
            'sysinfo': dev.sys_info
        })


def get_device_by_name(deviceName):
    for addr, dev in devices.items():
        if dev.alias.lower() == deviceName.lower():
            asyncio.run(dev.update())
            return dev
Exemplo n.º 24
0
def get_all_switches():
    found_devices = asyncio.run(Discover.discover())
    devices = [dev for addr, dev in found_devices.items()]
    return devices
Exemplo n.º 25
0
async def test_type_detection_bulb(dev: SmartDevice):
    d = Discover._get_device_class(dev._last_update)("localhost")
    # TODO: light_strip is a special case for now to force bulb tests on it
    if not d.is_light_strip:
        assert d.is_bulb
        assert d.device_type == DeviceType.Bulb
Exemplo n.º 26
0
 def discover_new(self):
     LOGGER.info('start')
     devices = asyncio.run(
         Discover.discover(target=self.poly.network_interface['broadcast'],
                           on_discovered=self.discover_new_add_device))
     LOGGER.info("done")
Exemplo n.º 27
0
	def discoverDevices(self, requestId, channel):
		"""
			Discover all devices on the network and send a Response event containing all of the devices.
		"""
		self.getLogger().debug(f"Discovering devices")
		self.queue.put(Job(
			lambda: self._sendResponseEvent(channel, "kasa.Response", {
				"requestId":requestId,
				"data":Any("sequence<kasa.Device>", [self._createDeviceEvent(addr, dev) for addr, dev in asyncio.run(Discover.discover()).items()]),
			})
		))
Exemplo n.º 28
0
async def test_type_unknown():
    invalid_info = {"system": {"get_sysinfo": {"type": "nosuchtype"}}}
    with pytest.raises(SmartDeviceException):
        Discover._get_device_class(invalid_info)
Exemplo n.º 29
0
async def test_type_detection_lightstrip(dev: SmartDevice):
    d = Discover._get_device_class(dev._last_update)("localhost")
    assert d.is_light_strip
    assert d.device_type == DeviceType.LightStrip
Exemplo n.º 30
0
async def test_type_detection_dimmer(dev: SmartDevice):
    d = Discover._get_device_class(dev._last_update)("localhost")
    assert d.is_dimmer
    assert d.device_type == DeviceType.Dimmer