Пишемо протоколи лічильників Меркурій 230 і Меркурій 200 для OpenSCADA

Для кого
— Для тих хто використовує OpenSCADA, але не може реалізувати більше ніж рішення «з коробки»
— Для тих хто шукає СКАДу для себе, але так і не може визначиться
— Для тих хто закинув цей проект, так і не розібравшись як він працює

Навіщо
— Дане рішення дозволяє зчитувати показання лічильників меркурій 230 і меркурій 200 без будь-яких лімітів
— Це безкоштовно


Проекту openscada (oscada.org) приділяють незаслужено мало уваги, про нього написана всього одна стаття на хабре. Більшість інженерів бояться чіпати і триметрової палицею цей продукт, чорт його знає який цей ваш лінукс. Розробляє його вже не перший десяток років фактично один чоловік, Роман Савоченко.

Не маючи раніше досвіду зі SCADA взагалі (а з лінуксом трохи дружив) вибрав саме його для реалізації моніторингу об'єктів на підприємстві. Так як порівняти мені було не з чим, інтерфейс і всі зв'язки даних з один одним я сприйняв як належне. Дуже допоміг відеоурок «швидкий старт», особисто я вважаю таких уроків можна було зробити і побільше. Документацію теж довелося перечитувати не раз, але воно того варте. Підключивши перший модуль збору даних Невід+ довго не міг зрозуміти чому він не працює. Адже як сумісний з протоколом DCON він у списку проекту числився(точніше його аналог). Поліз в оригінал протоколу і… виявилося, що він зовсім з ним не сумісний, як і багато інші модулі збору зі списку. Перше звернення на форум проблему мою виправило і ще кілька помилок досить оперативно. Розповідати про всі тонкощі системи я не буду, краще прочитайте вищезгадану статтю на хабре або подивіться «швидкий старт».

Через якийсь час мені знадобилося знімати показання з електролічильників Меркурій 230. Підтримки цих лічильників у openscada немає. Спробував утиліту taskgroup від творця всім відомого konfiguratorа, опитувати лічильники за CSD їй виявилося дохлим номером. Але все не так погано як могло бути, openscada система гранично модульна і написати свій модуль можна хоч на С++, хоч на мові високого рівня прямо в ній. Опис протоколу обміну для меркурія 230 без проблем можна знайти в мережі, виробник «Инкотекс» звичайно може надати вам опис за запитом, але мені не хотілося зв'язуватися з цією тяганиною.

Отже, підключаємо шину з лічильниками, для наочності і кращої орієнтації в протоколі ставимо konfigurator і сніффер послідовно порту, відкриваємо документацію. Намагаємося прочитати дані з лічильника з адресою 75.

всі скріншоти клікабельні



Як бачимо побігли наші дані.



Протокол обміну для меркурій 230 дуже схожий на протокол modbus.

Запит на відкриття каналу зв'язку призначений для доступу до даних з вказівкою рівня доступу. В лічильнику реалізований дворівневий доступ до даних: перший (нижчий) — рівень споживача, і другий (вищий) рівень господаря



Спробуємо з допомогою конфігуратора опитати наш лічильник і бачимо що перший запит це і є пароль, а відповідь лічильника це 4 байти. включають в себе



Тепер спробуємо це реалізувати на openscada. В С++ я не сильний, тому вирішив реалізувати на мові, вбудованому в саму СКАДу, який там зветься JavaLikeCalc.Javascript. Сам код опитування реалізується у двох модулях UserProtocol і DevLib. Створимо пристрій в бібліотеці пристроїв і назвемо m230. Додамо атрибути netaddr(мережевий адресу), password(пароль), transport(послідовний порт) і answer(відповідь на запит пароля). І напишемо запит.



Тепер перейдемо до протокольної частини і створимо в UserProtocol наш користувацький протокол і назвемо його так само m230. Почнемо з перетворення мережевої адреси. Код розрахунку контрольної суми modbus CRC16 вже був написаний давно, мені залишилося його тільки вставити в свій код.



Створимо і транспорт, прописавши в ньому потрібний порт, швидкість і таймінги.



Тепер створимо пристрою в LogivLev, в ньому створимо контролер а так само параметри (вони ж і є лічильники). Вибираємо наш шаблон, в конфігурації прописуємо мережеву адресу, пароль і транспорт.



