I tried to get all my 3 IKEA Bilresa to work in only one pyscript file. All 3 have similar setup in different rooms. This works for me. Sorry for swedish annotiatons.
Room 1,2 and 3. 3 different Bilresa one for each room. Mode 1 (left LED), mode 2 (middle LED), mode 3 (right LED) (say room 2,3,4 in code)
Mode 1: Ceiling lamp - on/ff (klick), Dimmable light (scroll left/right). TAK
Mode 2: Window light (if plug klick on/off) (if dimmable klick on/off and scroll left/right for dimmer). FONSTER
Mode 3: Rollerblind motor aqara (aqara - klick up/down, scroll left or right to move blinds partly up/down. COVER
# ========= TRIGGER =========
@state_trigger(
# TAK
"event.bilresa_scroll_wheel_knapp_1_2",
"event.bilresa_scroll_wheel_knapp_2_2",
"event.bilresa_scroll_wheel_knapp_3_2",
"event.bilresa_scroll_wheel_knapp_1_3",
"event.bilresa_scroll_wheel_knapp_2_3",
"event.bilresa_scroll_wheel_knapp_3_3",
"event.bilresa_scroll_wheel_knapp_1_4",
"event.bilresa_scroll_wheel_knapp_2_4",
"event.bilresa_scroll_wheel_knapp_3_4",
# FÖNSTER
"event.bilresa_scroll_wheel_knapp_4_2",
"event.bilresa_scroll_wheel_knapp_5_2",
"event.bilresa_scroll_wheel_knapp_6_2",
"event.bilresa_scroll_wheel_knapp_4_3",
"event.bilresa_scroll_wheel_knapp_5_3",
"event.bilresa_scroll_wheel_knapp_6_3",
"event.bilresa_scroll_wheel_knapp_4_4",
"event.bilresa_scroll_wheel_knapp_5_4",
"event.bilresa_scroll_wheel_knapp_6_4",
# GARDIN
"event.bilresa_scroll_wheel_knapp_7_2",
"event.bilresa_scroll_wheel_knapp_8_2",
"event.bilresa_scroll_wheel_knapp_9_2",
"event.bilresa_scroll_wheel_knapp_7_3",
"event.bilresa_scroll_wheel_knapp_8_3",
"event.bilresa_scroll_wheel_knapp_9_3",
"event.bilresa_scroll_wheel_knapp_7_4",
"event.bilresa_scroll_wheel_knapp_8_4",
"event.bilresa_scroll_wheel_knapp_9_4",
)
def handle_all(var_name=None, value=None, old=None):
# SPÄRR 1: Avbryt omedelbart om tillståndet blir tomt eller okänt
if not value or value in ["unknown", "unavailable"]:
return
# ========= ATTRIBUT =========
attrs = state.getattr(var_name)
if not attrs:
return
event_type = attrs.get("event_type")
if not event_type:
return
# SPÄRR 2: Lyssna bara på giltiga knapphändelser
if event_type not in ["InitialPress", "multi_press_1", "multi_press_2", "multi_press_3", "multi_press_4", "multi_press_5", "multi_press_6", "multi_press_7"]:
return
# SPÄRR 3: KONTROLLERA ATT HÄNDELSEN ÄR FÄRSK (Stoppar alla nätverksdippar)
try:
from datetime import datetime
tids_strang = value.split("+")[0]
handelse_tid = datetime.fromisoformat(tids_strang)
sekunder_sedan = (datetime.utcnow() - handelse_tid).total_seconds()
if sekunder_sedan > 5.0:
log.info(f"Bilresa Spärr: Blockerade gammal nätverkssignal för {var_name} ({sekunder_sedan}s gammal)")
return
except Exception as e:
pass
# ========= PARSA =========
parts = var_name.split("_")
knapp = parts[-2]
rum = parts[-1]
log.info(f"Bilresa: rum={rum} knapp={knapp} event={event_type}")
# ========= MULTIPRESS =========
count = 1
if event_type.startswith("multi_press_"):
try:
count = int(event_type.split("_")[-1])
except:
count = 1
step = max(5, 5 * count)
# ========= ENHETER PER RUM =========
if rum == "2": # DISAS RUM
TAK = "light.e27_1"
FONSTER = None
COVER = "cover.rullgardin_01"
elif rum == "3": # TILLAS RUM
TAK = "light.e27_2"
FONSTER = "switch.grillplats_plug"
COVER = "cover.rullgardin_03"
elif rum == "4": # LOS RUM
TAK = "light.e27_6"
FONSTER = "light.e14_2"
COVER = "cover.rullgardin_02"
else:
return
# ========= TAKLAMPA LOGIK =========
if knapp == "1":
light.turn_on(entity_id=TAK, brightness_step_pct=step, transition=0.1)
elif knapp == "2":
light.turn_on(entity_id=TAK, brightness_step_pct=-step, transition=0.1)
elif knapp == "3":
if state.get(TAK) == "on": light.turn_off(entity_id=TAK)
else: light.turn_on(entity_id=TAK)
# ========= FÖNSTERLAMPA LOGIK =========
elif knapp == "4":
if not FONSTER: return
if FONSTER.startswith("switch"):
switch.turn_on(entity_id=FONSTER)
else:
if event_type == "InitialPress":
light.turn_on(entity_id=FONSTER)
else:
light.turn_on(entity_id=FONSTER, brightness_step_pct=step, transition=0.1)
elif knapp == "5":
if not FONSTER: return
if FONSTER.startswith("switch"):
switch.turn_off(entity_id=FONSTER)
else:
if event_type == "InitialPress":
light.turn_off(entity_id=FONSTER)
else:
light.turn_on(entity_id=FONSTER, brightness_step_pct=-step, transition=0.1)
elif knapp == "6":
if not FONSTER: return
if FONSTER.startswith("switch"): switch.toggle(entity_id=FONSTER)
else:
if state.get(FONSTER) == "on": light.turn_off(entity_id=FONSTER)
else: light.turn_on(entity_id=FONSTER)
# ========= RULLGARDIN LOGIK =========
elif knapp in ["7", "8", "9"]:
if not COVER: return
current_state = state.get(COVER)
cover_attrs = state.getattr(COVER)
pos = cover_attrs.get("current_position", 0) if cover_attrs else 0
if knapp == "7":
if event_type == "InitialPress": cover.open_cover(entity_id=COVER)
else:
new_pos = min(100, pos + step)
cover.set_cover_position(entity_id=COVER, position=new_pos)
elif knapp == "8":
if event_type == "InitialPress": cover.close_cover(entity_id=COVER)
else:
new_pos = max(0, pos - step)
cover.set_cover_position(entity_id=COVER, position=new_pos)
elif knapp == "9":
if current_state == "closed" or pos == 0: cover.open_cover(entity_id=COVER)
else: cover.close_cover(entity_id=COVER)