latonita / esphome-energomera-iec

Компонент EspHome для счетчиков Энергомера CE102M, CE301, CE303 (IEC/МЭК/ГОСТ 61107)
MIT License
5 stars 3 forks source link

Энергомера CE307 R34 #1

Open klim123123 opened 2 months ago

klim123123 commented 2 months ago

Спасибо что поделились проектом! Подключил к счетчику CE307 по вашей схеме, завелось все с полпинка. Но есть проблема с получением информации о показаниях счетчика Т1, Т2 и сумма.(а это было самое главное зачем я покупал новый счетчик) На запрос ET0PE() выдается ошибка ERR12 (Неизвестное имя параметра) Попробовал достать команду только для Т1, через AdminTools. Вижу запросы EMD01 и MD0. Попробовал их, так же выдается ошибка ERR12. Если не затруднит направьте в какую сторону копать, что не так делают. Спасибо

Запрос
18.08.2024 23:28:27.922
175 63 33 141 10                                          ??!?.

Ответ
18.08.2024 23:28:27.971
47 69 77 82 53 92 50 67 69 51 48 55 54 46 49 48           /EMR5\2CE3076.10
13 10                                                     ..

Запрос
18.08.2024 23:28:27.997
6 48 53 177 141 10                                        .05??.

Ответ
18.08.2024 23:28:28.050
1 80 48 2 40 56 51 66 67 50 52 57 41 3 101                .P0.(83BC249).e

