In het huis waarin we deze zomer zijn gaan wonen hangt een op afstand bestuurbaar gordijnen systeem. Dit systeem werkt goed en betrouwbaar middels de afstandsbediening die bij het systeem hoort. Het zijn rolgordijnen van Luxaflex welke de techniek van HunterDouglas gebruiken. Over de integratie van dit HunterDouglas systeem is wel wat te vinden op internet, maar er is geen verkrijgbaarheid van de hub. Daarnaast zou het maar de vraag zijn of mijn verouderde versie van het systeem überhaupt zou werken op de hub en of de hub dan weer werkt met Home Assistant. Toch wil ik de gordijnen met Home Assistant kunnen bedienen. Dat werd een uitdaging, maar het is gelukt!

Elimineren van losse afstandsbedieningen

In mijn eerdere artikel Mitsubishi Airco’s toevoegen aan Home Assistant was ik ook al bezig geweest met het verminderen van het gebruik van de losse afstandsbedieningen in ons huis. We hadden er dus één voor de airco, twee voor dit gordijnen systeem en één voor de somfy zonnewering (die is deze zomer aan de beurt!). Door het inbouwen van een ESP in de Mitshibisi Airco was ik al verlost van één afstandsbediening, nu zijn de twee van het Luxaflex systeem aan de beurt.

Hoe voeg je een ouderwetse afstandsbediening toe aan Home Assistant?

Met deze vraag begon mijn zoektocht naar een oplossing. De oplossing die ik als eerste had was het kopiëren van de infrarood codes van de afstandsbediening. Doordat je een infrarood code die de originele afstandsbediening stuurt aanleert aan Home Assistant, kun je via Home Assistant opnieuw het commando versturen. Ik bestelde een Tuya IR sender/receiver voor een paar euro. Het werkt helaas niet zoals verwacht.

Methode 1: aanleren van infrarood code

In de Tuya app kun je mooi de commando’s aanleren die de afstandsbediening stuurt. Door op de knop in de app te drukken kun je die commando’s opnieuw versturen.

Voorbeelden van met IR codes aangeleerde apparaten in Tuya SmartLife app

Helaas gebeurde er vervolgens niets met het gordijn. Na wat onderzoek bleek dat het protocol dat de afstandsbediening gebruikt niet een standaard protocol is en dat het gebruik maakt van ‘rolling codes’. In rolling codes veranderd er steeds een stukje code en is het een soort van beveiligd. Daarbij komt nog, had het wel gewerkt via de Tuya app, had het nog steeds niet gewerkt via Home Assistant, want de Tuya integratie geeft deze ‘apparaten’ door als ‘unsupported’. Ik moest dus een andere aanpak bedenken.

Methode 2: aanleren van de RF code

De afstandbediening heeft twee manieren om de gordijnen te bedienen. Via infrarood of via RF op 2.4Ghz. Via RF op 2.4Ghz werkt de besturing veel betrouwbaarder dan via IR. Het heeft dus zeker de voorkeur om de aansturing via RF te laten gaan. Na veel zoeken op forums en de rest van het internet kwam ik geen overtuigende resultaten tegen hoe ik dit RF signaal kan reproduceren via ESPHome.

Methode 3: Automatische druk op knop

Het derde idee was eigenlijk heel simpel. Ik hergebruik de afstandbediening en moet gewoon doen alsof er op de knop gedrukt wordt.

Ik heb de afstandsbediening opengemaakt, de binnenkant bekeken en een plan gemaakt.

De afstandsbediening in kwestie heeft 7 knoppen en werkt op twee AAA-batterijen, dus 3V. Onder de rubber knopjes zit een contactje wat hierop reageert. Ik heb wat van het zwarte materiaal weggekrab met een mesje en toen werd het koperbaantje zichtbaar. Door de aparte koperbaantjes door te verbinden aan elkaar simuleerde ik een druk op de knop. Top! Nu moest ik nog een component vinden dat dat voor me kan doen in samenwerking met een ESP.

Optocoupler voor het simuleren van een druk op de knop

Om een druk op de knop te simuleren maak je gebruik van een optocoupler. Door aan de ene kant een stuursignaal op de optocoupler te zetten gaat de andere zijde geleiden en is het net alsof er op de knop gedrukt wordt. Voor mezelf heb ik het volgende simpele schema gemaakt:

