变量说明

变量是一个非数字符号,代表某个数据。它提供了数据定义、运算、传递功能,支持用于下发数据、数据源等配置中。

1. 创建变量

步骤一:在编辑器的资源管理中心,选择某个文件夹 ,点击“创建变量”按钮。

image

步骤二:配置

按照规则填入配置变量的名称、描述,引用方式(静态、动态)。

image

2. 编辑变量

在变量卡片中双击,弹出变量编辑框。在弹窗中可以修改变量的名称、描述、值等配置,也可查看变量code等信息。

截屏2023-01-16 下午5

可通过点击变量卡片下部的编辑按钮,编辑变量名称后按“Enter”键或者点击别处,修改变量名称。

截屏2023-01-16 下午5

3. 删除变量

  1. 可以选中某个变量后,点击“删除”选项。

截屏2023-01-17 上午10
  1. 也可以通过选中某个变量,点击右下角的删除按钮,来删除某个变量。

  2. 若要批量删除变量,可选中多个变量后,点击“删除选中”按钮。

截屏2023-01-17 上午10

4. 变量引用方式

4.1. 引用方式1——静态变量

静态变量数据来源是固定的不变的。

配置静态变量数据源类型:

  1. HTTP接口:数据源从HTTP接口中获取;

  2. 设备数据点:从设备点位中获取数据源;

  3. 固定值:手动输入一些静态的数据;

  4. 数据库:从数据库中获取变量类型;

  5. MQTT:通过网络连接发送的信息数据包;

  6. 告警变量:设备告警类数据;

  7. 文件:.csv / .json / .xlsx后缀的文件内容作为变量

  8. 虚拟变量:几个变量通过过滤器进行加减乘除等操作后返回得到一个虚拟变量。

1)设备属性点示例

配合数采一体机使用时,组态系统默认集成了设备属性列表,在变量类型中选择设备属性点,在选择属性栏可以根据设备模板选择具体的设备实例,再选择设备属性,即可将设备属性值匹配到变量上。

imageimage

选择设备属性后,可以继续填写数据过滤脚本,对已获取到的设备属性值进行二次加工。

2)数据库示例

1.配置变量为静态引用方式下的数据库类型,其中数据库类型分为PgSQL(功能强大的开源对象系统管理系统)、MySQL(关系类型数据库管理系统)、SqlServer(微软推出的关系数据库管理系统)

2.配置数据库类型以及数据库的地址、端口数据库名称用户名和地址,点击配置栏右上方按钮可以检查连接配置是否有效。

配置数据库

3.设置数据源默认值:勾选设置数据源默认值,未接收到有效数据返回时预置的默认值,用于保证初始显示效果。收到首次返回即失效。

默认值

4.配置完成点击确定,即创建了一个数据库类型的变量

注:版本限制

MySQL 5.6及以上

PostgreSQL 11 及以上

SQL Server 2005 及以上

3)MQTT变量示例

1.配置引用变量

数据来源选择MQTT变量,配置MQTT协议的host(接入地址)、port(端口)、topic(主题)、用户名及密码。

mqtt

4)告警变量示例

告警变量需选择监听告警的设备模板、设备、告警级别、告警类型。常用于告警类组件。

截屏2022-08-30 下午3

5)文件变量示例

  1. 在资源管理中,选中某个文件夹,点击“创建变量”按钮

截屏2022-12-19 上午11

2.点击创建变量后,出现创建变量弹窗, 在变量类型下拉框中选择文件, 选择文件后会展示文件变量的面板

image

3.点击上传文件按钮, 文件类型支持 csv / json / xlsx 格式, 上传之后会展示文件解析结果

image

image

4.确认解析内容无误之后,点击确认按钮创建变量, 显示创建变量成功的提示则表示创建成功。

文件类变量可以用在柱状图等图表组件的数据源中。

6)虚拟变量示例

1.配置引用变量

数据来源选择虚拟变量,选择需要的引用变量(不能少于一个),默认为两个,可添加或删除引用变量,点击刷新按钮返回结果为由几个引用变量组合成的虚拟变量。

