Heizung, Volkszaehler

The visualisation software volkszaehler does a very good job, as I have seen in the project VolkszaehlerACE3000 (Dockstar). So, I like to use it also for my Heizung temperature measurement.

The old style diagram was drawn by GNUplot, see the diagram below. Every 5 minutes a new diagram was calculated and ready for web visualization. But there was no interactive element to walk along the time axis. Also an automatic scaling in the vertical axis was difficult to make.

By finding the volkszaehler software it is now possible to do all that, what I missed in the old system.

/!\ Update 2019-12-22

Now volkszaehler works with an i5 server (1 GB RAM).











Data Input

Because the temperature data are located on another computer (EeePC900) in the local network, they have to be transfered to the local server, every 5 minutes. This transfer is triggered via cron job.

The simple way is to use scp with the utiliy sshpass and insert the password per script. In order to protect the remote password, this is done with root rights.

In order to avoid the sshd logging reverse mapping checking getaddrinfo for . [] failed - POSSIBLE BREAK-IN ATTEMPT! add in the server side file /etc/hosts the string rudiswiki14

If the transfer does not work, add for debugging the option -v to the scp call and start it manually.

# shell script to transfer temperature data

$ sudo cat /root/cp_heizung.sh
# File: cp_heizung.sh
# 2014-02-14 RudolfReuter
# copy actual temperatures from Heizung to local folder
# remote: /var/volatile/www/heizdata.csv
# local: /run/user/heizdata.csv

sshpass -p 'xxx' scp -pq -o StrictHostKeyChecking=no rudi@ /run/user/heizdata.csv

# setup on target computer
$ sudo nano /root/cp_heizung.sh

$ man sshpass   # check for sshpass installed
# if sshpass is not yet installed
$ sudo apt install sshpass

# Temperature data transfer every 5 minutes (root level)
$ sudo crontab -l
# for heizung volkszaehler copy remote data to local every 5 minutes
*/5 * * * * /root/cp_heizung.sh >/dev/null 2>&1

# setup on target computer
# edit crontab
$ sudo crontab -e

# restart cron
$ sudo service cron restart

The cron jobs have 4 pitfalls, which are difficult to debug. Take care about:

$ sudo crontab -l

Volkszaehler Web Frontend

For the setup of the channels and the interaction please have a look at Data Web Visualzation


phpmyadmin Utility

Now install first the database utility phpmyadmin.

/!\ If there was already a mySQL/MariaDB setup made, the root password must be cleared, see here for the explanation, and later restored. Otherwise you get an error: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO).

# remove root password
$ mysql -u root -p
ENTER password
MariaDB [(none)]> SET PASSWORD FOR root@localhost=PASSWORD('');
Query OK, 0 rows affected (0.01 sec)

Now install phpmyadmin.

$ sudo apt-get install phpmyadmin
[sudo] Passwort für rudi: 
Paketlisten werden gelesen... Fertig
Creating config file /etc/php/7.2/mods-available/bz2.ini with new version
Creating config file /etc/dbconfig-common/config with new version
Creating config file /etc/dbconfig-common/phpmyadmin.conf with new version
Creating config file /etc/phpmyadmin/config-db.php with new version
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
# see before how to remove the database root password.

Verbindungsmethode: Unix-Socket
MySQL-Datenbankname für phpmyadmin: phpmyadmin
MySQL-Benutzername: phpmyadmin@localhost
MySQL-Anwendungspasswort: o..

Now restore the database root password:

$ mysql_secure_installation


In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] y
New password: ...
Re-enter new password: ...
Password updated successfully!
Reloading privilege tables..
 ... Success!

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] n
 ... skipping.

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] n
 ... skipping.

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

Install Volkszaehler

Installation on Ubuntu 18.04-64.

Install and setup the volkszaehler per shell script:

$ mkdir $HOME/Install/volkszaehler
# Get the install script
$ cd $HOME/Install/volkszaehler
$ wget https://raw.github.com/volkszaehler/volkszaehler.org/master/bin/install.sh

# Make it executable
$ sudo chmod u+x install.sh

