Exemplo n.º 1
0
async def test_get_plug_by_index(dev: SmartStrip):
    assert dev.get_plug_by_index(0) == dev.plugs[0]

    with pytest.raises(SmartDeviceException):
        dev.get_plug_by_index(-1)

    with pytest.raises(SmartDeviceException):
        dev.get_plug_by_index(len(dev.plugs))
Exemplo n.º 2
0
def power_get(host, port, index):
    assert port is None
    index = int(index)
    strip = SmartStrip(host)
    asyncio.run(strip.update())
    assert (len(strip.children) >
            index), "Trying to access non-existant plug socket on strip"
    return strip.children[index].is_on
Exemplo n.º 3
0
    def try_connect(self):
        try:
            from kasa import SmartStrip

            self.strip = SmartStrip(self.plug_address)
            asyncio.run(self.strip.update())
            self.output_setup = True
        except Exception as e:
            self.logger.error(
                "Output was unable to be setup: {err}".format(err=e))
Exemplo n.º 4
0
 async def connect(self):
     try:
         self.strip = SmartStrip(self.address)
         await self.strip.update()
         return 0, f'Strip {self.strip.alias}: {self.strip.hw_info}'
     except Exception:
         return 1, str(traceback.print_exc())
Exemplo n.º 5
0
    async def kill(self, ctx):
        if not await self.isOnCooldown(ctx) and not await self.voteInEffect(ctx
                                                                            ):
            print('vote started...')
            self.start_vote = True
            dev = SmartStrip("192.168.0.165")
            await dev.update()
            await ctx.send(f'Kill vote started, type !y or !n in chat!')
            #vote delay
            await asyncio.sleep(self.vote_delay)
            print('vote ended...')
            #handle pass/fail and reset vote bool
            if (self.ycount > self.ncount):
                await ctx.send(f'Vote passed!')
                print(self.cooldown_end)
                self.cooldown_end = time.time() + self.kill_delay

                #reboot plug1
                await dev.children[0].turn_off()
                await asyncio.sleep(1)
                await dev.children[0].turn_on()

                print('on cooldown...')
                await self.kill_wait()
                print('off cooldown...')

            else:
                await ctx.send(f'Vote failed!')
            self.ycount = 0
            self.ncount = 0
            self.voter_list = []
            self.start_vote = False
            print('reset!')
class TpLinkHandlerSmartStrip(SmartDeviceException):
	def __init__(self, address):
		self.worker = ThreadedWorker()
		self.device = SmartStrip(address)

	def update(self):
		asyncio.run(self.device.update())

	def update_two(self):
		asyncio.create_task(self.device.update())

	def update_three(self):
		future = asyncio.run_coroutine_threadsafe(self.device.update(), self.worker.loop)
		result = future.result()

	def shutdown_btn(self, settings):
		if settings.get(["navButton", "deviceOne"]):
			asyncio.create_task(self.device.children[0].turn_off())
		if settings.get(["navButton", "deviceTwo"]):
			asyncio.create_task(self.device.children[1].turn_off())
		if settings.get(["navButton", "deviceThree"]):
			asyncio.create_task(self.device.children[2].turn_off())
		return "shutdown"

	def turnOn_btn(self, settings):
		if settings.get(["navButton", "deviceOne"]):
			asyncio.create_task(self.device.children[0].turn_on())
		if settings.get(["navButton", "deviceTwo"]):
			asyncio.create_task(self.device.children[1].turn_on())
		if settings.get(["navButton", "deviceThree"]):
			asyncio.create_task(self.device.children[2].turn_on())
		return "Turning on"

	def turn_on(self, plugNumber):
		asyncio.run(self.device.children[plugNumber].turn_on())

	def shutdown(self, plugNumber):
		asyncio.run(self.device.children[plugNumber].turn_off())

	def get_plug_information(self):
		return self.device.hw_info

	def __repr__(self):
		pass
Exemplo n.º 7
0
async def _power_set(host, port, index, value):
    """We embed the coroutines in an `async` function to minimise calls to `asyncio.run`"""
    assert port is None
    index = int(index)
    strip = SmartStrip(host)
    await strip.update()
    assert (len(strip.children) >
            index), "Trying to access non-existant plug socket on strip"
    if value is True:
        await strip.children[index].turn_on()
    elif value is False:
        await strip.children[index].turn_off()