Не зайвим буде і включити архівацію у відповідній вкладці.



Переходимо до вкладки Атрибути і бачимо наші 4 байта відповіді від лічильника. Пароль прийнятий, відмінно!



Що ж спробуємо вважати показання електроенергії. Додаємо в атрибути шаблону кілька записів ще кілька рядків коду для кожного тарифу і для їх суми.



Далі додамо в наш протокол ще рядка. Не лишнім буде перевірити відповідь на той чи запит прийшов і перевірити довжину пакета. Кожен 4 байта корисної інформації відповіді інтерпретується своєю послідовністю байт для читання енергії вона видно на скріншоті. В кінці з 16ричной системи дані переводимо у десяткову, до того ж це число треба поділити на 1000.



Заходимо знову в конфігурацію шаблону, ставимо галку «Зчитувати енергію від скидання» і в атрибутах у нас вже видно дані про тарифи.



На цьому зупинятися ми не збираємося і спробуємо додати миттєві дані — напруга, струм і потужність. Тут все теж саме, міняємо тільки другий, третій і четвертий байт, які відповідають у нас за те, яку інформацію ми хочемо отримати від лічильника.





Трохи змін додамо і на стороні протоколу.Перевіряємо відповідь на байти з чого будуємо припущення про його довжині і перевіряємо її, додаємо свою послідовність байт, переводимо в десяткову систему і ділимо на 100 для відповіді про напрузі та потужності на 1000 для відповіді про струмі.



Тепер в атрибутах нашого лічильника бачимо всі його основні дані, яких звичайно в рази більше і при бажанні можна додати ще, наприклад частоту в герцах і багато іншого.



Додамо для наочності ще кілька лічильників. Але це не все, дані треба не просто читати, але і представити їх в зручному вигляді. Для цього в openscada існує Vision (робочий інтерфейс) в якому дані можна представити у зручному для вас вигляді, хоч у вигляді мнемосхеми, у вигляді графіків, у вигляді документів ітд. Візьмемо стандартний документ з шаблону і відредагуємо його щоб вийшло так.



А в обробку документа додамо рядок, щоб можна було легко читати архіви даних по днях.



У підсумку запускаємо проект і відкриваємо наш документ.



Якщо треба уявити миттєві значення або з архіву то створюємо графік, додаючи туди наші значення. Ось приклад значень лічильника по напрузі.



Але через деякий час не полишала ідея написати заодно і протокол для однофазних лічильників меркурій 200. Опис протоколу я в мережі не знайшов, але світ не без добрих людей.

Мережевий адресу тут і є пароль лічильника. За замовчуванням він дорівнює останнім 6 цифр серійного номера. Спробуємо написати шаблон.

Ось схема пакета запиту і відповіді



Серійний номер лічильника занадто довгий, щоб умістити його в 32-бітове ціле число, тому розділимо його на дві частини.

Код запиту тарифу 0x27, пишемо структуру запиту і виділяємо які байти за який тариф у нас відповідають. І ділимо це значення на 100. І перевіряємо наш відповідь на обсяг символів.

Щоб зчитувати миттєві значення використовуємо код запиту 0х63. Також перевіримо наш відповідь на кількість байтів. Нюанси по кожному з цих значень теж враховуємо.

Але що робити якщо лічильник закодований програмою наладчик+? До щастя як кодує наладчик+ всім вже давно відомо, тому додаємо рядок на початок нашого коду.



Перейдемо до протокольної стороні. Перетворюємо нашу адресу в шістнадцяткову систему. Розрахунок контрольної суми і запит як і в попередньому протоколі.



Додамо кілька лічильників і в конфігурації шаблону пропишемо наші налаштування.



І у вкладці Атрибути бачимо як лічильник віддає потрібні нам значення.



Створимо документ щоб переглядати ці значення в більш зручному вигляді. Відредагуємо наш шаблон документа. Запустимо наш проект.



Все виявилося зовсім нескладно. Цей протокол можна скачати на форумі oscada.org/ru/forum у розділі «Розробка OpenSCADA». І на даний момент, наскільки мені відомо це єдине безкоштовне рішення для меркурієв на необмежену кількість лічильників.

p.s. Написав я цю справу ще 3 роки тому, тільки недавно вирішив цим поділиться.
P. P. S. У статті скоріше всього є неточності, якими Роман явно був би незадоволений.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.