latonita / esphome-energomera-iec

Компонент EspHome для счетчиков Энергомера CE102M, CE301, CE303 (IEC/МЭК/ГОСТ 61107)
MIT License
4 stars 2 forks source link
ce102m ce301 ce303 energomera energomera-ce102m energomera-ce301 energomera-ce303 energy iec61107 meter

ESPHome компонент для подключения счетчиков электроэнергии Энергомера CE102M CE207 CE208 CE301 CE303 CE307 CE308 по RS-485 (ГОСТ МЭК/IEC 61107-2011)

1. Назначение

Компонент для считывания данных с электросчетчиков, поддерживающих протокол МЭК/IEC 61107, таких как Энергомера СЕ102М, СЕ301, СЕ303. Потенциально, может работать и сдругими счетчиками поддерживающими данный ГОСТ. Кроме того, работает и с некоторыми счетчиками Энергомера, заявленными как СПОДЭС (SPds в названии - например CE207-R7.849.2.OA SPds). Проверено на нескольких CE207, СЕ208, СЕ307, СЕ308.

2. Отказ от ответственности

Пользуясь данным ПО пользователь полностью берет на себя всю ответственность за любые последствия.

3. Функции

4. Пример отображения в home-assistant

Пример отображения в home-asistant

5. Подключение

Устройства:

5.1 Рекомендуемый вариант подключения с RS-485 модулем с автоматическим выбором направления передачи

На данный момент в продаже много модулей RS-485 с расширеным набором функций - с логикой автоматического выбора направления передачи, защитными диодами и предохранителями. Эти модули рекомендуются к использованию, т.к. более надежны.
Например, модуль XY-017 Модуль XY-017

┌───────┐           3.3В     ┌─────────────┐                 ┌────────────────┐
│       │            └── VCC ┤             │                 │                │
│  MCU  ├ RX ──────────── RX ┤ RS485<->TTL ├ A ───┐─┐─┐─── A ┤ Электросчетчик │
│ ESPxx ├ TX ──────────── TX ┤   module    ├ B ───└─└─└─── B ┤                │
│       │                    │             │                 │                │
│       │                    │             │          ┌─── + ┤                │
│       ├ GND ────────── GND ┤             │      9-12В ── - ┤                │
└───────┘                    └─────────────┘                 └────────────────┘

Иногда RX/TX на модуле перепутаны - ничего страшного, просто меняем.

5.2 Вариант подключения с классическим RS-485 модулем с 4 входами

Классический модуль с RO/DI/DE/RE входами + общая земля. MAX485 расчитан на 5В, а MAX3485 на 3.3В, хотя первый в 90% случаев прекрасно работает и от 3.3В тоже.

Модуль без автоматического выбора направления


┌───────┐           3.3В     ┌─────────────┐                 ┌────────────────┐
│       │            └───VCC ┤             │                 │                │
│  MCU  ├ RX ──────────── RO ┤ RS485<->TTL ├ A ───┐─┐─┐─── A ┤ Электросчетчик │
│ ESPxx ├ TX ──────────── DI ┤   module    ├ B ───└─└─└─── B ┤                │
│       ├ FLOW ──────┬─── RE ┤             │                 │                │
│       │            └─── DE ┤             │          ┌─── + ┤                │
│       ├ GND ────────── GND ┤             │      9-12В ── - ┤                │
└───────┘                    └─────────────┘                 └────────────────┘

6. Настройка основного компонента

Подлючаем внешний компонент из репозитория

external_components:
  - source: github://latonita/esphome-energomera-iec
    refresh: 30s
    components: [energomera_iec]

Конфигурируем UART 9600 7E1:

uart:
  rx_pin: GPIO16
  tx_pin: GPIO17
  baud_rate: 9600
  data_bits: 7
  parity: EVEN
  stop_bits: 1

Основной модуль

energomera_iec:
  id: ce102m
  update_interval: 30s
