Ongeveer een jaar geleden besloot ik om wat aan domotica te gaan doen. Mijn eerste mijlpaal was het automatiseren van de thermostaat in onze woonkamer. Dat deed ik door de bestaande wandthermostaat te vervangen door de Wifi Desktop Thermostaat (Elektor-project 160269, gepubliceerd in Elektor januari/februari 2018 [1][2]) die ik opnieuw had geprogrammeerd met ESPHome-firmware. Die geeft toegang tot alle bedieningselementen van de desktopthermostaat (d.w.z. één relais, twee drukknoppen en drie LED’s), daardoor kunnen ze worden geautomatiseerd door een domoticacontroller zoals Home Assistant.

In deze configuratie speelt Home Assistant, die op een Raspberry Pi draait, de rol van thermostaat. Dat betekent dat hij beslist wanneer de verwarming wordt in- of uitgeschakeld. De desktop-thermostaat zelf is een eenvoudig op afstand bedienbaar relais met enkele LED’s geworden.
 

Leuk, maar...

Het systeem werkte prima en hielp ons comfortabel door de winter van 2019 op 2020. Maar er waren wel enkele ongemakken:

 

  • er is een WiFi-netwerk nodig;
  • Home Assistant moet actief zijn;
  • het zag er niet fraai uit.

 

Toekomstbestendig

Bij mijn experimenten was het eerste probleem niet ernstig: de meesten van ons hebben wel een actief WiFi-netwerk. En als dat niet meer werkt is meestal het herstarten van de router voldoende om het te herstellen. Maar zoals velen van ons al meerdere keren in ons leven hebben meegemaakt: technologieën komen en gaan. Er is dus geen garantie dat er altijd een WiFi-netwerk zal zijn. Maar onze huizen staan er waarschijnlijk nog wel over een jaar of dertig. Met andere woorden, een meer toekomstbestendig ontwerp zou wenselijk zijn.
 

Achterwaarts compatibel

Het tweede punt heeft te maken met het eerste: ook Home Assistant en de Raspberry Pi kunnen ooit verdwijnen. Maar er is meer. Ik weet wel hoe ik moet omgaan met Home Assistant op een Raspberry Pi, maar de meeste mensen die ik ken hebben daar geen kaas van gegeten. Om mijn automatische thermostaat geschikt te maken voor andere mensen, moet hij ook ‘achterwaarts compatibel’ zijn. Hij moet er uitzien als een klassieke muurthermostaat en zich ook zo gedragen. Het automatiseringsgedeelte moet niet worden opgelegd, maar moet discreet en optioneel zijn. Het is beschikbaar voor wie het wil gebruiken, maar voor anderen mag het niet in de weg zitten.
 

Een kwestie van smaak

Over smaak valt niet te twisten. De automatische desktop-thermostaat bungelde aan een stuk draad dat uit een gat in de muur kwam waar de oude thermostaat had gezeten (figuur 1).

Figuur 1. Sommigen vonden deze manier van het installeren van een slimme thermostaat in de woonkamer ‘onesthetisch’.

Een paar ongebruikte, op het lichtnet aangesloten draden die uit de muur staken, had ik met stukjes isolatietape beschermd tegen domme mensen. Omdat de desktop-thermostaat een 5V-voeding op een USB-aansluiting nodig had, voedde ik hem met een telefoonoplader die met een nabijgelegen stopcontact was verbonden. Dat betekent dat er verschillende zeer zichtbare draden naar het apparaat gingen, terwijl er bij de oorspronkelijke thermostaat geen draadje te zien was. Het was een constructie die bij bezoekers veel vragen opriep, maar echt mooi vonden ze het niet, eerder ‘lelijk’, ‘raar’ of ‘gevaarlijk’.
 

Terug naar de tekentafel

De tekortkomingen van de eerste versie van de desktop-thermostaat deden mij besluiten om het ontwerp te herzien om de meeste, of liever nog, alle ongemakken op te lossen. Dat resulteerde in de volgende specificaties:

 

  • lokaal, dus temperatuur instellen op het apparaat zelf;
  • lokale besturing heeft voorrang op de automatisering;
  • voeding uit het lichtnet;
  • professioneel ogende aansluiting en behuizing.

 

Het tweede punt betreft de software, de drie andere hebben te maken met de elektronica van de nieuwe thermostaat.