Het deel met de optocoupler moet net zo vaak gemaakt worden als dat je knoppen wilt bedienen. In mijn geval dus 7. Dat is ook de reden dat ik heb gekozen voor een ESP32. 7 GPIO’s is net te veel voor een Wemos D1 mini. Om het voor mezelf makkelijk te maken heb ik alle optocouplers op een stukje PCB gesoldeerd. Alle GND’s heb ik met elkaar verbonden (groene draad). Alle pins naar de ESP heb ik met rood draad uitgevoerd. De draden naar de knoppen op de afstandsbediening heb ik voorzien van blauw draad. Let op, dit komt niet helemaal overeen met de kleur draden van de schets. Nu het softwarematige gedeelte nog.

ESPHome gebruiken voor het vervangen van je oude afstandsbediening

Op de Wemos S2 Mini gaan we ESPHome flashen. Voor het uitvoeren van een actie voor mijn gordijnen moet je steeds twee knoppen indrukken. Eerst een cijferknop van het gordijn dat je wilt bedienen. Op de originele afstandsbediening zijn dat de knoppen 1,2,3,4 en ALL. Daarna moet je kiezen of je het gordijn omhoog of omlaag wilt doen. Hiervoor druk je normaal op knop UP of DOWN. Alle afstandsbediening knoppen heb ik in ESPHome nagemaakt door middel van de volgende code:

  switch:
  - platform: gpio
    pin: 7
    id: UP
  - platform: gpio
    pin: 5
    id: ALL
  - platform: gpio
    pin: 9
    id: DOWN
  - platform: gpio
    pin: 3
    id: EEN
  - platform: gpio
    pin: 34
    id: DRIE
  - platform: gpio
    pin: 21
    id: TWEE
  - platform: gpio
    pin: 17
    id: VIER

Om een druk op de knop te simuleren heb ik per knop een script gemaakt in ESPHome. Deze zet de pin voor 0.2 seconden op HIGH en zet ‘m daarna weer op LOW. Zo ‘denkt’ de afstandsbediening dus dat er op de knop gedrukt is, maar dat hebben we dus via ESPHome gedaan!

# Definieer het script dat de sequentie uitvoert
script:
  - id: PRESS_ALL
    mode: single
    then:
      - switch.turn_on: ALL
      - delay: 0.2s
      - switch.turn_off: ALL
      - delay: 0.2s
  
  - id: PRESS_DOWN
    mode: single
    then:
      - switch.turn_on: DOWN
      - delay: 0.2s
      - switch.turn_off: DOWN
      - delay: 0.2s
  - id: PRESS_UP
    mode: single
    then:
      - switch.turn_on: UP
      - delay: 0.2s
      - switch.turn_off: UP
      - delay: 0.2s
  - id: PRESS_EEN
    mode: single
    then:
      - switch.turn_on: EEN
      - delay: 0.2s
      - switch.turn_off: EEN
      - delay: 0.2s
  - id: PRESS_TWEE
    mode: single
    then:
      - switch.turn_on: TWEE
      - delay: 0.2s
      - switch.turn_off: TWEE
      - delay: 0.2s
  - id: PRESS_DRIE
    mode: single
    then:
      - switch.turn_on: DRIE
      - delay: 0.2s
      - switch.turn_off: DRIE
      - delay: 0.2s
  - id: PRESS_VIER
    mode: single
    then:
      - switch.turn_on: VIER
      - delay: 0.2s
      - switch.turn_off: VIER
      - delay: 0.2s

Nu willen we dit natuurlijk ook via Home Assistant kunnen doen. Dat kan door het maken van buttons. Deze buttons doen zich voor zoals op de afstandsbediening, dus als enkele acties.

# Maak een virtuele knop voor Home Assistant om het script te starten
button:
  - platform: template
    name: "ALL UP"
    on_press:
      then:
        - script.execute: PRESS_ALL
        - script.execute: PRESS_UP
  - platform: template
    name: "ALL DOWN"
    on_press:
      then:
        - script.execute: PRESS_ALL
        - script.execute: PRESS_DOWN
  - platform: template
    name: "UP"
    on_press:
      then:
        - script.execute: PRESS_UP
  - platform: template
    name: "DOWN"
    on_press:
      then:
        - script.execute: PRESS_DOWN
  - platform: template
    name: "EEN"
    on_press:
      then:
        - script.execute: PRESS_EEN
  
  - platform: template
    name: "TWEE"
    on_press:
      then:
        - script.execute: PRESS_TWEE
  - platform: template
    name: "DRIE"
    on_press:
      then:
        - script.execute: PRESS_DRIE
  - platform: template
    name: "VIER"
    on_press:
      then:
        - script.execute: PRESS_VIER
   

Gordijnen toevoegen aan Home Assistant

