产品定价 立即试用
云平台
欧洲地区
文档 > 集成 > OPC-UA
入门
指南 API 常见问题
目录

OPC-UA集成

文档信息图标
ThingsBoard PE 功能

专业版支持Platform Integrations功能。
请使用ThingsBoard Cloud自行安装平台实例。

OPC UA集成可从OPC UA服务器向ThingsBoard流式传输数据,并将设备负载转换为ThingsBoard格式。

OPC-UA集成教程

本教程将配置ThingsBoard与OPC-UA之间的集成,从OPC UA C++ Demo Server获取空调数据,并允许用户通过集成下行功能开关任一台空调。

前提条件

  • Download and install the OPC UA C++ Demo Server.

    注意:该服务器目前仅支持 Windows。

  • Launch the UA Admin Dialog after installation.
  • Make sure the hostname/IP address and port are configured correctly.
    You'll need these details to set up the OPC-UA integration in ThingsBoard.

image

  • Launch the UaCPPServer.
    A console window will appear displaying the server's endpoint URLs

image

ThingsBoard设置

上行数据转换器

首先,我们需要创建上行数据转换器,用于接收来自OPC UA服务器的消息。转换器应将传入的负载转换为所需的消息格式。 消息必须包含deviceNamedeviceType。这些字段用于将数据提交到正确的设备。如果找不到设备,将自动创建一个新设备。 以下是来自OPC UA集成的负载示例:

负载:

1
2
3
{
    "temperature": "72.15819999999641"
}

元数据:

1
2
3
4
5
6
7
{
    "opcUaNode_namespaceIndex": "3",
    "opcUaNode_name": "AirConditioner_1",
    "integrationName": "OPC-UA Airconditioners",
    "opcUaNode_identifier": "AirConditioner_1",
    "opcUaNode_fqn": "Objects.BuildingAutomation.AirConditioner_1"
}

我们将获取元数据中的opcUaNode_name值,将其映射为deviceName,并将deviceType设置为airconditioner

当然,您可以根据具体的使用场景采用其他映射方式。

此外,我们还将获取temperaturehumiditypowerConsumption字段的值,并将其作为设备遥测数据。

进入“集成中心”部分的数据转换器页面,创建一个新的上行转换器。 要查看事件,请启用调试模式。在函数解码器字段中,指定用于解析和转换数据的脚本。

调试模式

启用调试模式可追踪与integrations执行相关的事件、状态及潜在错误,便于开发和排障。

文档信息图标

注意:调试模式可能迅速增加磁盘占用,因为所有调试事件都会存入数据库。 自ThingsBoard 3.9起,平台仅在integrations创建后的前15分钟内存储完整调试事件,之后仅保留错误事件。

调试模式设置可组合使用或完全关闭。

可使用 TBEL(TBEL)或 JavaScript 开发用户自定义函数。 建议使用 TBEL,其在ThingsBoard 中的执行效率远高于 JS。

使用以下函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var data = decodeToJson(payload);
var deviceName = metadata['opcUaNode_name'];
var namespaceIndex = metadata['opcUaNode_namespaceIndex'];
var deviceType = 'airconditioner';

var result = {
   deviceName: deviceName,
   deviceType: deviceType,
   telemetry: {
   },
   attributes: {
       namespaceIndex: namespaceIndex
   }
};

if (data.temperature != null) {
    result.telemetry.temperature = toFixed(data.temperature, 2);
}

if (data.humidity != null) {
   result.telemetry.humidity = toFixed(data.humidity, 2);
}

if (data.powerConsumption != null) {
   result.telemetry.powerConsumption = toFixed(data.powerConsumption, 2);
}

if (data.state != null) {
   result.attributes.state = data.state == '1' ? true : false;
}

/** Helper functions 'decodeToString' and 'decodeToJson' are already built-in **/

return result;

image

使用以下函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var data = decodeToJson(payload);
var deviceName = metadata['opcUaNode_name'];
var deviceType = 'airconditioner';

var result = {
   deviceName: deviceName,
   deviceType: deviceType,
   telemetry: {
   },
   attributes: {
   }
};

if (data.temperature) {
    result.telemetry.temperature = Number(Number(data.temperature).toFixed(2));
}

if (data.humidity) {
    result.telemetry.humidity = Number(Number(data.humidity).toFixed(2));
}

if (data.powerConsumption) {
    result.telemetry.powerConsumption = Number(Number(data.powerConsumption).toFixed(2));
}

if (data.state !== undefined) {
    result.attributes.state = data.state === '1' ? true : false;
}

function decodeToString(payload) {
   return String.fromCharCode.apply(String, payload);
}

function decodeToJson(payload) {
   var str = decodeToString(payload);
   var data = JSON.parse(str);
   return data;
}

return result;

image

下行数据转换器

要从ThingsBoard向OPC UA节点发送下行消息,我们需要定义一个下行转换器。

通常,下行转换器的输出应具有以下结构:

1
2
3
4
5
[{
    "contentType": "JSON",
    "data": "{\"writeValues\":[],\"callMethods\":[{\"objectId\":\"ns=3;s=AirConditioner_1\",\"methodId\":\"ns=3;s=AirConditioner_1.Stop\",\"args\":[]}]}",
    "metadata": {}
}]
  • contentType - 定义数据的编码方式{TEXT | JSON | BINARY}。对于OPC UA集成,默认使用JSON。
  • data - 将由OPC UA集成处理并发送到目标OPC UA节点的实际数据:
    • writeValues - 写入值方法数组:
      • nodeId - 目标节点,使用OPC UA NodeId格式ns=<namespaceIndex>;<identifiertype>=<identifier>
      • value - 要写入的值
    • callMethods - 调用方法数组:
  • metadata - 在OPC UA集成中不使用,可以为空。


进入集成中心部分 -> 数据转换器页面,创建一个新的下行转换器。

可使用 TBEL(TBEL)或 JavaScript 开发用户自定义函数。 建议使用 TBEL,其在ThingsBoard 中的执行效率远高于 JS。

使用以下函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var data = {
    writeValues: [],
    callMethods: []
};

if (msgType === 'RPC_CALL_FROM_SERVER_TO_DEVICE') {
    if (msg.method === 'setState') {
        var targetMethod = msg.params === 'true' ? 'Start' : 'Stop';
        var writeValue = {
              nodeId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName'],
              value: msg.params
        };
        data.writeValues.push(writeValue);
        var callMethod = {
              objectId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName'],
              methodId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName']+'.'+targetMethod,
              args: []
        };
        data.callMethods.push(callMethod);
    }
}

var result = {
    contentType: "JSON",
    data: JSON.stringify(data),
    metadata: {}
};

return result;

image

使用以下函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var data = {
    writeValues: [],
    callMethods: []
};

if (msgType === 'RPC_CALL_FROM_SERVER_TO_DEVICE') {
    if (msg.method === 'setState') {
        var targetMethod = msg.params === 'true' ? 'Start' : 'Stop';
        var writeValue = {
              nodeId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName'],
              value: msg.params
        };
        data.writeValues.push(writeValue);
        var callMethod = {
              objectId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName'],
              methodId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName']+'.'+targetMethod,
              args: []
        };
        data.callMethods.push(callMethod);
    }
}

var result = {
    contentType: "JSON",
    data: JSON.stringify(data),
    metadata: {}
};

return result;

image

该转换器将使用setState方法处理发送到设备的RPC命令,并通过布尔类型的params值来调用空调的”Start”或”Stop”方法。

目标节点通过传入消息元数据中的deviceName字段来确定。

OPC-UA集成

  • 打开“集成中心”部分 -> “集成”页面,点击+图标创建新的集成。
  • 从可用类型列表中,选择“OPC-UA”作为集成类型。

image

  • 下一步是添加最近创建的上行和下行转换器。

image

image

  • 指定主机:hostname/IP(参见前提条件);
  • 指定端口:port(参见前提条件);
  • 安全策略:None(可选Basic128Rsa15 / Basic256 / Basic256Sha256 / None);
  • 身份认证:Anonymous(可选Anonymous / Username)。

image

  • 映射配置:
    • 映射类型:Fully Qualified Name(可选Fully Qualified Name / ID);
    • 指定设备节点模式:Objects.BuildingAutomation.AirConditioner_\d+$

    (用于将扫描到的OPC UA节点FQN/ID匹配到设备名称的正则表达式。 在本示例中,OPC UA Explorer上的路径为Objects\.BuildingAutomation\.AirConditioner_X,其中X是从1到N的数字。 因此我们使用Objects\.BuildingAutomation\.AirConditioner_\d+$作为正则表达式,因为\d+表示从1到N的任意数字,$表示字符串的结尾);

    • 订阅标签(要订阅的节点标签(Path)列表,以及映射到输出消息中使用的键(Key)):
      • state - State;
      • temperature - Temperature;
      • humidity - Humidity;
      • powerConsumption - PowerConsumption。
  • 点击“添加”

image

OPC-UA集成已添加完成。

OPC-UA服务器会模拟从设备向ThingsBoard发送遥测数据。如果您的操作全部正确,集成完成后“设备”页面上应出现10个新设备。请确认这一点。

image

打开任意一台空调的详情页面,导航到“最新遥测”选项卡。 您将看到遥测值在频繁更新。

image

空调规则链

为了演示OPC-UA集成和规则引擎的功能,我们将创建一个单独的规则链来处理与OPC-UA集成相关的上行和下行消息。

让我们创建Airconditioners规则链。

  • 下载airconditioners.json文件;
  • 进入“规则链”页面。要导入此JSON文件,请点击屏幕右上角的+图标,然后选择“导入规则链”
  • 将下载的JSON文件拖放到导入规则链窗口中。点击“导入”
  • “Airconditioners”规则链将会打开。双击“integration downlink”节点,在集成字段中指定OPC-UA Integration
  • 应用所有更改。
  • 打开并编辑Root Rule Chain
  • 找到rule chain节点,将其拖放到规则链中。将其命名为Airconditioners,指定Airconditioners规则链,然后点击“添加”
  • 点击“message type switch”节点右侧的灰色圆圈,将其拖动到“rule chain”节点的左侧。在此选择“Attributes Updated”“Post telemetry”“RPC Request to Device”
  • 点击“添加”并保存规则链。

空调仪表板

为了可视化空调数据并测试RPC命令,我们将创建Airconditioners仪表板。

  • 下载airconditioners_dashboard.json文件;
  • 进入“仪表板”页面;
  • 要导入此JSON文件,请点击屏幕右上角的+图标,然后选择“导入仪表板”
  • 将下载的JSON文件拖放到导入仪表板窗口中。点击“导入”

image

  • 打开Airconditioners仪表板;
  • 您将看到所有10台空调最近一分钟内的遥测数据;
  • 点击实体部件中的详情按钮,打开任意一台空调的详情页面;

image

  • 您会看到空调状态指示灯为绿色。尝试点击On/Off Round switch来关闭空调;

image

  • 空调状态指示灯将变为灰色,温度将开始上升,湿度将开始增加,功耗将停止。

image

视频教程

请观看以下视频教程,了解如何逐步设置OPC-UA集成。



另请参阅

下一步