Eis nummer één vraagt om een intuïtieve gebruikersinterface om de gewenste temperatuur in te stellen. De desktop-thermostaat heeft twee drukknoppen om de gewenste temperatuur omhoog/omlaag in te stellen. Maar hij heeft geen display om de ingestelde temperatuur zichtbaar te maken. Het toevoegen van een display is lastig, gezien het beperkte aantal I/O-pennen dat beschikbaar is op de WiFi-module. Het gebruik van een potentiometer met een gekalibreerde schaal zoals de originele thermostaat leek eenvoudiger en is mogelijk dankzij de analoge ingang van de WiFi-module.

Ook de derde ontwerpeis vraagt wat denkwerk. Er is ongeveer 1 W aan vermogen nodig voor een WiFi-verbinding en voor het voeden van het relais. Het is mogelijk om een kleine voeding met een transformator te bouwen, maar het is moeilijk om die klein genoeg te maken; we willen geen grote doos aan de muur. De originele thermostaat had een transformatorloze voeding die prima is voor relatief constante belastingen, maar ik weet niet zeker of hij goed zou presteren als hij een WiFi-node zou moeten voeden. Daarom wilde ik liever in plaats daarvan een kleine AC/DC-convertermodule gebruiken.

Bij het zoeken naar een behuizing in diverse catalogi vond ik niets dat me geschikt leek. Maar zelfbouw van een goed uitziende behuizing op maat is niet mijn sterkste punt. Gelukkig hebben we vandaag de dag FabLabs, 3D-printen en lasersnijden tot onze beschikking, zelfs op afgelegen plaatsen, dus dat moest op te lossen zijn. Maar toch koos ik voor een andere aanpak: ik wilde proberen de behuizing van de originele thermostaat te hergebruiken, omdat die alles wat ik wilde al in zich had: een potentiometer met een schaalverdeling, een LED en een aan/uit-schakelaar. Verder had hij montagegaten op de juiste plaatsen en een goede manier om een printplaat via de onderkant aan te sluiten op het lichtnet, waarbij alle draden uit het zicht blijven.

Het kwam er dus op neer dat ik een nieuw ontwerp voor de desktop-thermostaat moest gaan maken, dat zou passen in de bestaande behuizing met de potentiometer, de LED, de aan/uit-schakelaar en de aansluiting voor de netspanning op exact dezelfde posities als in de oorspronkelijke thermostaat.

Het hertekenen van het schema van de desktop-thermostaat was vrij gemakkelijk (figuur 2).

Figuur 2. In principe is de nieuwe discreet aangesloten thermostaat hetzelfde als de Elektor Desktop Thermostaat uit 2018, met een nieuwe voeding. Ook is er een potentiometer toegevoegd voor het instellen van de doeltemperatuur.

Ik heb de USB-voeding vervangen door een 5V-AC/DC-module, en ik heb een potentiometer met een spanningsbegrenzende weerstand toegevoegd omdat de WiFi-module geen hogere spanning aan kan dan 1,1 V. De twee drukknoppen en de drie LED’s heb ik erin gelaten omdat ze misschien ooit van pas kunnen komen.

Gelukkig bleek de AC/DC-module toevallig net onder de kunststof steun van de potentiometer te passen. De potentiometer, de netschakelaar en netaansluiting heb ik uit de oude thermostaat gehaald (figuur 3).

Figuur 3. Sommige onderdelen van de oude thermostaat zijn hergebruikt in het nieuwe ontwerp. Dat geldt ook voor de behuizing, vandaar de merkwaardige vorm van de nieuwe print. Het legde ook beperkingen op aan de plaatsing van bepaalde onderdelen.

Ik moest het relais vervangen door een 5V-type omdat het relais van de oude thermostaat op 48 V werkte. Het is me niet gelukt om het relais uit de desktop-thermostaat te monteren, maar gelukkig was het relais van de oude thermostaat een standaardtype dat nog steeds verkrijgbaar is, ook in een 5V-versie.

Het kostte heel wat moeite om alles op een printplaat te proppen die in de originele behuizing paste, maar uiteindelijk is het me gelukt. Alle SMD-componenten, inclusief de WiFi-module, gingen aan de onderkant van de printplaat (figuur 4), terwijl alle bedrade onderdelen een plekje vonden aan de bovenkant.