# Run the script
$ sudo bash install.sh
volkszaehler.org installation script

checking prerequisites: php: /usr/bin/php
 mysql: /usr/bin/mysql
 awk: /usr/bin/awk
 sed: /bin/sed
 grep: /bin/grep
 wget: /usr/bin/wget
 mktemp: /bin/mktemp
 mkdir: /bin/mkdir
 git: /usr/bin/git

checking php version: 7.2.24-0ubuntu0.18.04.1 >= 7.1, ok

volkszaehler setup...
volkszaehler path? [/home/rudi/volkszaehler.org]
git clone volkszaehler.org into /home/rudi/volkszaehler.org
Klone nach '/home/rudi/volkszaehler.org' ...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (16/16), done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 12105 (delta 5), reused 4 (delta 0), pack-reused 12089
Empfange Objekte: 100% (12105/12105), 7.56 MiB | 4.67 MiB/s, Fertig.
Löse Unterschiede auf: 100% (6843/6843), Fertig.
link from webserver to volkszaehler directory? [/var/www/volkszaehler.org] 
linking /var/www/volkszaehler.org to /home/rudi/volkszaehler.org
[sudo] Passwort für rudi:

checking composer...
~/volkszaehler.org ~/Install/volkszaehler
composer not found, downloading...
All settings correct for using Composer

Composer (version 1.9.1) successfully installed to: /home/rudi/volkszaehler.org/composer.phar
Use it: php composer.phar

composer: /home/rudi/volkszaehler.org/composer.phar

installing dependencies...
~/volkszaehler.org ~/Install/volkszaehler
Loading composer repositories with package information
Updating dependencies
# 5 min wait time ***********

Package operations: 58 installs, 0 updates, 0 removals
  - Installing symfony/routing (v4.4.2): Downloading (100%)         
  - Installing symfony/polyfill-mbstring (v1.13.1): Downloading (100%)         
  - Installing symfony/polyfill-php72 (v1.13.1): Downloading (100%)         
  - Installing symfony/polyfill-intl-idn (v1.13.1): Downloading (100%)         
  - Installing symfony/mime (v5.0.2): Downloading (100%)         
  - Installing symfony/http-foundation (v4.4.2): Downloading (100%)         
  - Installing ralouphie/getallheaders (3.0.3): Downloading (100%)         
  - Installing psr/http-message (1.0.1): Downloading (100%)         
  - Installing guzzlehttp/psr7 (1.6.1): Downloading (100%)         
  - Installing evenement/evenement (v3.0.1): Downloading (100%)         
  - Installing react/event-loop (v1.1.0): Downloading (100%)         
  - Installing react/stream (v1.1.0): Downloading (100%)         
  - Installing react/promise (v2.7.1): Downloading (100%)         
  - Installing react/promise-timer (v1.5.1): Downloading (100%)         
  - Installing react/cache (v1.0.0): Downloading (100%)         
  - Installing react/dns (v1.2.0): Downloading (100%)         
  - Installing react/socket (v1.3.0): Downloading (100%)         
  - Installing ratchet/rfc6455 (v0.2.6): Downloading (100%)         
  - Installing cboden/ratchet (v0.4.1): Downloading (100%)         
  - Installing psr/container (1.0.0): Downloading (100%)         
  - Installing symfony/service-contracts (v2.0.1): Downloading (100%)         
  - Installing symfony/polyfill-php73 (v1.13.1): Downloading (100%)         
  - Installing symfony/console (v4.4.2): Downloading (100%)         
  - Installing doctrine/lexer (1.2.0): Downloading (100%)         
  - Installing doctrine/annotations (v1.8.0): Downloading (100%)         
  - Installing doctrine/reflection (v1.0.0): Downloading (100%)         
  - Installing doctrine/event-manager (1.1.0): Downloading (100%)         
  - Installing doctrine/collections (1.6.4): Downloading (100%)         
  - Installing doctrine/cache (1.10.0): Downloading (100%)         
  - Installing doctrine/persistence (1.3.3): Downloading (100%)         
  - Installing doctrine/instantiator (1.3.0): Downloading (100%)         
  - Installing doctrine/dbal (v2.10.0): Downloading (100%)         
  - Installing doctrine/inflector (1.3.1): Downloading (100%)         
  - Installing doctrine/common (v2.11.0): Downloading (100%)         
  - Installing doctrine/orm (v2.7.0): Downloading (100%)         
  - Installing symfony/polyfill-ctype (v1.13.1): Downloading (100%)         
  - Installing symfony/yaml (v4.4.2): Downloading (100%)         
  - Installing guzzlehttp/promises (v1.3.1): Downloading (100%)         
  - Installing guzzlehttp/guzzle (6.5.2): Downloading (100%)         
  - Installing influxdb/influxdb-php (1.15.0): Downloading (100%)         
  - Installing symfony/event-dispatcher-contracts (v1.1.7): Downloading (100%)         
  - Installing symfony/event-dispatcher (v4.4.2): Downloading (100%)         
  - Installing andig/dbcopy (1.3.3): Downloading (100%)         
  - Installing andig/php-shunting-yard (1.0.2): Downloading (100%)         
  - Installing react/promise-stream (v1.2.0): Downloading (100%)         
  - Installing ringcentral/psr7 (1.2.2): Downloading (100%)         
  - Installing react/http (v0.8.5): Downloading (100%)         
  - Installing psr/log (1.1.2): Downloading (100%)         
  - Installing symfony/var-dumper (v5.0.2): Downloading (100%)         
  - Installing symfony/debug (v4.4.2): Downloading (100%)         
  - Installing symfony/error-handler (v4.4.2): Downloading (100%)         
  - Installing symfony/http-kernel (v4.4.2): Downloading (100%)         
  - Installing psr/http-server-handler (1.0.1): Downloading (100%)         
  - Installing react/child-process (v0.6.1): Downloading (100%)         
  - Installing symfony/process (v5.0.2): Downloading (100%)         
  - Installing php-pm/php-pm (2.0.2): Downloading (100%)         
  - Installing php-pm/httpkernel-adapter (2.0.2): Downloading (100%)         
  - Installing webpatser/laravel-uuid (3.0.2): Downloading (100%)         