变量345

2.配置数据过滤脚本

勾选数据过滤脚本,在编码框过滤函数中对引用变量操作,如下:

勾选过滤器

3.刷新返回结果

点击刷新按钮,最终返回结果即为创建的虚拟变量。

返回结果

7)Nats变量

NATS是一个开源的消息传递系统,用于在云中或者在数据中心内部传递数据。

1.点击创建变量后,出现创建变量弹窗, 在变量类型下拉框中选择nats, 选择nats后会展示nats变量的面板。

2.填写nats表单中的必填项,非必填项可不填写。

3.填写完表单数据之后,确认表单中的必填项填写完成,点击确认按钮创建变量, 显示创建变量成功toast则表示创建成功,变量将会展示在footerPanel中。

8)Kafka 变量

Apache Kafka是一种高吞吐量的分布式发布订阅消息系统,用于在云中或者在数据中心内部传递数据

1.点击创建变量后,出现创建变量弹窗, 在变量类型下拉框中选择kafka, 选择nats后会展示kafka变量的面板。

2.填写kafka表单中的必填项,非必填项可不填写。

3.填写完表单数据之后,确认表单中的必填项填写完成,点击确认按钮创建变量, 显示创建变量成功toast则表示创建成功,变量将会展示在footerPanel中。

4.2 引用方式2——动态变量

动态变量数据来源是可变的,通过通配符可实现来源路径的变化。

配置动态变量数据源类型:

设备数据点:从设备点位中获取数据源。

实例:

image

步骤一:变量类型选择设备数据点;

步骤二:设置属性点动态路径,使用“{{}}”设置通配符,在数据源引用本变量时,可动态指定通配符,从而实现动态路径引用,对设备属性点,标准引用格式是“{{AssetCode}}/{{AttributeCode}}”可类似“Device_{{Num}}/Temperature”方式实现部分动态路径。

image

配置动态路径参数:

动态1--4

点击刷新按钮获取返回结果。

5. 使用变量

  1. 可在数据配置中做为数据源使用,详见配置数据源变量部分:

截屏2023-01-17 上午10

  1. 按钮类组件“下发变量通道”。在按钮类组件的“通道”中选择变量,即可将按钮数据下发到变量对应的数据点位:

按钮变量

6. 变量数据主动投递

在很多工业应用场景中都需要实时显示设备的监测数据,工业组态提供了实时数据投递能力,允许用户提前进行数据点配置,通过数据主动投递方式,将实时数据同步至组态变量中,以便于在可视化界面中展示设备实时数据。

6.1 创建变量

您可以将数据投递至除虚拟变量外的任何变量上。

在指定的资源文件夹下,点击创建变量按钮。

示例中创建固定值变量用于演示,首先定义变量名,每个变量名都不允许重复,建议用户用英文+数字来表示,如果需要分段,可以用”下划线(_)“来拼接,如 ”device_01_status“,变量描述可以是中文,主要是便于区分和管理。

选择变量类型可以选择 ”固定值“,可以指定该变量的值,如示例中指定该变量值为 ”1“,则该变量在实时数据投递前值都为 ”1“,后续可以同步设备属性值至该变量上。

当然该值可以是任意字符串,比如设备数据,该变量”device_01“ 即为设备消息数据,后续实时数据同步也可以按照设备维度进行数据投递。

变量创建成功后,可在变量详情中查看变量Code,变量Code将作为后续实时数据同步的变量唯一标识。

6.2 实时数据同步

工业组态提供了两种方式完成实时数据投递,

  1. HTTP POST方式,适合数据更新频率较低

  2. Nats 消息推送方式,适合数据更新频率较高

HTTP POST 方式

工业组态提供了Restful API 接口,可用于第三方程序通过API方式向工业组态投递数据,以下使用Postman工具进行测试。

curl --location --request POST 'http://127.0.0.1:7001/open/v1/tag/hub/push' \
--header 'Content-Type: application/json' \
--data-raw '[
 {
 "code": "tag_20n7QQ7CONEcFm2Ishmk",
 "value": {
 "status": 0,
 "temperature": "38摄氏度"
 }
 },
 {
 "code": "tag_20YEVwpwrkmR75V7Wvv6",
 "value": 1
 }
]'

