{"id":7031,"date":"2017-12-24T20:14:52","date_gmt":"2017-12-24T19:14:52","guid":{"rendered":"https:\/\/ingmarverheij.com\/?p=7031"},"modified":"2017-12-27T09:57:24","modified_gmt":"2017-12-27T08:57:24","slug":"built-smart-heat-recovery-system","status":"publish","type":"post","link":"https:\/\/ingmarverheij.com\/en\/built-smart-heat-recovery-system\/","title":{"rendered":"I built a smart heat recovery system!"},"content":{"rendered":"<p>Begin 2015 I\u2019ve started on my first IoT project; building a smart heat recovery system (or warmte terugwin unit \u2013 WTW). Back then I wrote an article (in Dutch, see <a href=\"https:\/\/ingmarverheij.com\/bediening-wtw-altijd-op-de-verkeerde-plek\/\">here<\/a>) explaining why I felt this was necessary and my initial approach. I never could have expected the journey I started, I had opened Pandora\u2019s box.<\/p>\n<p>I must admit it has been a fun ride with many ups and some downs (otherwise there would have been no ups)! I\u2019ve learned so many things, ranging from hardware design, PCB\u2019s, software coding and the IoT ecosystem in general. Mainly it\u2019s been a journey refreshing my memory, some things I haven\u2019t done since I was 17 and I was eager on learning it again.<\/p>\n<blockquote><p>In this article I want to share with you the result of *almost* 3 years of learning; my IoT project is finished<\/p><\/blockquote>\n<p><!--more--><\/p>\n<h1><strong>Result<\/strong><\/h1>\n<p>Whenever the humidity is too high in the bathroom \u2013 <strong>someone\u2019s taking a shower \/ bath<\/strong> \u2013 the heat recovery system automatically <strong>boosts<\/strong> to the highest state (3). When the humidity is low enough it goes back to the desired state. Additionally, a push notification is send to my phone when the filter requires changing.<\/p>\n<p><em>I ended up adding a mechanical fan to suck more air out of the bathroom, switched with a smart power plug.<\/em><\/p>\n<p>&nbsp;<\/p>\n<h1><strong>Components<\/strong><\/h1>\n<ul>\n<li>RenoventHR module ***<\/li>\n<li>Automation Engine<\/li>\n<li>Smart Humidity Sensor<\/li>\n<li>Smart power plug<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h4>COTS components<\/h4>\n<p>Let\u2019s start with the easy part. I\u2019ve used common of the shelf (COTS) hardware to read the humidity in the bathroom and switch the added mechanical fan (bonus). Since I had some equipment from Xiaomi laying around I ended up using:<\/p>\n<ul>\n<li>Xiaomi Mi Smart Temperature and Humidity Sensor<\/li>\n<li>Xiaomi Mi Zigbee Smart Socket Plug<\/li>\n<li><em>Xiaomi Mi Smart Home Gateway 2<\/em><\/li>\n<\/ul>\n<p>Having connected modules doesn\u2019t make a solution smart, only when the components are connected with each other (with some logic) it can truly become smart. For that I needed \u201chome automation\u201d software, I went with <a href=\"https:\/\/home-assistant.io\/\">Home Assistant<\/a> as that\u2019s widely distributed and supports many hardware out of the box. Later in this article I\u2019ll share the logic to make this a smart solution and the configuration associated.<\/p>\n<p>&nbsp;<\/p>\n<h1><strong>RenoventHR module<\/strong><\/h1>\n<p>This is the actual module I\u2019ve built. My baby.<\/p>\n<blockquote><p><em>It is named RenoventHR since as connect this module to a <a href=\"https:\/\/www.brinkclimatesystems.nl\/nl-nl\/qr\/renovent-hr-medium-large\" target=\"_blank\" rel=\"noopener\">Brink RenoventHR<\/a>\u00a0<\/em><\/p><\/blockquote>\n<p>When designing this module, I had the following design requirements:<\/p>\n<ul>\n<li>Mode\/state information should be visible on the device;<\/li>\n<li>Mode\/state should be configurable manually (physical, with buttons);<\/li>\n<li>Mode\/state should be configurable via a mobile device;<\/li>\n<li>Mode\/state should be configurable via automation system (REST + MQTT);<\/li>\n<li>Filter change indicator should be readable via automation system (REST + MQTT);<\/li>\n<li>Connected via Wi-Fi;<\/li>\n<li>Configuration should be configurable (no passwords in the code);<\/li>\n<li>Hardware should appear OEM (no loose wires);<\/li>\n<li><em>Needless to say, the WAF (wife acceptance factor) is important.<\/em><\/li>\n<\/ul>\n<p>I\u2019ve tried to make the solution replicable, for you (the reader) but also for the people in my neighborhood with similar systems. The module consists of two parts; hardware and software. Let\u2019s start with the hardware as that\u2019s the part I\u2019m most proud of, also because that\u2019s where the learning curve was highest.<\/p>\n<p>&nbsp;<\/p>\n<h2><strong>Hardware<\/strong><\/h2>\n<p>The module is a custom-built PCB which I designed in AutoDesk <a href=\"https:\/\/www.autodesk.com\/products\/eagle\/overview\">EAGLE<\/a>. After many (\u2026) prototypes on breadboards I finally ordered some PCBs. Though the first attempt was unsuccessful, revision 0.4 is now in production. Not bad.<\/p>\n<p>The design is based around an <strong>ESP8266<\/strong>, a low-cost but very powerful and flexible module which features Wi-Fi and GPIO pins. The onboard <strong>EEPROM<\/strong> is used to store the configuration and current mode\/state (so it persists on a reboot). To simplify the design the module is using the <a href=\"https:\/\/www.adafruit.com\/product\/2471\"><strong>Adafruit HUZZAH ESP8266<\/strong><\/a> which costs roughly $10. Because of my requirements I found the amount of available GPIO pins on the ESP8266 was not enough, so I added a 8 bit I\/O <strong>port expander<\/strong> (<a href=\"https:\/\/ww1.microchip.com\/downloads\/en\/DeviceDoc\/21919e.pdf\">MCP23008<\/a>). This port expanded also comes with configurable interrupt pins which was just what I needed. To mimic the physical switch and the 4 modes (0,1,2 and 4) it features two <strong>relays<\/strong> (one SPST and one SPDT). Manually switching up and down is down with two <strong>push buttons<\/strong> and changing the operation mode (from normal to setup-mode) is done with a <strong>rocker switch<\/strong>. A small <strong>0.96\u201d OLED screen<\/strong> is attached to show the state\/mode and the IP address of the module. <strong>Mini USB<\/strong> provides a steady 5V to the module.<\/p>\n<p>I\u2019ve uploaded the files: <em>schematic, board <\/em>and <em>part list<\/em> on GitHub. Feel free to use them, feel encouraged to share if you used (or modified) them. The link is below.<\/p>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2015\/01\/DMGIrDXXUAICR0X.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7017 size-thumbnail\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2015\/01\/DMGIrDXXUAICR0X-150x150.jpg\" alt=\"\" width=\"150\" height=\"150\" \/><\/a><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/Image-Board.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7044 size-thumbnail\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/Image-Board-150x150.png\" alt=\"\" width=\"150\" height=\"150\" \/><\/a><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/Image-Schematic.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7045 size-thumbnail\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/Image-Schematic-150x150.png\" alt=\"\" width=\"150\" height=\"150\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h2><strong>Software<\/strong><\/h2>\n<p>Another thing I like about the ESP8266 is that I can run \u201cArduino code\u201d on it. Not only is the IDE and syntax easy, there\u2019s a huge community that provides a wealth of information. I won\u2019t run you through the entire code here (it\u2019s on GitHub) but I\u2019ll share the functionality with you.<\/p>\n<p><em>I\u2019ve added some comments in the code to explain the functionality and used the <\/em><a href=\"https:\/\/en.wikipedia.org\/wiki\/Hungarian_notation\"><em>Hungarian notation<\/em><\/a><em> for variables (well, my interpretation of it \ud83d\ude06\u00a0<\/em><em>).<\/em><\/p>\n<p>&nbsp;<\/p>\n<h3>Operating mode<\/h3>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/IMG_9089.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-7050 alignright\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/IMG_9089-169x300.jpg\" alt=\"\" width=\"169\" height=\"300\" srcset=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/IMG_9089-169x300.jpg 169w, https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/IMG_9089-576x1024.jpg 576w, https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/IMG_9089-28x50.jpg 28w, https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/IMG_9089.jpg 750w\" sizes=\"auto, (max-width: 169px) 100vw, 169px\" \/><\/a>The device has two operating modes: <em>normal<\/em> and <em>setup<\/em>. In the <strong>setup<\/strong> mode the device acts as a Wi-Fi Access Point (SSID <em>RenoventHR<\/em>) and serves a webpage. The IP address is shown on the OLED so the user knows where to point the browser to.<\/p>\n<p>On the webpage the following can be configured:<\/p>\n<ul>\n<li><strong>SSID<\/strong>: The SSID of the Wi-Fi network the device should connect to in <em>normal<\/em><\/li>\n<li><strong>Passphrase<\/strong>: The passphrase for the Wi-Fi network<\/li>\n<li><strong>MQTT broker (optional)<\/strong>: The address of the MQTT broker the device should connect to in <em>normal<\/em> If no address is provided the device won\u2019t try to connect.<\/li>\n<\/ul>\n<p><em>Since I\u2019m lazy I included a button to scan for available networks. <\/em><\/p>\n<p>The data is stored in the <strong>EEPROM<\/strong> of the ESP8266. This way no user data is stored in the code and I can reconfigure it without the need to re-program.<\/p>\n<p>&nbsp;<\/p>\n<p>The <strong>normal<\/strong> mode connects to the Wi-Fi network read from the EEPROM (during boot). It hosts a webserver to change the mode via a mobile device (AJAX webpage), via HTTP REST and MQTT. An <strong>interrupt<\/strong> is attached to the <em>rocker switch<\/em> so the device will automatically reboot and start in the other mode when the switch is switched.\u00a0<em>Getting an ESP8266 to reliable reboot wasn\u2019t all that easy, but connecting GPIO16 to the reset pin and issuing ESP.deepsleep() does the trick.<\/em><\/p>\n<p>&nbsp;<\/p>\n<h3>Interfaces<\/h3>\n<p>Interfacing with the module can be done with 4 methods <em>(these interfaces are only available in the normal operating mode)<\/em>:<\/p>\n<ul>\n<li>Physically<\/li>\n<li>Webpage<\/li>\n<li>HTTP REST<\/li>\n<li>MQTT<\/li>\n<\/ul>\n<h4><\/h4>\n<h4>Physical<\/h4>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2015\/01\/IMG_7429.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright wp-image-7022 size-thumbnail\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2015\/01\/IMG_7429-150x150.jpg\" alt=\"\" width=\"150\" height=\"150\" \/><\/a>There are two pushbuttons connected to the device to which interrupts are attached. After a button is pressed the <em>wtwState<\/em> is raised\/lowered. Immediately the relays are switched to the desired state and \u2013 when configured \u2013 the new setting is broadcasted via MQTT.<\/p>\n<p>The OLED display will display the current <em>wtwState<\/em>.<\/p>\n<p>&nbsp;<\/p>\n<h4><\/h4>\n<h4>Webpage<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignright wp-image-7023 size-thumbnail\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2015\/01\/IMG_7431-150x150.png\" alt=\"\" width=\"150\" height=\"150\" \/><\/p>\n<p>An AJAX webpage is available on the IP address of the module (which is visible on the OLED screen), the page is optimized for a mobile phone. Using this webpage, a user can manually change the <em>wtwState<\/em>. The page is <em>dynamic<\/em>,\u00a0meaning that if the state is changed with another method this is reflected on the webpage.<\/p>\n<p>If the filter needs to be changed this is visible on the webpage.<\/p>\n<p>&nbsp;<\/p>\n<h4><\/h4>\n<h4>HTTP REST<\/h4>\n<p>Status information about the module can be obtained by issuing the following HTTP REST command:<\/p>\n<pre class=\"\">https:\/\/&lt;address&gt;\/status<\/pre>\n<p>This will return a JSON file containing the following information:<\/p>\n<ul>\n<li><strong>wtwState<\/strong>: the current wtwState [0\/1\/2\/3]<\/li>\n<li><strong>changeFilter<\/strong>: 0 = filter is good, 1 = filter needs to be changed<\/li>\n<\/ul>\n<p>The <em>wtwState<\/em> can we set using a HTTP REST command:<\/p>\n<pre class=\"\">https:\/\/&lt;address&gt;\/changeState?state=value<\/pre>\n<p>where <em>value<\/em> is the new state. This will return the same JSON file as with \/status<\/p>\n<h4><\/h4>\n<h4>MQTT<\/h4>\n<p>When the connection with the MQTT broker \u2013 for whatever reason \u2013 is disconnected it will retry every 5 seconds (configurable). The module publishes the following topics:<\/p>\n<ul>\n<li><strong>RenoventHR\/wtwState<\/strong>: the current wtwState [0\/1\/2\/3]<\/li>\n<li><strong>RenoventHR\/changeFilter<\/strong>: 0 = filter is good, 1 = filter needs to be changed<\/li>\n<\/ul>\n<p>The information is broadcasted every 5 seconds (configurable) but also when the state is changed using another method.<\/p>\n<p>It also subscribes to the following topic:<\/p>\n<ul>\n<li><strong>RenoventHR\/setWTWstate<\/strong>: Sets the new <em>wtwState <\/em>[0\/1\/2\/3]<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3><strong>Security<\/strong><\/h3>\n<p>During the design of the module I\u2019ve thought hard about the security implications.<\/p>\n<p>Though the possible impact on a breach is limited \u2013 <em>so a hacker can change the mode\/state of my WTW, meh<\/em> \u2013 there\u2019s a bigger risk. Since the device is connected via Wi-Fi there\u2019s a risk that:<\/p>\n<ul>\n<li>Someone can sniff the credentials;<\/li>\n<li>The credentials are read from the EEPROM of the module.<\/li>\n<\/ul>\n<p>To mitigate the first risk as much as possible I\u2019m uploading the latest available firmware of the ESP8266. For instance, the latest ESP8266 firmware is protected against KRACK (<a href=\"https:\/\/github.com\/esp8266\/Arduino\/issues\/3725\">link<\/a>). The second problem I took for granted. I could have encrypted the credentials before I stored them in the EEPROM, but since the software (and thus encryption keys) are on GitHub that\u2019s kind off useless.<\/p>\n<p>Another possible risk is that a malicious user could sniff unprotected traffic. I haven\u2019t implemented HTTPS or SMQTT (using TLS), simply because this is a home automation module\u2026 not an enterprise module.<\/p>\n<p><strong>TIP<\/strong>: When you\u2019re planning on running this module (or any other IoT device) my advice is to create a separate Wii SSID and network segment to reduce the risks. After all, when the Wi-Fi credentials are stolen from your unsafe IoT device\u2026 your network if exposed.<\/p>\n<p>&nbsp;<\/p>\n<h1><strong>Home Assistant<\/strong><\/h1>\n<p><a href=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/Screen-Shot-2017-12-24-at-20.00.17.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-medium wp-image-7047\" src=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/Screen-Shot-2017-12-24-at-20.00.17-300x132.png\" alt=\"\" width=\"300\" height=\"132\" srcset=\"https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/Screen-Shot-2017-12-24-at-20.00.17-300x132.png 300w, https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/Screen-Shot-2017-12-24-at-20.00.17-768x338.png 768w, https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/Screen-Shot-2017-12-24-at-20.00.17-1024x451.png 1024w, https:\/\/ingmarverheij.com\/wp-content\/uploads\/2017\/12\/Screen-Shot-2017-12-24-at-20.00.17-50x22.png 50w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>To make the solution smart, in fact just to make it a solution, I needed a platform that allowed me to connect different components and add some intelligence. I went with <a href=\"https:\/\/home-assistant.io\/\">Home Assistant<\/a> as that\u2019s widely distributed and supports many hardware out of the box. What\u2019s also convenient is that it comes with a <a href=\"https:\/\/home-assistant.io\/components\/mqtt\/\">MQTT broker<\/a> out of the box.<\/p>\n<p>&nbsp;<\/p>\n<p>The configuration is stored in the <a href=\"https:\/\/en.wikipedia.org\/wiki\/YAML\">YAML file format<\/a>. This all starts with the <a href=\"https:\/\/home-assistant.io\/getting-started\/configuration\/\">configuration.yaml<\/a> file, I\u2019ve used some !include statements to split the configuration in separate files. <a href=\"https:\/\/home-assistant.io\/docs\/configuration\/secrets\/\">Secrets<\/a> are all stored in a separate file (secrets.yaml). The relevant parts of the files are provided below.<\/p>\n<p>&nbsp;<\/p>\n<h2>configuration.yaml<\/h2>\n<p>Being the base configuration file, it contains the most \u201crandom\u201d information. The relevant parts are:<\/p>\n<ul>\n<li>enabling the MQTT broker;<\/li>\n<li>including files for automation, group, notify and sensors (described below);<\/li>\n<li>Configuring the Xiaomi Agara gateway details<\/li>\n<li>Define an alert which sends a notification every 12h if the filters needs to be changed;<\/li>\n<li>Define a boolean (switch) to indicate the WTW is in boost mode;<\/li>\n<li>Define a number (slider) to set the desired WTW state.<\/li>\n<\/ul>\n<p>The last two are visible on the GUI (see screenshots)<\/p>\n<pre class=\"\"># Include MQTT broker\r\nmqtt:\r\n\r\n# Include other files\r\nautomation: !include automations.yaml\r\ngroup: !include groups.yaml\r\nnotify: !include notify.yaml\r\nsensor: !include sensor.yaml\r\n\r\n# Xiaomi\r\nxiaomi_aqara:\r\n  gateways:\r\n   - mac: &lt;macaddress&gt;\r\n     key: !secret xiaomi_aqara\r\nalert:\r\n  wtw_filter_change:\r\n    name: Your WTW needs a new filter!\r\n    done_message: Your WTW filter is changed. Awesome!\r\n    entity_id: sensor.renoventhr_changefilter\r\n    state: '1'\r\n    repeat: 720 # Every 12 hours\r\n    can_acknowledge: False\r\n    skip_first: False\r\ninput_boolean:\r\n  wtw_boost:\r\n    name: WTW state is boosted\r\n    initial: off\r\n    icon: mdi:vanish\r\ninput_number:\r\n  wtw_desired_state:\r\n    name: WTW desired state\r\n    min: 0\r\n    max: 3\r\n    initial: 2\r\n    icon: mdi:fan<\/pre>\n<p>&nbsp;<\/p>\n<h2>automations.yaml<\/h2>\n<p>In this section we define the <a href=\"https:\/\/home-assistant.io\/components\/automation\/\">automations<\/a> (or logic) that take place on state changes. I\u2019ve defined a number to make the system as user friendly as possible:<\/p>\n<ul>\n<li><u>wtwBoostGUI<\/u>: Changes the state of the WTW \u2013 by publishing a value via MQTT- and switches the mechanical fan to the state defined with the switch on the GUI. It also hides\/shows the slider (for desired state) and sends a notification to inform me;<\/li>\n<li><u>wtwDesiredState<\/u>: Change the state of the WTW based on the input provided with the slider;<\/li>\n<li><u>wtwFilterChange<\/u>: Turns on a LED if the filter needs to be changed (and turns it off when its changed);<\/li>\n<li><u>bathroom_humidity_high<\/u>: Sets the wtw Boost switch to True if the humidity is higher than 65%.<\/li>\n<li><u>bathroom_humidity_low<\/u>: Sets the wtw Boost switch to False if the humidity is lower than 60%.<\/li>\n<\/ul>\n<pre class=\"\">- id: wtwBoostGUI\r\n  alias: 'WTW - Handle actions on boost'\r\n  trigger:\r\n    platform: state\r\n    entity_id: input_boolean.wtw_boost\r\n  action:\r\n    - service: group.set_visibility\r\n      data_template:\r\n        entity_id: group.wtw_user_state\r\n        visible: \"{{ trigger.from_state.state }}\"\r\n    - service: notify.notify\r\n      data_template:\r\n        title: \"WTW boost\"\r\n        message: \"WTW boost is {{ trigger.to_state.state }}\"\r\n    - service_template: &gt;-\r\n            {% if (trigger.to_state.state == 'on') %}\r\n              switch.turn_on\r\n            {% else %} \r\n              switch.turn_off\r\n            {% endif %}\r\n      entity_id:\u00a0 switch.plug_158d00015dc530\r\n    - service: mqtt.publish\r\n      data_template:\r\n        topic: \"RenoventHR\/setWTWstate\"\r\n        retain: true\r\n        payload: &gt;-\r\n                 {% if (trigger.to_state.state == 'on') %}\r\n                    3\r\n                 {% else %}\r\n                   {{ states.input_number.wtw_desired_state.state | int }}\r\n                 {% endif %}\r\n- id: wtwDesiredState\r\n  alias: wtwDesiredStateSensor\r\n    hide_entity: True\r\n  trigger:\r\n    platform: state\r\n    entity_id: input_number.wtw_desired_state\r\n  action:\r\n    - service: mqtt.publish\r\n      data_template:\r\n        topic: \"RenoventHR\/setWTWstate\"\r\n        retain: true\r\n        payload: '{{trigger.to_state.state | int}}'\r\n\r\n- id: wtwFilterChange\r\n  alias: 'WTW - Turn light on if filter needs change'\r\n  trigger:\r\n    platform: state\r\n    entity_id: sensor.renoventhr_changefilter\r\n  action:\r\n    - service: light.turn_off\r\n      entity_id: light.gateway_light_34ce00907b0f\r\n    - condition: state\r\n      entity_id: sensor.renoventhr_filterchange\r\n      state: '1'\r\n    - service: light.turn_on\r\n      entity_id: light.gateway_light_34ce00907b0f\r\n      data:\r\n        color_name: \"red\"\r\n- id: bathroom_humidity_high\r\n  alias: Monitor humidity in bathoom &gt; 65%\r\n  trigger:\r\n    platform: state\r\n    entity_id: sensor.humidity_158d000170f9aa\r\n  condition:\r\n    condition: and\r\n    conditions:\r\n      - condition: numeric_state\r\n        entity_id: sensor.humidity_158d000170f9aa\r\n        above: 65\r\n      - condition: state\r\n        entity_id: input_boolean.wtw_boost\r\n        state: 'off'\r\n  action:\r\n    - service: notify.notify\r\n      data:\r\n        title: \"Bathroom Humidity\"\r\n        message: 'Humidity is too high ({{ states.sensor.humidity_158d000170f9aa.state }} %)'\r\n    - service: input_boolean.turn_on\r\n      entity_id: input_boolean.wtw_boost\r\n- id: bathroom_humidity_low\r\n  alias: Monitor humidity in bathoom &lt; 60%\r\n  trigger:\r\n    platform: state\r\n    entity_id: sensor.humidity_158d000170f9aa\r\n  condition:\r\n    condition: and\r\n    conditions:\r\n      - condition: numeric_state\r\n        entity_id: sensor.humidity_158d000170f9aa\r\n        below: 65\r\n      - condition: state\r\n        entity_id: input_boolean.wtw_boost\r\n        state: 'on'\r\n  action:\r\n    - service: notify.notify\r\n      data:\r\n        title: \"Bathroom Humidity\"\r\n        message: 'The humidity in now okay ({{ states.sensor.humidity_158d000170f9aa.state }} %)'\r\n    - service: input_boolean.turn_off\r\n      entity_id: input_boolean.wtw_boost<\/pre>\n<p>&nbsp;<\/p>\n<h2>customize.yaml<\/h2>\n<p>The <a href=\"https:\/\/home-assistant.io\/docs\/configuration\/customizing-devices\/\">customize<\/a> section allows you to customize the look and feel of some sensors. In this case I\u2019m changing the name to a more readable name and icon of the WTW state and Change Filter.<\/p>\n<pre class=\"\">sensor.renoventhr_wtwstate:\r\n  friendly_name: WTW stand\r\n  icon: mdi:fan\r\nsensor.renoventhr_changefilter:\r\n  friendly_name: Filter Vervangen \r\n  icon: mdi:exclamation<\/pre>\n<p>&nbsp;<\/p>\n<h2>groups.yaml<\/h2>\n<p>The GUI is mostly configured using the <a href=\"https:\/\/home-assistant.io\/components\/group\/\">groups<\/a> section. What components are showed and in what tabs is defined here. In the screenshot you\u2019ll see I\u2019ve put the boost and desired state on the front-page where the actual sensors are in tabs that correspondent to the actual floors.<\/p>\n<pre class=\"\">default_view:\r\n  view: yes\r\n  icon: mdi:home\r\n  entities:\r\n    - group.floor1\r\n    - group.floor2\r\n    - group.wtw_user\r\n    - group.wtw_user_state\r\n    - alert.wtw_filter_change\r\nwtw_user:\r\n  name: WTW Status\r\n  icon: mdi:fan\r\n  entities:\r\n    - input_boolean.wtw_boost\r\nwtw_user_state:\r\n  name: State\r\n  icon: mdi:settings\r\n  entities:\r\n    - input_number.wtw_desired_state\r\nfloor1:\r\n  name: 1e verdieping\r\n  view: yes\r\n  entities:\r\n    - group.bathroom\r\nbathroom:\r\n  name: Badkamer\r\n  entities:\r\n    - sensor.humidity_158d000170f9aa\r\n    - sensor.temperature_158d000170f9aa\r\n    - switch.plug_158d00015dc530\r\nfloor2:\r\n  name: 2e verdieping\r\n  view: yes\r\n  entities:\r\n    - group.wtw\r\nwtw:\r\n  name: Renovent HR\r\n  entities:\r\n    - sensor.renoventhr_wtwstate\r\n    - sensor.renoventhr_changeFilter<\/pre>\n<p>&nbsp;<\/p>\n<h2>sensor.yaml<\/h2>\n<p>Unlike the Xiaomi Agara gateway my module isn\u2019t present by default, it needs to be defined in the <a href=\"https:\/\/home-assistant.io\/components\/sensor\/\">sensor<\/a> section. Since I\u2019ve equipped the module with a MQTT interface I\u2019m using two <a href=\"https:\/\/home-assistant.io\/components\/sensor.mqtt\/\">MQTT sensors<\/a> and point them to the corresponding topics.<\/p>\n<pre class=\"\"># Renovent HR\r\n  - platform: mqtt\r\n    name: RenoventHR_wtwState\r\n    state_topic: RenoventHR\/wtwState\r\n  - platform: mqtt\r\n    name: RenoventHR_changeFilter\r\n    state_topic: RenoventHR\/changeFilter<\/pre>\n<p>&nbsp;<\/p>\n<h1><strong>Source Files<\/strong><\/h1>\n<p>If you want to access the PCB design (schematic, board and part list) or the Arduino code, you can find them on Github:\u00a0<a href=\"https:\/\/github.com\/IngmarVerheij\/RenoventHR\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/<\/a><\/p>\n<p>&nbsp;<\/p>\n<h1><strong>To-do<\/strong><\/h1>\n<p>I know, in the introduction I told you I was finished. Well the module is finished and so is the solution, but I still need to design and print a case for the module. Once that\u2019s finished (and I\u2019m satisfied) I\u2019ll upload another photo.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Begin 2015 I\u2019ve started on my first IoT project; building a smart heat recovery system (or warmte terugwin unit \u2013 WTW). Back then I wrote an article (in Dutch, see here) explaining why I felt this was necessary and my initial approach. I never could have expected the journey I started, I had opened Pandora\u2019s [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","footnotes":""},"categories":[288],"tags":[682,685,680,681,683,684,661],"class_list":["post-7031","post","type-post","status-publish","format-standard","hentry","category-other","tag-esp8266","tag-hass","tag-heat-recovery","tag-iot","tag-mqtt","tag-rest","tag-wtw"],"_links":{"self":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/7031","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/comments?post=7031"}],"version-history":[{"count":17,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/7031\/revisions"}],"predecessor-version":[{"id":7055,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/posts\/7031\/revisions\/7055"}],"wp:attachment":[{"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/media?parent=7031"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/categories?post=7031"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ingmarverheij.com\/en\/wp-json\/wp\/v2\/tags?post=7031"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}