Gå til innhold
  • Bli medlem
Støtt hjemmeautomasjon.no!

Preben

Medlemmer
  • Innlegg

    6
  • Ble med

  • Besøkte siden sist

Innlegg skrevet av Preben

  1. Hei,

     

    Har mekka litt for å få HAN-data fra Kamstrup-måleren min (1-fas) inn i Home Assistant.

     

    Bruker ESPHome med en ESP32 for å få inn data, forsøkte med en ESP8266, men den var ikke helt glad i software serieport, derfor måtte jeg ty til 32'en.

     

    Koden er ganske stygg foreløpig, men kanskje det kan hjelpe noen andre på vei:)

     

    Parser dataen ved å lese ut OBIS-koder og så hente tilknyttede data. Ingen CRC-sjekk e.l. da dingsen min ikke ser ut til å lese korrupte data i det hele tatt så langt.

     

    Har lånt en del inspirasjon fra RoarFreds HAN-leser, selv om jeg endte opp med noe ganske annerledes etterhvert:)

     

    ESPHome-konfigurasjonsfil:

    esphome:
      name: ams
      platform: ESP32
      board: nodemcu-32s
      includes:
        mbus.h
    
    wifi:
      power_save_mode: light
      networks:
      - ssid: "LulzNettOppe"
        password: ##PASSORD##
      - ssid: "LulzNettEkstra"
        password: ##PASSORD##
      - ssid: "LulzNett"
        password: ##PASSORD##
    
    # Enable logging
    logger:
      level: DEBUG
    
    # Enable Home Assistant API
    api:
    
    ota:
    
    uart:
      id: uart_bus
      tx_pin: GPIO17
      rx_pin: GPIO16
      baud_rate: 2400
    
    # Example configuration entry
    dallas:
      - pin: GPIO25
      
    sensor:
      - platform: dallas
        address: 0xEA0214808622FF28
        name: "Temperature Sikringsskap"
    
      - platform: custom
        lambda: |-
          auto mbus_reader = new MbusReader(id(uart_bus));
          App.register_component(mbus_reader);
          return {mbus_reader->wattage_sensor, mbus_reader->reactive_power_sensor, mbus_reader->amperage_sensor, mbus_reader->voltage_sensor, mbus_reader->energy_sensor, mbus_reader->reactive_energy_sensor};
        
        sensors:
        - name: "AMS Wattage"
          unit_of_measurement: kW
          accuracy_decimals: 3
          filters:
            - multiply: 0.001
        - name: "AMS Reactive Power"
          unit_of_measurement: VAr
          accuracy_decimals: 0
          internal: true
        - name: "AMS Amperage"
          unit_of_measurement: A
          accuracy_decimals: 2
          filters:
            - multiply: 0.01
        - name: "AMS Voltage"
          unit_of_measurement: V
          accuracy_decimals: 0
        - name: "AMS Hourly Energy"
          unit_of_measurement: kWh
          accuracy_decimals: 3
          filters:
            - multiply: 0.01
        - name: "AMS Hourly Reactive Energy"
          unit_of_measurement: kVArh
          accuracy_decimals: 3
          internal: true
          filters:
            - multiply: 0.01

    mbus.h:

    #include "esphome.h"
    
    class MbusReader : public Component, public uart::UARTDevice, public Sensor {
     public:
      MbusReader(uart::UARTComponent *parent) : uart::UARTDevice(parent) {}  
      uint8_t temp_byte = 0;
      uint8_t *temp_byte_pointer = &temp_byte;
      uint8_t uart_buffer_[512]{0};
      uint16_t uart_counter = 0;
      char uart_message[550];
      char temp_string[10];
      char obis_code[32];
      char temp_obis[10];
      uint32_t obis_value = 0;
      float wattage = 0;
      float amperage = 0;
      float voltage = 0;
      float energy = 0;
    
      Sensor *wattage_sensor = new Sensor();
      Sensor *amperage_sensor = new Sensor();
      Sensor *voltage_sensor = new Sensor();
      Sensor *energy_sensor = new Sensor();
      Sensor *reactive_power_sensor = new Sensor();
      Sensor *reactive_energy_sensor = new Sensor();
    
      void setup() override {
    
      }
    
      void loop() override {
        bool have_message = read_message();
      }
    
      bool read_message() {
        while(available() >= 1) {
          read_byte(this->temp_byte_pointer);
          if(temp_byte == 126) {
            if(uart_counter > 2) {
              uart_buffer_[uart_counter] = temp_byte;
              uart_counter++;
              uart_message[0] = '\0';
              strcpy(uart_message, "");
              for (uint16_t i = 0; i < uart_counter && i < 256; i++) {
                //sprintf(temp_string, "%02X", uart_buffer_[i]);
                //strncat(uart_message, temp_string, 2);
                if(uart_buffer_[i-1] == 9 && uart_buffer_[i] == 6) {
                  obis_code[0] = '\0';
                  strcpy(obis_code, "");
                  for (uint16_t y = 1; y < 6; y++) {
                    sprintf(temp_obis, "%d.", uart_buffer_[i + y]);
                    strcat(obis_code, temp_obis);
                  }
                  sprintf(temp_obis, "%d", uart_buffer_[i + 6]);
                  strcat(obis_code, temp_obis);
                  ESP_LOGV("uart", "OBIS code found: %s message length: %d", obis_code, uart_buffer_[i + 7]);
                  obis_value = 0;
                  if(uart_buffer_[i + 7] == 6) {
                    for(uint8_t y = 0; y < 4; y++) {
                      obis_value += (long)uart_buffer_[i + 8 + y] << ((3-y) * 8);
                    }
                  } else if(uart_buffer_[i + 7] == 18) {
                    for(uint8_t y = 0; y < 2; y++) {
                      obis_value += (long)uart_buffer_[i + 8 + y] << ((1-y) * 8);
                    }
                  }
                  
                  if(strcmp(obis_code, "1.1.1.7.0.255") == 0) {
                      ESP_LOGV("uart", "Wattage: %d", obis_value);
                      wattage_sensor->publish_state(obis_value);
                  } else if (strcmp(obis_code, "1.1.31.7.0.255") == 0) {
                      ESP_LOGV("uart", "Amperage: %d", obis_value);
                      amperage_sensor->publish_state(obis_value);
                  } else if (strcmp(obis_code, "1.1.32.7.0.255") == 0) {
                      ESP_LOGV("uart", "Voltage: %d", obis_value);
                      voltage_sensor->publish_state(obis_value);
                  } else if (strcmp(obis_code, "1.1.1.8.0.255") == 0) {
                      ESP_LOGV("uart", "Energy Usage Last Hour: %d", obis_value);
                      energy_sensor->publish_state(obis_value);
                  } else if (strcmp(obis_code, "1.1.4.7.0.255") == 0) {
                      ESP_LOGV("uart", "Reactive Power: %d", obis_value);
                      reactive_power_sensor->publish_state(obis_value);
                  } else if (strcmp(obis_code, "1.1.4.8.0.255") == 0) {
                      ESP_LOGV("uart", "Reactive Power Last Hour: %d", obis_value);
                      reactive_energy_sensor->publish_state(obis_value);
                  } else {
                    ESP_LOGV("uart", "Unknown OBIS %s, value: %d", obis_code, obis_value);
                  }
                }
                //strncat(uart_message, " ", 1);
                }
              ESP_LOGV("uart", "%d length received", uart_counter);
              //ESP_LOGI("uart", "%d length received: %s", uart_counter, uart_message);
              ESP_LOGV("uart", "Message length: %d", uart_message[3]);
              uart_counter = 0;
              uart_message[0] = '\0';
              strcpy(uart_message, "");
            } else {
              uart_counter = 0;
            }
          }
          uart_buffer_[uart_counter] = temp_byte;
          uart_counter++;
        }
    
        return false;
      }  
    };

     

    • Like 1
    • Thanks 1
×
×
  • Opprett ny...

Viktig informasjon

Vi har plassert informasjonskapsler/cookies på din enhet for å gjøre denne siden bedre. Du kan justere dine innstillinger for informasjonskapsler, ellers vil vi anta at dette er ok for deg.