Запрос
18.08.2024 23:28:28.050
129 80 177 130 40 183 183 183 183 183 183 169 3 33           ?P??(???????.!

Ответ
18.08.2024 23:28:28.088
6                                                         .

Запрос
18.08.2024 23:28:28.093
129 210 177 130 197 77 68 48 177 40 48 46 48 172 177 169           ?????MD0?(0.0???
3 123                                                     .{

Ответ
18.08.2024 23:28:28.193
2 69 77 68 48 49 40 49 56 46 48 56 46 50 52 44            .EMD01(18.08.24,
48 46 51 52 52 57 49 41 13 10 40 48 46 51 52 51           0.34491)..(0.343
53 41 13 10 3 89                                          5)...Y

Запрос
18.08.2024 23:28:28.310
129 66 48 3 245                                           ?B0.?
latonita commented 2 months ago

Спасибо. Подскажите точно модель счётчика и в каком она корпусе?

klim123123 commented 2 months ago

Точная модель CE307 R34.749.OA.QYUVLFZ SPds Версия ПО 3076v1,85BD Корпус вот такой: http://www.energomera.ru/images/product/e307_r34_7929.jpg

latonita commented 2 months ago

Посмотрел. Через админ тулс по какому протоколу вы к нему подключились и считывете данные? Вообще, пишут, что счетчик совместим с протоколом СПОДЭС/DLMS. Попробуйте эти компоненты:

В сентябре я смогу сделать компонент именно под СПОДЭС, но нужны будут логи побольше. Можно будет удаленно настроить, напишите мне на anton.viktorov@live.com для детальной информации.

latonita commented 2 months ago

Задам вопрос производителю пока что. по поводу 61107

klim123123 commented 2 months ago

Да счетчик совместим с протоколом СПОДЭС/DLMS и IEC61107. Удалось выяснить через AdminTools. Мне показалось в IEC61107 проще, по этому я и стал в нем копаться. Логи выше от меня, как раз это IEC61107. Удалось получить Т1 посылая следующие команды. Правда почему-то ответ приходит странным, с помощью применения операции XOR с маской 80 удалось привести ответ в читаемый формат.

>> AF 3F 21 8D 0A
<< AF C5 4D D2 35 5C B2 C3 C5 33 30 B7 36 2E B1 30 8D 0A
>> 06 30 35 B1 8D 0A
<< 81 50 30 82 28 C3 B4 36 35 36 41 30 B7 A9 03 96
>> 81 D2 B1 82 C5 4D 44 30 B1 28 30 2E 30 AC B1 A9 03 7B
<< 82 C5 4D 44 30 B1 28 B2 30 2E 30 B8 2E B2 B4 AC 30 2E B4 35 30 33 B8 A9 8D 0A 28 30 2E B4 30 33 B8 39 A9 8D 0A 03 0A

после применения правила XOR с маской 0x80 получаем 02 45 4D 44 30 31 28 32 30 2E 30 38 2E 32 34 2C 30 2E 34 35 30 33 38 29 0D 0A 28 30 2E 34 30 33 38 39 29 0D 0A 03 0A переводим в ASCII, получаем .EMD01(20.08.24,0.45038) (0.40389)

latonita commented 2 months ago

правильно ли я понмаю, что

klim123123 commented 2 months ago

через ваш скрипт на запросы CURRE, VOLTA, POWEP, TERMO, SNUMB, TIME, DATE приходят нормальные ответы. на запрос EMD01 приходит ошибка ERR12. увидел я EMD01 в ответе через AdminTools, по этому решил попробовать. через ваш скрипт не видно какое именно приходит точно ответ(или я не знаю как включить детали). просто выдается ошибвка в логе:

[15:22:13][D][energomera_iec:360]: Requesting data for 'ET0P1()'
[15:22:13][D][energomera_iec:392]: Received name: '', values: 1, idx: 1(ERR12), 2(), 3(), 4(), 5(), 6(), 7(), 8(), 9(), 10(), 11(), 12()
[15:22:13][E][energomera_iec:396]: Request '' either not supported or malformed. Error code ERR12
[15:22:13][D][energomera_iec:360]: Requesting data for 'ET0PE(1)'
[15:22:14][D][energomera_iec:392]: Received name: '', values: 1, idx: 1(ERR12), 2(), 3(), 4(), 5(), 6(), 7(), 8(), 9(), 10(), 11(), 12()
[15:22:14][E][energomera_iec:396]: Request '' either not supported or malformed. Error code ERR12
[15:22:14][D][energomera_iec:360]: Requesting data for 'ET2PE()'
klim123123 commented 2 months ago

ответы с xor 0x80 удалось получить если напрямую посылать команды на счетчик, без вашего скрипта. т.к. я не знаю как из скрипта посылать такие команды.

latonita commented 2 months ago

чтобы получить больше информации можно включить log level = verbose или very_verbose

что говорит команда EMD01(0.0,F)? EMDzz(i.a,m) - вытаскивание из архива zz=01 - активная энергия, потребление i = 0, тольок одна последняя запись a = 0, значение НА этот день m = маска шестнадцатиричная, .... F = 111111 все )

p.s. нашел такой документ, крайне мутный и без нормальных примеров http://files.energomera.ru/files/d16a4cf6cb04040ba8d87555ef5986f7.docx

latonita commented 2 months ago

например так. или даже VERY_VERBOSE, не помню точно, где выдается все данные

# Enable logging
logger:
  level: VERBOSE
  logs: 
    wifi: INFO
    mdns: INFO
    sensor: INFO
    json: INFO
    api: INFO
    api.service: INFO
    scheduler: INFO

если какие-то компоненты будут много выдавать данных - их сюда в список тоже можно включить и ограничить им логгинг INFO

klim123123 commented 2 months ago

Похоже удалось получить что нужно Только срабатывает RX timeout. Наверное его нужно как то отключить.

[15:42:55][D][energomera_iec:360]: Requesting data for 'EMD01()'
[15:42:55][V][energomera_iec:593]: TX: <SOH>R1<STX>EMD01()<ETX><10> (13)
[15:42:55][V][energomera_iec:794]: State::WAITING_FOR_RESPONSE -> DATA_RECV
[15:42:55][W][energomera_iec:231]: RX timeout.
[15:42:55][V][energomera_iec:247]: RX: (20.08.24,0.45972)<CR><LF>(0.41323)<CR><LF>(0.04649)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.20552)<CR><LF>(0.14629)<CR><LF>(0.10791)<CR><LF>EMD01(19.08.24,0.41445)<CR><LF>(0.38837)<CR><LF>(0.02608)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.17685)<CR><LF>(0.12969)<CR><LF> (256)
[15:42:55][W][energomera_iec:261]: Retrying [1/3]...
[15:42:55][V][energomera_iec:593]: TX: <SOH>R1<STX>EMD01()<ETX><10> (13)
[15:42:56][W][energomera_iec:231]: RX timeout.
[15:42:56][V][energomera_iec:247]: RX: .24,0.34637)<CR><LF>(0.3435)<CR><LF>(0.00287)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.13373)<CR><LF>(0.10473)<CR><LF>(0.10791)<CR><LF>EMD01(15.12.23,0.31625)<CR><LF>(0.31625)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.0)<CR><LF>(0.11465)<CR><LF>(0.09369)<CR><LF>(0.10791)<CR><LF> (256)
latonita commented 2 months ago

