Aproveitando OPC UA para Desenvolvimento Robusto de IIoT na Edge
Adaptado de Industrial Internet Application Development, por Alena Traukina, Jayant Thomas, Prashant Tyagi, Kishore Reddipalli.
Capítulo 3. Desenvolvimento IIoT na Edge (Continuação)
Por Alena Traukina, Jayant Thomas, Prashant Tyagi, Kishore Reddipalli
Protocolos M2M Industriais – OPC UA
Nesta seção, tentaremos construir um app IoT simples para enviar dados de um módulo simulador de sensor a um dispositivo receptor (PC ou nuvem), usando um hub Raspberry Pi e o protocolo OPC UA:
O protocolo OPC UA é similar ao Modbus, mas trabalha com mais tipos de dados, não tem limitações sérias, enquanto provê segurança, compressão e baixa latência.
O protocolo foi desenvolvido pela OPC Foundation como protocolo de comunicação máquina-a-máquina industrial. OPC UA (Unified Architecture) é uma versão aprimorada do protocolo Open Platform Communications (OPC), com uma das maiores mudanças sendo que o novo protocolo está disponível gratuitamente sem restrições.
Na tabela a seguir, você encontra uma descrição mais detalhada do protocolo para entender se é adequado às suas necessidades:
| Chave | Valor |
|---|---|
| Open source | Sim |
| Camada OSI | Transporte ou Aplicação |
| Tipos de dados | Inteiro, float, string, Booleano, data, hora, e mais |
| Limitações | Não adequado para arquitetura complexa |
| Operações possíveis | Leitura/escrita/monitoramento/consulta de variáveis |
| Latência | Baixa |
| Uso | IIoT |
| Segurança | Sim |
| Compressão | Sim |
Tabela 5: Especificações do protocolo OPC UA
Requisitos para Construção da Aplicação
- Software necessário:
- Node.js 6+ (download)
- PostgreSQL (download)
- Cloud Foundry CLI (download)
- Request (página npm)
- NodeOPCUA (página npm)
- Async (página npm)
- Docker (guia de instalação)
- Hardware necessário:
- Raspberry Pi 3 (modelo B)
- Adaptador de energia (2A/5V)
- Cartão microSD (8 GB+) e adaptador SD
- Cabo Ethernet para conexão de rede com fio
Preparando o Cartão SD
Para preparar um cartão SD, siga a sequência de ações descrita:
- Baixe a imagem mais recente do Raspbian LITE (disponível em Raspberry Pi Downloads).
- Conecte seu cartão SD a um computador e use o Etcher (balena.io/etcher) para gravar o arquivo
.imgdo Raspbian no cartão SD. - Habilite SSH:
cd /Volumes/boot
touch ssh
- Para habilitar Wi-Fi, crie
wpa_supplicant.confcom o seguinte conteúdo:
network={
ssid="SEU_SSID"
psk="SUA_SENHA_WIFI"
}
Para criar um arquivo no console Linux, use o editor GNU nano. Ele vem pré-instalado na maioria das distribuições Linux. Execute o comando nano NOME_ARQUIVO e siga as instruções exibidas.
- Crie o diretório
/home/pi/hub - Crie o arquivo
/home/pi/hub/package.jsoncom o seguinte conteúdo:
{
"name": "hub",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"async": "^2.4.0",
"node-opcua": "0.0.64",
"request": "^2.81.0"
}
}
- Crie o arquivo
/home/pi/hub/index.jscom o seguinte conteúdo, substituindoREMOTE-SERVER-ADDRESS.comeREMOTE-SENSOR-ADDRESSpor valores reais:
var opcua = require("node-opcua"); var async = require("async");
var request = require("request");
var session, subscription;
var client = new opcua.OPCUAClient();
var sensor = "opc.tcp://REMOTE-SENSOR-ADDRESS:4334/UA/resourcePath";
var receiver = "https://REMOTE-SERVER-ADDRESS.com:8080";
async.series( [
// estabelecendo conexão
function (cb) {
client.connect(sensor, function (err) {
if (err) {
console.log("Conexão com " + sensor + " falhou");
} else {
console.log("Conexão bem-sucedida");
}
cb(err);
});
},
// iniciar sessão
function (cb) {
client.createSession(function (err, res) {
if (!err) session = res;
cb(err);
});
},
// ler valor
function (cb) {
session.readVariableValue("ns=1;s=Variable1", function (err, dataValue) {
if (!err) console.log("Variable1 = ", dataValue.value.value);
cb(err);
});
},
// escrever valor
function (cb) {
session.writeSingleNode("ns=1;s=Variable1", new opcua.Variant({
dataType: opcua.DataType.Double, value: 100
}), function (err) {
cb(err);
});
},
// assinar mudanças
function (cb) {
subscription = new opcua.ClientSubscription(session, {
maxNotificationsPerPublish: 5,
priority: 5,
publishingEnabled: true,
requestedLifetimeCount: 5,
requestedMaxKeepAliveCount: 3,
requestedPublishingInterval: 500,
});
subscription.on("started", function () {
console.log("subscription id: ", subscription.subscriptionId);
}).on("terminated", function () {
cb();
});
setTimeout(function () {
subscription.terminate();
}, 5000);
// instalar item monitorado
var monitor = subscription.monitor({
attributeId: opcua.AttributeIds.Value,
nodeId: opcua.resolveNodeId("ns=1;s=Variable1"),
},
{
discardOldest: true,
samplingInterval: 50,
queueSize: 5,
},
opcua.read_service.TimestampsToReturn.Both
);
monitor.on("changed", function (dataValue) {
console.log("Variable1 = ", dataValue.value.value);
// enviar para receptor
var data = {
device: "sensor1",
timestamp: Date.now(),
Variable1: dataValue.value.value
};
request.post({url: receiver, form: data}, function (err) {
if (err) console.log("Falha ao enviar " + JSON.stringify(data) + " para " + receiver);
});
});
},
// fechar sessão
function (cb) {
session.close(function (err) {
if (err) console.log("Falha ao fechar sessão"); cb();
});
}
],
function (err) { if (err) {
console.log("Falhou com erro:", err);
} else {
console.log("Concluído com sucesso");
}
client.disconnect(function () {
});
}
);
- Crie o arquivo
/home/pi/hub/Dockerfilecom o seguinte conteúdo:
FROM hypriot/rpi-node:boron-onbuild
- Crie o diretório
/home/pi/sensor - Crie o arquivo
/home/pi/sensor/package.jsoncom o seguinte conteúdo:
{
"name": "sensor",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"node-opcua": "0.0.64"
}
}
- Crie o arquivo
/home/pi/sensor/index.jscom o seguinte conteúdo:
var opcua = require("node-opcua");
var min = 1;
var max = 100;
var host = new opcua.OPCUAServer({
buildInfo: {
buildDate: new Date(2018, 8, 8),
buildNumber: "1234",
productName: "productName",
},
port: 4334,
resourcePath: "UA/resourcePath",
});
host.initialize(function () {
var space = host.engine.addressSpace;
var componentOf = space.addObject({
browseName: "browseName",
organizedBy: space.rootFolder.objects,
});
var variable1 = 0;
// gerar novo valor
setInterval(function () {
variable1 = Math.floor(max - Math.random() * (max - min));
}, 500);
space.addVariable({
browseName: "browseName",
componentOf: componentOf,
dataType: "Double",
nodeId: "ns=1;s=Variable1", // nodeID string
value: {
get: function () {
return new opcua.Variant({dataType: opcua.DataType.Double, value: variable1});
},
set: function (variant) {
variable1 = parseFloat(variant.value);
return opcua.StatusCodes.Good;
}
}
});
host.start(function () {
var endpoint = host.endpoints[0].endpointDescriptions()[0].endpointUrl;
console.log("Endpoint: ", endpoint);
});
});
- Configure os valores min e max no início do arquivo
/home/pi/sensor/index.js.
- Crie o arquivo
/home/pi/sensor/Dockerfilecom o seguinte conteúdo:
FROM hypriot/rpi-node:boron-onbuild
Tecnologia da Internet das Coisas
- Segurança IoT Industrial: Principais Tendências e Melhores Práticas para 2020
- Cisco Revela Arquitetura Abrangente de Segurança IIoT e Edge Intelligence para Visibilidade OT
- Protegendo a Internet Industrial das Coisas: Estratégias, Padrões e Cadeia de Confiança
- ECM3532: Primeira Placa de Sensor IA Integrada Ultra-Baixo Consumo da Eta Compute Acelera Desenvolvimento Edge
- Glassboard: Aproveitando a Impressão 3D para Desenvolvimento Rápido e Confiável de Produtos
- Perspectiva Futura: Avançando Industrial IoT para Excelência em Produção
- Edge Computing: A Chave para o Sucesso da IoT Industrial em Tempo Real
- Alavancando IIoT e IA para Impulsionar Vendas e Produtividade para Fabricantes e Distribuidores
- Containers Capacitam Desenvolvimento Ágil de Apps IoT
- Edge Computing e IIoT: Transformando Estratégia de Dados Industrial