Exemplo n.º 8
0
async def cli(ctx, host, alias, target, debug, bulb, plug, lightstrip, strip,
              klap, user, password):
    """A tool for controlling TP-Link smart home devices."""  # 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(f"Alias is given, using discovery to find host {alias}")
        host = await 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 password != "" and user == "":
        click.echo("Using a password requires a username")
        return

    if klap or user != "":
        authentication = Auth(user=user, password=password)
    else:
        authentication = None

    if host is None:
        click.echo("No host name given, trying discovery..")
        await ctx.invoke(discover)
        return
    else:
        if not bulb and not plug and not strip and not lightstrip:
            click.echo("No --strip nor --bulb nor --plug given, discovering..")
            dev = await Discover.discover_single(host, authentication)
        elif bulb:
            dev = SmartBulb(host)
        elif plug:
            dev = SmartPlug(host, authentication)
        elif strip:
            dev = SmartStrip(host)
        elif lightstrip:
            dev = SmartLightStrip(host)
        else:
            click.echo(
                "Unable to detect type, use --strip or --bulb or --plug!")
            return
        ctx.obj = dev

    if ctx.invoked_subcommand is None:
        await ctx.invoke(state)
Exemplo n.º 9
0
 def start(self):
     LOGGER.debug(f'{self.pfx} start')
     self.dev = SmartStrip(self.host)
     super(SmartStripNode, self).start()
     self.update()
     self.check_st()
     LOGGER.info(f'{self.pfx} {self.dev.alias} has {len(self.dev.children)+1} children')
     for pnum in range(len(self.dev.children)):
         naddress = "{}{:02d}".format(self.address,pnum+1)
         nname    = self.dev.children[pnum].alias
         LOGGER.info(f"{self.pfx} adding plug num={pnum} address={naddress} name={nname}")
         self.nodes.append(self.controller.addNode(SmartStripPlugNode(self.controller, self, naddress, nname, self.dev.children[pnum])))
     self.ready = True
     LOGGER.debug(f'{self.pfx} done')
Exemplo n.º 10
0
    async def change_outlet_state(self, channel, state):
        from kasa import SmartStrip

        self.strip = SmartStrip(self.plug_address)
        await self.strip.update()
        if state:
            msg = await self.strip.children[channel].turn_on()
            self.output_states[channel] = True
        else:
            msg = await self.strip.children[channel].turn_off()
            self.output_states[channel] = False
        await self.strip.update()

        return msg
Exemplo n.º 11
0
    async def try_connect(self):
        from kasa import SmartStrip

        lf = LockFile()
        if lf.lock_acquire(self.lock_file, timeout=self.lock_timeout):
            try:
                self.strip = SmartStrip(self.plug_address)
                await self.strip.update()
                self.logger.debug(
                    f'Strip {self.strip.alias}: {self.strip.hw_info}')
                self.output_setup = True
            except Exception as err:
                self.logger.error(f"Output was unable to be setup: {err}")
            finally:
                time.sleep(self.switch_wait)
                lf.lock_release(self.lock_file)
Exemplo n.º 12
0
  def _load_hardware(self):
    # Input format should be either:
    # - [IP],[POWER_SWITCH_NR]

    # Use an internal caching for speeding things up.
    self.__state_cache = terrariumCache()
    self._async = terrariumAsync()

    address = self._address
    if len(address) == 1:
      self._device['device'] = SmartPlug(address[0])
      self._device['switch'] = 0
    else:
      self._device['device'] = SmartStrip(address[0])
      self._device['switch'] = int(address[1])-1

    return self._device['device']