rx timeout срабатывает, т..к очень много данных идет. EM-D это по дням. надо ограничить последним днем. например EMD01(0) насколько я понял из "книжки"

klim123123 commented 2 months ago

пробую разные команды. похоже что-то пошло в правильном направлении.

[15:47:05][D][energomera_iec:360]: Requesting data for 'EMD01(0.0,1)'
[15:47:05][V][energomera_iec:593]: TX: <SOH>R1<STX>EMD01(0.0,1)<ETX>{ (18)
[15:47:05][V][energomera_iec:794]: State::WAITING_FOR_RESPONSE -> DATA_RECV
[15:47:06][V][energomera_iec:637]: RX: <STX>EMD01(20.08.24,0.45991)<CR><LF>(0.41342)<CR><LF><ETX><08> (39)
[15:47:06][V][energomera_iec:792]: State::DATA_RECV
[15:47:06][D][energomera_iec:392]: Received name: 'EMD01', values: 2, idx: 1(**20.08.24,0.45991**), 2(**0.41342**), 3(), 4(), 5(), 6(), 7(), 8(), 9(), 10(), 11(), 12()
[15:47:06][D][energomera_iec:498]: Setting value for sensor 'EMD01(0.0,1)' to '20.08.24,0.45991', idx = 1
[15:47:06][E][energomera_iec:506]: Cannot convert incoming data to a number. Consider using a text sensor. Invalid data: '20.08.24,0.45991'
latonita commented 2 months ago

если счетчик так и не выдаст единственное число в ответе в скобках, то надо будет парсить через шаблоны типа такого:

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;
latonita commented 2 months ago

Думаю, кроме настройки индекса в сенсор можно добавить опциональный параметр пропуска первых N символов, чтобы не заниматься парсингом. <STX>EMD01(20.08.24,0.45991)<CR><LF>(0.41342)<CR><LF><ETX><08> если мы знаем, что там в первом значении всегда идет дата DD.MM.YY и запятая, можно опустить первые 9 символов.

вопрос, что там за "0." ? и что за значениея 45991 и 41342? вчера и сегодня?

klim123123 commented 2 months ago

вопрос, что там за "0." ? и что за значение 45991 и 41342? вчера и сегодня?

0.4599 - это общее потребление по всем тарифам 0.41342 - Т1 счетчик новый. по этому такие показания )

Вот так достаю Т1

    request: EMD01(0.0,1)
    index: 2

Сейчас найду сумму и все остальное.

У счетчика еще есть возможно размыкать реле нагрузки встроенное. И настраивать его по неправильному уровню напряжения. Позже исследую, напишу.

latonita commented 2 months ago

еще думаю, что вместо пропуска символов можно придумать еще sub-index - номер параметра внутри скобок, если там параметры перечислены через запятую. наверное, это будет разумнее

klim123123 commented 2 months ago

еще думаю, что вместо пропуска символов можно придумать еще sub-index - номер параметра внутри скобок, если там параметры перечислены через запятую. наверное, это будет разумнее

да это хорошая идея. правильно ли я понимаю что достать второе число тут (20.08.24,0.46178) сейчас можно только через lambda?

latonita commented 2 months ago

да это хорошая идея. правильно ли я понимаю что достать второе число тут (20.08.24,0.46178) сейчас можно только через lambda?

да, именно так. я добавлю такую возможность в ближайшее время.

klim123123 commented 2 months ago

в итоге вот что у меня получилось. буду ждать sub-index, чтобы поправить Электроэнергию. данные снимаются на Энергомера CE307 R34 Спасибо за скрипт!

sensor:
  - platform: template
    name: "Электроэнергия"
    unit_of_measurement: "kWh"
    accuracy_decimals: 4
    device_class: energy
    state_class: total_increasing
    lambda: |-
      // Удаляем первые 9 символов и преобразуем остаток в число
      std::string raw_data = id(raw_data_sensor).state;
      if (raw_data.length() > 9) {
        std::string value_str = raw_data.substr(9);
        return atof(value_str.c_str());
      } else {
        return 0.0f;  // Возвращаем 0.0, если длина строки меньше 9 символов
      }

  - platform: energomera_iec
    request: EMD01(0.0,1)
    index: 2
    name: Электроэнергия T1
    unit_of_measurement: kWh
    accuracy_decimals: 4
    device_class: energy
    state_class: total_increasing

  - platform: energomera_iec
    request: EMD01(0.0,3)
    index: 3
    name: Электроэнергия T2
    unit_of_measurement: kWh
    accuracy_decimals: 4
    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: 4
    unit_of_measurement: kW
    accuracy_decimals: 3
    device_class: power
    state_class: measurement

  - platform: energomera_iec
    name: Активная мощность фаза A
    request: POWEP()
    unit_of_measurement: kW
    accuracy_decimals: 3
    index: 1
    device_class: power
    state_class: measurement

  - platform: energomera_iec
    name: Активная мощность фаза B
    request: POWEP()
    unit_of_measurement: kW
    accuracy_decimals: 3
    index: 2
    device_class: power
    state_class: measurement

  - platform: energomera_iec
    name: Активная мощность фаза C
    request: POWEP()
    unit_of_measurement: kW
    accuracy_decimals: 3
    index: 3
    device_class: power
    state_class: measurement

  - platform: energomera_iec
    name: "Температура"
    request: TERMO()
    unit_of_measurement: "°C"
    accuracy_decimals: 2
    filters:
      - multiply: 0.01

text_sensor:
  - platform: energomera_iec
    name: Заводской номер
    request: SNUMB()
    entity_category: diagnostic

  - platform: energomera_iec
    name: Время
    request: TIME_()
    entity_category: diagnostic

  - platform: energomera_iec
    name: "Formatted Date"
    request: DATE_()
    filters:
      - lambda: |-
          std::string str{x};          // Получаем исходную строку
          str.erase(0, 2);             // Удаляем первые два символа (нн)
          str.insert(6, "20");         // Вставляем "20" перед годом
          return str;                  // Возвращаем отформатированную строку

  - platform: energomera_iec
    request: EMD01(0.0,1)
    index: 1
    name: "Raw Data"
    id: raw_data_sensor
klim123123 commented 2 months ago

К сожалению Реле можно управлять только через СПОДЭС Или какойто специальный пароль нужен для IEC61107. Я пробовал 777777 и пустой.

image

latonita commented 2 months ago

По-моему, реле всегда управлял поставщик энергии, программируя разные пороги превышения. Там нужен пароль на запись параметров какого то уровня

Get Outlook for Androidhttps://aka.ms/AAb9ysg