如上图,变量数据可以统一投递至接口 /open/v1/tag/hub/push, 请求参数为变量数据数组,允许一次性投递多个变量数据。但是存在以下限制:

  1. 单次请求至多投递100条数据

  2. 单条投递数据大小需在10KB以下

  3. 每秒最多请求200次

Nats 消息推送方式

针对数据量大,数据更新频率高的应用场景,工业组态还提供了Nats 消息中间件方式进行实时消息同步。

Nats是一个开源的,云原生的消息系统。Apcera,百度,西门子,VMware,HTC和爱立信等公司都有在使用。

核心基于EventMachine开发,原理是基于消息发布订阅机制,每台服务器上的每个模块会根据自己的消息类别向MessageBus发布多个消息主题,而同时也向自己需要交互的模块,按照需要的主题订阅消息。能够达到每秒8-11百万个消息,整个程序很小只有3M Docker image,它不支持持久化消息,如果你离线,你就不能获得消息。使用nats streaming可以做到持久化,缓存等功能。

Nats的核心原则是性能,可伸缩和易用性。由于可伸缩性的复杂性,nats旨在容易使用和实现,且能提供多种质量的服务。一些适用nats的场景有:

  • 高吞吐量的消息分散 —— 少数的生产者需要将数据发送给很多的消费者。

  • 寻址和发现 —— 将数据发送给特定的应用实例,设备或者用户,也可用于发现并连接到基础架构中的实例,设备或用户。

  • 命令和控制(控制面板)—— 向程序或设备发送指令,并从程序/设备中接收状态,如SCADA,卫星遥感,物联网等。

  • 负载均衡 —— 主要应用于程序会生成大量的请求,且可动态伸缩程序实例。

  • N路可扩展性 —— 通信基础架构能够充分利用go的高效并发/调度机制,以增强水平和垂直的扩展性。

  • 位置透明 —— 程序在各个地理位置上分布者大量实例,且你无法了解到程序之间的端点配置详情,及他们所生产或消费的数据。

  • 容错

工业组态作为Nats的消息订阅者,用户的第三方平台只需要向指定的topic队列推送实时数据即可。

Topic有以下两种:通用Topic和变量独立Topic

通用Topic

tag/data/push

工业组态支持统一将投递数据推送至通用的Topic中,数据格式同http方式,示例如下

[
 {
   "code": "tag_20n7QQ7CONEcFm2Ishmk",
   "value": {
     "status": 0,
     "temperature": "38摄氏度"
   }
 },
 {
   "code": "tag_20YEVwpwrkmR75V7Wvv6",
   "value": 1
 }
]

所有变量实时数据都会通过这个Topic进行推送和接收。

变量独立Topic

tag/data/push/${tagCode}

对于单个变量数据更新频率非常大的应用场景,工业组态也提供了变量维度的Topic队列来推送数据至指定变量上。该模式下投递的数据必须为字符串,无需进行额外数据格式包装。

"1"

比如需要投递数据至变量 ”device_01_status“,其变量Code为 ”tag_20YEVwpwrkmR75V7Wvv6“, 则投递Topic地址则为 tag/data/push/tag_20YEVwpwrkmR75V7Wvv6

代码示例

Golang 示例如下

package main

import (
    "encoding/json"
    "time"

    nats "github.com/nats-io/nats.go"
)

type TagPushData struct {
    Code string `json:"code"`
    Value interface{} `json:"value"`
    Timestamp int64 `json:"timestamp"`
}

type NatsDriver struct {
    conn *nats.Conn
    subMap map[string]*nats.Subscription
}

func (n *NatsDriver) NewClient(host string, option ...nats.Option) (nc *nats.Conn, err error) {
    nc, err = nats.Connect(host, option...)
    n.conn = nc
    return
}

func (n *NatsDriver) Subscribe(topic string, cb func(m *nats.Msg)) (err error) {
    sub, err := n.conn.Subscribe(topic, cb)
    n.subMap[topic] = sub
    return
}

