Here I am going to present a very nice private project to keep you busy in these beautiful, warm summer days. Building your own home automation using the open-source platform Home Assistant.
Home Assistant is a powerful, highly customisable open-source home automation platform that allows users to control and automate their smart home devices. It can work in a Docker container in your private home cloud, on a Raspberry Pi machine, or even inside an old notebook or pc. It integrates with all your smart devices and controllers, allows you to collect data, build dashboards, run analytics, use AI, and run triggered automations. Programming is straightforward, mostly using low-code YAML configurations and scripting inside these configurations. There is also Python support for complex tasks, but you probably won’t need it. Setting it up for your home, you will be not only automating your smart-home devices from a central place, but also exercising with important technologies used today, like microservices, IOT integrations, AI, and Data science.
Short info
Home Assistant works with a complete automation object model that, out of the box, handles all the tasks needed for robust home automation. The most important ones are Areas, Devices, and Entities. Automation components are registered as devices, callable services, or stateful entities and can be grouped per location using Areas. Here is the basic core structure of the Home Assistant:

Configuration of everything is done using YAML files, and you can script in the YAML files using a scripting language called Jinja 2. Getting accustomed to that kind of low-code programming takes time, but once you become familiar with it, it becomes fun and flexible. Here is an example configuration with YAML and a Jinja script in it:
template:
- sensor:
- name: "Daily Gas Cost"
unique_id: daily_gas_cost
state: "{{ (states('sensor.gasusage_today')|float * states('input_number.gasprice')|float)|round(2) }}"
availability: "{{ states('sensor.gasusage_today')|is_number }}"
unit_of_measurement: "€"
device_class: monetary
state_class: total
The administrator interface is really basic and user-friendly; you can do nearly all the basic configuration tasks here from the interface:

Dashboards have their own designer, and it is really simple and flexible. Here you can create a dashboard to control from the web and mobile app interfaces of Home Assistant:

Home Assistant also has a beautiful app to control everything from your mobile phone:

For programming, you can set up and use an internal editor, but there is also a plug-in to connect Visual Studio Code to program your own automations and use auto-complete inside Jinja and YAML files, described here.
Getting started
Let’s get hands-on with setting up the Home Assistant. I want to set it up as a microservice in a Docker container in my own private cloud. There are other ways to install it, including buying a paid hosting, but for security reasons, I recommend that you use a home-based device. Here you can find more info on how to install it: https://www.home-assistant.io/installation/. After installing, I recommend you also install community plug-ins from HACS (Home Assistant Community Store), since the components that come with Home Assistant core are a bit too basic: https://www.hacs.xyz/docs/use/configuration/basic/. You need to have a GitHub account to install it.
After installing Home Assistant, connect it to a domain name in your own domain controller and set up multi-factor authentication to be able to use it remotely or from mobile apps: https://www.home-assistant.io/docs/authentication/multi-factor-auth/.
The first appliance you want to integrate is your smart electricity-gas meter. These meters have a port on them to read the values, and you can purchase a dongle to connect to the port and send the data to a network receiver. The device looks like this. Obtain one and follow the instructions to connect it to WIFI:

Then you need to integrate it into Home Assistant. Many smart-home devices today have a way to integrate into a home assistant and explain it on their websites and manuals. But we will not use the default way for our electricity meter. I do not recommend connecting it directly to Home Assistant, but rather to use a broker service for a more stable and lightweight integration. To achieve this, we will use the MQTT protocol. MQTT stands for Message Queuing Telemetry Transport, and is a lightweight, publish-subscribe network protocol designed for connecting remote devices with limited resources, like devices in a home IoT space. Therefore, I install a MQTT broker, Mosquitto, as an additional microservice in my container group and connect my electricity meter to it using the MQTT protocol:


Then connect the broker to your home assistant using MQTT discovery, and use the standard DMSR reader component to connect your electricity meter using MQTT to Home Assistant (https://www.home-assistant.io/integrations/dsmr_reader/):

And voila, now you can manage your energy usage from Home Assistant’s energy tab and dashboard components:

Customizing
After you connect all your devices following the instructions, now it is time to customize the limited standard functionalities they offer and build our dream smart home with fancy automations, dashboards, and integrations.
The devices you have added contain stateful objects called “entities”, from which you can read and change the state of the other components, or programmatically using Jinja scripts. Here is an example of how you can read the state of an entity inside a YAML configuration:

We can create our own entities using the ‘Helpers’ to store globally used variables and use, record, and assign them just like the other sensors and entities in Home Assistant. Their last value is always saved before a system restart, and if you configure it so, their historical values are also recorded. Here, I create three Helpers as “input control” entities from the Settings>Devices>Helpers>Create Helper, two for recording the up-to-date electric and gas prices, and one for keeping the state of my boiler:

After creating my helpers and registering up-to-date electric and gas prices in them, I would like to calculate my daily, weekly, monthly, and yearly energy usage. I do so by creating custom sensors and calculating the value using Jinja scripts. To do so, create a “packages” folder in your Home Assistant root directory and include it in Home Assistant configuration.yaml:

Then add a new YAML file here called “mysensors.yaml” to include your new custom sensors:
template:
- sensor:
- name: "Daily Gas Cost"
unique_id: daily_gas_cost
state: "{{ (states('sensor.gasusage_today')|float * states('input_number.gasprice')|float)|round(2) }}"
availability: "{{ states('sensor.gasusage_today')|is_number }}"
unit_of_measurement: "€"
device_class: monetary
state_class: total
- name: "Weekly Gas Cost"
unique_id: weekly_gas_cost
state: "{{ (states('sensor.gasusage_this_week')|float * states('input_number.gasprice')|float)|round(2) }}"
availability: "{{ states('sensor.gasusage_this_week')|is_number }}"
unit_of_measurement: "€"
device_class: monetary
state_class: total
- name: "Monthly Gas Cost"
unique_id: monthly_gas_cost
state: "{{ (states('sensor.gasusage_this_month')|float * states('input_number.gasprice')|float)|round(2) }}"
availability: "{{ states('sensor.gasusage_this_month')|is_number }}"
unit_of_measurement: "€"
device_class: monetary
state_class: total
- name: "Daily Electric Cost"
unique_id: daily_electric_cost
state: "{{ (states('sensor.daily_energy_delivered')|float * states('input_number.electricprice')|float)|round(2) }}"
availability: "{{ states('sensor.daily_energy_delivered')|is_number }}"
unit_of_measurement: "€"
device_class: monetary
state_class: total
- name: "Weekly Electric Cost"
unique_id: weekly_electric_cost
state: "{{ (states('sensor.weekly_energy_delivered')|float * states('input_number.electricprice')|float)|round(2) }}"
availability: "{{ states('sensor.weekly_energy_delivered')|is_number }}"
unit_of_measurement: "€"
device_class: monetary
state_class: total
- name: "Monthly Electric Cost"
unique_id: monthly_electric_cost
state: "{{ (states('sensor.monthly_energy_delivered')|float * states('input_number.electricprice')|float)|round(2) }}"
availability: "{{ states('sensor.monthly_energy_delivered')|is_number }}"
unit_of_measurement: "€"
device_class: monetary
state_class: total
Now I can track my electricity and gas usage in Euros and see them on my dashboard in value boxes or graphs:

Speaking of graphs, the standard ones from Home Assistant are some too basic. In my dashboards, I use the community-made HACS component called Apex charts. It provides much more flexibility and programming options, as well as multi-dimensional displays. Read here on how to add it to your Home Assistant: https://community.home-assistant.io/t/beginner-how-to-add-how-to-add-apexchart/721152. Here I program a fancy temperature graph from the data from my smart temperature valves using Apex chart control:

The YAML I use is as follows:
type: custom:apexcharts-card
header:
show: false
title: Greenhouse
graph_span: 24h
cache: true
update_interval: 5m
now:
show: true
span:
start: hour
offset: "-23h"
hours_12: false
apex_config:
stroke:
width: 3
curve: smooth
yaxis:
show: true
showAlways: true
showForNullSeries: true
seriesName: Temp
opposite: false
reversed: false
logarithmic: false
tickAmount: 30
min: 14
max: 26
forceNiceScale: true
floating: false
decimalsInFloat: 0
series:
- entity: sensor.living_room_temperature
name: Living
- entity: sensor.bedroom_temperature
name: Bedroom
- entity: sensor.office_temperature
name: Office
- entity: sensor.bathroom_temperature
name: Bathroom
Advanced customisations using templates and automations
I find the functionality of my boiler thermostat to be a bit too simple. I have decided to add radio buttons to change the mode of my boiler to Eco, Away, and Off via my Home Assistant dashboard. For a radio button, I use the horizontal stack card component:

All 4 buttons should run the same logic. Also, if my boiler restarts, it needs to update the buttons here, calling the same. So I need to use a kind of common global function and call it from everywhere needed, also on startup. Home Assistant has a feature called “templates” that contains reusable Jinja scripts, which are stored in the “custom_templates” folder of Home Assistant:

The modes and the current mode of my boiler are registered in the third helper I created in the previous section (evohome). Here, I decide to map the status of my boiler to my custom helper called “evohome”, and assign it to my horizontal stack component:

I create two templates called evohometostat.jinja and stattoevohome.jinja, first maps the boiler mode change event to my helper, and second maps the helper value changes to boiler mode changes. Here is their code:
{% macro evohome_to_stat() %}
{%- if (state_attr('climate.greenhouse','preset_mode') == 'none') -%}Default
{%- elif (state_attr('climate.greenhouse','preset_mode') == 'away') -%}Away
{%- elif (state_attr('climate.greenhouse','preset_mode') == 'eco') -%}Eco
{%- elif (is_state('climate.greenhouse','off')) -%}Off
{% else %}Default
{%- endif -%}
{% endmacro %}
{% macro stat_to_evohome() %}
{%- if is_state('input_select.evohome','Default') -%}Auto
{%- elif is_state('input_select.evohome','Away') -%}Away
{%- elif is_state('input_select.evohome','Eco') -%}AutoWithEco
{%- elif is_state('input_select.evohome','Off') -%}HeatingOff
{% else %}Auto
{%- endif -%}
{% endmacro %}
Then I need to trigger them from my horizontal stack, from the startup of the system, and from boiler mode change events. To be able to do that, I need to create Home Assistant Automations. Go to Settings>Automations&Scenes in the Home Assistant menu. Here, I created two automations. First is from the boiler (named “Greenhouse”) mode change to the custom helper option change and button group update. This automation needs to use the evohome_to_stat() function and only run if the state of the boiler mode has changed from the last known mode. I set it up like this:

Note the usage of the statement {% from “template.jinja” import evohome_to_stat %} just before calling the template. You need to include the template function before using it, just like the “using” keyword of .NET.
The second automation will do the opposite; it will update the mode of the boiler when we change the mode on our dashboard. I declare it like this:

You can also configure automations manually from the “automations.yaml” file in the root folder. Here is how the automations look in Visual Studio:

To test my new boiler control dashboard item, first I check that the automations are loaded by default on Home Assistant startup. I check if these lines exist in the “configuration.yaml” file:

Then I need to restart the Home Assistant service. You can do it very easily from the developer tools menu of Home Assistant. I do the “Quick reload” option to perform a soft restart :

And afterwards, time to play with my new boiler control buttons and see them working fine:

Cheers!
We are now experienced with the basics of Home Assistant, and yet done some advanced functionality like running automations with templates. There is certainly more Home Assistant can do, but I think I have given you a nice introduction here. Have fun and enjoy the warm sunny days!
Home Assistant Official Documentation: https://www.home-assistant.io/docs