Optimising warm water management with solar thermal energy

Out of the box, a lot of solar thermal energy installations are not really functioning in a transparent way. It is quite difficult to really know what the installation is doing and how much energy it adds into the warm water reservoir. Our installation, a Buderus gas condensing boiler system (Logamax plus GB162-25 V3) that manages our solar thermal panels, does give some information on the output of the system, but it does not have a unit, thus the numbers are not really directly interpretable, besides seeing if you produced more, less or a lot less/more energy through the solar thermal panels compared to the previous days.

Solar thermal installation’s added energy to the warm water system

After 10 years, our solar thermal installation failed to function for an undefined period of time (we don’t know how the system really failed), including at least one summer. The result was that the solar liquid became very viscous as during the summer months it overheated and boiled in the panels. The result was partially blocked hoses carrying the solar liquid from the roof to the heating system in the basement. Fortunately, some minor flow still was assured so that we could flush the whole system and get rid of most of the solidified liquid that was blocking the hoses. A faulty pump was the reason for this failure.

The Buderus management system showed that the pump was working. What I did not know was, that the display only indicated that it had sent electricity to the pump. It did not get any reliable feedback from the pump indicating if the pump really pumps. So technically, the user is blind and does not really know if the pump is really working or not. After flushing the hoses and panels, as well as installing a new pump, the system was refilled with fresh solar fluid and luckily the system came back to life.

I was then looking for a monitoring solution and find this device from a dutch enthusiast. Its EMS-ESP software helps me render the information from my heating system, including solar thermal panels, visible in my home automation system.

From there started a journey to understand how the heating system works and figuring out how to set it up correctly. To optimise the system, maximise the collection of heat from the sun and minimise gas consumption and heat losses, I worked on the following variables:

  • I augmented the maximal temperature of the warm water, when heated by the solar thermal system. I went up to 80°C (beware that such a high temperature also has side-effects, mainly on the longevity of the appliance). Be careful that your warm water recipient does not feed very hot water into your pipes. The risk to burn yourself, especially for kids, is extremely high. Make sure to have a mixing tap installed (at the exit of your warm water appliance and before your pipe system) that only lets water flow to your house system with a pre-defined maximal temperature, for example 50°C.
  • I reduced the temperature where the gas condensing fills in to heat up the warm water. The lower you can go in temperature, and still have enough warm water at your disposal, the better it is, as cou can use more energy from the sun. Ideally, the boiler is at 45°C each morning so that I have enough reserve to add a lot of heat to it. My gas boiler jumps in when warm water temperature drops to 45°C.
  • I configured the warm water circulation pump so that it only kicks in, when imminent warm water demands from a remote location in the house happen. The circulation pump starts when the light in the shower is witched on. We just have to wait for half a minute to make sure warm water is available in the water collector next to the shower. Having the circulation pump run all day, “extracts” the heat from your warm water reservoir. Without any circulation, my warm water reservoir looses between 0.5 and 0.7°C per hour.
  • To avoid excessive gas consumption, I completely switch off the heating circuit of the gas system during summer months (I only keep the warm water circuit switched onI). Our system happens to consume between 1 and 1.5 cubic-metre of gas even if all heating appliances are shut off an d the outside thermostat communicates to the system that there is no heating needed. This might by a configuration issue, but until now I could not find an issue in the configuration parameters.

Exemplary data on solar thermal energy for hot water

We found it particularly difficult to find objective real life data on the usage of solar heat panels for hot drinking water. Our solar system (installed for for hot water only, not for heating up the house) is configured to allow for hot drinking water temperatures up to 80°C. A (child-)protection is installed so that the boiler will never deliver more than 60°C at all times. The gas condensing heating system only kicks in when the water temperature in the upper part of the water reservoir drops to 45 °C and will stop heating when the upper part is at 55°C. The following examples are based on real data coming out of our system, which consists of a Buderus Logamax Plus GB162-25 v3 gas condensing heater and a Buderus SM300/1 W warm water reservoir.

To better understand how these water heating systems function, feel free to consult this article (in german). The article also shows a graph of the water reservoir with the upper and lower parts and its corresponding heating systems.

  1. Example of heat consumption after showering
1 bath & 2 showers (July 20th, 21°C outside temp at 9:00, sunny conditions, Western Europe)

The above graph (green line) shows that our warm water reserve is at 75°C at 08:45 in the upper part of our boiler. The first chute at 8:45 is due to a bath tub filling, at 9:05 one person takes a shower, at 09:30 a second person takes a shower. The remaining temperature is around 57°C.

Around 9:40, the sun is providing enough heat through the solar heat panels (yellow line) and the lower sector temperature (blue line) in the boiler begins to rise.

  1. Example of the gas heating helping out to provide sufficient hot water

When the water temperature drops in the upper part of the boiler to 45°C, the gas heating will heat this part up to 55°C again. This normally takes around 10 minutes and consumes around 0.2 cubic meter of gas. (To properly measure this, the house heating part of the gas system is manually switched off. The only gas consumption is due to warm water heating.)