Maar het allermooiste is het om je gordijnen via een cover entity te bedienen! Je krijgt in Home Assistant daarmee ook andere ondersteunde acties zoals het draaien (tilt) van de rolgordijnen wat die van mij ook ondersteunen. Dit is wel wat meer tricky, omdat er vanuit de gordijnen geen terugkoppeling is van hoe ze staan. Dit probeer ik op te vangen door per gordijn een global variabele op te slaan wat de laatste actie was. Over het algemeen werkt het wel goed, maar als de batterijen van de gordijnen leeg raken willen ze nog wel eens een commando missen en uit sync raken. Kun je handmatig wel weer oplossen. Door onderstaande code maak je per gordijn een cover aan met de juiste commando’s en globals. Wanneer Home Assistant de open actie verstuurt, voert ESPHome de acties uit onder ‘open_action’.

globals:
  - id: laatste_richting_1
    type: std::string
    initial_value: '"stop"'
  - id: laatste_richting_2
    type: std::string
    initial_value: '"stop"'
  - id: laatste_richting_3
    type: std::string
    initial_value: '"stop"'
  - id: laatste_richting_4
    type: std::string
    initial_value: '"stop"'
    
cover:
  - platform: template
    id: cover_een
    name: Gordijn Werkkamer
    assumed_state: true
    device_class: blind
    open_action: 
      then:
        - lambda: |-
            id(laatste_richting_1) = "open";
        - script.execute: PRESS_EEN
        - script.execute: PRESS_UP    
    close_action: 
      then:
        - lambda: |-
            id(laatste_richting_1) = "close";
        - script.execute: PRESS_EEN
        - script.execute: PRESS_DOWN
    tilt_action: 
      then:
        - if:
            condition:
              lambda: 'return id(laatste_richting_1) == "close";'
            then:
              # Wanneer het grodijn dicht is en je wilt tilten, moet je naar beneden drukken
              - script.execute: PRESS_EEN
              - script.execute: PRESS_DOWN
        - lambda: |-
            id(laatste_richting_1) = "tilt_open";  
        - if:
            condition:
              lambda: 'return id(laatste_richting_1) == "tilt_open";'
            then:
              - script.execute: PRESS_EEN
              - script.execute: PRESS_UP
        - lambda: |-
            id(laatste_richting_1) = "close";  
    stop_action:
      then:
        - if:
            condition:
              lambda: 'return id(laatste_richting_1) == "open";'
            then:
              - script.execute: PRESS_EEN
              - script.execute: PRESS_DOWN
        - if:
            condition:
              lambda: 'return id(laatste_richting_1) == "close";'
            then:
              - script.execute: PRESS_EEN
              - script.execute: PRESS_UP
        - lambda: |-
            id(laatste_richting_1) = "stop";
############################################################   
  - platform: template
    id: cover_twee
    name: Gordijn Woonkamer
    assumed_state: true
    device_class: blind
    open_action: 
      then:
        - lambda: |-
            id(laatste_richting_2) = "open";
        - script.execute: PRESS_TWEE
        - script.execute: PRESS_UP    
    close_action: 
      then:
        - lambda: |-
            id(laatste_richting_2) = "close";
        - script.execute: PRESS_TWEE
        - script.execute: PRESS_DOWN
    tilt_action: 
      then:
        - if:
            condition:
              lambda: 'return id(laatste_richting_2) == "close";'
            then:
              # Wanneer het grodijn dicht is en je wilt tilten, moet je naar beneden drukken
              - script.execute: PRESS_TWEE
              - script.execute: PRESS_DOWN
        - lambda: |-
            id(laatste_richting_2) = "tilt_open";  
        - if:
            condition:
              lambda: 'return id(laatste_richting_2) == "tilt_open";'
            then:
              - script.execute: PRESS_TWEE
              - script.execute: PRESS_UP
        - lambda: |-
            id(laatste_richting_2) = "close";  
    stop_action:
      then:
        - if:
            condition:
              lambda: 'return id(laatste_richting_2) == "open";'
            then:
              - script.execute: PRESS_TWEE
              - script.execute: PRESS_DOWN
        - if:
            condition:
              lambda: 'return id(laatste_richting_2) == "close";'
            then:
              - script.execute: PRESS_TWEE
              - script.execute: PRESS_UP
        - lambda: |-
            id(laatste_richting_2) = "stop";