#  address: 123456789
#  receive_timeout: 500ms         # время ожидания ответа от счетчика
#  delay_between_requests: 100ms  # задержка между запросами к счетчику
#  flow_control_pin: GPIO32

7. Настройка сенсоров для опроса счетчика

Реализованы два типа сенсоров:

Названия функций для запроса берем из документации на счетчик. Если запрос возвращает несколько значений, то, по-умолчанию, берется первое, но можно выбрать указав номер ответа (индекс, начинается с 1). Если в скобках указано несколько значений через запятую, то можно указать какое именно брать (суб-индекс, начинается с 1). Примеры запросов и ответов от счетчика: Счетчик Запрос Ответ счетчика Индекс Суб-индекс Результат
CE102M VOLTA() VOLTA(228.93) не указан не указан 228.93
CE301/303 VOLTA() VOLTA(228.93)VOLTA(230.02)VOLTA(235.12) не указан не указан 228.93
CE301/303 VOLTA() VOLTA(228.93)VOLTA(230.02)VOLTA(235.12) 1 не указан 228.93
CE301/303 VOLTA() VOLTA(228.93)VOLTA(230.02)VOLTA(235.12) 2 не указан 230.02
*, кроме СПОДЭС ET0PE() ET0PE(34261.8262567)(25179.1846554)(9082.6416013)(0.0)(0.0)(0.0) 2 не указан 25179.1846554
CE307/308 EMD01(0.0,1) EMD01(20.08.24,0.45991)(0.41342) 1 2 0.45991
CE307/308 EMD01(0.0,1) EMD01(20.08.24,0.45991)(0.41342) 2 не указан 0.41342

Запросы берем из руководств на счетчики. Например, Руководство по эксплуатации CE102M , или Руководство пользователя CE301 и CE303.

Кроме того, оказалось, что некоторые СПОДЭС счетчики Энергомера (например, 307 и 308, и, возможно, также 207 и 208) тоже уверенно отвечают на запросы по стандарту МЭК, но с некоторыми особенностями. Например, там не работает команда ET0PE для получения накопленной энергии. Вместо этого можно использовать команды работы с архивом EMDzz/ENDzz и аналогичные. Документация по командам CE208 и CE308, взятая с форума поддержки Энергомеры.

7.1 Пример. Запрос потребления электроэнергии в кВт*ч

sensor:
  - platform: energomera_iec
    request: ET0PE()
    index: 2
    name: Энергия Тариф 1
    unit_of_measurement: kWh
    accuracy_decimals: 3
    device_class: energy
    state_class: total_increasing

  - platform: energomera_iec
    request: ET0PE()
    index: 3
    name: Энергия Тариф 2
    unit_of_measurement: kWh
    accuracy_decimals: 3
    device_class: energy
    state_class: total_increasing

7.2 Пример. Запрос даты

Дату счетчик возвращает в формате нн.дд.мм.гг, где - день недели 00 - воскресенье, 01 понедельник. Пример: 03.13.07.24. Превратить это в нормальную дату можно, например,так:

text_sensor:
  - platform: energomera_iec
    name: Date
    request: DATE_()
    filters:
      - lambda: |-
          std::string str{x};
          str.erase(0,3);
          str.insert(6,"20");
          return str;

Некоторые счетчики (например, СЕ207) дату возвращают в формате н.дд.мм.гг, например 3.11.09.24. Поэтому в lambda выражении надо поправить удаление лишних символов: str.erase(0,2);:

text_sensor:
  - platform: energomera_iec
    name: Date
    request: DATE_()
    filters:
      - lambda: |-
          std::string str{x};
          str.erase(0,2); 
          str.insert(6,"20");
          return str;

8. Примеры готовых конфигураций

