Apator, Izar, AT-WMBUS-16-2 odczyt wodomierza ESPHome + CC1101

Ja mam wmbusmeters w osobnym kontenerze pod proxmox’em i jest stabilny.

Szczepan, ty umiesz w programowaniu, więc może na coś wpadniesz z tym ID.

Coś chyba z dekodowaniem. Jest różnica w zerowym bajcie Little endian :confused:
U mnie:
Poprawne ID: 1095753644 Little endian AC DF 4F 41
Błędne ID: 1095753600 Little endian 80 DF 4F 41

Tylko dlaczego to działa w repo od Maćka, a po przerzuceniu do esphome już nie…

W pliku h mam tylko coś takiego, czyli proste odwołania do funkcji z rapo Maćka:

#include "Arduino.h"
#include "ArduinoJson.h"
#include "izar_wmbus.h"

uint32_t meterId = 0x414FDFAC;  s

IzarWmbus reader;

class MyCustomSensor : public Component {
 public:
  Sensor *water_sensor = new Sensor();                            
  Sensor *id_sensor = new Sensor();                              
  
  void setup() {
       reader.init(meterId);                           
  }
  
IzarResultData data;
StaticJsonDocument<200> doc;

  void loop() {

    FetchResult result = reader.fetchPacket(&data);
    if (result == FETCH_SUCCESSFUL) {
        waterUsage_temp = data.waterUsage;
        if (waterUsage_temp > 0) {    //filtrowanie wartości mniejszych od 0 
            waterUsage = waterUsage_temp;
        } 
        water_sensor->publish_state(waterUsage);
        id_sensor->publish_state(meterId);

    } else {
        delay(300);
        reader.ensureRx(); 
    }
  }
};

a w samym esphome tylko wywołanie custom sensor:

- platform: custom
  lambda: |-
    auto my_sensor = new MyCustomSensor();
    App.register_component(my_sensor);
    return {my_sensor->water_sensor, my_sensor->id_sensor}; ```

Nie mam pojęcia co się dzieje w nie moim kodzie :wink:
Może to jest jakiś inny licznik u sąsiada?
Jak wygląda cały telegram?

Załącz jego printowanie:

Wtedy zobaczysz czy to kod coś źle działa czy też to jest inny licznik.
Telegram możesz zdekodować na stronie wmbusmeters’a:
https://wmbusmeters.org/

Właśnie ja nie ingeruję w żaden sposób w kody Maćka, tylko zaczytuję całe repo.
U siebie tylko wczytuję ID i zużycie.

To na pewno mój licznik, bo sprawdzałem już sąsiadów. Poza tym w pliku H mam wpisane ograniczenie odczytu do ID:414FDFAC, czyli mój licznik i wyświetla jego prawidłowy stan w litrach. Tylko ID dziesiętnie się nie zgadza końcówka. U mnie to wsio ryba bo jużdziała, problem tylko w tym, że jak ktoś chce odpalić to na esphome za pomocą mojego repo, to dostanie błędny adres swojego licznika i to nie zadziała.
Jak widać Jordan to potwierdził.
Napisałem do Maćka, ale cuś nie reaguje na razie

2 polubienia

Wykorzystując:

Jestem w stanie odebrać (dekodowanie pozostawiam wmbusmeters’owi) ramki z następujących wodomierzy/nakładek radiowych (popularne w domach, albo dostępne na rynku w PL w przystępnych cenach):

  • Ramki z IZAR’a są podsyłane co ~8 sekund (każdego dnia i nocy) - konfiguracja wodociągów.
  • Ramki z Apatora co ~1 minutę (każdego dnia i nocy) - prawdopodobnie domyślna konfiguracja producenta (wodomierz zakupiony prywatnie).
  • Ramki z Maddaleny co ~2 minuty (pomiędzy godzinami 7 a 19 w dnie robocze) - prawdopodobnie domyślna konfiguracja producenta (wodomierz zakupiony prywatnie).
  • Ramki z BMETERS co ~1 minutę (pomiędzy godzinami 6 a 20 w dnie robocze) - prawdopodobnie domyślna konfiguracja producenta (wodomierz zakupiony prywatnie).

W wmbusmeters mam je skonfigurowane jak poniżej:

  • IZAR
name=wodomierz_izar
type=izar
id=44332211
key=
  • Apator
name=wodomierz_apator
type=apator162
id=33222111
key=00000000000000000000000000000000
  • Maddalena
name=wodomierz_maddalena
type=evo868
id=87654321
key=
  • BMETERS
name=wodomierz_bmeters
type=hydrodigit
id=22221111
key=00000000000000000000000000000000

JSON’y produkowane przez wmbusmeters’a wyglądają jak poniżej:

  • IZAR
{"media":"water","meter":"izar","name":"wodomierz_izar","id":"44332211","prefix":"C19SB","serial_number":"456","total_m3":123.825,"last_month_total_m3":111.207,"last_month_measure_date":"2022-11-30","remaining_battery_life_y":12,"current_alarms":"no_alarm","previous_alarms":"leakage","transmit_period_s":8,"manufacture_year":"2019","timestamp":"2022-12-12T09:04:34Z","device":"rtlwmbus[cmd_0]","rssi_dbm":-42}
  • Apator
{"media":"water","meter":"apator162","name":"wodomierz_apator","id":"33222111","total_m3":12.061,"timestamp":"2022-12-12T09:04:28Z","device":"rtlwmbus[cmd_0]","rssi_dbm":-39}
  • Maddalena
{"media":"water","meter":"evo868","name":"wodomierz_maddalena","id":"87654321","current_status":"TPL_MFCT_20","fabrication_no":"000000000000","total_m3":23.023,"consumption_at_set_date_m3":0,"set_date":"2000-01-01","consumption_at_set_date_2_m3":0,"set_date_2":"2000-01-01","max_flow_since_datetime_m3h":8.5,"max_flow_datetime":"2022-12-10 06:15","consumption_at_history_{NULL}_m3":null,"history_reference_date":"-219246529-17-32540","history_{NULL}_date":"-219246529-17-32076","device_date_time":"2022-12-12 10:38","timestamp":"2022-12-12T09:39:10Z","device":"rtlwmbus[cmd_0]","rssi_dbm":-49}
  • BMETERS
{"media":"water","meter":"hydrodigit","name":"wodomierz_bmeters","id":"22221111","total_m3":45.059,"meter_datetime":"2022-12-12 10:42","timestamp":"2022-12-12T09:41:01Z","device":"rtlwmbus[cmd_0]","rssi_dbm":-66}

Co do stabilności odczytu poprzez CC1101 (wraz z BLE proxy na ESPHome) to przez poprzednie 4 dni nie miałem żadnego problemu (nawet jak się coś zawiesiło po stronie CC1101/ESPHome to automatyczne recovery zadziałało).

1 polubienie

A jak konfigurujesz device w wmbusmeters?
Auto czy jakoś statyczny? W logu widzę że masz rtlwmbus

Aktualnie na potrzeby testów na jednej maszynie mam:

device=rtlwmbus:CMD(nc -lk 8558)

A w produkcji (druga maszyna) mam:

device=stdin

oraz skrypt, który odpala:

socat -u TCP4-LISTEN:8338,reuseaddr,fork - | wmbusmeters --useconfig=/etc/

Jedyna różnica to występowanie RSSI w tym dummy rtlwmbus.

Ktoś pomoże od początku ogarnąć ESPHome + CC1101 z nakładką Apator? Mam komponenty ale mam problemy z kodami. Nie ukrywam w programowaniu jestem groszek, tj. zielony

Chyba znalazłem tego samego sprzedawcę na Alledrogo, jak części dotrą to spróbuje powtórzyć Twój sukces :slight_smile:

1 polubienie

Jakby co to brałem tutaj

Rozkminiłem temat błędnego ID.
Wartości w custom sensor są przechowywane w zmiennej float, która ma ograniczoną pojemność i obcina liczby. Nie ma opcji zmiany typu zmiennej. Przerobiłem w związku z tym wyświetlanie ID na custom text sensor. Dodatkowo jest obsługa DHT22
Zaktualizowane repo:

@EMil_Emil z czym masz problem?
Błędy w kompilacji, czy w ogóle nie wiesz jak podejść do tematu?

Zainstaluj Visual Studio Code + nakładka PlatformIO i potem już z górki:)

3 polubienia

No ja poszedłem na łatwiznę i kupiłem tu i tu. Z twojego zdjęcia wywnioskowałem że to ten komplecik :slight_smile:

HTTP server started

CC1101 connection OK
CC1101 version: 20
CC1101 initialized
Attempting MQTT connection…connected
Attempting MQTT connection…connected
Attempting MQTT connection…connected
Attempting MQTT connection…connected
Attempting MQTT connection…connected

I tak cały czas - nic więcej prócz info o pomyślnym połączeniu, zero ramek itp a siedzę 2m od licznika (nakładki).

RTL-SDR w tym samym czasie czyta z niej bez problemu

No właśnie bardziej wersja jak to ugryźć

Bartosz, zamień miejscami fizyczne połączenie GDO0 z GDO2, bez zmian w sofcie

Emil, musisz zainstalowac PlatformIO
Instrukcja w linku co wcześniej podalem.
Potem pobierasz repo z githuba, otwierasz w platformIO, ustawiasz dane swojej sieci wifi i mqtt (jak chcesz korzystać), kompilujesz i wgrywasz

Dziękuje dobry człowieku coś zaczął widzieć :slight_smile:

To jeszcze jedno pytanie - projekt Olka jest pod ESP8266 - dużo jest roboty, żeby go przerobić na ESP32 ?

Prawdopodobnie tylko implementacja w platformio.ini
Przynajmniej tak bylo w repo Maćka.
Apatora nie uruchamialem na esp32

Pany, siedzę nad wrzuceniem odczytu Apatora do esphome.
Już wszystkie biblioteki odpowiednio wrzucone, ładnie się kompiluje i wgrywa, ale niestety nie mam żadnej odpowiedzi. W PlatformIO można odczytać terminalem, co tam esp wypluwa, a w esphome słabo z tym.
Nie wiem czy CC1101 się prawidłowo połączył. Pakiet raczej nie przychodzi. Czy ktoś z szanownych zna się bardziej na esphome? Czy można jakoś wymusić głębsze debudowanie (w pliku h, a nie yaml)?

Możesz powciskać trace’y z ESPHome, np:

ESP_LOGD

Pokaż kod, jak masz ustawiony ten utworzony komponent? W ESPHome pętla loop to nie to samo (jeżeli chodzi o czas wykonania) co w czystym arduino.

Pomiędzy Izar’em a Apatorem jest (z punktu widzenia ramki T1) duża różnica w tym jak korzystamy z CC1101.
Ramka Izara jest krótką ramką, mieści się ona spokojnie w buforze, który oferuje CC1101.
Ramka Apatora jest o wiele dłuższa, odczyt musi być przeprowadzany ciągle z bufora.

Ten wymóg ciągłego odczytu bufora ma wpływ na to jak go trzeba zorganizować w pętli loop.
W “czystym” platformio/arduino nie jest to problemem - pętla loop jest wykonywana jedna za drugą, bez żadnych opóźnień.
Niestety w ESPHome już tak nie jest (a przynajmniej nie domyślnie). loop z ESPHome jest usypiana na pewien czas (i akurat wtedy nie złapiemy dalszych części składowych ramki Apatorowej).
Jest możliwość “przyspieszenia” tej pętli. Komponent musi zostać ustawiony jako high_freq.

Poniżej kod, w którym wrzuciłem odczyty z main.cpp z repo Olka.
Doszedłem już, że radio się chyba łączy. Dałem na razie w pętli loop LOGD, który jest wyświetlany ciągle w zależności od zwracanego boola z funkcji rf_mbus_init() (przerobiłem funkcję bo była void).

my_sensor.h:

#include "esphome.h"
#include "Arduino.h"
#include "ArduinoJson.h"
#include "vector"
#include "crc.hpp"
#include "mbus_packet.hpp"
#include "wmbus_utils.h"
#include "utils.hpp"
#include "aes.h"
#include "3outof6.hpp"
#include "util.h"
#include "mbus_defs.hpp"
#include "tmode_rf_settings.hpp"
#include "rf_mbus.hpp"


uint8_t MBpacket[291];


class MySensor :public Component, public Sensor {
      public: Sensor *my_sensor = new Sensor();
      
  
void setup() {
  memset(MBpacket, 0, sizeof(MBpacket));
  rf_mbus_init();
}


void loop() {

	if( rf_mbus_init()) { 
		ESP_LOGD("custom", "CC1101 connection OK");
	}
	else {
		ESP_LOGD("custom", "CC1101 connection error");
    }
    
    
  if (rf_mbus_task(MBpacket)) {
  
    ESP_LOGD("custom","Jest pakiet\n");

    
    int test2 = 654321;
    my_sensor->publish_state(test2);
    
    uint8_t lenWithoutCrc = crcRemove(MBpacket, packetSize(MBpacket[0]));    
    std::vector<uchar> frame(MBpacket, MBpacket+lenWithoutCrc);
    std::string sf = bin2hex(frame);

    char dll_id[9];
    sprintf(dll_id + 0, "%02X", frame[7]);
    sprintf(dll_id + 2, "%02X", frame[6]);
    sprintf(dll_id + 4, "%02X", frame[5]);
    sprintf(dll_id + 6, "%02X", frame[4]);

    Serial.printf("ID = %s\n", dll_id);
    
    std::vector<uchar> key;
    key.assign(16,0);
    std::vector<uchar>::iterator pos;
    pos = frame.begin();
    uchar iv[16];
    int i=0;
    for (int j=0; j<8; ++j) { iv[i++] = frame[2+j]; }
    for (int j=0; j<8; ++j) { iv[i++] = frame[11]; }
    pos = frame.begin() + 15;

    
    int num_encrypted_bytes = 0;
    int num_not_encrypted_at_end = 0;
    if (decrypt_TPL_AES_CBC_IV(frame, pos, key, iv, &num_encrypted_bytes, &num_not_encrypted_at_end)) {
      std::vector<uchar>::iterator fv;
      fv = std::find(pos, frame.end(), 0x10);
      if (fv != frame.end()){
        int v;
        memcpy(&v, &fv[1], 4);
        my_sensor->publish_state(v);
      }
    }
      
    memset(MBpacket, 0, sizeof(MBpacket));
  }
        

}

  
};





Nie ustawiasz komponenta jako high_freq, więc tracisz dane przy odbiorze (a dalej to juz nie ma się prawa zdekodowac itp).