Figuur 4. Alle SMD’s zitten aan de onderzijde van de print. De sporen die verbonden zijn met de verwarming (rechtsboven) zijn met extra soldeer verdikt om zonder oververhitting grote stromen te kunnen transporteren. De gleuf eronder zorgt voor een galvanische scheiding tussen de hoog- en laagspanningsonderdelen. Het zwarte ding dat naar rechts uitsteekt, is de temperatuursensor, beschermd met krimpkous. Alle warmteproducerende onderdelen bevinden zich aan de linkerzijde van de print en moeten na de installatie van de thermostaat naar boven wijzen.

Ik kon wat extra printoppervlak winnen door een paar ongebruikte montagegaten van de behuizing af te dekken. Ik moest ook een aantal plastic obstakels in de behuizing wegzagen. Om alle sporen te kunnen routen, moest ik hier en daar wat creatief omgaan met de aanbevolen isolatienormen voor de afstand tussen printsporen.
 

Software

De firmware voor ESPHome die ik voor mijn eerste versie had gecompileerd, moest ook opnieuw worden bekeken. In plaats van eenvoudigweg alle sensoren en actuatoren van de thermostaat te koppelen met de controller en Home Assistant voor de rest te laten zorgen, moest ik nu automatiseren in ESPHome. Dit programmeren en configureren gebeurt in het YAML-bestand van het ESPHome-project van de thermostaat (zie “Domotica helemaal niet moeilijk”).
 

Meten van de kamertemperatuur

Declareer eerst de temperatuursensor die de kamertemperatuur meet. Omdat de gebruikte sensor een DS18B20 is (oorspronkelijk van Dallas, nu van Maxim of zelfs Analog Devices), die is aangesloten op GPIO-pen 5, en omdat ESPHome een speciale Dallas-component heeft, vertaalt dit zich naar de volgende code:

 

dallas:
  - pin: GPIO5
 
sensor:
  - platform: dallas
    address: 0x6D00000C24013928
    name: "Measured temperature"
    id: t_room
    filters:
      - offset: 0.0

 

De eerste regel geeft aan dat ESPHome zijn Dallas 1-wire communicatiemodule moet gebruiken en die moet koppelen aan GPIO5. De sensor is dan van het platform dallas. Het address is optioneel. Maar als u een adres geeft, moet dat wel correct zijn. U kunt het adres vinden in de logging van ESPHome (gebruik niet het mijne, elke sensor heeft een uniek adres). Het opgeven van een id (t_room) is nodig omdat we ergens anders in het YAML-bestand naar de sensor willen verwijzen (zie verderop). Het toevoegen van filters maakt het mogelijk om de gemeten temperatuur op een of andere manier te compenseren indien nodig.
 

Instellen van de temperatuur

Het instellen van de gewenste temperatuur gaat met de potentiometer. Omdat de waarde een spanning is, voegen we hem toe aan het sensorgedeelte van het YAML-bestand in de vorm van een sensor van het type adc platform. Met behulp van zogenaamde sensorfilters wordt de ingangsspanning omgezet naar een temperatuurwaarde die overeenkomt met de op de behuizing afgedrukte schaal. De vergelijking Ttarget = 25 x Vin + 6,75 voldeed goed in mijn geval. Dat vertaalt zich in een vermenigvuldiging met 25 en een offset van 6,75. Door de eenheden te specificeren als °C, zal automatiseringssoftware zoals Home Assistant deze gegevens behandelen als een temperatuur.

Figuur 5. Na enkele kleine aanpassingen van de oude thermostaatbehuizing (lees: wegsnijden van wat plastic) past de nieuwe print goed.

  - platform: adc
    name: "Target temperature"
    id: t_target
    icon: "mdi:temperature-celsius"
    pin: A0
    update_interval: 5s
    # Convert potentiometer scale to °C (min=6.75°C, max=31.75°C)
    filters:
      - multiply: 25.0
      - offset: 6.75
    unit_of_measurement: "°C"
    on_value:
      then:
      - lambda: |-
          auto call = id(t_controller).make_call();
          call.set_target_temperature(x);
          call.perform();

 

Figuur 6. Klaar! De twee drukknoppen zijn bereikbaar via twee uitsparingen (links) en de sensor steekt uit de onderkant. De groene en gele LED’s zijn alleen zichtbaar door de ventilatiesleuven om te voorkomen dat de kamer ’s nachts wordt verlicht. Door het gebruik van verschillende kleuren is het gemakkelijk om te zien welke er brandt.

