Для начала проведем небольшой анализ архитектурных подходов в системах АСУТП: от проприетарных SCADA к унифицированным стандартам OPC UA.

В сфере промышленной автоматизации (АСУТП) традиционный подход к выбору систем верхнего уровня управления, таких как SCADA (Supervisory Control And Data Acquisition), зачастую сводится к выбору решений, предлагаемых производителями аппаратных контроллеров. Типичная практика включает использование следующих проприетарных платформ:

  1. Siemens: SIMATIC WinCC

  2. Wonderware: InTouch

  3. Schneider Electric: EcoStruxure

  4. И другие аналогичные решения включая совсем не дешевые российские разработки.

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

Несмотря на широкое распространение, проприетарные SCADA-системы обладают рядом существенных ограничений, которые снижают их применимость по сравнению с более гибкими решениями, такими как ручное заполнение форм Microsoft Excel (в контексте аналитики и отчетности):

  1. Высокая стоимость лицензирования программного обеспечения.

  2. Значительные затраты и длительные сроки разработки "под ключ", включая конфигурирование, программирование и интеграцию.

  3. Избыточный объем встроенных компонентов и функционала, что приводит к увеличению размера установочных пакетов (например, 10-20 ГБ для решений Siemens), не всегда полностью используемого в конкретных проектах.

  4. Закрытая архитектура, характеризующаяся ограниченной функциональностью и сложной интеграцией со сторонним программным обеспечением.

Стоимость разработки и внедрения таких комплексных SCADA-решений сопоставима с затратами на создание всей системы автоматизации первого уровня (полевого уровня). Это делает их доступными преимущественно для крупных промышленных предприятий с соответствующими бюджетами и ресурсами.

Стандартное описание системы АСУиТП
Стандартное описание системы АСУиТП

Для малых и средних предприятий возникает потребность в более легковесных и экономически эффективных решениях, ориентированных на следующие ключевые задачи:

  1. Удаленный мониторинг производственных процессов.

  2. Сбор, хранение и визуализация данных в виде графиков.

  3. Логирование и учет производственных рецептов.

  4. Автоматизированная загрузка рецептов на оборудование с верификацией данных.

Именно в этом контексте стандарт OPC UA (Unified Architecture) приобретает все большее значение в промышленной автоматизации, предлагая унифицированный и открытый подход к интеграции.

Интеграция решений
Интеграция решений

Система автоматизированного управления технологическими процессами (АСУТП) на основе OPC UA (Open Platform Communications Unified Architecture) представляет собой современное решение, обеспечивающее интеграцию и взаимодействие различных компонентов автоматизации. В данном контексте, SCADA-система получает непосредственный доступ к контроллерам, что значительно упрощает управление и мониторинг процессов.

Основные компоненты разработанной системы АСУТП СКАДА на OPC UA:

  1. Контроллеры, такие как Siemens Simatic S7-1200 и S7-1500, поддерживают OPC UA, что позволяет им напрямую обмениваться данными с SCADA-системой. Это обеспечивает низкую задержку и высокую надежность передачи данных.

  2. OPC UA - Это протокол для обмена данными, который обеспечивает безопасность, оперативность и масштабируемость. Поддерживает разнообразные типы данных и позволяет интегрировать устройства от разных производителей.

  3. СКАДА -система: Программа написанная на Visual С++ по технологии MFC в системах с операционной средой Windows