Warm water temperature, heated by solar panels and gas heating system (July)

The above graph shows on the green line, above the Day 13 when the gas heating jumps in to heat up the upper part of the warm water reservoir. Over the week’s time shown in the graph, this happened 4 times. We are in July and outside temperatures are mid to end 20s°C and it is sunny.

  1. How much energy will be lost over night, when nobody uses warm water?
Temperature loss over time (due to non-perfect reservoir insulation)

Over 10 hours, from 22:30 to 8:30, the temperature in the upper part (yellow line) of the hot water reservoir drops by 5.5°C. Of cours, the lower part drops quicker, but when using hot water, it is taken from the upper part. So the heat losses are around 0.55°C per hour when the hot water is around 70°C. The losses might vary, if the overall temperature is lower. The higher the overall temperature is (and thus the difference to the room temperature), the higher the loss of heat will be. Around 60°C, we measure 0.51°C losses per hour. These losses cannot be avoided. Any insulation will produce heat losses.

Set up SSH keys on Ubuntu 24.04

Login to your Ubuntu client with the username for which you want to create a key pair. Create the key with the following command:

ssh-keygen

The keys will be saved in your home directory under: /.ssh/id_rsa

Now copy your public key to the server that you want to connect to crom your client without using a password:

ssh-copy-id myusername@remote_host

That’s it. Now try to connect to your server with that username. If all works fine, no password will be asked for.

For a more comprehensive tutorial with more explanations, please consult this excellent page.

Install and configure AWSTATS

General configuration

Using awstats to analyse your web usage statistics if your Apache webserver is running behind an Nginx reverse proxy server, needs some special configuration steps.

Install awstats on your system:

sudo apt install awstats

Enable the awstats apache configuration (and cgi if it is not enabled yet):

sudo a2enmod cgi
sudo a2enconf awstats

Restart the apache service:

sudo systemctl restart apache2

Edit the configuration awstats configuration file or create a configuration file for each virtual host. We are using combined log formats and need to configure this.

sudo cp /etc/awstats/awstats.conf /etc/awstats/awstats.www.mysite.com.conf 
sudo nano /etc/awstats/awstats.www.mysite.com.conf

Configure the virtual host log file path in your awstats configuration file. Make sure you select the correct one (might be the SSL log file).

LogFile="/var/log/apache2/www.mysite.com.access_log"
LogFormat=1

Configure the domain name and domain aliases:

SiteDomain="www.mysite.com"
HostAliases="mysite.com XYZ.mysite.com"

Optionally, if you want DNS lookup (conversing of IP’s into hostnames):

DNSLookup=1

Now update the awstats statistics folder by running the following command:

sudo /usr/lib/cgi-bin/awstats.pl -config=www.mysite.com -update 

Go to your awstats page:

https://www.mysite.com/cgi-bin/awstats.pl?config=www.mysite.com

Depending on your configuration, cgi-bin might need to be replaced by awstats.

Note on security: Make sure that your awstats statistics page is not visible from outside, even more if you are allowing your statistics to be updated through the web interface. I am forcing an htaccess realm through the Nginx reverse proxy on these directory.

If you want to update your statistics through the web interface, set the corresponding flag.

AllowToUpdateStatsFromBrowser=1

The following files have to be readable or writable by the apache service (www-data) user:

/var/lib/awstats (read & write)
/var/log/apache2/www.mysite.com.access_log (read)

Alternatively, add a crontab (edit /etc/crontab) entry:

* */15 * * * root /usr/lib/cgi-bin/awstats.pl -config=www.mysite.com -update > /dev/null

Configuration when running your web server behind an NGINX reverse proxy

Configure your reverse proxy correctly

In the NGINX reverse proxy configuration for your website, make sure you send the real IP-address of the client requesting your page through the header information to the web server. Add the following lines to the root location of your NGINX reverse proxy configuration for your web site (sudo nano /etc/nginx/sites-available/www.mysite.com). For more information on this, check here.

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;

Configure your web server to write the correct IP of the client into the log file (instead of the reverse proxy IP). Add the following to your apache virtual host file (sudo nano /etc/apache2/sites-available/www.mysite.com.conf):

RemoteIPHeader X-Real-IP
RemoteIPInternalProxy IP.PROXY.SERVER
RemoteIPTrustedProxy IP.PROXY.SERVER
RemoteIPHeader X-Forwarded-For
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined

%{X-Forwarded-For}i replaces the first parameter in the combined log format, which normally is %h or %a. So if the LogFormat is set in your configuration file, make sure it has the above format.

Apache needs the remoteip module to be enabled in order to treat this information:

sudo a2enmod remoteip