From: klim123123 @.> Sent: Tuesday, August 20, 2024 7:55:50 PM To: latonita/esphome-energomera-iec @.> Cc: Anton Viktorov @.>; Comment @.> Subject: Re: [latonita/esphome-energomera-iec] Энергомера CE307 R34 (Issue #1)

К сожалению Реле можно управлять только через СПОДЭС Или какойто специальный пароль нужен для IEC61107. Я пробовал 777777 и пустой.

image.png (view on web)https://github.com/user-attachments/assets/e4a24bf3-6b97-4628-b4b5-cca19f7564de

— Reply to this email directly, view it on GitHubhttps://github.com/latonita/esphome-energomera-iec/issues/1#issuecomment-2299321905, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AA6O66UPQRM4HCSP5CHDYMLZSNYJNAVCNFSM6AAAAABMWVCJ5OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEOJZGMZDCOJQGU. You are receiving this because you commented.Message ID: @.***>

klim123123 commented 2 months ago

Через СПОДЭС можно управлять реле без проблем самому вручную. Видимо у них считается IEC61107 небезопасный, по этому такое важное как управление реле, только через СПОДЭС. И да, на счетчике стоят пороги отключение по низкому/высокому напряжению в сети.

latonita commented 2 months ago

@klim123123 попробуйте ветку https://github.com/latonita/esphome-energomera-iec/tree/subidx

external_components:
    - source: github://latonita/esphome-emergomera-iec@subidx
    ...

чтобы из строки <STX>EMD01(20.08.24,0.45991)<CR><LF>(0.41342)<CR><LF><ETX><08> вытащить 0.45991, нужно указать index:1, sub_index: 2

вставьте кусочек лога сюда плиз. у меня нет тестового стенда сейчас для проверки.

klim123123 commented 2 months ago

[21:03:55][D][energomera_iec:360]: Requesting data for 'EMD01(0.0,1)' [21:03:55][V][energomera_iec:608]: TX: R1EMD01(0.0,1){ (18) [21:03:55][V][energomera_iec:827]: State::WAITING_FOR_RESPONSE -> DATA_RECV [21:03:56][V][energomera_iec:652]: RX: EMD01(21.08.24,0.47107)(0.42458)<09> (39)

[21:03:56][D][energomera_iec:392]: Received name: 'EMD01', values: 2, idx: 1(21.08.24,0.47107), 2(0.42458), 3(), 4(), 5(), 6(), 7(), 8(), 9(), 10(), 11(), 12() [21:03:56][D][energomera_iec:505]: Extracting value for sensor 'EMD01(0.0,1)', idx = 1, sub_idx = 2 from '21.08.24,0.47107' [21:03:56][D][energomera_iec:512]: Setting value using sub-index = 2, extracted sensor value is '0.47107' [21:03:56][D][energomera_iec:502]: Setting value for sensor 'EMD01(0.0,1)', idx = 2 to '0.42458' [21:03:56][D][energomera_iec:502]: Setting value for sensor 'EMD01(0.0,1)', idx = 1 to '21.08.24,0.47107' [21:03:56][D][energomera_iec:502]: Setting value for sensor 'EMD01(0.0,1)', idx = 1 to '21.08.24,0.47107'

klim123123 commented 2 months ago
  - platform: energomera_iec
    request: EMD01(0.0,1)
    index: 1
    sub_index: 2
    name: Электроэнергия сумма
    unit_of_measurement: kWh
    accuracy_decimals: 4
    device_class: energy
    state_class: total_increasing

  - platform: energomera_iec
    request: EMD01(0.0,1)
    index: 2
    name: Электроэнергия T1
    unit_of_measurement: kWh
    accuracy_decimals: 4
    device_class: energy
    state_class: total_increasing

  - platform: energomera_iec
    request: EMD01(0.0,3)
    index: 3
    name: Электроэнергия T2
    unit_of_measurement: kWh
    accuracy_decimals: 4
    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: 4
    unit_of_measurement: kW
    accuracy_decimals: 3
    device_class: power
    state_class: measurement

  - platform: energomera_iec
    name: Активная мощность фаза A
    request: POWEP()
    unit_of_measurement: kW
    accuracy_decimals: 3
    index: 1
    device_class: power
    state_class: measurement

  - platform: energomera_iec
    name: Активная мощность фаза B
    request: POWEP()
    unit_of_measurement: kW
    accuracy_decimals: 3
    index: 2
    device_class: power
    state_class: measurement

  - platform: energomera_iec
    name: Активная мощность фаза C
    request: POWEP()
    unit_of_measurement: kW
    accuracy_decimals: 3
    index: 3
    device_class: power
    state_class: measurement

  - platform: energomera_iec
    name: "Температура"
    request: TERMO()
    unit_of_measurement: "°C"
    accuracy_decimals: 2
    filters:
      - multiply: 0.01

text_sensor:
  - platform: energomera_iec
    name: Заводской номер
    request: SNUMB()
    entity_category: diagnostic

  - platform: energomera_iec
    name: Время
    request: TIME_()
    entity_category: diagnostic

  - platform: energomera_iec
    name: "Formatted Date"
    request: DATE_()
    filters:
      - lambda: |-
          std::string str{x};          // Получаем исходную строку
          str.erase(0, 2);             // Удаляем первые два символа (нн)
          str.insert(6, "20");         // Вставляем "20" перед годом
          return str;                  // Возвращаем отформатированную строку