Немного про забытый стандарт разработки Microsoft Foundation Class (MFC) — это мощная библиотека, разработанная для упрощения создания настольных приложений под операционную систему Windows. Она предоставляет объектно-ориентированную обертку над многими API Win32, Win64 и COM, что значительно облегчает разработку программного обеспечения. Давайте подробнее рассмотрим ключевые аспекты MFC:

  1. Объектно-ориентированная библиотека: MFC использует принципы объектно-ориентированного программирования, что позволяет разработчикам создавать более структурированные и поддерживаемые приложения.

  2. Упрощение разработки: MFC сокращает время разработки, предоставляя готовые классы и функции для выполнения распространенных задач, таких как обработка окон, управление событиями и работа с графикой.

  3. Поддержка Windows API: Библиотека оборачивает Win32 API в удобные для использования C++ классы, что позволяет разработчикам сосредоточиться на логике приложения, а не на низкоуровневых деталях.

  4. Интеграция с Visual Studio: MFC полностью интегрирована с Microsoft Visual Studio, что обеспечивает удобные инструменты для разработки, отладки и тестирования приложений.

  5. Гибкость и расширяемость: MFC позволяет разработчикам создавать как простые, так и сложные приложения, включая поддержку различных интерфейсов, таких как диалоговые окна, меню и панели инструментов.

Для обеспечения полноценного функционирования SCADA-системы (Supervisory Control And Data Acquisition) требуется комплексное решение, включающее интеграцию с реляционной базой данных SQL Server и использование современного протокола связи OPC UA.

1. Интеграция с Базой Данных SQL Server:

SCADA-система должна осуществлять взаимодействие с SQL Server для извлечения и хранения критически важных конфигурационных и операционных данных. Ключевые наборы данных, получаемые из базы, включают:

  • I. Список контроллеров для связи и параметры их подключений: Эта информация управляется структурой StrDBCP, которая содержит:

    • iNom: Уникальный идентификатор записи.

    • iNOMEQ: Ссылка на соответствующую запись в базе данных оборудования.

    • strADRESS: Сетевой адрес контроллера (IP-адрес или hostname).

    • iType: Тип подключаемого оборудования.

    • bStartOnLine: Флаг автоматического запуска подключения при старте системы.

    • bOnLine: Текущий статус подключения (онлайн/офлайн).

    • UA_Client* g_clientOnline: Указатель на объект клиента OPC UA, используемый для установления соединения.

    • UA_UInt32 g_subscriptionId: Идентификатор активной подписки на данные OPC UA.

    • UA_StatusCode uStatus: Код статуса последней операции с подпиской.

    • DWORDLONG* arrayValue: Указатель на массив для хранения получаемых данных.

    • UINT sizearray: Размер массива для хранения данных.

  • II. Список данных для чтения из контроллера: Структура StrDBINI определяет параметры для чтения данных с контроллеров:

    • iNom: Уникальный идентификатор записи.

    • iTYPECPU: Идентификатор контроллера, к которому относится данная запись.

    • iID: Идентификатор тега или переменной в пакете данных контроллера.

    • iIDUA: Идентификатор узла (NodeId) в адресном пространстве OPC UA.

    • iTYPEID: Тип данных переменной (например, целочисленный, вещественный, булев).

    • bSaveDb: Флаг, указывающий, следует ли логировать данное значение в базу данных.

    • iEQ: Идентификатор оборудования, к которому относится данный параметр.

    • iLine: Столбец в интерфейсе SCADA для отображения данного параметра.

  • III. Список сохраненных данных: Структура StrDBVAL используется для хранения исторических значений переменных:

    • iNom: Уникальный идентификатор записи.

    • CTime timeVal: Временная метка записи.

    • iNOMEQ: Идентификатор оборудования, к которому относится значение.

    • iItem: Идентификатор переменной (тега).

    • iVal: Значение переменной.

  • IV. Подключение к данным верхней MES-системы: Для обеспечения комплексного управления и мониторинга, SCADA-система должна интегрироваться с MES (Manufacturing Execution System). Полной структуры MES мы приводить не будем (большой объем), ключевые сущности, с которыми осуществляется взаимодействие, включают:

    • StrDBEQ: Список оборудования.

    • StrDBCFG: Конфигурация рецептов.

    • StrDBSTATUS: Статусы оборудования.

    • StrDBPRODUCT: Список производимых продуктов.

    • StrDBPART: Список партий продукции.

    • StrDBUser: Список пользователей с правами доступа.

    • StrDBMAT: Список материалов, используемых в рецептах.

    • StrDBREC: Список рецептов, связанных с продуктами.