Writing lock file
Generating autoload files

volkszaehler.org is not configured yet. creating new config from sample config file.
mysql root user? [root] 
mysql root password? [] ... see KeePass
mysql database? [volkszaehler] 
mysql admin to volkszaehler database? [vz-admin] 
mysql admin password? [] ..... see KeePass
mysql user? [vz] 
mysql password? [demo] 

create volkszaehler.org database and admin user? [y] y
creating database volkszaehler...
[sudo] Passwort für rudi: ...
creating db user vz-admin...
creating database schema...
~/volkszaehler.org ~/Install/volkszaehler
 ! [CAUTION] This operation should not be executed in a production environment!                 
 Creating database schema...
 [OK] Database schema created successfully!                                                     
 Processing entity "Volkszaehler\Model\Aggregate"
 Processing entity "Volkszaehler\Model\Entity"
 Processing entity "Volkszaehler\Model\Channel"
 Processing entity "Volkszaehler\Model\Aggregator"
 Processing entity "Volkszaehler\Model\Property"
 Processing entity "Volkszaehler\Model\Data"

 Proxy classes generated to "/home/rudi/volkszaehler.org/lib/Model/Proxy"

create volkszaehler.org database user? [y] 
creating db user vz with proper rights...

allow channel deletion? [n] y
granting db user vz delete rights...

insert demo data in to database? [n] n

Install Web Server

The easiest setup is with the PPM (PHP based) web server on port 8080.

1. Systemd Service setup

# Edit with editor "nano":
$ sudo nano /etc/systemd/system/middleware.service
Description=Volkszaehler.org Middleware
After=syslog.target network.target

ExecStart=/usr/bin/php /var/www/volkszaehler.org/vendor/bin/ppm start -c /var/www/volkszaehler.org/etc/middleware.json --cgi-path=/usr/bin/php
ExecReload=/bin/kill -HUP $MAINPID