To load the following module in the main Apache configuration file (sudo nano /etc/apache2/apache2.conf), delete the hash sign (#) before the following line:

LoadModule remoteip_module modules/mod_remoteip.so

Test the configuration and reload the apache service.

apache2ctl configtest
service apache2 restart

If you believe you have header issues and don’t know if the bug is on the level of the reverse proxy or the web server, check what header information is arriving at the web server.

Display the received headers (from reverse proxy) in html file

If you are running a reverse proxy server in front of your webserver, it might sometimes be useful to see which header variables are reaching your webserver. To achieve this, create the following headers.php file in the root of your webserver documents folder:

<?php
echo "<h1>Received Headers</h1>";
$headers =  getallheaders();
foreach($headers as $key=>$val){
  echo $key . ': ' . $val . '<br>';
}
echo "======================"
//echo '<pre>'; print_r($_SERVER); echo '</pre>';

?>

openHAB gauge for car fuel tank status

I need a gauge style widget that shows the percentage of fuel left in the tank. The item delivers a number between 0 and 1 and I wanted to display a percentage number between 0 and 100. Here is the functioning code that modifies an item value in the valueText component.

component: oh-gauge-card
config:
  action: navigate
  actionPage: page:cars
  actionPageTransition: f7-dive
  borderColor: =(items.myCar_FuelLevel.state<0.26)?"orange":"red"
  item: myCar_FuelLevel
  max: 1
  min: 0
  title: My car
  type: semicircle
  valueText: =(items.myCar_FuelLevel.state*100) + " %"
  valueTextColor: white
slots: null

renders to:

It might be more interesting to show the remaining mileage in the text though:

component: oh-gauge-card
config:
  action: navigate
  actionPage: page:cars
  actionPageTransition: f7-dive
  borderColor: =(items.myCar_FuelLevel.state<0.26)?"orange":"red"
  item: myCar_FuelLevel
  max: 1
  min: 0
  title: My car
  type: semicircle
  valueText: =(items.MyCar_DistanceLeft.state)
  valueTextColor: white
slots: null

which renders to:

openHAB Command Line Interface commands

  backup [--full] [filename]   -- Stores the current configuration of openHAB.
  clean-cache                  -- Cleans the openHAB temporary folders.
  console                      -- Opens the openHAB console.
  info                         -- Displays distribution information.
  reset-ownership              -- Gives openHAB control of its own directories.
  restore [--textconfig] [--uiconfig] filename
                               -- Restores openHAB configuration from a backup.
  showlogs                     -- Displays the log messages of openHAB.
  start [--debug]              -- Starts openHAB in the terminal.
  status                       -- Checks to see if openHAB is running.
  stop                         -- Stops any running instance of openHAB.

Command a Philips Hue light from a KNX switch through openHAB

I am using openHAB as my main home automation server. I want to be able to switch on/off Philips Hue lights with the Gira KNX TS3 sensors installed in my rooms.

Basically, you need to create a group address, map it to the TS switch channel, create a virtual KNX device in openHAB and create two rules to link both objects (one rule for switching ON and one for switching OFF).

In the ETS software, create a group address (e.g. 1/9/9) and map it to the TS button’s channel that should allow switching the Hue light ON and OFF.

In openHAB, create a KNX device thing called Virtual KNX switch. Add a channel with type Switch Control and configure it to address 1/9/9. Map an item of type Contact to this channel (let’s name it KitchenVirtualSwitch).

Assuming that your Hue light is called HueLight, create a rule to switch the light ON:

configuration: {}
triggers:
  - id: "1"
    configuration:
      command: ON
      itemName: KitchenVirtualSwitch
    type: core.ItemCommandTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: "

        \          HueLight.sendCommand(ON)

        \          logInfo( \"openHAB.Rules\",\"KitchenVirtualSwitch TS => Hue ON\"
        )

        \ "
    type: script.ScriptAction

The logInfo entry is optional, but very helpful when debugging. Let’s create a second rule for switching the light OFF:

configuration: {}
triggers:
  - id: "1"
    configuration:
      command: OFF
      itemName: KitchenVirtualSwitch
    type: core.ItemCommandTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: "

        \          HueLight.sendCommand(OFF)

        \          logInfo( \"openHAB.Rules\",\"KitchenVirtualSwitch TS => Hue OFF\"
        )

        \ "
    type: script.ScriptAction

Home Assistant Nginx Proxy configuration

Here is a working NGINX proxy configuration for Home Assistant:

server {

    server_name HOST.DOMAIN.NAME;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / {
        satisfy any;
        allow 10.X.X.0/24;
        allow 10.X.X.0/24;
        deny all;
        auth_basic              "Restricted access";
        auth_basic_user_file    /etc/passwords/passwords;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_headers_hash_max_size 512;
        proxy_headers_hash_bucket_size 128;
        proxy_pass http://INTERNAL_HOME_ASSISTANT_IP:8123;
        include proxy_params;
     }


    listen 443 ssl;

    ssl_certificate /etc/letsencrypt/live/HOST.DOMAIN.NAME/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/HOST.DOMAIN.NAME/privkey.pem; # managed by Certbot
}

server {
    if ($host = HOST.DOMAIN.NAME) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name HOST.DOMAIN.NAME;

}