Home Assistant - odczyt stanu licznika wody z zakładką APATOR

Home Assistant - odczyt stanu licznika wody z zakładką APATOR

W Poznaniu Aquanet celem szybszego odczytywania stanu liczników, montuje na nich nakładki APATOR (AT-WMBUS -16-2). Skoro montuje - czemu by z nich nie skorzystać i nie umieścić w domowej automatyce?

Więcej o Apator: AT-WMBUS -16-2 

Rozgłaszają one protokołem wmbus między innymi stan licznika.

Potrzebujemy:

  1. home assistant
  2. serwer mqtt
  3. dongla pozwalającego na odczyt danych
  4. wmbusmeters (https://github.com/weetmuts/wmbusmeters)

Istnieje kilka “dongli”, ja użyłem najtańszej opcji czyli uniwersalnego tunera tv pozwalającego na nasłuch dowolnych częstotliwości (mam DVB-T oparty o chipset RTL2838 Realteka - kosztujący ok 10$) i narzędzi rtl_sdr wraz z interpreterem rtl-wmbus (https://github.com/xaelsouth/rtl-wmbus.git).

Po skompletowaniu sprzętu zacznijmy od narzędzi. Potrzebujemy:

  1. rtl_sdr - Instalujemy go standardowo z dystrybucji: apt install rtl-sdr
  2. rtl_wmbus - Ściągamy go z githuba i kompilujemy:
root@hs:~# git clone https://github.com/xaelsouth/rtl-wmbus.git
Cloning into 'rtl-wmbus'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 58 (delta 0), reused 1 (delta 0), pack-reused 54
Unpacking objects: 100% (58/58), done.
root@hs:~# cd rtl-wmbus
root@hs:~/rtl-wmbus# make
mkdir -p "build"
gcc -DNDEBUG -O3                  -Iinclude -std=gnu99 -Wall -W -Waggregate-return -Wbad-function-cast -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment -Wfloat-equal -Winline -Wmain -Wmissing-noreturn -Wmissing-prototypes -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wshadow -Wsign-compare -Wstrict-prototypes -Wswitch -Wunreachable-code -Wunused -Wuninitialized -o "build/rtl_wmbus" rtl_wmbus.c -lm 
In file included from rtl_wmbus.c:37:0:
atan2.h: In function ‘atan2_approximation2’:
atan2.h:48:11: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
     if (x == 0.0f)
           ^~
atan2.h:51:15: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
         if (y == 0.0f) return 0.0f;
               ^~
In file included from rtl_wmbus.c:38:0:
net_support.h: In function ‘get_net’:
net_support.h:17:12: warning: missing initializer for field ‘sin_addr’ of ‘struct sockaddr_in’ [-Wmissing-field-initializers]
     struct sockaddr_in address = {.sin_family = AF_INET, .sin_port = htons(port)};
            ^~~~~~~~~~~
In file included from /usr/include/arpa/inet.h:22:0,
                 from net_support.h:7,
                 from rtl_wmbus.c:38:
/usr/include/netinet/in.h:241:20: note: ‘sin_addr’ declared here
     struct in_addr sin_addr;  /* Internet address.  */
                    ^~~~~~~~
In file included from rtl_wmbus.c:39:0:
t1_c1_packet_decoder.h: At top level:
t1_c1_packet_decoder.h:252:5: warning: no previous prototype for ‘get_mode_a_tlg_length’ [-Wmissing-prototypes]
 int get_mode_a_tlg_length(uint8_t lfield)
     ^~~~~~~~~~~~~~~~~~~~~
t1_c1_packet_decoder.h:257:5: warning: no previous prototype for ‘get_mode_b_tlg_length’ [-Wmissing-prototypes]
 int get_mode_b_tlg_length(uint8_t lfield)
     ^~~~~~~~~~~~~~~~~~~~~
rtl_wmbus.c:47:14: warning: ‘lp_1600kHz_56kHz’ defined but not used [-Wunused-function]
 static float lp_1600kHz_56kHz(int sample, size_t i_or_q)
              ^~~~~~~~~~~~~~~~
root@hs:~/rtl-wmbus# cp build/rtl_wmbus /usr/bin/rtl_wmbus

Możemy w tym momencie sprawdzić czy otrzymujemy jakieś dane:

root@hs:~# /usr/bin/rtl_sdr -f 868.9M -s 1.6e6 - | /usr/bin/rtl_wmbus
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
[R82XX] PLL not locked!
Sampling at 1600000 S/s.
Tuned to 868900000 Hz.
Tuner gain set to automatic.
Reading samples in async mode...
T1;1;1;2020-02-13 23:04:26.000;18;18;XXXXXX;0x3e4401069010610205077a2f0030859a6e91067b22f31422bf3f94e848ac8d2f82ff60f6e8291bafbee2e2a4c5084e319cead6ff6459ef3d250fd32c596b24
^CSignal caught, exiting!
User cancel, exiting...

XXXXXX - to będzie numer nakładki - warto go skonfrontować z nakładką, by nie zczytywać przypadkiem licznika sąsiada :-)

Co dalej?

Jak komunikacja działa - w następnym etapie zainstalujmy i skonfigurujmy wmbusmeters. Ściągamy go, kompilujemy i instalujemy:

root@hs:~# git clone https://github.com/weetmuts/wmbusmeters.git
Cloning into 'wmbusmeters'...
remote: Enumerating objects: 11, done.
remote: Counting objects: 100% (11/11), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 2896 (delta 3), reused 8 (delta 3), pack-reused 2885
Receiving objects: 100% (2896/2896), 1.09 MiB | 1.98 MiB/s, done.
Resolving deltas: 100% (2239/2239), done.
root@hs:~# cd wmbusmeters
root@hs:~/wmbusmeters# ./configure 
Nothing here yet!
Run 'make'
or  'make HOST=arm'
root@hs:~/wmbusmeters# make
Building 0.9.26
g++ -Os -fPIC -fmessage-length=0 -std=c++11 -Wall -Wno-unused-function -Ibuild src/aes.cc -c -E > build/aes.o.src
[...]
g++ -o build/testinternals build/aes.o build/aescmac.o build/cmdline.o build/config.o build/dvparser.o build/meters.o build/meter_amiplus.o build/meter_apator162.o build/meter_cma12w.o build/meter_ebzwmbe.o build/meter_ehzp.o build/meter_esyswm.o build/meter_eurisii.o build/meter_fhkvdataiii.o build/meter_hydrus.o build/meter_hydrodigit.o build/meter_iperl.o build/meter_izar.o build/meter_lansenth.o build/meter_mkradio3.o build/meter_multical21.o build/meter_multical302.o build/meter_omnipower.o build/meter_q400.o build/meter_qcaloric.o build/meter_rfmamb.o build/meter_supercom587.o build/meter_vario451.o build/printer.o build/serial.o build/shell.o build/util.o build/units.o build/wmbus.o build/wmbus_amb8465.o build/wmbus_im871a.o build/wmbus_cul.o build/wmbus_d1tc.o build/wmbus_rtlwmbus.o build/wmbus_simulator.o build/wmbus_rawtty.o build/wmbus_utils.o build/testinternals.o  -lpthread
root@hs:~/wmbusmeters# make install
Building 0.9.26
binaries: installed /usr/bin/wmbusmeters and /usr/sbin/wmbusmetersd
man page: installed /usr/share/man/man1/wmbusmeters.1.gz
user: wmbusmeters unmodified
conf file: /etc/logrotate.d/wmbusmeters unchanged
conf file: /etc/wmbusmeters.conf unchanged
conf dir: /etc/wmbusmeters.d unchanged
systemd: removing /etc/systemd/system/wmbusmeters.service
systemd: backup stored here: /root/old.wmbusmeters.service.backup
systemd: installed /etc/systemd/system/wmbusmeters@.service
udev: removing /etc/udev/rules.d/99-wmbus-usb-serial.rules
udev: backup stored here: /root/old.wmbusmeters-wmbus-usb-serial.rules.backup
udev: installed /etc/udev/rules.d/99-wmbus-usb-serial.rules


You need to reload systemd configuration! Please do:
sudo systemctl daemon-reload


You need to reload udev configuration! Please do:
sudo udevadm control --reload-rules
sudo udevadm trigger
root@hs:~/wmbusmeters# 
root@hs:~/wmbusmeters# sudo systemctl daemon-reload
root@hs:~/wmbusmeters# sudo udevadm control --reload-rules
root@hs:~/wmbusmeters# sudo udevadm trigger
root@hs:~/wmbusmeters# 

Następnie konfigurujemy: w pliku /etc/wmbusmeters.conf:

loglevel=normal
device=rtlwmbus:868.9M
logtelegrams=false
format=json
meterfiles=/var/log/wmbusmeters/meter_readings
meterfilesaction=append
logfile=/var/log/wmbusmeters/wmbusmeters.log
shell=/usr/local/bin/wmbus-mqtt

plus konfiguracja licznika: /etc/wmbusmeters.d/apatorXXXX:

name=apatorXXXX
type=apator162
id=XXXX
key=00000000000000000000000000000000

(pod XXXX wstawiamy 8 cyfrowy numer licznika - uzyskany wyżej)

Został jeszcze skrypt /usr/local/bin/wmbus-mqtt

#!/bin/sh
/usr/bin/mosquitto_pub -h localhost -t wmbusmeters/$METER_ID -m "$METER_JSON"

To skrypt, więc pamiętajmy o uprawnieniach do wykonywania: chmod 755 /usr/local/bin/wmbus-mqtt po wyłożeniu i włożeniu sticka, wmbusmeters powinien odpalić się automatycznie. Jak nie, uruchamiamy go i sprawdzamy czy działa:

root@hs:~# systemctl start wmbusmeters@-dev-rtlsdr_2.service
root@hs:~# systemctl status wmbusmeters@-dev-rtlsdr_2.service 
● wmbusmeters@-dev-rtlsdr_2.service - "wmbusmeters service on /dev/rtlsdr_2"
   Loaded: loaded (/etc/systemd/system/wmbusmeters@.service; disabled; vendor preset: enabled)
   Active: active (running) since Fri 2020-02-14 22:54:04 UTC; 9s ago
  Process: 30140 ExecStart=/usr/sbin/wmbusmetersd --device=/dev/rtlsdr_2 /var/run/wmbusmeters/wmbusmeters--dev-rtlsdr_2.pid (code=exited, status=0/SUCCESS)
  Process: 30139 ExecStartPre=/bin/chown -R wmbusmeters:wmbusmeters /var/run/wmbusmeters (code=exited, status=0/SUCCESS)
  Process: 30138 ExecStartPre=/bin/mkdir -p /var/run/wmbusmeters (code=exited, status=0/SUCCESS)
  Process: 30125 ExecStartPre=/bin/chown -R wmbusmeters:wmbusmeters /var/log/wmbusmeters (code=exited, status=0/SUCCESS)
  Process: 30108 ExecStartPre=/bin/mkdir -p /var/log/wmbusmeters/meter_readings (code=exited, status=0/SUCCESS)
 Main PID: 30141 (wmbusmetersd)
    Tasks: 6 (limit: 4915)
   CGroup: /system.slice/system-wmbusmeters.slice/wmbusmeters@-dev-rtlsdr_2.service
           ├─30141 /usr/sbin/wmbusmetersd --device=/dev/rtlsdr_2 /var/run/wmbusmeters/wmbusmeters--dev-rtlsdr_2.pid
           ├─30147 /bin/sh -c /usr/bin/rtl_sdr -f 868.9M -s 1.6e6 - | /usr/bin/rtl_wmbus
           ├─30152 /usr/bin/rtl_sdr -f 868.9M -s 1.6e6 -
           └─30153 /usr/bin/rtl_wmbus

Feb 14 22:54:04 hs systemd[1]: Starting "wmbusmeters service on /dev/rtlsdr_2"...
Feb 14 22:54:04 hs wmbusmetersd[30140]: (wmbusmeters) started /var/run/wmbusmeters/wmbusmeters--dev-rtlsdr_2.pid
Feb 14 22:54:04 hs systemd[1]: Started "wmbusmeters service on /dev/rtlsdr_2".

(lub inny proces - tabulator powinien podpowiedzieć).

W tym momencie w logu /var/log/wmbusmeters/wmbusmeters.log powinniśmy dostać informacje:

(wmbusmeters) logging started 2020-02-14 22:54:04
(wmbusmeters) waiting for telegrams

a w /var/log/wmbusmeters/meter_readings/apatorXXX powinny zacząć pojawiac się odczyty:

{"media":"water","meter":"apator162","name":"apatorXXXX","id":"XXXX","total_m3":123.035,"timestamp":"2020-02-14T22:09:03Z"}
{"media":"water","meter":"apator162","name":"apatorXXXX","id":"XXXX","total_m3":123.036,"timestamp":"2020-02-14T22:27:53Z"}
{"media":"water","meter":"apator162","name":"apatorXXXX","id":"XXXX","total_m3":123.036,"timestamp":"2020-02-14T22:46:19Z"}

Równolegle na szynie mqtt powinny zacząć pojawiać się dane, które możemy zacząć zczytywać do HA:

- platform: mqtt
    state_topic: "wmbusmeters/XXXX"
    name: Apator XXXX
    value_template: '{{ value_json["total_m3"] }}'
    unit_of_measurement: 'm³'

Warto zrobić sobie od razu liczniki - dzienne, miesięczne, roczne:

utility_meter:
  hourly_water:
    source: sensor.apator_XXXX
    cycle: hourly
  daily_water:
    source: sensor.apator_XXXX
    cycle: daily
  monthly_water:
    source: sensor.apator_XXXX
    cycle: monthly
  yearly_water:
    source: sensor.apator_XXXX
    cycle: yearly

Niuansy techniczne: 

  • jak rtl nic nie odczytuje - warto sprawdzić czy antenka jest dobrze dociśnięta. 
  • Proces rtl_wmbus pochłania ok 20% rdzenia na i5 - na malince z tego co pamiętam sporo więcej. 
  • nakładki dostosowane są do godzin pracy inkasentów, co za tym idzie wysyłają dane co ok 30 sekund w godzinach 5:00-17:00, a między 17:00 a 5 - co ok 20-30 minut. Próbując więc skonfigurować wieczorem odczyt można sobie poczekać na pierwszy pakiecik…
  • proces rtl_sdr czasami przy restarcie wmbusmeters nie ubija się - można go wtedy ubić ręcznie (killall -9 rtl_sdr) by niepotrzebnie nie czekać.

Chcesz wiedzieć więcej? Dołącz do grupy na FB. Będzie nam też miło jak polubisz Fanpage!

Odkurzacz pionowy bezprzewodowy JIMMY JV85 PRO

Od: 979 zł 1499 zł | Powiadom gdy cena spadnie

Najmocniejszy ręczny odkurzacz od tego producenta, który nie jest smart ale w naszych rękach takim się stanie. Bardzo duża liczba akcesoriów i łamana rura główna oraz wymienna bateria, która starcza na 70 minut sprzątania i wygoda w użytkowaniu to ogromne plusy tego sprzętu.

Dziwi brak reklam? Przeczytaj dlaczego i wesprzyj bloga na  lub