2. Server configuration setup:

# Edit:
$ nano ~/volkszaehler.org/etc/middleware.json
    change: „static-directory“: „/var/www/volkszaehler.org/htdocs“, (was "htdocs")

3. Middleware routing URL setup

# Edit:
$ nano ~/volkszaehler.org/htdocs/js/options.js
title: 'Local (default)',
url: ''            # was 'api'
//live: 8082

4. Activate Systemd Service at boot time:

# Edit:
$ sudo systemctl enable middleware
Created symlink /etc/systemd/system/multi-user.target.wants/middleware.service > /etc/systemd/system/middleware.service

5. Start Systemd Service:

$ sudo systemctl start middleware

6. Test:

# Web-browser:  # show volkszaehler empty diagram - OK

Port old Database

I wanted to transfer an old Volkszaehler database (about 5 years) to a new computer.

First try was with dbcopy, but I could not make it to work for transfering the database via network to another computer.

Next try was with the Mariadb/mySQL tools mysqldump and mysql, see:

# Export data:
$ mysqldump -u root -p volkszaehler > sicherung-vz-2019121959.sql # 117 MB size
# Enter password and wait some minutes

# Transfer file to other computer

then save back:

# Import data:
$ mysql -u root -p volkszaehler < sicherung-vz-2019121959.sql
# Enter password

# Test: Web-browser:

Install on Dockstar

The little computer DockStarOverview does have a minimum Debian Linux (architecture armel). Most commands are included in busybox. The web server in implemented in a moin wiki. So, a lot of dependencies have to be installed.

/!\ This installation is mainly a copy of an already existing installation (i386). Fortunately most programs of volkszaehler are architecture independent (exception vzlogger, which is not needed in this case).

If you want to know, what programs and versions are installed on the source computer, you can do with:

# 1 columns output
$ dpkg-query --show
adduser 3.113+nmu3

# 2 columns output, for printing
$ dpkg-query --show | pr --columns 2 -T -w 120 -l1
accountsservice 0.6.15-2ubuntu9.7                           acl 2.2.51-5ubuntu1

or with full info
$ dpkg -l
Gewünscht=Unbekannt/Installieren/R=Entfernen/P=Vollständig Löschen/Halten
| Status=Nicht/Installiert/Config/U=Entpackt/halb konFiguriert/
         Halb installiert/Trigger erWartet/Trigger anhängig
|/ Fehler?=(kein)/R=Neuinstallation notwendig (Status, Fehler: GROSS=schlecht)
||/ Name                       Version            Architektur        Beschreibung
ii  adduser                    3.113+nmu3         all        add and remove users and groups

$ sudo apt-get update

$ sudo apt-get install apache2-mpm-prefork
$ sudo apt-get install php5

$ sudo apt-get install git-core libapache2-mod-php5 php5-cli php5-mysql php-apc mysql-server mysql-client

# phpmyadmin does work very slow
$ sudo apt-get install phpmyadmin

# install.sh does not work at checking the dependencies, change the script:
deps=( bash php mysql awk sed grep wget mktemp mkdir tar )
for binary in "${deps[@]}"; do
        #binpath="$(which $binary)"
        #if [ -n "$binpath" ] ; then
        if hash $binary 2>/dev/null; then
                binpath="$(which $binary)"
                echo " $binary: $binpath"
# because the busybox "which" command does not work as expected, see "Link".

$ sudo ./install.sh
configure volkszaehler.org? [y]
mysql user? [vz]
mysql password? [demo] oz...
mysql database? [volkszaehler]

create database? [y]
mysql admin user? [root]
mysql admin password? [] oz...
creating database volkszaehler...
Creating database schema...
Database schema created successfully!
creating db user vz with proper rights...

insert demo data in to database? [n]

# set rights for web server
$ sudo chown -R www-data:www-data /var/www

# dump the database on the old computer
# Attention, a dump with phpmyadmin does NOT work.
$ sudo mysqldump -u root -p volkszaehler >vz_heizung2.sql
[sudo] password for rudi:
Enter password:

# restore the database 
$ sudo mysql -u root -p volkszaehler < vz_heizung2.sql
[sudo] password for rudi:
Enter password:
# 5 min wait time

Access is via web browser to, and setup the channels.

# script needs calculator "bc"
$ sudo apt-get install bc

# create a link to vzclient
$ sudo ln -s /var/www/volkszaehler.org/bin/vzclient /usr/local/bin/vzclient
# old installation
$ sudo ln -s /var/www/volkszaehler.org/misc/tools/vzclient /usr/local/bin/vzclient 

# setup cron job
$ crontab -e
# If you get a permission problem:
$ sudo chown rudi:rudi /var/spool/cron/crontabs/rudi

# append to the file

# copy heizung values to volkszaehler database, every 3 minutes
*/3 * * * * $HOME/Install/volkszaehler/heizung_vz.sh > /dev/null

Setup Volkszaehler Web Frontend

Open web URL volkszaehler.

Create 6 channels:

Copy data to database

Now, that the temperature data are on the local computer, they can be inserted into the database, with the following shell script.

# show example data
$ cat /run/user/heizdata.csv
2014-02-16 09:22:13;1;566;519;431;151;71

$ cat heizung_vz.sh
# File: heizung_vz.sh
# 2014-02-15 RudolfReuter
# Separate heizung data and copy in database
# setup /etc/vzclient.conf


#echo $HDATA

# extract proper field and adjust decimal point, pumpe*2 for better visability
VP=`cut -d ";" -f 2 $HPATH`
VP=$(echo "scale=1; $VP*2" | bc)
TV=`cut -d ";" -f 3 $HPATH`
TV=$(echo "scale=1; $TV/10" | bc)
TR=`cut -d ";" -f 4 $HPATH`
TR=$(echo "scale=1; $TR/10" | bc)
TW=`cut -d ";" -f 5 $HPATH`
TW=$(echo "scale=1; $TW/10" | bc)
TD=`cut -d ";" -f 6 $HPATH`
TD=$(echo "scale=1; $TD/10" | bc)
TA=`cut -d ";" -f 7 $HPATH`
TA=$(echo "scale=1; $TA/10" | bc)

# copy existing values to database
[ -z "$VP" ] || /usr/local/bin/vzclient -u $UUID_VP add data value=$VP > /dev/null
[ -z "$TV" ] || /usr/local/bin/vzclient -u $UUID_TV add data value=$TV > /dev/null
[ -z "$TR" ] || /usr/local/bin/vzclient -u $UUID_TR add data value=$TR > /dev/null
[ -z "$TW" ] || /usr/local/bin/vzclient -u $UUID_TW add data value=$TW > /dev/null
[ -z "$TD" ] || /usr/local/bin/vzclient -u $UUID_TD add data value=$TD > /dev/null
[ -z "$TA" ] || /usr/local/bin/vzclient -u $UUID_TA add data value=$TA > /dev/null

Database Channels

Database utility vzclient

For the maintenance of the volkszaehler database there is a utility vzclient, written in Python. For easier use, setup a configuration file:

$ cat /etc/vzclient.conf

Give the user the right to delete channels:

$ mysql -u root -p
Enter password:
mysql > grant delete on volkszaehler.* to 'vz'@'localhost';
Query OK, 0 rows affected (0.01 sec)
mysql> quit

# delete unused channel
$ vzclient -u cdb2cbc0-926a-11e3-badc-c5ffaebea3fc delete channel

# show channel property
$ vzclient -u 6ac83df0-9641-11e3-8754-0b95768ead82 get channel

# edit channel property
$ vzclient -u a9774800-934a-11e3-87f8-81f5f2axxxxx edit channel cost=0.0003

or, if you have forgotten to set the property "public"
$ vzclient -u 6ac83df0-9641-11e3-8754-0b95768ead82 edit channel public=true

# get data tuples
$ vzclient -u a9774800-934a-11e3-87f8-81f5f2axxxxx get data tuples=10

Database service