func (n *NatsDriver) Unsubscribe(topic string) (err error) {
    if n.subMap[topic] != nil {
    err = n.subMap[topic].Unsubscribe()
    }
    return
}

func (n *NatsDriver) Publish(topic string, data []byte) (err error) {
    err = n.conn.Publish(topic, data)
    return
}

func main() {
    n := &NatsDriver{}

    // 创建nats连接,提供用户名密码进行鉴权
    n.NewClient("nats://127.0.0.1:4222", nats.UserInfo("iadc", "iadc@nats"))

    // 方案一: 投递到通用Topic
    // 按要求构建投递数据
    datas := []TagPushData{
      {
        Code: "tag_20n7QQ7CONEcFm2Ishmk",
        Value: map[string]interface{}{
          "status": 1,
          "temperature": "40摄氏度",
        },
      },
      {
        Code: "tag_20YEVwpwrkmR75V7Wvv6",
        Value: 0,
      },
    }

    strDatas, _ := json.Marshal(datas)

    n.Publish("tag/data/push", strDatas)

    time.Sleep(3 * time.Second)

    // 方案二: 投递到变量指定Topic
    // 原始数据即为投递数据,投递值为字符串
    val := "11"
    n.Publish("tag/data/push/tag_20YEVwpwrkmR75V7Wvv6", []byte(val))

    time.Sleep(3 * time.Second)

}

Java代码示例

<dependencies>
  <dependency>
    <groupId>io.nats</groupId>
    <artifactId>jnats</artifactId>
    <version>1.0</version>
  </dependency>
  <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.14.1</version>
  </dependency>
  <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.14.1</version>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.5</version>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.6.4</version>
  </dependency>
</dependencies>
import com.fasterxml.jackson.databind.ObjectMapper;
import io.nats.client.Connection;
import io.nats.client.Nats;
import io.nats.client.Options;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;


public class NatsDemo {

    private Connection conn;

    public void newClient() throws IOException {

        // 建联,使用默认用户名密码
        Options o = new Options.Builder().userInfo("iadc", "iadc@nats").build();

        // 连接地址从组态变量控制台中获取
        Connection nc = Nats.connect("nats://11.238.108.198:4222", o);

        conn = nc;
    }

    public void publish() throws IOException, InterruptedException {

        // 方案一: 投递到通用Topic
        // 按要求构建投递数据
        List<LinkedHashMap<String, Object>> list = new ArrayList<>();

        LinkedHashMap<String, Object> map1 = new LinkedHashMap<>();
        map1.put("code", "tag_20GHAEW9KGgRpS2iVkqK");

        Map value = new HashMap();
        value.put("status", 4);
        value.put("temperature", "41摄氏度");
        map1.put("value", value);

        list.add(map1);

        LinkedHashMap<String, Object> map2 = new LinkedHashMap<>();
        map2.put("code", "tag_20nhGvqeRLv3ykoCNPph");
        map2.put("value", 0);

        list.add(map2);


        ObjectMapper objectMapper = new ObjectMapper();

        String json = objectMapper.writeValueAsString(list);

        System.out.println(json);

        conn.publish("tag/data/push", json.getBytes(StandardCharsets.UTF_8));

        Thread.sleep(3000);    //延时3秒

        // 方案二: 投递到变量指定Topic
        // 原始数据即为投递数据,投递值为字符串
        String value2 = "14";
        conn.publish("tag/data/push/tag_20nhGvqeRLv3ykoCNPph", value2.getBytes(StandardCharsets.UTF_8));

        Thread.sleep(3000);    //延时3秒
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        NatsDemo natsDemo = new NatsDemo();
        natsDemo.newClient();
        natsDemo.publish();
        System.exit(0);
    }
}

投递地址查看

在变量详情中,可查看数据主动投递的投递地址

image

6.3 组态画面预览查看投递数据

将变量绑定至文本组件,打开 ”页面预览“ 即可查看到实时推送过来的设备数据

阿里云首页 工业互联网平台 相关技术圈