Реализация просмотра SCADA-данных в мобильном IoT-приложении
SCADA-система — Supervisory Control and Data Acquisition — живёт на стационарных рабочих станциях оператора. WinCC, Ignition, InduSoft, Aveva — у каждой свой формат данных, свои API, своя история совместимости. Мобильное приложение для просмотра SCADA-данных — это не замена стационарного клиента, а «вторые глаза» для мастера смены, который ходит по цеху. Задача: актуальные данные тегов, тренды, алерты — без права управления.
OPC UA: универсальный путь к SCADA-данным
Большинство современных SCADA-систем поддерживают OPC UA сервер. Это стандартный путь получить данные без проприетарных API. Мобильное приложение подключается к OPC UA серверу через TCP или WebSocket (OPC UA over WebSocket, UA Binary транспорт).
Библиотека для Android/Kotlin — Eclipse Milo через JVM-слой, или Eclipse4J. Для Flutter — нет официальной OPC UA библиотеки, используем Platform Channels к нативному клиенту или REST-шлюз:
// Android, Eclipse Milo OPC UA Client
val client = OpcUaClient.create(
"opc.tcp://scada-server.factory.local:4840",
endpointFilter = { endpoints ->
endpoints.filter { it.securityMode == MessageSecurityMode.SignAndEncrypt }
.minByOrNull { it.securityPolicyUri }
},
configConsumer = { configBuilder ->
configBuilder.setIdentityProvider(
UsernameProvider("operator", "password")
)
configBuilder.setRequestTimeout(UInteger.valueOf(5000))
}
)
client.connect().get()
// Чтение тегов по NodeId
val nodeId = NodeId(2, "Furnace1.Temperature")
val dataValue = client.readValue(0.0, TimestampsToReturn.Both, nodeId).get()
val temperature = (dataValue.value.value as Float).toDouble()
val serverTimestamp = dataValue.serverTime
Для просмотра нескольких сотен тегов одновременно — подписка через OPC UA Subscription вместо polling:
val subscription = client.subscriptionManager
.createSubscription(1000.0) // publishing interval 1000ms
.get()
val monitoredItems = nodeIds.map { nodeId ->
MonitoredItemCreateRequest(
ReadValueId(nodeId, AttributeId.Value.uid(), null, null),
MonitoringMode.Reporting,
MonitoringParameters(
UInteger.valueOf(clientHandleCounter++),
500.0, // sampling interval
null,
UInteger.valueOf(10), // queue size
true
)
)
}
subscription.createMonitoredItems(
TimestampsToReturn.Both,
monitoredItems,
{ item, value -> handleTagUpdate(item.readValueId.nodeId, value) }
).get()
Ignition SCADA: REST API и WebDev модуль
Ignition (Inductive Automation) популярен на новых производствах. В нём есть WebDev модуль, который позволяет создавать REST endpoints прямо из Ignition Python scripts. Более современный путь — Ignition Perspective с WebSocket API для мобильных клиентов.
Для прямого REST доступа к тегам через Ignition Gateway REST API:
GET https://ignition.factory.com/system/webdev/api/tags?tagPaths=
Furnaces/Furnace1/Temperature,
Furnaces/Furnace1/Pressure
Authorization: Bearer {token}
Ignition отдаёт значения тегов с quality (Good, Bad, Uncertain) и timestamp. Quality — важный параметр: если датчик потерял связь, значение может быть устаревшим с quality = Bad, а UI должен это показать.
WinCC REST API через OpenPCS
WinCC (Siemens) — через REST API OpenPCS или через WinCC OA WebClient. Siemens TIA Portal V18+ поддерживает WinCC Unified, который имеет собственный WebSocket API через nginx-прокси.
Для старых WinCC Classic — только OPC DA (DCOM) или OPC UA с установкой шлюза Matrikon/Kepware на сервере SCADA.
Тренды: запрос исторических данных
SCADA хранит историю тегов во встроенной БД (Ignition — MySQL/MSSQL, WinCC — SIMATIC historian). Запрос через OPC UA Historical Data Access (HDA):
val historyReadRequest = HistoryReadValueId(
nodeId = NodeId(2, "Furnace1.Temperature"),
indexRange = null,
dataEncoding = null
)
val readDetails = ReadRawModifiedDetails(
isReadModified = false,
startTime = startDateTime.toOpcDateTime(),
endTime = endDateTime.toOpcDateTime(),
numValuesPerNode = UInteger.valueOf(500),
isReturnBounds = true
)
val historyData = client.historyRead(
readDetails,
TimestampsToReturn.Source,
false,
listOf(historyReadRequest)
).get()
Для отображения трендов в Flutter — fl_chart с LineChart. При 500+ точках используем showingTooltipIndicators только для выбранного диапазона, иначе chart тормозит при скролле.
Безопасность и доступ
SCADA-данные — чувствительная информация. Несколько обязательных мер:
- Мобильное приложение никогда не должно иметь прямой доступ к OPC UA серверу из интернета. Только через VPN или обратный прокси с mTLS.
- Авторизация через корпоративный IdP (Active Directory / LDAP).
- Только чтение: роль «mobile viewer» без прав на запись тегов.
- Сессионные логи: кто читал какие теги и когда.
Разработка мобильного SCADA-вьювера с OPC UA и историческими трендами: 4-6 недель для одной платформы. Поддержка нескольких SCADA-систем одновременно и сложные дашборды с real-time чартами — 2-3 месяца. Стоимость рассчитывается индивидуально.







