Енергооблік у складі SCADA системи торгового центру
Розповім, як писав консольну програму для зняття показань із лічильників Меркурій 230 у торговому центрі. Посилання на вихідники наприкінці статті.
Почалося все з SCADA системи. Пощастило нам отримати проект на розробку та впровадження SCADA для торгового центру. Ну, як пощастило... Загалом розробка цієї системи окрема історія, яку, якщо читачеві буде цікаво, я розповім і поділюся набитими шишками. Та й система ще повністю не прийнята, тому поки не світитимемо подробицями.
- Контроль температур у приміщеннях; - централізоване управління вентиляцією за розкладом; - управління підживленням ГВП; - облік води та електрики; - SMS повідомлення.
У цій статті про електрику. З вибором моделі електрики слухали, тому тут особливих проблем не зазнав. Вирішив зупинитися на Меркурії. Для 3х фаз - 234ті (електрики купили 230) для однофазної мережі 206та модель. Далі вийшло, що електрики насували по всьому ТЦ лише трифазні лічильники. Ну, мені тільки менше проблем. Хоча не зрозумію навіщо.
Програмував я раніше в основному ПЛК і невеликі скрипти на C #. Але тут вирішив, що зможу зробити енергооблік (хотілося досвіду в програмуванні набратися). Погарячкував, звичайно.
Ідея була така:
- опитувальник-сервер веде енергооблік до бази даних; — SCADA система відповідає за візуалізацію
Спосіб опитування
Розробка самого опитувальника
Про патерни проектування навіть не чув. Тому наробив помилок одночасно, т.к. захопився успадкуванням (і не особливо грамотно). За розумними книжками – треба було застосовувати композицію. Надалі треба буде переробити всю бібліотеку.
Ланцюжок успадкування вийшов такий:
MeterDevice– загальний клас для всіх лічильників. Реалізує обмінпо COM порту з Modbus подібним протоколом;Mercury230- клас з набором функцій опитування для конкретного лічильника;Mercury230_DatabaseSignals– клас з конкретними параметрами лічильника (струми, напруги тощо) та функцією їх оновлення. Наслідування в ньому було не зручним рішенням. Т.к. потім сьорбнув проблем із серіалізацією та десеріалізацією об'єктів. Але цей клас так міцно вліз у код, що відступати не можна було.
Ключовим у функціях опитування вирішив зробити структуруRXmes. У ньому зберігати результат відповіді сам масив байтів відповіді. Будь-яка функція опитування (наприклад, запит серійного номера) оперує в собі цією структурою:
Таким чином, функція отримання серійного номера лічильника Меркурій 230 вийшла така:
Кому цікаво подивитися інші функції - можна подивитися вихідні записи.
Протокол зв'язку зі SCADA
Спочатку протокол простого TCP півночі був простенький. Відповідь SCAD по TCP виглядала для Меркурія 230того так.
Скадою дані парсилися і виводилися на іконку відповідного лічильника Все було б добре, але замовник вирішив (і уперся рогом), що всі дані потрібні в табличному вигляді. Та ще й захотів задавати ліміти всіх параметрів під час роботи. А вихід за ліміти має індикуватися.
Порвавши у собі волосся, т.к. SCADA табличні дані відображати не вміла, сів писати окрему програму для візуалізації.
Свій протокол вже ставав незручним, т.к. кількість параметрів зростала. Наприклад, для струму з'явилися верхній боковий вівтар, стан аварії, гістерезис включення аварії. Вийшло, що для параметрів сформувався окремий клас:
Тут врятувала серіалізація об'єктів. Спробувавши Байтову, XML та JSON серіалізацію, було вирішено зупинитися на JSON(DataContractJsonSerializer). Вона зручно читалася оком, обсяг даних виходив менше XML. І взагалі DataContractJsonSerializer прощав відсутність конструктора без аргументів. Це значно спрощувало життя.
База даних
Звичайно, найважливішим моментом був запис показань лічильників. Т.к. Scada система працювала з MySql, то й опитувальник було вирішено зав'язувати із нею. Тут особливих проблем не було.
Питання було лише одне – «які записувати?», т.к. варіантів лічильник дає багато. Власне коди для запиту:
Спочатку було вирішено записувати споживання за місяць та за добу. Крім того, було реалізовано простенький механізм зняття показань за місяцями за рік. І контроль цих даних. Якщо даних не вистачало, вони дописувалися.
Але вже ближче до кінця я отримую вимогу, щоб у звітах завжди було написано свідчення на початок і на кінець періоду. Людям, найнятим на обслуговування, не подобалася одна колонка «Потребно». Довелося додавати зчитування на початок місяця та доби.
Вийшла трохи милиця, але все ж таки робоча програма обліку електроенергії. Зараз програма опитує близько 70 лічильників. Консольна програма крутиться на сервері, а клієнтська частина працює на АРМі користувача.
Вихідник опитувальника викладаю на GitHub. Посилання на клієнтську частину постараюся викласти згодом.