Для однофазного счетчика CE102M * [Скачать конфиг ce102m.yaml](ce102m.yaml) ``` esphome: name: energomera-ce102m esp32: board: esp32dev framework: type: arduino logger: level: DEBUG external_components: - source: github://latonita/esphome-energomera-iec refresh: 30s components: [energomera_iec] uart: rx_pin: GPIO16 tx_pin: GPIO17 baud_rate: 9600 data_bits: 7 parity: EVEN stop_bits: 1 energomera_iec: id: ce102m update_interval: 30s # receive_timeout: 500ms # delay_between_requests: 150ms # flow_control_pin: GPIO32 sensor: - platform: energomera_iec request: ET0PE() index: 1 name: Электроэнергия unit_of_measurement: kWh accuracy_decimals: 3 device_class: energy state_class: total_increasing - platform: energomera_iec request: ET0PE() index: 2 name: Электроэнергия T1 unit_of_measurement: kWh accuracy_decimals: 3 device_class: energy state_class: total_increasing - platform: energomera_iec request: ET0PE() index: 3 name: Электроэнергия T2 unit_of_measurement: kWh accuracy_decimals: 3 device_class: energy state_class: total_increasing - platform: energomera_iec name: Ток request: CURRE() unit_of_measurement: A accuracy_decimals: 2 device_class: current state_class: measurement - platform: energomera_iec name: Напряжение request: VOLTA() unit_of_measurement: V accuracy_decimals: 1 device_class: voltage state_class: measurement - platform: energomera_iec name: Частота request: FREQU() unit_of_measurement: Hz accuracy_decimals: 2 device_class: frequency state_class: measurement - platform: energomera_iec name: Коэффициент мощности request: COS_f() unit_of_measurement: "%" accuracy_decimals: 2 device_class: power_factor state_class: measurement - platform: energomera_iec name: Активная мощность request: POWEP() unit_of_measurement: kW accuracy_decimals: 3 device_class: power state_class: measurement text_sensor: - platform: energomera_iec name: Заводской номер request: SNUMB() entity_category: diagnostic - platform: energomera_iec name: Время request: TIME_() entity_category: diagnostic - platform: energomera_iec name: Дата request: DATE_() entity_category: diagnostic filters: - lambda: |- std::string str{x}; str.erase(0,3); str.insert(6,"20"); return str; wifi: ssid: !secret wifi_ssid password: !secret wifi_password reboot_timeout: 5min power_save_mode: NONE api: password: !secret api_password ota: password: !secret ota_password ```
Для трехфазных счетчиков CE301, CE303 * [Скачать конфиг ce303.yaml](ce303.yaml) ``` esphome: name: energomera-ce303 esp8266: board: nodemcuv2 logger: level: DEBUG external_components: - source: github://latonita/esphome-energomera-iec refresh: 10s components: [energomera_iec] uart: rx_pin: D5 tx_pin: D6 baud_rate: 9600 data_bits: 7 parity: EVEN stop_bits: 1 rx_buffer_size: 512 energomera_iec: id: ce303 address: 123456789 update_interval: 10s # delay_between_requests: 50ms # receive_timeout: 500ms sensor: - platform: energomera_iec request: ET0PE() index: 1 name: Электроэнергия unit_of_measurement: kWh accuracy_decimals: 3 device_class: energy state_class: total_increasing - platform: energomera_iec request: ET0PE() index: 2 name: Электроэнергия T1 unit_of_measurement: kWh accuracy_decimals: 3 device_class: energy state_class: total_increasing - platform: energomera_iec request: ET0PE() index: 3 name: Электроэнергия T2 unit_of_measurement: kWh accuracy_decimals: 3 device_class: energy state_class: total_increasing - platform: energomera_iec name: Ток фаза A request: CURRE() index: 1 unit_of_measurement: A accuracy_decimals: 3 device_class: current state_class: measurement - platform: energomera_iec name: Ток фаза B request: CURRE() index: 2 unit_of_measurement: A accuracy_decimals: 3 device_class: current state_class: measurement - platform: energomera_iec name: Ток фаза C request: CURRE() index: 3 unit_of_measurement: A accuracy_decimals: 3 device_class: current state_class: measurement - platform: energomera_iec name: Напряжение фаза A request: VOLTA() index: 1 unit_of_measurement: V accuracy_decimals: 3 device_class: voltage state_class: measurement - platform: energomera_iec name: Напряжение фаза B request: VOLTA() index: 2 unit_of_measurement: V accuracy_decimals: 3 device_class: voltage state_class: measurement - platform: energomera_iec name: Напряжение фаза C request: VOLTA() index: 3 unit_of_measurement: V accuracy_decimals: 3 device_class: voltage state_class: measurement - platform: energomera_iec name: Активная мощность request: POWEP() index: 1 unit_of_measurement: kW accuracy_decimals: 3 device_class: power state_class: measurement - platform: energomera_iec name: Активная мощность фаза A request: POWPP() unit_of_measurement: kW accuracy_decimals: 3 index: 1 device_class: power state_class: measurement - platform: energomera_iec name: Активная мощность фаза B request: POWPP() unit_of_measurement: kW accuracy_decimals: 3 index: 2 device_class: power state_class: measurement - platform: energomera_iec name: Активная мощность фаза C request: POWPP() unit_of_measurement: kW accuracy_decimals: 3 index: 3 device_class: power state_class: measurement text_sensor: - platform: energomera_iec name: Заводской номер request: SNUMB() entity_category: diagnostic - platform: energomera_iec name: Время request: TIME_() entity_category: diagnostic - platform: energomera_iec name: Дата request: DATE_() entity_category: diagnostic filters: - lambda: |- std::string str{x}; str.erase(0,3); str.insert(6,"20"); return str; wifi: ssid: !secret wifi_ssid password: !secret wifi_password api: password: !secret api_password ota: platform: esphome password: !secret ota_password ```
Для однофазного счетчика CE207 СПОДЭС ``` esphome: name: energomera-ce207-esp32 friendly_name: Energomera-ce207-esp32 esp32: board: esp32dev framework: type: arduino wifi: ssid: !secret wifi_ssid password: !secret wifi_password api: password: !secret api_password ota: platform: esphome password: !secret ota_password external_components: - source: github://latonita/esphome-energomera-iec refresh: 30s components: [energomera_iec] uart: rx_pin: GPIO16 tx_pin: GPIO17 baud_rate: 9600 data_bits: 7 parity: EVEN stop_bits: 1 energomera_iec: id: ce207 sensor: - platform: energomera_iec request: EMD01(0.0,3) index: 1 sub_index: 2 name: Электроэнергия unit_of_measurement: kWh accuracy_decimals: 3 device_class: energy state_class: total_increasing - platform: energomera_iec name: Ток request: CURRE() unit_of_measurement: A accuracy_decimals: 2 device_class: current state_class: measurement - platform: energomera_iec name: Напряжение request: VOLTA() unit_of_measurement: V accuracy_decimals: 1 device_class: voltage state_class: measurement - platform: energomera_iec name: Частота request: FREQU() unit_of_measurement: Hz accuracy_decimals: 2 device_class: frequency state_class: measurement - platform: energomera_iec name: Коэффициент мощности request: COS_f() unit_of_measurement: "%" accuracy_decimals: 2 device_class: power_factor state_class: measurement - platform: energomera_iec name: Активная мощность request: POWEP() unit_of_measurement: kW accuracy_decimals: 3 device_class: power state_class: measurement text_sensor: - platform: energomera_iec name: Заводской номер request: SNUMB() entity_category: diagnostic - platform: energomera_iec name: Время request: TIME_() entity_category: diagnostic - platform: energomera_iec name: Дата request: DATE_() entity_category: diagnostic filters: - lambda: |- std::string str{x}; str.erase(0,2); str.insert(6,"20"); return str; ```

9. Проблемы, особенности, рекомендации