Het gedeelte aan het einde, na on_value, is een automatisering en wordt later nog toegelicht. Maar eerst gaan we kijken naar het relais.
 

Schakelen van de verwarming

Dit is vrij eenvoudig omdat het relais niet meer is dan een schakelaar die is aangesloten op GPIO-pen 4 en dus deel uitmaakt van het gpio platform. Net als de temperatuursensor heeft het een id (heater) nodig om het te kunnen adresseren in andere delen van het YAML-bestand.

 

switch:
  - platform: gpio
    pin: GPIO4
    name: "Heater"
    id: heater

 

Klimaatregeling

We hebben nu dus een sensor om de kamertemperatuur te meten (t_room), een potentiometer om een doeltemperatuur in te stellen (t_target) en een relais om een verwarming in en uit te schakelen (heater).

ESPHome bevat een klimaatcomponent voor het regelen van verwarming en koeling. Een thermostaat is dus een klimaatcomponent. Het voordeel van het gebruik van een ingebouwde component is dat het u werk bespaart. Het zorgt er ook voor dat er een mooie grafische besturingswidget verschijnt in de gebruikersinterface van de Home Assistant.

 

climate:
  - platform: thermostat
    name: "Thermostat"
    id: t_controller
    sensor: t_room
    default_target_temperature_low: 20 °C
    heat_action:
      - switch.turn_on: heater
    idle_action:
      - switch.turn_off: heater
    hysteresis: 0.5
    away_config:
      default_target_temperature_low: 15 °C

 

De in dit artikel beschreven thermostaat kan niet koelen, hij kan alleen verwarmen. Daarom past hij in het ESPHome-platform thermostat. Hij heeft een id nodig zodat hij door andere zaken in het YAML-bestand kan worden aangestuurd. Ik heb hem als ID t_controller gegeven, omdat het platform al thermostat heet en we de boel niet door elkaar willen halen.

De klimaatcomponent heeft een temperatuursensor-ingang, die we aansluiten op t_room. Hij moet ook worden aangesloten op een verwarming, wat we kunnen doen met de switch heater die we eerder hebben gedefinieerd.

Ik had verwacht dat een klimaatcomponent ook een doelwaarde voor de temperatuur zou hebben, maar dat is niet het geval. (Misschien wordt die ooit nog eens toegevoegd in een toekomstige versie van ESPHome?) In plaats daarvan heeft hij een set-target-temperature-control, die lijkt op de potentiometer van de thermostaat. Gelukkig is er een manier om deze beperking te omzeilen, en dat is door gebruik te maken van zogenaamde ‘lambda’-blokken.
 

Lambda-blokken

Lambda-blokken zijn heel handig, maar ze hebben wel een groot nadeel. Het mooie is dat je er vrijwel alles mee kunt realiseren wat je wilt, het nadeel is, dat ze het hele concept van apparaatconfiguratie met een simpel YAML-bestand zonder kennis van C++ onderuit halen.

Simpel gezegd is een lambda-blok een stuk C++-code dat letterlijk in het ESPHome-project wordt geïnjecteerd. Om dat mogelijk te maken, moesten de ontwikkelaars zich in alle mogelijke bochten wringen om een bruikbare YAML-naar-C++-interface te bedenken. Het resultaat is dat de lambda-code ingewikkelder is dan normale C++ zou zijn geweest.

Eigenlijk zou je, zodra je lambda-blokken nodig hebt, moeten gaan nadenken over het maken van een eigen, aangepaste component. ESPHome ondersteunt aangepaste componenten voor bijna alles. Ik stond op het punt om een aangepaste klimaatcomponent te schrijven om de problemen die ik had op te lossen, maar uiteindelijk besloot ik dat onderwerp te bewaren voor een ander artikel.

Terug naar het instellen van de gewenste temperatuur van de klimaatcomponent. De C++ interface heeft een functie om de gewenste temperatuur in te stellen. Het lambda-blok in het bovenstaande on_value automatiseringsgedeelte van de potmetersensor (dat hieronder wordt herhaald) geeft aan hoe deze gebruikt moet worden. Telkens als er een nieuwe waarde beschikbaar is, wordt de methode set_target_temperature van de klimaatcomponent t_controller aangeroepen:

 

    on_value:
      then:
      - lambda: |-
          auto call = id(t_controller).make_call();
          call.set_target_temperature(x);
          call.perform();

 