2. Механизм подключения к контроллерам по протоколу OPC UA:

Подключение к контроллерам реализуется с использованием библиотеки open62541 (https://github.com/open62541/open62541), высокоуровневого клиента OPC UA.

  • Интеграция библиотеки: Для использования функционала OPC UA, в проект необходимо включить соответствующие заголовочные файлы:

    Код С++
    Код С++
  • Конфигурация безопасности: Поддерживаются различные политики безопасности для установления защищенных соединений:

Код С++
Код С++
  • Функция подключения CMainFrame::ConnectCPUOnline: Эта функция инициализирует клиент OPC UA, настраивает параметры соединения (включая URL конечной точки сервера, URI приложения и политику безопасности) и устанавливает соединение с контроллером. В приведенном примере кода используется политика SECURITYPOLICY_NONE для установления соединения.

bool CMainFrame::ConnectCPUOnline(UINT iAdr)
{
	UA_StatusCode       uStatus = UA_STATUSCODE_GOOD;
	UA_ClientConfig*	cc;
	UA_Int32            command;
	UA_Boolean          issecure;

	CT2A ascii(StrCPUADR[iAdr].strADRESS);

	//Initialize Client and Configuration
	StrCPUADR[iAdr].g_clientOnline = UA_Client_new();
	cc = UA_Client_getConfig(StrCPUADR[iAdr].g_clientOnline);

	/* set logging level (the demo logger interprets the context pointer as min. level) */
	/* cc->logger.context = (void*)UA_LOGLEVEL_TRACE; */
	cc->logger.context = (void*)UA_LOGLEVEL_ERROR;

	UA_ClientConfig_setDefault(cc);
	cc->securityMode = UA_MESSAGESECURITYMODE_NONE;
	cc->endpoint.endpointUrl = UA_String_fromChars(ascii.m_psz);
	cc->clientDescription.applicationUri = UA_String_fromChars(APPLICATIONURI);
	cc->securityPolicyUri = g_psChosenSecurityProfileUri;

	/********************************************************************
	 Establish the connection to the server
	********************************************************************/
	uStatus = UA_Client_connect(StrCPUADR[iAdr].g_clientOnline, ascii.m_psz);
	if (uStatus != UA_STATUSCODE_GOOD) {
		return false;
	}
	else
	{
		return true;
	}
}
  • Создание подписки и мониторинг данных: После успешного подключения, создается подписка на данные, и затем настраивается мониторинг для каждого требуемого тега.

// Создание подписки
UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();

/*	Create Subscription	***/
UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(StrCPUADR[iAdr].g_clientOnline, request, NULL, NULL, NULL);

if (response.responseHeader.serviceResult == UA_STATUSCODE_GOOD)
  StrCPUADR[iAdr].g_subscriptionId = response.subscriptionId;
else
  return false;

int iCount = 0;

UA_MonitoredItemCreateRequest monRequest = UA_MonitoredItemCreateRequest_default(g_NodeId_Variable);
UA_MonitoredItemCreateRequest dataItem;
UA_MonitoredItemCreateRequest_init(&dataItem);
dataItem.monitoringMode = UA_MONITORINGMODE_REPORTING;
dataItem.itemToMonitor.attributeId = UA_ATTRIBUTEID_VALUE;

UA_MonitoredItemCreateResult  monResponse;
UA_MonitoredItemCreateResult_init(&monResponse);

			for (UINT ini = 0; ini < m_iLoadDataIni; ini++)
			{
				if (StrCPUADR[iAdr].iNOMEQ == StrCPUINI[ini].iTYPECPU)
				{
					g_NodeId_Variable = UA_NODEID_NUMERIC(NAMESPACEINDEX_S7, StrCPUINI[ini].iIDUA);
					dataItem.itemToMonitor.nodeId = g_NodeId_Variable;
					monResponse = UA_Client_MonitoredItems_createDataChange(StrCPUADR[iAdr].g_clientOnline, StrCPUADR[iAdr].g_subscriptionId, UA_TIMESTAMPSTORETURN_BOTH, dataItem, NULL, UaServer_DataChangedCallback, NULL);
					if (monResponse.statusCode != UA_STATUSCODE_GOOD)
					{
						break;
					}
					iCount++;
				}
			}
  • Цикл обработки данных в отдельных потоках: Для обеспечения непрерывного опроса контроллеров и обработки поступающих данных, используется отдельный поток выполнения. Пример такого потока представлен ниже.

UINT OnLoadTreadOnline(LPVOID pParam)
{
	CMainFrame* pFrame = (CMainFrame*)pParam;

	while (pFrame->m_bOnline)
	{
		for (UINT all = 0; all < pFrame->m_iLoadDataAdr; all++)
		{
			if (pFrame->StrCPUADR[all].bOnLine)
				pFrame->StrCPUADR[all].uStatus = UA_Client_run_iterate(pFrame->StrCPUADR[all].g_clientOnline, 500);
		}
		Sleep(500);
	}

	return 0;
}

Этот поток периодически (с интервалом 500 мс) вызывает UA_Client_run_iterate для каждого активного клиента OPC UA, что обеспечивает получение обновленных данных от контроллеров.

Реализация функционала управления рецептурами и их версионирования на контроллерах

Для обеспечения гибкости производственных процессов и возможности воспроизводимости, SCADA-система включает функционал управления рецептурами, включая их загрузку на контроллеры и детальное логирование каждой операции загрузки.

Загрузка рецептуры на контроллер включает следующие этапы:

  • Извлечение данных рецептуры: SCADA-система запрашивает данные рецептуры из SQL Server, используя структуры StrDBREC и StrDBCFG.

  • Формирование набора данных для загрузки: На основе извлеченных данных, SCADA-система формирует пакет значений, соответствующих параметрам рецептуры, которые необходимо записать в контроллер.

  • Установление соединения с контроллером: Используется ранее описанный механизм подключения через OPC UA клиент (UA_Client* g_clientOnline) с применением соответствующей политики безопасности.

  • Запись данных в контроллер: Для каждого параметра рецептуры, SCADA-система выполняет операцию записи (write) в соответствующий тег (NodeId) контроллера, используя OPC UA. Это реализовано путем вызова функций типа UA_Client_write.

  • Верификация загруженных данных: После выполнения операции записи обязательно проводится верификация. Чтение записанных значений обратно из контроллера и сравнение их с исходными значениями рецептуры.

  • Логирование операции загрузки: Это критически важный этап, обеспечивающий прослеживаемость и аудит. Каждая успешная (или неуспешная) операция загрузки рецептуры фиксируется.

    Номер артикула, номер партии, даты загрузок. Проверенные данные отмечены синей галочкой.
    Номер артикула, номер партии, даты загрузок. Проверенные данные отмечены синей галочкой.

Итоговое резюме:

  1. Программное решение было разработано с применением эффективных методологий управления проектами, что позволило достичь исключительно короткого цикла разработки. В частности, полная реализация всего функционала заняла всего 3 месяца. Этот результат был достигнут благодаря высокой квалификации и продуктивности единственного разработчика, который продемонстрировал глубокое понимание предметной области и техническое мастерство.

  2. Программное решение демонстрирует исключительную гибкость в плане развертывания, будучи разработанным как нативное приложение для операционной системы Windows. Его исполняемый образ имеет минимальный размер — всего 6 Мб. Это достигается за счет отсутствия зависимостей от высокоуровневых фреймворков, таких как .NET. Таким образом, программа функционирует непосредственно на уровне операционной системы, начиная с Windows XP 64-bit и вплоть до современных версий, включая Windows 11. Такая архитектура обеспечивает высокую производительность, низкое потребление системных ресурсов и предсказуемое поведение в различных средах эксплуатации, минимизируя риски, связанные с версионными несовместимостями фреймворков.

  3. Механизм установления связи с целевыми контроллерами реализован с использованием параллельной обработки данных. Применение многопоточной архитектуры для инициализации каждого соединения позволяет достичь сверхбыстрого времени подключения — порядка 3 секунд для подключения всех контроллеров. Такой подход обеспечивает эффективное использование вычислительных ресурсов и значительно сокращает начальные задержки при запуске системы или при восстановлении связи после сбоев. Каждый поток управляет жизненным циклом одного соединения, что гарантирует изоляцию процессов и предотвращает взаимное влияние при возникновении ошибок на уровне отдельных подключений.

  4. Эффективное управление памятью и интеграция с СУБД: Несмотря на скромный объем оперативной памяти, занимаемый самим исполняемым кодом и данными (20 Мб), программа активно взаимодействует с SQL Server. Такая конфигурация достигается за счет стратегического кэширования части данных непосредственно в оперативной памяти приложения, в виде блоков данных. Это позволяет минимизировать количество обращений к дисковой подсистеме СУБД, ускоряя доступ к часто используемой информации и снижая нагрузку на сервер базы данных. Такой подход обеспечивает оптимальный баланс между скоростью доступа к данным и потреблением оперативной памяти, делая решение эффективным даже в условиях ограниченных ресурсов.

  5. Пропускная способность канала связи и масштабируемость: Программа демонстрирует высокую эффективность использования пропускной способности сетевого канала при работе с промышленными контроллерами. При одновременном чтении 30 параметров с 5 контроллеров (150 параметров), общий объем трафика составляет всего 16 Кбайт. Масштабируемость решения подтверждается линейным увеличением потребления трафика: при работе с 50 контроллерами (1500 параметров) трафик возрастает до 160 Кбайт. Это свидетельствует о высокой степени оптимизации протокола передачи данных и позволяет успешно применять решение в системах с большим количеством подключаемых устройств без существенного увеличения нагрузки на сетевую инфраструктуру.

    Обмен с контроллерами
    Обмен с контроллерами
  6. Программное решение предоставляет единую, высокоинформативную панель управления (dashboard), предназначенную для динамической визуализации операционного статуса всего парка промышленного оборудования.

  7. Продвинутый механизм архивирования, парсинга и экспорта исторических данных для аналитики: Система располагает сложным модулем для сбора, обработки и анализа исторических данных, который обеспечивает глубокую детализацию информации о работе оборудования. Этот модуль выполняет комплексный парсинг сохраненных потоков данных, фиксируя каждое событие и изменение состояния с высокой временной точностью. Данные сохраняются в виде структурированных временных рядов, что позволяет проводить всесторонний анализ производительности, выявлять закономерности и аномалии.

    Основной отчет о работе оборудования
    Основной отчет о работе оборудования
  8. Формирования регламентированной отчетности. Интеграция с Microsoft Excel посредством прямого экспорта данных предоставляет пользователям максимальную гибкость в дальнейшем исследовании информации, позволяя применять любые инструменты анализа, доступные в офисных приложениях, и создавать кастомизированные отчеты для руководства и технических специалистов.

    Он же выгруженный в Excel
    Он же выгруженный в Excel
  9. Отображать на графике данные по нескольким параметрам одновременно, обеспечивая корреляционный анализ и выявление взаимосвязей между различными показателями. Эта функция является неоценимым активом для инженеров по эксплуатации и технологов, предоставляя им возможность детально изучать историю работы оборудования, выявлять причины проблем и оптимизировать производственные циклы на основе объективных данных.

    График работы оборудования
    График работы оборудования
  10. Реализация рецептур с хранением каждой загрузки на контроллер потребовало комплексного подхода, включающего работу с базами данных, протоколом OPC UA, а также разработку механизмов логирования и верификации для обеспечения надежности и прослеживаемости производственных процессов.

    Рецепт включает в себя более 50 параметров
    Рецепт включает в себя более 50 параметров

Итог. Система АСУТП на базе OPC UA с непосредственным доступом SCADA к контроллерам Siemens представляет собой мощное решение для автоматизации процессов, обеспечивая высокую эффективность, безопасность и гибкость при минимальной стоимости разработки.