Exemplo n.º 13
0
    async def connect(self):
        self.logger.debug("try_connect")
        from kasa import SmartStrip

        try:
            self.strip = SmartStrip(self.plug_address)
            await self.strip.update()
            self.logger.debug(
                f'Connected to {self.strip.alias}: {self.strip.hw_info}')
            self.output_setup = True
            self.failed_connect_count = 0
        except Exception as err:
            self.logger.error(f"Output was unable to be setup: {err}")
            self.failed_connect_count += 1
            wait_timer = time.time()
            if self.failed_connect_count > 19:
                if self.failed_connect_count == 20:
                    self.logger.error(
                        "Failed to connect 20 times. Increasing reconnect attempt interval to 300 seconds."
                    )
                while wait_timer > time.time() - 300 and self.running:
                    time.sleep(1)
            elif self.failed_connect_count > 4:
                if self.failed_connect_count == 5:
                    self.logger.error(
                        "Failed to connect 5 times. Increasing reconnect attempt interval to 60 seconds."
                    )
                while wait_timer > time.time() - 60 and self.running:
                    time.sleep(1)
            else:
                self.logger.error("Failed to connect. Retrying in 5 seconds.")
                while wait_timer > time.time() - 5 and self.running:
                    time.sleep(1)

        if self.first_connect and self.output_setup:
            self.first_connect = False
            for channel in channels_dict:
                if channel not in self.output_states:
                    self.output_states[channel] = None
                if self.options_channels['state_startup'][channel] == 1:
                    await self.strip.children[channel].turn_on()
                elif self.options_channels['state_startup'][channel] == 0:
                    await self.strip.children[channel].turn_off()
                self.logger.debug(
                    f'Strip children: {self.strip.children[channel]}')
Exemplo n.º 14
0
async 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(f"Alias is given, using discovery to find host {alias}")
        host = await 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..")
        await 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 = await 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:
        await ctx.invoke(state)
Exemplo n.º 15
0
    async def get_status(self):
        from kasa import SmartStrip

        lf = LockFile()
        if lf.lock_acquire(self.lock_file, timeout=self.lock_timeout):
            try:
                self.strip = SmartStrip(self.plug_address)
                await self.strip.update()
                for channel in channels_dict:
                    if self.strip.children[channel].is_on:
                        self.output_states[channel] = True
                    else:
                        self.output_states[channel] = False
            except Exception as err:
                self.logger.error(
                    f"get_status() raised an exception when taking a reading: {err}"
                )
                return 'error', err
            finally:
                time.sleep(self.switch_wait)
                lf.lock_release(self.lock_file)
Exemplo n.º 16
0
 def load_hardware(self):
     address = self.__get_address()
     if len(address) == 2:
         self._device = SmartStrip(address[0])
     else:
         self._device = SmartPlug(address[0])
Exemplo n.º 17
0
class OutputModule(AbstractOutput):
    """An output support class that operates an output."""
    def __init__(self, output, testing=False):
        super().__init__(output, testing=testing, name=__name__)

        self.strip = None
        self.outlet_switching = False
        self.status_thread = None
        self.outlet_status_checking = False
        self.timer_status_check = time.time()
        self.first_connect = True

        self.plug_address = None
        self.status_update_period = None

        self.setup_custom_options(OUTPUT_INFORMATION['custom_options'], output)

        output_channels = db_retrieve_table_daemon(OutputChannel).filter(
            OutputChannel.output_id == self.output.unique_id).all()
        self.options_channels = self.setup_custom_channel_options_json(
            OUTPUT_INFORMATION['custom_channel_options'], output_channels)

    def initialize(self):
        self.setup_output_variables(OUTPUT_INFORMATION)

        if not self.plug_address:
            self.logger.error("Plug address must be set")
            return

        try:
            self.try_connect()

            self.status_thread = threading.Thread(target=self.status_update)
            self.status_thread.start()

            if self.output_setup:
                self.logger.debug('Strip setup: {}'.format(self.strip.hw_info))
                for channel in channels_dict:
                    if self.options_channels['state_startup'][channel] == 1:
                        self.output_switch("on", output_channel=channel)
                    elif self.options_channels['state_startup'][channel] == 0:
                        self.output_switch("off", output_channel=channel)
                    self.logger.debug('Strip children: {}'.format(
                        self.strip.children[channel]))
        except Exception as e:
            self.logger.error("initialize() Error: {err}".format(err=e))

    def try_connect(self):
        try:
            from kasa import SmartStrip

            self.strip = SmartStrip(self.plug_address)
            asyncio.run(self.strip.update())
            self.output_setup = True
        except Exception as e:
            if self.first_connect:
                self.first_connect = False
                self.logger.error(
                    "Output was unable to be setup: {err}".format(err=e))
            else:
                self.logger.debug(
                    "Output was unable to be setup: {err}".format(err=e))

    def output_switch(self,
                      state,
                      output_type=None,
                      amount=None,
                      output_channel=None):
        if not self.is_setup():
            msg = "Error 101: Device not set up. See https://kizniche.github.io/Mycodo/Error-Codes#error-101 for more info."
            self.logger.error(msg)
            return msg

        while self.outlet_status_checking and self.running:
            time.sleep(0.1)

        try:
            self.outlet_switching = True
            if state == 'on':
                asyncio.run(self.strip.children[output_channel].turn_on())
                self.output_states[output_channel] = True
            elif state == 'off':
                asyncio.run(self.strip.children[output_channel].turn_off())
                self.output_states[output_channel] = False
            msg = 'success'
        except Exception as e:
            msg = "State change error: {}".format(e)
            self.logger.error(msg)
            self.output_setup = False
        finally:
            self.outlet_switching = False
        return msg

    def is_on(self, output_channel=None):
        if self.is_setup():
            if output_channel is not None and output_channel in self.output_states:
                return self.output_states[output_channel]
            else:
                return self.output_states

    def is_setup(self):
        return self.output_setup

    def stop_output(self):
        """Called when Output is stopped."""
        if self.is_setup():
            for channel in channels_dict:
                if self.options_channels['state_shutdown'][channel] == 1:
                    self.output_switch('on', output_channel=channel)
                elif self.options_channels['state_shutdown'][channel] == 0:
                    self.output_switch('off', output_channel=channel)
        self.running = False

    def status_update(self):
        while self.running:
            if self.timer_status_check < time.time():

                while self.timer_status_check < time.time():
                    self.timer_status_check += self.status_update_period

                while self.outlet_switching and self.running:
                    time.sleep(0.1)
                self.outlet_status_checking = True
                self.logger.debug("Checking state of outlets")

                if not self.output_setup:
                    self.try_connect()
                    if not self.output_setup:
                        self.logger.debug("Could not connect to power strip")

                try:
                    if self.output_setup:
                        asyncio.run(self.strip.update())
                        for channel in channels_dict:
                            if self.strip.children[channel].is_on:
                                self.output_states[channel] = True
                            else:
                                self.output_states[channel] = False
                except Exception as e:
                    self.logger.debug(
                        "Could not query power strip status: {}".format(e))
                    self.output_setup = False
                finally:
                    self.outlet_status_checking = False

            time.sleep(1)
	def __init__(self, address):
		self.worker = ThreadedWorker()
		self.device = SmartStrip(address)
Exemplo n.º 19
0
async def test_get_plug_by_name(dev: SmartStrip):
    name = dev.plugs[0].alias
    assert dev.get_plug_by_name(name) == dev.plugs[0]

    with pytest.raises(SmartDeviceException):
        dev.get_plug_by_name("NONEXISTING NAME")
Exemplo n.º 20
0
    if bulb:
        asyncio.run(bulb.update())
        asyncio.run(bulb.set_brightness(30))


def bulb_brightness_100():
    if bulb:
        asyncio.run(bulb.update())
        asyncio.run(bulb.set_brightness(100))


### TPLINK KASA HS300
### Change the ip addresss accordingly

print('LOADING SMART-STRIP <--- HS300')
strip = SmartStrip("192.168.1.22")


# Plug1
def on_plug_0():
    strip.turn_on(index=0)


def off_plug_0():
    strip.turn_off(index=0)


# Plug2
def on_plug_1():
    strip.turn_on(index=1)
Exemplo n.º 21
0
import asyncio
import logging

from time import sleep
from kasa import SmartStrip

LOG = logging.getLogger(__name__)

STRIPS = [SmartStrip("192.168.0.123"), SmartStrip("192.168.0.194")]


def reboot_plug(plug):
    LOG.info("rebooting plug %s", plug.alias)
    asyncio.run(plug.turn_off())
    sleep(3)
    asyncio.run(plug.turn_on())


def find_plug(plug_name):
    return_value = None
    for strip in STRIPS:
        asyncio.run(strip.update())
        for plug in strip.children:
            if plug_name in plug.alias:
                return_value = plug
    return return_value