In gewoon C/C++ zou dat er ongeveer zo uitzien:

 

t_controller.set_target_temperature(x);

 

Als bij de klimaatcomponent een doeltemperatuur mogelijk was geweest, had het nog eenvoudiger kunnen zijn. Bijvoorbeeld:

 

climate:
  - platform: thermostat
    name: "Thermostat"
    id: t_controller
    sensor: t_room
    target: t_target
    
...

 

Hoe dan ook.

Helaas is deze manier van het automatiseren van on_value te simplistisch, omdat die voorrang heeft op de afstandsbediening van de gewenste temperatuur van bijvoorbeeld Home Assistant. Om dit op te lossen zou de automatisering alleen mogen draaien wanneer t_target verandert (dus wanneer iemand de potentiometer draait). Omdat ESPHome geen on_value_changed automatisering voor sensoren heeft, moeten we dat zelf regelen in het lambda-blok:

 

    on_value:
      then:
      - lambda: |-
          static float x_last = 0.0;
          if (x<x_last-0.1 || x>x_last+0.1)
          {
            x_last = x;
            auto call = id(t_controller).make_call();
            call.set_target_temperature(x);
            call.perform();
          }

 

De kleine hysterese bij x (±0,1 in dit geval) vermindert de gevoeligheid van de automatisering voor ruis in het sensorsignaal.
 

Het deltafilter

Een andere, mooiere, oplossing is het gebruik van een deltafilter bij t_target. Dit filter geeft alleen een nieuwe waarde door als die met een verschil van plus of min delta afwijkt van de vorige waarde. Dus als delta = 1 en de laatste waarde was gelijk aan 20, dan wordt de volgende waarde pas doorgegeven als deze lager is dan 19 of hoger dan 21.

 

  - platform: adc
    name: "Target temperature"
    id: t_target
    …
    filters:
      - multiply: 25.0
      - offset: 6.75
      - delta: 0.2
    
...

 

Filters worden uitgevoerd in de volgorde waarin ze in de broncode staan, dus het delta-filter werkt op de waarde die is omgezet in graden celsius, en niet rechtstreeks op de ingangsspanning. De waarde ervan moet klein zijn, anders is het moeilijk om de thermostaat een klein beetje omhoog of omlaag te zetten (wat heel belangrijk is voor het bedieningscomfort).
 

Laatste loodjes

Als het YAML-configuratiebestand klaar is, kan de firmware in de WiFi-module worden geladen. De eerste keer (dus als de module die nog niet met ESPHome-compatibele software werkt) moet daarvoor de seriële poort worden gebruikt (beschikbaar op header K2). Zie [3] voor de exacte procedure. Zodra het apparaat ESPHome uitvoert en OTA-programmering (Over-the-Air) is ingeschakeld (het YAML-bestand bevat dan de regel ota), kan de thermostaat opnieuw worden geprogrammeerd zonder fysiek te zijn aangesloten op het ontwikkelsysteem. Met andere woorden, hij kan dan aan de muur worden gemonteerd op de plaats van de oude thermostaat.

De thermostaat wordt zó gemonteerd dat de temperatuursensor niet wordt verwarmd door de WiFi-module en de voeding.
 

Conclusie

In dit artikel hebben we gezien hoe een bestaande ‘domme’ thermostaat kan worden vervangen door een zelfgemaakte slimme thermostaat met WiFi-verbinding en die geschikt is voor domotica. Het bouwen van een prototype dat ongeveer doet wat het moet doen was niet al te moeilijk; er iets van maken dat door iedereen op elk moment gebruikt kan worden en dat esthetisch gezien acceptabel is, kostte wat meer moeite. De nieuwe thermostaat zal ongetwijfeld nog wat moeten worden verfijnd, maar omdat hij op afstand kan worden geprogrammeerd (‘in het veld’, noemen ze dat), is dat gemakkelijk te doen.

 

(200519-04)


Wilt u meer van die fantastische Elektor-artikelen?


► Neem vandaag nog een abonnement op Elektor - u mist nooit meer een artikel, project of handleiding!