Skip to content

Instantly share code, notes, and snippets.

@webartoli
Last active December 20, 2021 20:38
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save webartoli/7247008c2f3ab31e20e7ca5b70328a46 to your computer and use it in GitHub Desktop.
Save webartoli/7247008c2f3ab31e20e7ca5b70328a46 to your computer and use it in GitHub Desktop.
Home assistant - appdeamon - deconz - IKEA tradfri remote control

Home Assistant - Reuse dimming logic using AppDaemon

I have a multiple IKEA tradfri remotes attached to deconz and I want write once the logic to dim lights.

After some searches I discover the AppDaemon solution and this is the results of my draft works.

Install

I have installed the plugin provided by community addons

How it works

Basically this component exposes some properties to the caller: in apps.yaml there is the wiring between the appdaemon app and entities

In this case we have 2 apps attached to the same devices:

  • the 1st control brightness with UP and DOWN buttons
  • the 2nd control color temperature with LEFT and RIGT buttons
---
remote_corridoio_brightness:
module: tradfri
class: TradfriRemoteDimmer
target:
light: light.faretto_4
remote: tradfri_remote_control_
dimmer:
attribute: brightness
step: 15
down:
button: DOWN
limit: 0
up:
button: UP
limit: 255
remote_corridoio_temp:
module: tradfri
class: TradfriRemoteDimmer
target:
light: light.faretto_4
remote: tradfri_remote_control_
dimmer:
attribute: color_temp
step: 15
down:
button: LEFT
limit: 175
up:
button: RIGHT
limit: 333
from typing import Callable
class Dimmer(object):
def __init__(self, min: int, max: int, step: int, get_value: Callable[[], int], set_value: Callable[[int], None]):
self.__min = min
self.__max = max
self.__step = step
self.__get_value = get_value
self.__set_value = set_value
def up(self):
self.__is_dimming = True
value = self.__get_value()
limit = self.__max
update = lambda x: x + self.__step
hasExceeded = lambda x: x >= limit
self.__dim(value, limit, update, hasExceeded)
def down(self):
self.__is_dimming = True
value = self.__get_value()
limit = self.__min
update = lambda x: x - self.__step
hasExceeded = lambda x: x <= limit
self.__dim(value, limit, update, hasExceeded)
def stop(self):
self.__is_dimming = False
def __dim(self, value, limit, update, hasExceeded):
if self.__is_dimming == False:
return
newVal = update(value)
if hasExceeded(newVal):
self.__set_value(limit)
self.stop()
else:
self.__set_value(newVal)
self.__dim(newVal, limit, update, hasExceeded)
import appdaemon.plugins.hass.hassapi as hass
from dimmer import Dimmer
from tradfri_remote import TradfriRemoteButtons
class TradfriRemoteDimmer(hass.Hass):
def initialize(self):
self.target_light = self.args['target']['light']
self.target_remote = self.args['target']['remote']
self.dim_attribute = self.args['dimmer']['attribute']
self.button = TradfriRemoteButtons()
self.dimmer = Dimmer(
self.args['dimmer']['down']['limit'],
self.args['dimmer']['up']['limit'],
self.args['dimmer']['step'],
self.get,
self.set
)
self.log(f"Initialized [{self.dim_attribute}] dimming to IKEA tradfri remote control [{self.target_remote}] on target lights [{self.target_light}]")
self.listen_event(self.deconz_event, "deconz_event", id = self.target_remote)
def deconz_event(self, event_name, data, kwargs):
self.button.long_press_handle(data['event'], self.args['dimmer']['up']['button'], self.dimmer.up, self.dimmer.stop)
self.button.long_press_handle(data['event'], self.args['dimmer']['down']['button'], self.dimmer.down, self.dimmer.stop)
def get(self):
return self.get_state(self.target_light, attribute = self.dim_attribute)
def set(self, value):
self.turn_on(self.target_light, **{self.dim_attribute: value})
class TradfriRemoteButtons(object):
def __init__(self):
self.buttons = {'MID':1, 'UP':2, 'DOWN':3, 'LEFT':4, 'RIGHT':5}
self.release_mode = {'HOLD':1, 'CLICK':2, 'RELEASE':3}
def get_code(self, button, release):
return int(f"{self.buttons[button]}00{self.release_mode[release]}")
def is_code(self, code, button, release):
return code == self.get_code(button, release)
def long_press_handle(self, code, button, hold, release):
if (self.is_code(code, button, 'HOLD')): return hold()
if (self.is_code(code, button, 'RELEASE')): return release()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment