mampfes / esphome_obis_d0

esphome external component to support meters with OBIS D0 interface
MIT License
43 stars 7 forks source link

ISKRA 2013 M13 1376, Drehstromzähler (MT174-D1A52-G22-M3K0) + No data #8

Closed zibous closed 1 year ago

zibous commented 1 year ago

I try to check the values with your component, but I do do not receive an data for the different tariffs.

# ----------------------------------------------------------------
#  protocoll for ISk5MT174
# ----------------------------------------------------------------
# serial port read data d2 protocoll for ISk5MT174
# /ISk5MT174-0001               Device Name
# 0.9.1(120054)                 Current time (hh:mm:ss)
# 0.9.2(1200703)                Date (1YY.MM.DD)
# 0.0.0(00339188)               *Device address 1
# 0.2.0(1.03)                   *Firmware version
# C.1.6(FDF5)                   *Firmware check sum
# 1.8.1(0011404.409*kWh)        Positive active energy (A+) in tariff T1 [kWh]
# 1.8.2(0023813.725*kWh)        Positive active energy (A+) in tariff T2 [kWh]
# 2.8.1(0015608.962*kWh)        Negative active energy (A-) in tariff T1 [kWh]
# 2.8.2(0000900.569*kWh)        Negative active energy (A-) in tariff T2 [kWh]
# ----------------------------------------------------------------

Bildschirmfoto 2023-02-21 um 10 55 53

It worked with Tasmota.

substitutions:
  device_name_short: "iskra174" # used by esp-home config
  device_description: "Smartmeter Device for Gridmeter ISKRA 2013 M13 1376, Drehstromzähler Version obis"
  domain: !secret domain
  appversion: "2.0.1"

esphome:
  name: "${device_name_short}"
  comment: "${device_description}"
  platform: ESP8266
  board: d1_mini
  project:
    name: "OE9psj.esp32MT174O"
    version: ${appversion}

## ---------------------------------------------------
## Compoments
## ---------------------------------------------------
external_components:  
  - source: github://mampfes/esphome_obis_d0

## ---------------------------------------------------
## WIFI Settings
## ---------------------------------------------------
wifi:
  networks:
    - ssid:  !secret ssid1_name
      password: !secret ssid1_pswd
    - ssid:  !secret ssid2_name
      password: !secret ssid2_pswd
  domain: !secret domain

## ---------------------------------------------------
## WEBSERVER Settings
## ---------------------------------------------------
web_server:
  port: 80
  version: 2
  local: true

## ---------------------------------------------------
## OTA Settings
## ---------------------------------------------------
ota:
  password: !secret ota_pswd
  on_error:
    then:
      - logger.log:
          format: "OTA update error %d"
          args: ["x"]

# ----------------------------------------------------------------
# Native API Component
# ----------------------------------------------------------------
api:
  id: espapi
  port: 6053
  #  The amount of time to wait before rebooting when no client connects to the API.
  # Can be disabled by setting this to 0s
  reboot_timeout: 0s

# ----------------------------------------------------------------
# Logger
# The baud rate to use for the serial UART port. Defaults to 115200. 
# Set to 0 to disable logging via UART.
# ----------------------------------------------------------------
logger:
  level: VERBOSE #makes uart stream available in esphome logstream
  baud_rate: 0 #disable logging over uart

# ----------------------------------------------------------------
# Serial interface
# ser = serial.Serial(SERIALPORT, 
#                     300, 
#                     serial.SEVENBITS, 
#                     serial.PARITY_EVEN, 
#                     timeout=TIMEOUT)
# ----------------------------------------------------------------
uart:
  id: my_uart
  tx_pin: 16     # D0 GIPO16
  rx_pin: 14       # D5 GIPO14
  baud_rate: 300
  data_bits: 7
  parity: EVEN
  stop_bits: 1 
  debug:
    direction: BOTH
    dummy_receiver: true
    after:
      delimiter: "\n"
    sequence:
      - lambda: UARTDebug::log_string(direction, bytes);

obis_d0:
  - id: my_sm
    uart_id: my_uart

# Some devices need to be triggered to send their data. We can use the
# integrated "interval" component for that: 2F3F210D0A
# see: https://github.com/jplitza/esphome_components  
interval:
  - interval: 60sec
    then:      
      - logger.log: "Init reading data for ${device_name_short}"
      - uart.write:
          id: my_uart
          data: [0x2F, 0x3F, 0x21, 0x0D, 0x0A]

# ----------------------------------------------------------------
#  protocoll for ISk5MT174
# ----------------------------------------------------------------
# serial port read data d2 protocoll for ISk5MT174
# /ISk5MT174-0001               Device Name
# 0.9.1(120054)                 Current time (hh:mm:ss)
# 0.9.2(1200703)                Date (1YY.MM.DD)
# 0.0.0(00339188)               *Device address 1
# 0.2.0(1.03)                   *Firmware version
# C.1.6(FDF5)                   *Firmware check sum
# 1.8.1(0011404.409*kWh)        Positive active energy (A+) in tariff T1 [kWh]
# 1.8.2(0023813.725*kWh)        Positive active energy (A+) in tariff T2 [kWh]
# 2.8.1(0015608.962*kWh)        Negative active energy (A-) in tariff T1 [kWh]
# 2.8.2(0000900.569*kWh)        Negative active energy (A-) in tariff T2 [kWh]
# ----------------------------------------------------------------

switch:

  # simple uart.write testcase
  - platform: template
    name: "Test uart.write"
    turn_on_action:
      - logger.log: "Send 1.8.1"
      - uart.write:
          id: my_uart
          data: "1.8.1(0011404.409*kWh)\n"
      - delay: 100ms   
      - logger.log: "Send 1.8.2"
      - uart.write:
          id: my_uart
          data: "1.8.2(0023813.725*kWh)\n"
      - delay: 100ms    
      - logger.log: "Send 1.8.1"
      - uart.write:
          id: my_uart
          data: "2.8.1(0015608.962*kWh)\n"
      - delay: 100ms    
      - logger.log: "Send 2.8.2"
      - uart.write:
          id: my_uart
          data: "2.8.2(0000900.569*kWh)\n"

sensor:

  - platform: obis_d0
    obis_d0_id: my_sm
    name: "Verbrauch HT"
    id: mt174ht
    obis_code: "1.8.1"
    unit_of_measurement: kWh
    accuracy_decimals: 0
    device_class: energy
    state_class: total_increasing
    value_regex: "\\d{7}\\.\\d{3}\\*kWh"

  - platform: obis_d0
    obis_d0_id: my_sm
    name: "Verbrauch NT"
    id: mt174nt
    obis_code: "1.8.2"
    unit_of_measurement: kWh
    accuracy_decimals: 0
    device_class: energy
    state_class: total_increasing
    value_regex: "\\d{7}\\.\\d{3}\\*kWh"

  - platform: obis_d0
    obis_d0_id: my_sm
    name: "Einspeisung T1"
    id: mt174t1
    obis_code: "2.8.1"
    unit_of_measurement: kWh
    accuracy_decimals: 0
    device_class: energy
    state_class: total_increasing
    value_regex: "\\d{7}\\.\\d{3}\\*kWh"

  - platform: obis_d0
    obis_d0_id: my_sm
    name: "Einspeisung T2"
    id: mt174t2
    obis_code: "2.8.2"
    unit_of_measurement: kWh
    accuracy_decimals: 0
    device_class: energy
    state_class: total_increasing
    value_regex: "\\d{7}\\.\\d{3}\\*kWh"

Log:

10:52:56    [D] [switch:013]    'Test uart.write' Turning ON.
10:52:56    [D] [main:215]  Send 1.8.1
10:52:56    [D] [uart_debug:158]    >>> "1.8.1(0011404.409*kWh)\n"
10:52:56    [V] [component:200] Component web_server took a long time for an operation (0.78 s).
10:52:56    [V] [component:201] Components should block for at most 20-30ms.
10:52:56    [D] [main:225]  Send 1.8.2
10:52:56    [D] [uart_debug:158]    >>> "1.8.2(0023813.725*kWh)\n"
10:52:56    [V] [component:200] Component template.switch took a long time for an operation (0.78 s).
10:52:56    [V] [component:201] Components should block for at most 20-30ms.
10:52:56    [D] [main:235]  Send 1.8.1
10:52:56    [D] [uart_debug:158]    >>> "2.8.1(0015608.962*kWh)\n"
10:52:56    [V] [component:200] Component template.switch took a long time for an operation (0.78 s).
10:52:56    [V] [component:201] Components should block for at most 20-30ms.
10:52:56    [D] [main:245]  Send 2.8.2
10:52:56    [D] [uart_debug:158]    >>> "2.8.2(0000900.569*kWh)\n"
10:52:56    [V] [component:200] Component template.switch took a long time for an operation (0.78 s).
10:52:56    [V] [component:201] Components should block for at most 20-30ms.
10:53:05    [D] [main:136]  Init reading data for iskra174
10:53:05    [D] [uart_debug:158]    >>> "/?!\r\n"

What am I doing wrong?

zibous commented 1 year ago

As it looks, the UART interface cannot send and receive at the same time. If I use two infrared reader - one as a transmitter and one as a receiver, it works and even better with an ESP32 ((az-delivery-devkit-v4)) instead of an ESP8266.

Bildschirmfoto 2023-02-23 um 18 02 32

Here is the configuration I use for testing :

## ----------------------------------------
## ESPHome Smart Meter OBIS D0 Component
## ----------------------------------------
substitutions:
  device_name_short: "mt174esp" # used by esp-home config
  device_description: "Smartmeter Device (az-delivery-devkit-v4) for Gridmeter ISKRA 2013 M13 1376, Drehstromzähler Version obis, infrared reader"
  domain: !secret domain
  appversion: "2.0.0"
  # device configuration
  board: "az-delivery-devkit-v4"
  uart_tx_pin: "GPIO17"
  uart_rx_pin: "GPIO16"
  uart_baudrate: "300"
  update_interval: "60s"

esphome:
  name: "${device_name_short}"
  comment: "${device_description}"  
  platform: esp32
  board: az-delivery-devkit-v4
  project:
    name: "OE9psj.esp32MT174ESP"
    version: ${appversion}
  build_path: ./build/${device_name_short}

  on_boot:
    priority: 700
    then:
      - logger.log:
          level: info
          format: "BOOTMESSAGE:${device_name_short} API is connected, Device ready!"
      - globals.set:
          id: boot_counter
          value: !lambda "return id(boot_counter)+=1;"
      - syslog.log:
          level: 4
          tag: "ESPINFO"
          payload: "BOOTMESSAGE:${device_name_short} API is connected, Device ready!" 

  on_shutdown:
    priority: 700
    then:
      - syslog.log:
         level: 4
         tag: "ESPINFO"
         payload: "${device_name_short} is down!"
      - logger.log: 
          level: info
          format: "${device_name_short} is down!"

## ---------------------------------------------------
## Compoments obis_d0, backup
## https://github.com/mampfes/esphome_obis_d0
## https://github.com/zdzichu6969/esphome-component
## https://github.com/TheStaticTurtle/esphome_syslog
## ---------------------------------------------------
external_components:
  - source:
      type: local
      path: custom_components
    components: [ obis_d0 ]
  - source:
      type: local
      path: custom_components
    components: [backup]
  - source:
      type: local
      path: custom_components
    components: [syslog]    

## ---------------------------------------------------
## syslog service
## ---------------------------------------------------
syslog:
    ip_address: !secret syslog_server
    port: !secret syslog_port
    min_level: DEBUG

## ---------------------------------------------------
# Global variables
## ---------------------------------------------------
globals:
  - id: boot_counter
    type: int
    restore_value: yes
    initial_value: "0"

## ---------------------------------------------------
## WIFI Settings
## ---------------------------------------------------
wifi:
  networks:
    - ssid:  !secret ssid3_name
      password: !secret ssid3_pswd
    - ssid:  !secret ssid2_name
      password: !secret ssid2_pswd
  domain: !secret domain

## ---------------------------------------------------
## WEBSERVER Settings
## ---------------------------------------------------
web_server:
  port: 80
  version: 2
  local: true

## ---------------------------------------------------
## OTA Settings
## ---------------------------------------------------
ota:
  password: !secret ota_pswd
  on_error:
    then:
      - logger.log:
          format: "OTA update error %d"
          args: ["x"]

## ---------------------------------------------------
# Native API Component
## ---------------------------------------------------
api:
  id: espapi
  port: 6053
  #  The amount of time to wait before rebooting when no client connects to the API.
  # Can be disabled by setting this to 0s
  reboot_timeout: 0s

## ---------------------------------------------------
# Logger
# Set baud_rate to 0 to disable logging via UART.
## ---------------------------------------------------
logger:
  level: INFO
  baud_rate: 0 #disable logging over uart
  logs:
     obis_d0: INFO

## ---------------------------------------------------
## Save your ESPHome device configuration in firmware 
## and recover it if you lost source files.
## ---------------------------------------------------
backup:
  auth:
    username: !secret web_username
    password: !secret web_password
  force_update: false

## ---------------------------------------------------
## SNTP Time server
## ---------------------------------------------------
time:
  - platform: sntp
    id: sntp_time
    timezone: Europe/Berlin
    servers:
      - 0.at.pool.ntp.org
      - 0.pool.ntp.org
      - 1.pool.ntp.org
    on_time_sync:
      then:
        - logger.log: "Synchronized sntp clock"

## ---------------------------------------------------
# Serial interface uart 
## ---------------------------------------------------
uart:
  id: my_uart
  tx_pin: GPIO17 #D5 orange
  rx_pin: GPIO16 #D2 white
  baud_rate: 300
  data_bits: 7
  parity: EVEN
  stop_bits: 1
  debug:
     direction: BOTH
     dummy_receiver: true
     sequence:
        - lambda: |-
            UARTDebug::log_string(direction, bytes);
            std::string str(bytes.begin(), bytes.end());
            id(syslogMessage)->execute(str.c_str());            

obis_d0:
  - id: my_sm
    uart_id: my_uart

# ---------------------------------------------------
# Testcase protocoll for ISk5MT174
# only works with a second device
# ---------------------------------------------------
# serial port read data d2 protocoll for ISk5MT174
# /ISk5MT174-0001               Device Name
# 0.9.1(130203)                 Current time (hh:mm:ss)
# 0.9.2(0230223)                Date (1YY.MM.DD)
# 0.0.0(00339188)               *Device address 1
# 0.2.0(1.03)                   *Firmware version
# C.1.6(FDF5)                   *Firmware check sum
# 1.8.1(0011404.409*kWh)        Positive active energy (A+) in tariff NT [kWh]
# 1.8.2(0023813.725*kWh)        Positive active energy (A+) in tariff HT [kWh]
# 2.8.1(0015608.962*kWh)        Negative active energy (A-) in tariff T1 [kWh]
# 2.8.2(0000900.569*kWh)        Negative active energy (A-) in tariff T2 [kWh]
## ---------------------------------------------------
script:

  - id: syslogMessage
    parameters:
      message: string
    then:
      - syslog.log:
         level: 4
         tag: "ESPINFO"
         payload: !lambda return message;

  - id: sendObisData
    then:
      - logger.log: "Start sending D0 data for ${device_name_short}"
      - uart.write:
          id: my_uart
          data: "/ISk5MT174-0001\r\n"
      - delay: 5ms
      - uart.write:
          id: my_uart
          data: "0.9.1(130203)\r\n"
      - delay: 5ms
      - uart.write:
          id: my_uart
          data: "0.9.2(0230223)\r\n"
      - delay: 5ms
      - uart.write:
          id: my_uart
          data: "0.0.0(00339188)\r\n"
      - delay: 5ms
      - uart.write:
          id: my_uart
          data: "0.2.0(1.03)\r\n"
      - delay: 5ms
      - uart.write:
          id: my_uart
          data:  "C.1.6(FDF5)\r\n"
      - delay: 5ms
      - uart.write:
          id: my_uart
          data:  "1.8.1(0016519.075*kWh)\r\n"
      - delay: 5ms
      - uart.write:
          id: my_uart
          data:  "1.8.2(0029595.323*kWh)\r\n"
      - delay: 5ms
      - uart.write:
          id: my_uart
          data:  "2.8.1(0020656.624*kWh)\r\n"
      - delay: 5ms
      - uart.write:
          id: my_uart
          data:  "2.8.2(0001220.103*kWh)\r\n"
      - delay: 5ms
      - uart.write:
          id: my_uart
          data:  "F.F.0(0000000)\r\n"
      - logger.log: "End sending D0 data for ${device_name_short}"

# ---------------------------------------------------
# Switches
# ---------------------------------------------------
switch:

  # simple uart.write testcase
  - platform: template
    name: "Test uart.write"
    optimistic: true
    on_turn_on:
      then:
        - logger.log: "Send Obis Test Data"
        - script.execute: sendObisData

  - platform: template
    name: Reset Boot Counter
    turn_on_action:
      then:
        - lambda: |-
            id(boot_counter) = 0;
            id(bootcounter).update();
        - logger.log: ${device_name_short} reset boot counter o.k!

  - platform: restart
    name: "Restart"
    id: restart_switch

# ---------------------------------------------------
# Sensors
# ---------------------------------------------------
sensor:
  # 1.8.1(0011404.409*kWh) Positive active energy (A+) in tariff HT [kWh]
  - platform: obis_d0
    obis_d0_id: my_sm
    name: "1. Verbrauch HT"
    id: mt174ht
    obis_code: "1.8.1"
    unit_of_measurement: kWh
    accuracy_decimals: 3
    device_class: energy
    state_class: total_increasing
    value_regex: "(\\d{7}\\.\\d{3}\\*kWh)"

  # 1.8.2(0023813.725*kWh) Positive active energy (A+) in tariff NT [kWh]
  - platform: obis_d0
    obis_d0_id: my_sm
    name: "2. Verbrauch NT"
    id: mt174nt
    obis_code: "1.8.2"
    unit_of_measurement: kWh
    accuracy_decimals: 3
    device_class: energy
    state_class: total_increasing
    value_regex: "\\d{7}\\.\\d{3}\\*kWh"

  # 2.8.1(0015608.962*kWh) Negative active energy (A-) in tariff T1 [kWh]
  - platform: obis_d0
    obis_d0_id: my_sm
    name: "3. Einspeisung T1"
    id: mt174t1
    obis_code: "2.8.1"
    unit_of_measurement: kWh
    accuracy_decimals: 3
    device_class: energy
    state_class: total_increasing
    value_regex: "\\d{7}\\.\\d{3}\\*kWh"

  # 2.8.2(0000900.569*kWh)  Negative active energy (A-) in tariff T2 [kWh]
  - platform: obis_d0
    obis_d0_id: my_sm
    name: "4. Einspeisung T2"
    id: mt174t2
    obis_code: "2.8.2"
    unit_of_measurement: kWh
    accuracy_decimals: 3
    device_class: energy
    state_class: total_increasing
    value_regex: "\\d{7}\\.\\d{3}\\*kWh"

  - platform: template
    name: Boot counter
    id: bootcounter
    accuracy_decimals: 0
    entity_category: "diagnostic"
    lambda: |-
      return (id(boot_counter));

  - platform: uptime
    name: Uptime
    id: uptime_sensor
    internal: true
    update_interval: ${update_interval}
    unit_of_measurement: seconds
    entity_category: "diagnostic"
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? String(days) + "d " : "") +
                (hours ? String(hours) + "h " : "") +
                (minutes ? String(minutes) + "m " : "") +
                (String(seconds) + "s")
              ).c_str();

  # Wifi quality RSSI
  - platform: wifi_signal
    name: Wlan Signal
    id: wifi_signal_db
    update_interval: 60s
    entity_category: "diagnostic"

# ---------------------------------------------------
# Text sensors
# ---------------------------------------------------
text_sensor:

  # 0.9.2(0230223) Date (1YY.MM.DD)
  - platform: obis_d0
    name: "MT174Mdate"
    id: mt174date
    internal: true
    obis_d0_id: my_sm
    obis_code: "0.9.2"
    value_regex: "\\d{7}"
    filters:
      - prepend: "2"
    on_value:
      then:
        - lambda: |-
            ESP_LOGD("main", "Date: %s%s-%s-%s", "2", x.substr(0,3).c_str(), x.substr(3,2).c_str(), x.substr(4,2).c_str());
            std::string result = x.substr(0,4) + "-" + x.substr(4,2) + "-" + x.substr(6,2);
            id(thedate).publish_state(result);

  # 0.9.1(130203)  Current time (hh:mm:ss)
  - platform: obis_d0
    name: "MT174Mtime"
    id: mt174time
    internal: true
    obis_d0_id: my_sm
    obis_code: "0.9.1"
    value_regex: "\\d{6}"
    on_value:
      then:
        - lambda: |-
            ESP_LOGD("main", "Time: %s:%s:%s", x.substr(0,2).c_str(), x.substr(2,2).c_str(), x.substr(4,2).c_str());
            std::string result = x.substr(0,2) + ":" + x.substr(2,2) + ":" + x.substr(4,2);
            id(thetime).publish_state(result);

  - platform: template
    name: 5. Messdatum
    id: thedate
    entity_category: "diagnostic"

  - platform: template
    name: 6. Messzeit
    id: thetime
    entity_category: "diagnostic"

  - platform: version
    name: Version
    id: appver
    entity_category: "diagnostic"

  - platform: template
    name: Online seit
    id: uptime_human
    icon: mdi:clock-start
    entity_category: "diagnostic"

  - platform: template
    name: Timestamp
    id: systime
    entity_category: "diagnostic"
    lambda: char str[20];
      time_t currTime = id(sntp_time).now().timestamp;
      strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%S", localtime(&currTime));
      return (std::string) str;

  ## Rest sensor to get all values
  ## value: HT|NT|T1|T2|timestamp
  - platform: template
    id: gridmeterdata
    update_interval: ${update_interval}
    lambda: |-
      std::string s;
      if (id(mt174t2).has_state()) {
        char buf[512];
        sprintf(buf, "%.3f|%.3f|%.3f|%.3f|%s",
              id(mt174ht).state,
              id(mt174nt).state,
              id(mt174t1).state,
              id(mt174t2).state,
              id(systime).state.c_str()
              );
        s = buf;
      }else{
        s = "No data found";
      }
      return s;

# EOF mt174_testcase.yaml
mampfes commented 1 year ago

fixed by #9