With the program pgpmyadmin it is much easier to service data in the mysql database. But it is more dangerous to have this program online. Therefore the configuration file is usually moved to another place, and just used in case:

# to use phpmyadmin do:
$ cd Install
$ sudo mv phpmyadmin.conf /etc/apache2/conf.d/phpmyadmin.conf
$ sudo /etc/init.d/apache2 reload

For data compression over time there is the tool vzcompress2.php. See at the Links for the operation.

* By default we assume the following resolution scheme:
 *   Newer than 7 Days      Keep Original
 *   Older than 7 Days      Datapoint per 1 Minute
 *   Older than 30 Days     Datapoint per 5 Minutes
 *   Older than 6 Month     Datapoint per 15 Minutes
 *   Older than 1 Year      Datapoint per 30 Minutes

# setup in crontab
$ $ crontab -e
# min h  dom mon dow   command
# for volkszaehler run script on first Sonntag in month at 9 o'clock
0 9 1-7 * * [ "$(date '+%a')" == "So" ] && php /var/www/volkszaehler.org/misc/tools/vzcompress2.php > $HOME/Install/volkszaehler/vzcompress.log


In the Volkszaehler package some libraries are used:

volkszaehler software

The frontend has a code size of 434 KB (Javascript).

The basic library volkszaehler has just a code size of 360 KB (PHP, json).

The misc folder holds 2.4 MB (interpreter language).


jQuery is a cross-platform JavaScript library designed to simplify the client-side scripting of HTML. It was released in January 2006 at BarCamp NYC by John Resig. Used by over 80% of the 10,000 most visited websites, jQuery is the most popular JavaScript library in use today. Package size: minified 96 KB.

jQuery UI

jQuery UI is a curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library. Whether you're building highly interactive web applications or you just need to add a date picker to a form control, jQuery UI is the perfect choice. Package size: minified 230 KB.


Composer is a tool for dependency management in PHP. It allows you to declare the dependent libraries your project needs and it will install them in your project for you. Package size: 102 KB.


The Doctrine Project is the home to several PHP libraries primarily focused on database storage and object mapping. The core projects are a Object Relational Mapper (ORM) and the Database Abstraction Layer (DBAL) it is built upon. Package size: 6.4 MB

Object relational mapper (ORM) for PHP that sits on top of a powerful database abstraction layer (DBAL). One of its key features is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL), inspired by Hibernates HQL. This provides developers with a powerful alternative to SQL that maintains flexibility without requiring unnecessary code duplication.

Powerful database abstraction layer (DBAL) with many features for database schema introspection, schema management and PDO abstraction.


JpGraph is an Object-Oriented Graph creating library for PHP >= 5.1 The library is completely written in PHP and ready to be used in any PHP scripts (both CGI/APXS/CLI versions of PHP are supported). Package size: 47.1 MB


PHPUnit is a programmer-oriented testing framework for PHP. Package size: 4.3 MB

Even good programmers make mistakes. The difference between a good programmer and a bad programmer is that the good programmer uses tests to detect mistakes as soon as possible. The sooner you test for a mistake the greater your chance of finding it and the less it will cost to find and fix. This explains why leaving testing until just before releasing software is so problematic. Most errors do not get caught at all, and the cost of fixing the ones you do catch is so high that you have to perform triage with the errors because you just cannot afford to fix them all.

Testing with PHPUnit is not a totally different activity from what you should already be doing. It is just a different way of doing it. The difference is between testing, that is, checking that your program behaves as expected, and performing a battery of tests, runnable code-fragments that automatically test the correctness of parts (units) of the software. These runnable code-fragments are called unit tests.


Symfony is a PHP framework for web projects. Package size: 1.3 MB

Speed up the creation and maintenance of your PHP web applications. Replace the repetitive coding tasks by power, control and pleasure.


List of pages in this category:

-- RudolfReuter 2014-02-15 14:08:07

Go back to CategoryVolkszaehler or StartSeite ; KontaktEmail (ContactEmail)

HeizungVolkszaehler (last edited 2019-12-30 13:45:07 by RudolfReuter)