################################################
  - platform: template
    id: cover_DRIE
    name: Gordijn Garage
    assumed_state: true
    device_class: blind
    open_action: 
      then:
        - lambda: |-
            id(laatste_richting_3) = "open";
        - script.execute: PRESS_DRIE
        - script.execute: PRESS_UP    
    close_action: 
      then:
        - lambda: |-
            id(laatste_richting_3) = "close";
        - script.execute: PRESS_DRIE
        - script.execute: PRESS_DOWN
    tilt_action: 
      then:
        - if:
            condition:
              lambda: 'return id(laatste_richting_3) == "close";'
            then:
              # Wanneer het grodijn dicht is en je wilt tilten, moet je naar beneden drukken
              - script.execute: PRESS_DRIE
              - script.execute: PRESS_DOWN
        - lambda: |-
            id(laatste_richting_3) = "tilt_open";  
        - if:
            condition:
              lambda: 'return id(laatste_richting_3) == "tilt_open";'
            then:
              - script.execute: PRESS_DRIE
              - script.execute: PRESS_UP
        - lambda: |-
            id(laatste_richting_3) = "close";  
    stop_action:
      then:
        - if:
            condition:
              lambda: 'return id(laatste_richting_3) == "open";'
            then:
              - script.execute: PRESS_DRIE
              - script.execute: PRESS_DOWN
        - if:
            condition:
              lambda: 'return id(laatste_richting_3) == "close";'
            then:
              - script.execute: PRESS_DRIE
              - script.execute: PRESS_UP
        - lambda: |-
            id(laatste_richting_3) = "stop";
#######################################################
  - platform: template
    id: cover_VIER
    name: Gordijn Achterdeur
    assumed_state: true
    device_class: blind
    open_action: 
      then:
        - lambda: |-
            id(laatste_richting_4) = "open";
        - script.execute: PRESS_VIER
        - script.execute: PRESS_UP    
    close_action: 
      then:
        - lambda: |-
            id(laatste_richting_4) = "close";
        - script.execute: PRESS_VIER
        - script.execute: PRESS_DOWN
    tilt_action: 
      then:
        - if:
            condition:
              lambda: 'return id(laatste_richting_4) == "close";'
            then:
              # Wanneer het grodijn dicht is en je wilt tilten, moet je naar beneden drukken
              - script.execute: PRESS_VIER
              - script.execute: PRESS_DOWN
        - lambda: |-
            id(laatste_richting_4) = "tilt_open";  
        - if:
            condition:
              lambda: 'return id(laatste_richting_4) == "tilt_open";'
            then:
              - script.execute: PRESS_VIER
              - script.execute: PRESS_UP
        - lambda: |-
            id(laatste_richting_4) = "close";  
    stop_action:
      then:
        - if:
            condition:
              lambda: 'return id(laatste_richting_4) == "open";'
            then:
              - script.execute: PRESS_VIER
              - script.execute: PRESS_DOWN
        - if:
            condition:
              lambda: 'return id(laatste_richting_4) == "close";'
            then:
              - script.execute: PRESS_VIER
              - script.execute: PRESS_UP
        - lambda: |-
            id(laatste_richting_4) = "stop";
########################################

In Home Assistant ziet dat er dan vervolgens zo uit op je dashboard:

De status van het gordijn wordt over het algemeen juist weergegeven door de entiteiten doordat assumed_state op true staat. Deze communiceert de laatste actie naar Home Assistant zodat het de status van het gordijn kan weergeven. Zoals ik al eerder scheef kan het zo zijn dat de gordijnen uit sync raken door bijna lege batterijen. Ze missen dan wel eens een commando.

Het werkt!

Door het vervangen van de oude afstandsbediening voor een ESP32 met ESPHome ben ik verlost van twee losse afstandsbedieningen. De zelfgemaakte afstandsbediening in Home Assistant werkt perfect en betrouwbaar. Ik heb geen reden om de oude afstandbediening nog te gebruiken. De implementatie van de gordijnen in Home Assistant via de cover enties van esphome is erg uitgebreid en werkt zoals je verwacht. Missie geslaagd!

Van welk apparaat heb jij een oude ouderwetse afstandbediening die je wilt gebruiken met Home Assistant? Laat het weten in de comments!

Wat vond je van deze blogpost?

Klik op een ster om een beoordeling te geven!

Gemiddelde score 5 / 5. Aantal stemmen: 5

Er heeft nog niemand gestemd. Wees de eerste, het kost niets en geen registratie!

Jammer dat de post niet behulpzaam was.

Laten we deze post verbeteren!

Wat zou er beter kunnen?

Door Wouter

2 gedachten over “Ouderwetse afstandsbediening gebruiken in Home Assistant”

Laat weten wat je van dit artikel vindt!

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers liken dit: