Set dimmer brightness without on/off or call integration's Python method directly

I have a TP-Link HS220 Dimmer switch, which is exposed in HA as a Light entity. The python-kasa library has the ability to set the brightness of the dimmer without changing its off/on state, which is useful for setting the brightness for late-night use.

Via the CLI for python-kasa, this is possible by calling kasa --host <ip of device> --type dimmer brightness <brightness value>. Is there a way to do this via Home Assistant? Any automation to change the brightness seems to require a turn_on event, and though the library supports changing the brightness (see here: https://github.com/python-kasa/python-kasa/blob/e3d76bea7557616a7a9e8f967368ce1d9009db5a/kasa/smartdimmer.py#L58), I can’t seem to find a way to do it in HA.

Alternatively, is it possible to call the Python API of the integration for this device directly, or is there no access to the device other than the API exposed by a Light entity?

Thanks!

Hey jedcred, I have been working on this problem recently and have made some progress. At the moment, I have approached this using the python-kasa API and Python method. I’m a bit new to development work in this community, so I’m splitting the solution into two parts:

  • Ensure that the Python script is working as intended and suites the overall problem
  • Create a Home Assistant service that populates and executes the script

I have written the script below which has worked well so far.

import asyncio
from kasa import SmartDimmer

# Establish the connection to the device(s)
kitchen_lights = SmartDimmer("192.168.86.64")
bathroom_lights = SmartDimmer("192.168.86.65")


# Sets the brightness of the selected device
async def set_brightness(device, brightness: int):
    await device.update()
    await device.set_brightness(brightness)
    await device.update()
    print(f"The brightness of {device.alias} is now {device.brightness}")


# Changes the brightness of however many devices are listed in the parameter below
async def change_brightness(devices, brightness: int):
    for dev in devices:
        await set_brightness(dev, brightness)
    # If the brightness change is wanted simultaneously instead of sequentially
    # await asyncio.gather(*[asyncio.create_task(set_brightness(dev, brightness)) for dev in devices])

# This launches only a single event loop, in this case, both my lights are set to a brightness level of 60
asyncio.run(change_brightness([kitchen_lights, bathroom_lights], 60))

My next step is to connect this to Home Assistant which has been a bit challenging due to my newness with everything. Ideally, once I have created the Home Assistant service, I can begin to mold this as a universal script that can be officially added to the TP-Link Kasa integration.

1 Like

griffinburkhardt and jedcred,

I have been working on this too. I have used the example provided by griffinburkhardt and various places around the internet to produce a custom component that is working for me. A warning: I have no experience with python. This is literally the first python project I have ever worked on beyond one other basic find and replace script. Treat it as insecure poorly written garbage.

These files create a custom service that adjusts the hard-coded IP addresses to a specific brightness. I do not yet have the skill to read the entities without hard coding them.

These files need to be placed in the config/custom_components/offbright folder that you will create:

manifest.json

{
    "domain": "offbright",
    "name": "TP-Link OffBright Service",
    "documentation": "https://developers.home-assistant.io/docs/dev_101_services",
    "requirements": ["python-kasa==0.5.0"],
    "dependencies": ["tplink"],
    "codeowners": ["@xdraconis", "@griffinburkhardt"],
    "iot_class": "local_push",
    "version": "0.1.0"
}

__init__.py

import asyncio
from kasa import SmartDimmer

DOMAIN = "offbright"
DEVICES = ["192.168.10.128", "192.168.10.148"]

# Sets the brightness of the selected device
async def set_brightness(device, brightness: int):
    await device.update()
    await device.set_brightness(brightness)
    await device.update()
    
async def set_offbright(call):
    """Handle the service call."""
    brightness = call.data.get("brightness", 0)
    await asyncio.gather(*[asyncio.create_task(set_brightness(SmartDimmer(dev), brightness)) for dev in DEVICES])
    
def setup(hass, config):
    """Set up is called when Home Assistant is loading our component."""
    hass.services.register(DOMAIN, "offbright", set_offbright)

    # Return boolean to indicate that initialization was successful.
    return True

services.yaml

offbright:
  name: OffBright
  description: Sets the brightness without turning on the lights.
#  target:
#    entity:
#      integration: tplink
#      domain: light
  fields:
    brightness:
      description: The percent brightness to set the lights to (0-100%)
      example: 100
      default: 100
      required: true
      selector:
        number:
          min: 1
          step: 1
          max: 100
          unit_of_measurement: "%"

After you add the files, you need to restart and then add ths to your configuration.yaml, and then restart again.

offbright:

While there isn’t a way set the dimmer brightness directly in the Action of an Automation, all you have to do is create a Scene for one (or more) dimmers, setting the brightness to the level you desire for each of the dimmers, then just call that Scene from Automation Action. It’s really pretty simple.

As far as I am aware, it is still not possible to adjust the brightness without turning on the bulb using the kasa integration, even if you use scenes.

I am however happy to report that the integration I detailed above is still working perfectly for me. It is still happily automatically adjusting the lights by 5% every 15 minutes (using an automation that calls it), regardless of whether they are on or off and without needing to turn them on.