From 651118cba3409a33be660fb800c4fb4b7f8e0d61 Mon Sep 17 00:00:00 2001 From: Leto_b Date: Wed, 10 Dec 2025 15:21:15 +0800 Subject: [PATCH] update opc ua --- src/.vuepress/public/img/opc-ua-new-1-en.png | Bin 0 -> 53126 bytes src/.vuepress/public/img/opc-ua-new-1.png | Bin 0 -> 56142 bytes .../Tree/API/Programming-OPC-UA_timecho.md | 99 ++++++------- .../V1.3.x/API/Programming-OPC-UA_timecho.md | 95 +++++-------- .../dev-1.3/API/Programming-OPC-UA_timecho.md | 95 +++++-------- .../latest/API/Programming-OPC-UA_timecho.md | 99 ++++++------- .../Tree/API/Programming-OPC-UA_timecho.md | 130 +++++++----------- .../V1.3.x/API/Programming-OPC-UA_timecho.md | 89 +++++------- .../dev-1.3/API/Programming-OPC-UA_timecho.md | 89 +++++------- .../latest/API/Programming-OPC-UA_timecho.md | 130 +++++++----------- 10 files changed, 332 insertions(+), 494 deletions(-) create mode 100644 src/.vuepress/public/img/opc-ua-new-1-en.png create mode 100644 src/.vuepress/public/img/opc-ua-new-1.png diff --git a/src/.vuepress/public/img/opc-ua-new-1-en.png b/src/.vuepress/public/img/opc-ua-new-1-en.png new file mode 100644 index 0000000000000000000000000000000000000000..f6b1f8a0e46c4ffd46bbdc932697e33c83bfe729 GIT binary patch literal 53126 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 literal 0 HcmV?d00001 diff --git a/src/.vuepress/public/img/opc-ua-new-1.png b/src/.vuepress/public/img/opc-ua-new-1.png new file mode 100644 index 0000000000000000000000000000000000000000..d050e0f24e3c4459ca789c07ad46f5166f699a59 GIT binary patch literal 56142 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 - - - - -- Features: - - - OPC UA will organize the device information received from Sink into folders under the Objects folder according to a tree model. - - - Each measurement point is recorded as a variable node and the latest value in the current database is recorded. - -### 1.2 OPC UA Pub/Sub Mode - -- **Pub/Sub Mode**: In this mode, IoTDB's stream processing engine sends data change events to the OPC UA Server through an OPC UA Sink. These events are published to the server's message queue and managed through Event Nodes. Other OPC UA Clients can subscribe to these Event Nodes to receive notifications upon data changes. - -
- -
- -- Features: - - - Each measurement point is wrapped as an Event Node in OPC UA. - - - - The relevant fields and their meanings are as follows: - - | Field | Meaning | Type (Milo) | Example | - | :--------- | :--------------- | :------------ | :-------------------- | - | Time | Timestamp | DateTime | 1698907326198 | - | SourceName | Full path of the measurement point | String | root.test.opc.sensor0 | - | SourceNode | Data type of the measurement point | NodeId | Int32 | - | Message | Data | LocalizedText | 3.0 | - - - Events are only sent to clients that are already listening; if a client is not connected, the Event will be ignored. - - -## 2. IoTDB OPC Server Startup method +## 2. OPC Service Startup Method ### 2.1 Syntax -The syntax for creating the Sink is as follows: +The syntax to start the OPC UA protocol: ```SQL @@ -110,31 +74,29 @@ start pipe p1; ### 2.4 Usage Limitations -1. **DataRegion Requirement**: The OPC UA server will only start if there is a DataRegion in IoTDB. For an empty IoTDB, a data entry is necessary for the OPC UA server to become effective. - -2. **Data Availability**: Clients subscribing to the server will not receive data written to IoTDB before their connection. +1. After starting the protocol, data needs to be written to establish a connection. Only data after the connection is established can be subscribed to. +2. Recommended for use in standalone mode. In distributed mode, each IoTDB DataNode acts as an independent OPC Server providing data and requires separate subscription. -3. **Multiple DataNodes may have scattered sending/conflict issues**: +## 3. Examples of Two Communication Modes - - For IoTDB clusters with multiple dataRegions and scattered across different DataNode IPs, data will be sent in a dispersed manner on the leaders of the dataRegions. The client needs to listen to the configuration ports of the DataNode IP separately.。 - - - Suggest using this OPC UA server under 1C1D. - -4. **Does not support deleting data and modifying measurement point types:** In Client Server mode, OPC UA cannot delete data or change data type settings. In Pub Sub mode, if data is deleted, information cannot be pushed to the client. +### 3.1 Client / Server Mode -## 3. IoTDB OPC Server Example +In this mode, IoTDB's stream processing engine establishes a connection with the OPC UA Server via an OPC UA Sink. The OPC UA Server maintains data within its Address Space, from which IoTDB can request and retrieve data. Additionally, other OPC UA Clients can access the data on the server. -### 3.1 Client / Server Mode +* Features: + * OPC UA organizes device information received from the Sink into folders under the Objects folder according to a tree model. + * Each measurement point is recorded as a variable node, storing the latest value from the current database. + * OPC UA cannot delete data or change data type settings. -#### Preparation Work +#### 3.1.1 Preparation Work 1. Take UAExpert client as an example, download the UAExpert client: https://www.unified-automation.com/downloads/opc-ua-clients.html 2. Install UAExpert and fill in your own certificate information. -#### Quick Start +#### 3.1.2 Quick Start -1. Use the following SQL to create and start the OPC UA Sink in client-server mode. For detailed syntax, please refer to: [IoTDB OPC Server Syntax](#syntax) +1. Use the following SQL to create and start the OPC UA Sink in client-server mode. For detailed syntax, please refer to: [IoTDB OPC Server Syntax](./Programming-OPC-UA_timecho.md#_2-1-syntax) ```SQL create pipe p1 with sink ('sink'='opc-ua-sink'); @@ -176,7 +138,26 @@ insert into root.test.db(time, s2) values(now(), 2) ### 3.2 Pub / Sub Mode -#### Preparation Work +In this mode, IoTDB's stream processing engine sends data change events to the OPC UA Server through an OPC UA Sink. These events are published to the server's message queue and managed through Event Nodes. Other OPC UA Clients can subscribe to these Event Nodes to receive notifications upon data changes. + +- Features: + + - Each measurement point is wrapped as an Event Node in OPC UA. + + - The relevant fields and their meanings are as follows: + + | Field | Meaning | Type (Milo) | Example | + | :--------- | :--------------- | :------------ | :-------------------- | + | Time | Timestamp | DateTime | 1698907326198 | + | SourceName | Full path of the measurement point | String | root.test.opc.sensor0 | + | SourceNode | Data type of the measurement point | NodeId | Int32 | + | Message | Data | LocalizedText | 3.0 | + + - Events are only sent to clients that are already listening; if a client is not connected, the Event will be ignored. + - If data is deleted, the information cannot be pushed to clients. + + +#### 3.2.1 Preparation Work The code is located in the [opc-ua-sink package](https://github.com/apache/iotdb/tree/rc/2.0.1/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua)under the iotdb-example package. @@ -187,7 +168,7 @@ The code includes: - Client configuration and startup logic(ClientExampleRunner) - The parent class of ClientTest(ClientExample) -### 3.3 Quick Start +#### 3.2.2 Quick Start The steps are as follows: @@ -199,7 +180,7 @@ insert into root.a.b(time, c, d) values(now(), 1, 2); ​ The metadata is automatically created and enabled here. -2. Use the following SQL to create and start the OPC UA Sink in Pub-Sub mode. For detailed syntax, please refer to: [IoTDB OPC Server Syntax](#syntax) +2. Use the following SQL to create and start the OPC UA Sink in Pub-Sub mode. For detailed syntax, please refer to: [IoTDB OPC Server Syntax](./Programming-OPC-UA_timecho.md#_2-1-syntax) ```SQL create pipe p1 with sink ('sink'='opc-ua-sink', diff --git a/src/UserGuide/V1.3.x/API/Programming-OPC-UA_timecho.md b/src/UserGuide/V1.3.x/API/Programming-OPC-UA_timecho.md index 3c1c026b0..31890ac50 100644 --- a/src/UserGuide/V1.3.x/API/Programming-OPC-UA_timecho.md +++ b/src/UserGuide/V1.3.x/API/Programming-OPC-UA_timecho.md @@ -18,56 +18,19 @@ # OPC UA Protocol -## OPC UA +## OPC UA Subscription Data -OPC UA is a technical specification used in the automation field for communication between different devices and systems, enabling cross platform, cross language, and cross network operations, providing a reliable and secure data exchange foundation for the Industrial Internet of Things. IoTDB supports OPC UA protocol, and IoTDB OPC Server supports both Client/Server and Pub/Sub communication modes. +This feature allows users to subscribe to data from IoTDB using the OPC UA protocol. The communication modes for subscription data support both Client/Server and Pub/Sub. -### OPC UA Client/Server Mode +Note: This feature is not about collecting data from external OPC Servers and writing it into IoTDB. -- **Client/Server Mode**:In this mode, IoTDB's stream processing engine establishes a connection with the OPC UA Server via an OPC UA Sink. The OPC UA Server maintains data within its Address Space, from which IoTDB can request and retrieve data. Additionally, other OPC UA Clients can access the data on the server. +![](/img/opc-ua-new-1-en.png) -::: center - - - -::: - -- Features: - - - OPC UA will organize the device information received from Sink into folders under the Objects folder according to a tree model. - - - Each measurement point is recorded as a variable node and the latest value in the current database is recorded. - -### OPC UA Pub/Sub Mode - -- **Pub/Sub Mode**: In this mode, IoTDB's stream processing engine sends data change events to the OPC UA Server through an OPC UA Sink. These events are published to the server's message queue and managed through Event Nodes. Other OPC UA Clients can subscribe to these Event Nodes to receive notifications upon data changes. - -::: center - - - -::: - -- Features: - - - Each measurement point is wrapped as an Event Node in OPC UA. - - - The relevant fields and their meanings are as follows: - - | Field | Meaning | Type (Milo) | Example | - | :--------- | :--------------------------------- | :------------ | :-------------------- | - | Time | Timestamp | DateTime | 1698907326198 | - | SourceName | Full path of the measurement point | String | root.test.opc.sensor0 | - | SourceNode | Data type of the measurement point | NodeId | Int32 | - | Message | Data | LocalizedText | 3.0 | - - - Events are only sent to clients that are already listening; if a client is not connected, the Event will be ignored. - -## IoTDB OPC Server Startup method +## OPC Service Startup Method ### Syntax -The syntax for creating the Sink is as follows: +The syntax to start the OPC UA protocol: ```sql create pipe p1 @@ -95,7 +58,7 @@ create pipe p1 | sink.user | User for OPC UA, specified in the configuration | String | Optional | root | | sink.password | Password for OPC UA, specified in the configuration | String | Optional | root | -### 示例 +### Example ```Bash create pipe p1 @@ -107,21 +70,20 @@ start pipe p1; ### Usage Limitations -1. **DataRegion Requirement**: The OPC UA server will only start if there is a DataRegion in IoTDB. For an empty IoTDB, a data entry is necessary for the OPC UA server to become effective. - -2. **Data Availability**: Clients subscribing to the server will not receive data written to IoTDB before their connection. - -3. **Multiple DataNodes may have scattered sending/conflict issues**: +1. After starting the protocol, data needs to be written to establish a connection. Only data after the connection is established can be subscribed to. +2. Recommended for use in standalone mode. In distributed mode, each IoTDB DataNode acts as an independent OPC Server providing data and requires separate subscription. - - For IoTDB clusters with multiple dataRegions and scattered across different DataNode IPs, data will be sent in a dispersed manner on the leaders of the dataRegions. The client needs to listen to the configuration ports of the DataNode IP separately.。 - - Suggest using this OPC UA server under 1C1D. +## Examples of Two Communication Modes -4. **Does not support deleting data and modifying measurement point types:** In Client Server mode, OPC UA cannot delete data or change data type settings. In Pub Sub mode, if data is deleted, information cannot be pushed to the client. +### Client / Server Mode -## IoTDB OPC Server Example +In this mode, IoTDB's stream processing engine establishes a connection with the OPC UA Server via an OPC UA Sink. The OPC UA Server maintains data within its Address Space, from which IoTDB can request and retrieve data. Additionally, other OPC UA Clients can access the data on the server. -### Client / Server Mode +* Features: + * OPC UA organizes device information received from the Sink into folders under the Objects folder according to a tree model. + * Each measurement point is recorded as a variable node, storing the latest value from the current database. + * OPC UA cannot delete data or change data type settings. #### Preparation Work @@ -181,11 +143,30 @@ start pipe p1; ::: -### Pub / Sub Mode +### Pub / Sub Mode + +In this mode, IoTDB's stream processing engine sends data change events to the OPC UA Server through an OPC UA Sink. These events are published to the server's message queue and managed through Event Nodes. Other OPC UA Clients can subscribe to these Event Nodes to receive notifications upon data changes. + +- Features: + + - Each measurement point is wrapped as an Event Node in OPC UA. + + - The relevant fields and their meanings are as follows: + + | Field | Meaning | Type (Milo) | Example | + | :--------- | :--------------------------------- | :------------ | :-------------------- | + | Time | Timestamp | DateTime | 1698907326198 | + | SourceName | Full path of the measurement point | String | root.test.opc.sensor0 | + | SourceNode | Data type of the measurement point | NodeId | Int32 | + | Message | Data | LocalizedText | 3.0 | + + - Events are only sent to clients that are already listening; if a client is not connected, the Event will be ignored. + - If data is deleted, the information cannot be pushed to clients. + #### Preparation Work -The code is located in the [opc-ua-sink 文件夹](https://github.com/apache/iotdb/tree/rc/1.3.3/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua) under the iotdb-example package. +The code is located in the [opc-ua-sink](https://github.com/apache/iotdb/tree/rc/1.3.5/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua) under the iotdb-example package. The code includes: @@ -194,7 +175,7 @@ The code includes: - Client configuration and startup logic(ClientExampleRunner) - The parent class of ClientTest(ClientExample) -### Quick Start +#### Quick Start The steps are as follows: diff --git a/src/UserGuide/dev-1.3/API/Programming-OPC-UA_timecho.md b/src/UserGuide/dev-1.3/API/Programming-OPC-UA_timecho.md index cb98a3bd8..31890ac50 100644 --- a/src/UserGuide/dev-1.3/API/Programming-OPC-UA_timecho.md +++ b/src/UserGuide/dev-1.3/API/Programming-OPC-UA_timecho.md @@ -18,56 +18,19 @@ # OPC UA Protocol -## OPC UA +## OPC UA Subscription Data -OPC UA is a technical specification used in the automation field for communication between different devices and systems, enabling cross platform, cross language, and cross network operations, providing a reliable and secure data exchange foundation for the Industrial Internet of Things. IoTDB supports OPC UA protocol, and IoTDB OPC Server supports both Client/Server and Pub/Sub communication modes. +This feature allows users to subscribe to data from IoTDB using the OPC UA protocol. The communication modes for subscription data support both Client/Server and Pub/Sub. -### OPC UA Client/Server Mode +Note: This feature is not about collecting data from external OPC Servers and writing it into IoTDB. -- **Client/Server Mode**:In this mode, IoTDB's stream processing engine establishes a connection with the OPC UA Server via an OPC UA Sink. The OPC UA Server maintains data within its Address Space, from which IoTDB can request and retrieve data. Additionally, other OPC UA Clients can access the data on the server. +![](/img/opc-ua-new-1-en.png) -::: center - - - -::: - -- Features: - - - OPC UA will organize the device information received from Sink into folders under the Objects folder according to a tree model. - - - Each measurement point is recorded as a variable node and the latest value in the current database is recorded. - -### OPC UA Pub/Sub Mode - -- **Pub/Sub Mode**: In this mode, IoTDB's stream processing engine sends data change events to the OPC UA Server through an OPC UA Sink. These events are published to the server's message queue and managed through Event Nodes. Other OPC UA Clients can subscribe to these Event Nodes to receive notifications upon data changes. - -::: center - - - -::: - -- Features: - - - Each measurement point is wrapped as an Event Node in OPC UA. - - - The relevant fields and their meanings are as follows: - - | Field | Meaning | Type (Milo) | Example | - | :--------- | :--------------------------------- | :------------ | :-------------------- | - | Time | Timestamp | DateTime | 1698907326198 | - | SourceName | Full path of the measurement point | String | root.test.opc.sensor0 | - | SourceNode | Data type of the measurement point | NodeId | Int32 | - | Message | Data | LocalizedText | 3.0 | - - - Events are only sent to clients that are already listening; if a client is not connected, the Event will be ignored. - -## IoTDB OPC Server Startup method +## OPC Service Startup Method ### Syntax -The syntax for creating the Sink is as follows: +The syntax to start the OPC UA protocol: ```sql create pipe p1 @@ -95,7 +58,7 @@ create pipe p1 | sink.user | User for OPC UA, specified in the configuration | String | Optional | root | | sink.password | Password for OPC UA, specified in the configuration | String | Optional | root | -### 示例 +### Example ```Bash create pipe p1 @@ -107,21 +70,20 @@ start pipe p1; ### Usage Limitations -1. **DataRegion Requirement**: The OPC UA server will only start if there is a DataRegion in IoTDB. For an empty IoTDB, a data entry is necessary for the OPC UA server to become effective. - -2. **Data Availability**: Clients subscribing to the server will not receive data written to IoTDB before their connection. - -3. **Multiple DataNodes may have scattered sending/conflict issues**: +1. After starting the protocol, data needs to be written to establish a connection. Only data after the connection is established can be subscribed to. +2. Recommended for use in standalone mode. In distributed mode, each IoTDB DataNode acts as an independent OPC Server providing data and requires separate subscription. - - For IoTDB clusters with multiple dataRegions and scattered across different DataNode IPs, data will be sent in a dispersed manner on the leaders of the dataRegions. The client needs to listen to the configuration ports of the DataNode IP separately.。 - - Suggest using this OPC UA server under 1C1D. +## Examples of Two Communication Modes -4. **Does not support deleting data and modifying measurement point types:** In Client Server mode, OPC UA cannot delete data or change data type settings. In Pub Sub mode, if data is deleted, information cannot be pushed to the client. +### Client / Server Mode -## IoTDB OPC Server Example +In this mode, IoTDB's stream processing engine establishes a connection with the OPC UA Server via an OPC UA Sink. The OPC UA Server maintains data within its Address Space, from which IoTDB can request and retrieve data. Additionally, other OPC UA Clients can access the data on the server. -### Client / Server Mode +* Features: + * OPC UA organizes device information received from the Sink into folders under the Objects folder according to a tree model. + * Each measurement point is recorded as a variable node, storing the latest value from the current database. + * OPC UA cannot delete data or change data type settings. #### Preparation Work @@ -181,11 +143,30 @@ start pipe p1; ::: -### Pub / Sub Mode +### Pub / Sub Mode + +In this mode, IoTDB's stream processing engine sends data change events to the OPC UA Server through an OPC UA Sink. These events are published to the server's message queue and managed through Event Nodes. Other OPC UA Clients can subscribe to these Event Nodes to receive notifications upon data changes. + +- Features: + + - Each measurement point is wrapped as an Event Node in OPC UA. + + - The relevant fields and their meanings are as follows: + + | Field | Meaning | Type (Milo) | Example | + | :--------- | :--------------------------------- | :------------ | :-------------------- | + | Time | Timestamp | DateTime | 1698907326198 | + | SourceName | Full path of the measurement point | String | root.test.opc.sensor0 | + | SourceNode | Data type of the measurement point | NodeId | Int32 | + | Message | Data | LocalizedText | 3.0 | + + - Events are only sent to clients that are already listening; if a client is not connected, the Event will be ignored. + - If data is deleted, the information cannot be pushed to clients. + #### Preparation Work -The code is located in the [opc-ua-sink 文件夹](https://github.com/apache/iotdb/tree/master/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua) under the iotdb-example package. +The code is located in the [opc-ua-sink](https://github.com/apache/iotdb/tree/rc/1.3.5/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua) under the iotdb-example package. The code includes: @@ -194,7 +175,7 @@ The code includes: - Client configuration and startup logic(ClientExampleRunner) - The parent class of ClientTest(ClientExample) -### Quick Start +#### Quick Start The steps are as follows: diff --git a/src/UserGuide/latest/API/Programming-OPC-UA_timecho.md b/src/UserGuide/latest/API/Programming-OPC-UA_timecho.md index a638f0f6d..47a6ce5b2 100644 --- a/src/UserGuide/latest/API/Programming-OPC-UA_timecho.md +++ b/src/UserGuide/latest/API/Programming-OPC-UA_timecho.md @@ -21,55 +21,19 @@ # OPC UA Protocol -## 1. OPC UA +## 1. OPC UA Subscription Data -OPC UA is a technical specification used in the automation field for communication between different devices and systems, enabling cross platform, cross language, and cross network operations, providing a reliable and secure data exchange foundation for the Industrial Internet of Things. IoTDB supports OPC UA protocol, and IoTDB OPC Server supports both Client/Server and Pub/Sub communication modes. +This feature allows users to subscribe to data from IoTDB using the OPC UA protocol. The communication modes for subscription data support both Client/Server and Pub/Sub. -### 1.1 OPC UA Client/Server Mode +Note: This feature is not about collecting data from external OPC Servers and writing it into IoTDB. -- **Client/Server Mode**:In this mode, IoTDB's stream processing engine establishes a connection with the OPC UA Server via an OPC UA Sink. The OPC UA Server maintains data within its Address Space, from which IoTDB can request and retrieve data. Additionally, other OPC UA Clients can access the data on the server. +![](/img/opc-ua-new-1-en.png) -
- -
- - -- Features: - - - OPC UA will organize the device information received from Sink into folders under the Objects folder according to a tree model. - - - Each measurement point is recorded as a variable node and the latest value in the current database is recorded. - -### 1.2 OPC UA Pub/Sub Mode - -- **Pub/Sub Mode**: In this mode, IoTDB's stream processing engine sends data change events to the OPC UA Server through an OPC UA Sink. These events are published to the server's message queue and managed through Event Nodes. Other OPC UA Clients can subscribe to these Event Nodes to receive notifications upon data changes. - -
- -
- -- Features: - - - Each measurement point is wrapped as an Event Node in OPC UA. - - - - The relevant fields and their meanings are as follows: - - | Field | Meaning | Type (Milo) | Example | - | :--------- | :--------------- | :------------ | :-------------------- | - | Time | Timestamp | DateTime | 1698907326198 | - | SourceName | Full path of the measurement point | String | root.test.opc.sensor0 | - | SourceNode | Data type of the measurement point | NodeId | Int32 | - | Message | Data | LocalizedText | 3.0 | - - - Events are only sent to clients that are already listening; if a client is not connected, the Event will be ignored. - - -## 2. IoTDB OPC Server Startup method +## 2. OPC Service Startup Method ### 2.1 Syntax -The syntax for creating the Sink is as follows: +The syntax to start the OPC UA protocol: ```SQL @@ -110,31 +74,29 @@ start pipe p1; ### 2.4 Usage Limitations -1. **DataRegion Requirement**: The OPC UA server will only start if there is a DataRegion in IoTDB. For an empty IoTDB, a data entry is necessary for the OPC UA server to become effective. - -2. **Data Availability**: Clients subscribing to the server will not receive data written to IoTDB before their connection. +1. After starting the protocol, data needs to be written to establish a connection. Only data after the connection is established can be subscribed to. +2. Recommended for use in standalone mode. In distributed mode, each IoTDB DataNode acts as an independent OPC Server providing data and requires separate subscription. -3. **Multiple DataNodes may have scattered sending/conflict issues**: +## 3. Examples of Two Communication Modes - - For IoTDB clusters with multiple dataRegions and scattered across different DataNode IPs, data will be sent in a dispersed manner on the leaders of the dataRegions. The client needs to listen to the configuration ports of the DataNode IP separately.。 - - - Suggest using this OPC UA server under 1C1D. - -4. **Does not support deleting data and modifying measurement point types:** In Client Server mode, OPC UA cannot delete data or change data type settings. In Pub Sub mode, if data is deleted, information cannot be pushed to the client. +### 3.1 Client / Server Mode -## 3. IoTDB OPC Server Example +In this mode, IoTDB's stream processing engine establishes a connection with the OPC UA Server via an OPC UA Sink. The OPC UA Server maintains data within its Address Space, from which IoTDB can request and retrieve data. Additionally, other OPC UA Clients can access the data on the server. -### 3.1 Client / Server Mode +* Features: + * OPC UA organizes device information received from the Sink into folders under the Objects folder according to a tree model. + * Each measurement point is recorded as a variable node, storing the latest value from the current database. + * OPC UA cannot delete data or change data type settings. -#### Preparation Work +#### 3.1.1 Preparation Work 1. Take UAExpert client as an example, download the UAExpert client: https://www.unified-automation.com/downloads/opc-ua-clients.html 2. Install UAExpert and fill in your own certificate information. -#### Quick Start +#### 3.1.2 Quick Start -1. Use the following SQL to create and start the OPC UA Sink in client-server mode. For detailed syntax, please refer to: [IoTDB OPC Server Syntax](#syntax) +1. Use the following SQL to create and start the OPC UA Sink in client-server mode. For detailed syntax, please refer to: [IoTDB OPC Server Syntax](./Programming-OPC-UA_timecho.md#_2-1-syntax) ```SQL create pipe p1 with sink ('sink'='opc-ua-sink'); @@ -176,7 +138,26 @@ insert into root.test.db(time, s2) values(now(), 2) ### 3.2 Pub / Sub Mode -#### Preparation Work +In this mode, IoTDB's stream processing engine sends data change events to the OPC UA Server through an OPC UA Sink. These events are published to the server's message queue and managed through Event Nodes. Other OPC UA Clients can subscribe to these Event Nodes to receive notifications upon data changes. + +- Features: + + - Each measurement point is wrapped as an Event Node in OPC UA. + + - The relevant fields and their meanings are as follows: + + | Field | Meaning | Type (Milo) | Example | + | :--------- | :--------------- | :------------ | :-------------------- | + | Time | Timestamp | DateTime | 1698907326198 | + | SourceName | Full path of the measurement point | String | root.test.opc.sensor0 | + | SourceNode | Data type of the measurement point | NodeId | Int32 | + | Message | Data | LocalizedText | 3.0 | + + - Events are only sent to clients that are already listening; if a client is not connected, the Event will be ignored. + - If data is deleted, the information cannot be pushed to clients. + + +#### 3.2.1 Preparation Work The code is located in the [opc-ua-sink package](https://github.com/apache/iotdb/tree/rc/2.0.1/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua)under the iotdb-example package. @@ -187,7 +168,7 @@ The code includes: - Client configuration and startup logic(ClientExampleRunner) - The parent class of ClientTest(ClientExample) -### 3.3 Quick Start +#### 3.2.2 Quick Start The steps are as follows: @@ -199,7 +180,7 @@ insert into root.a.b(time, c, d) values(now(), 1, 2); ​ The metadata is automatically created and enabled here. -2. Use the following SQL to create and start the OPC UA Sink in Pub-Sub mode. For detailed syntax, please refer to: [IoTDB OPC Server Syntax](#syntax) +2. Use the following SQL to create and start the OPC UA Sink in Pub-Sub mode. For detailed syntax, please refer to: [IoTDB OPC Server Syntax](./Programming-OPC-UA_timecho.md#_2-1-syntax) ```SQL create pipe p1 with sink ('sink'='opc-ua-sink', diff --git a/src/zh/UserGuide/Master/Tree/API/Programming-OPC-UA_timecho.md b/src/zh/UserGuide/Master/Tree/API/Programming-OPC-UA_timecho.md index f37cfc625..eea7e97fd 100644 --- a/src/zh/UserGuide/Master/Tree/API/Programming-OPC-UA_timecho.md +++ b/src/zh/UserGuide/Master/Tree/API/Programming-OPC-UA_timecho.md @@ -21,52 +21,18 @@ # OPC UA 协议 -## 1. OPC UA +## 1. OPC UA 订阅数据 -OPC UA 是一种在自动化领域用于不同设备和系统之间进行通信的技术规范,用于实现跨平台、跨语言和跨网络的操作,为工业物联网提供一个可靠和安全的数据交换基础。IoTDB 中支持 OPC UA协议, IoTDB OPC Server 支持 Client/Server 和 Pub/Sub 两种通信模式。 +本功能支持用户以 OPC UA 协议从 IoTDB 中订阅数据,订阅数据的通信模式支持 Client/Server 和 Pub/Sub 两种。 -### 1.1 PC UA Client/Server 模式 +注意:本功能并非从外部 OPC Server 中采集数据写入 IoTDB -- **Client/Server 模式**:在这种模式下,IoTDB 的流处理引擎通过 OPC UA Sink 与 OPC UA 服务器(Server)建立连接。OPC UA 服务器在其地址空间(Address Space) 中维护数据,IoTDB可以请求并获取这些数据。同时,其他OPC UA客户端(Client)也能访问服务器上的数据。 - -
- -
- - -- 特性: - - - OPC UA 将从 Sink 收到的设备信息,按照树形模型整理到 Objects folder 下的文件夹中。 - - 每个测点都被记录为一个变量节点,并记录当前数据库中的最新值。 - -### 1.2 OPC UA Pub/Sub 模式 - -- **Pub/Sub 模式**:在这种模式下,IoTDB的流处理引擎通过 OPC UA Sink 向OPC UA 服务器(Server)发送数据变更事件。这些事件被发布到服务器的消息队列中,并通过事件节点 (Event Node) 进行管理。其他OPC UA客户端(Client)可以订阅这些事件节点,以便在数据变更时接收通知。 - -
- -
- -- 特性: - - - 每个测点会被 OPC UA 包装成一个事件节点(EventNode)。 - - - 相关字段及其对应含义如下: - - | 字段 | 含义 | 类型(Milo) | 示例 | - | :--------- | :--------------- | :------------ | :-------------------- | - | Time | 时间戳 | DateTime | 1698907326198 | - | SourceName | 测点对应完整路径 | String | root.test.opc.sensor0 | - | SourceNode | 测点数据类型 | NodeId | Int32 | - | Message | 数据 | LocalizedText | 3.0 | - - - Event 仅会发送给所有已经监听的客户端,客户端未连接则会忽略该 Event。 - -## 2. IoTDB OPC Server 启动方式 +![](/img/opc-ua-new-1.png) +## 2. OPC 服务启动方式 ### 2.1 语法 -创建该 Sink 的语法如下: +启动 OPC UA 协议的语法: ```SQL create pipe p1 @@ -83,16 +49,16 @@ create pipe p1 ### 2.2 参数 -| **参数** | **描述** | **取值范围** | **是否必填** | **默认值** | -| ---------------------------------- | ------------------------------ | -------------------------------- | ------------ |------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| sink | OPC UA SINK | String: opc-ua-sink | 必填 | | -| sink.opcua.model | OPC UA 使用的模式 | String: client-server / pub-sub | 选填 | pub-sub | -| sink.opcua.tcp.port | OPC UA 的 TCP 端口 | Integer: [0, 65536] | 选填 | 12686 | -| sink.opcua.https.port | OPC UA 的 HTTPS 端口 | Integer: [0, 65536] | 选填 | 8443 | -| sink.opcua.security.dir | OPC UA 的密钥及证书目录 | String: Path,支持绝对及相对目录 | 选填 | iotdb 相关 DataNode 的 conf 目录下的 opc_security 文件夹 /
如无 iotdb 的 conf 目录(例如 IDEA 中启动 DataNode),则为用户主目录下的 iotdb_opc_security 文件夹 / | -| sink.opcua.enable-anonymous-access | OPC UA 是否允许匿名访问 | Boolean | 选填 | true | -| sink.user | 用户,这里指 OPC UA 的允许用户 | String | 选填 | root | -| sink.password | 密码,这里指 OPC UA 的允许密码 | String | 选填 | TimechoDB@2021 //V2.0.6.x 之前默认密码为root | +| **参数** | **描述** | **​ 取值范围 ​** | **是否必填** | **默认值** | +| ------------------------------------ | -------------------------------- | ---------------------------------- | -------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------| +| sink | OPC UA SINK | String: opc-ua-sink | 必填 | | +| sink.opcua.model | OPC UA 使用的模式 | String: client-server / pub-sub | 选填 | client-server | +| sink.opcua.tcp.port | OPC UA 的 TCP 端口 | Integer: [0, 65536] | 选填 | 12686 | +| sink.opcua.https.port | OPC UA 的 HTTPS 端口 | Integer: [0, 65536] | 选填 | 8443 | +| sink.opcua.security.dir | OPC UA 的密钥及证书目录 | String: Path,支持绝对及相对目录 | 选填 | 1. iotdb 相关 DataNode 的 conf 目录下的 opc\_security 文件夹 / ``。2. 如无 iotdb 的 conf 目录(例如 IDEA 中启动 DataNode),则为用户主目录下的 iotdb\_opc\_security 文件夹 /``| +| sink.opcua.enable-anonymous-access | OPC UA 是否允许匿名访问 | Boolean | 选填 | true | +| sink.user | 用户,这里指 OPC UA 的允许用户 | String | 选填 | root | +| sink.password | 密码,这里指 OPC UA 的允许密码 | String | 选填 | TimechoDB@2021 (V2.0.6.x 之前默认密码为root ) | ### 2.3 示例 @@ -100,36 +66,30 @@ create pipe p1 create pipe p1 with sink ('sink' = 'opc-ua-sink', 'sink.user' = 'root', - 'sink.password' = 'TimechoDB@2021'); //V2.0.6.x 之前默认密码为root + 'sink.password' = 'TimechoDB@2021');//V2.0.6.x 之前默认密码为root start pipe p1; ``` ### 2.4 使用限制 +1. 启动协议之后需要写入数据,才能建立连接,且仅能订阅建立连接之后的数据。 +2. 推荐在单机模式下使用。在分布式模式下,每一个 IoTDB DataNode 都作为一个独立的 OPC Server 提供数据,需要单独订阅。 -1. **必须存在 DataRegion**:在 IoTDB 有 dataRegion 时,OPC UA 的服务器才会启动。因此,对于一个空的 IoTDB,需要写入一条数据,OPC UA 的服务器才有效。 -2. **需连接才有数据**:每一个订阅该服务器的客户端,不会收到 OPC Server 在连接之前写入IoTDB的数据。 - -3. **多 DataNode 会有分散发送 / 冲突问题**: - - - 对于有多个 dataRegion,且分散在不同 DataNode ip上的 IoTDB 集群,数据会在 dataRegion 的 leader 上分散发送。客户端需要对 DataNode ip 的配置端口分别监听。 - - - 建议在 1C1D 下使用该 OPC UA 服务器。 - -4. **不支持删除数据和修改测点类型:**在Client Server模式下,OPC UA无法删除数据或者改变数据类型的设置。而在Pub Sub模式下,如果数据被删除了,信息是无法推送给客户端的。 - -## 3. IoTDB OPC Server 示例 - +## 3. 两种通信模式示例 ### 3.1 Client / Server 模式 -#### 准备工作 +在这种模式下,IoTDB 的流处理引擎通过 OPC UA Sink 与 OPC UA 服务器(Server)建立连接。OPC UA 服务器在其地址空间(Address Space) 中维护数据,IoTDB可以请求并获取这些数据。同时,其他OPC UA客户端(Client)也能访问服务器上的数据。 -1. 此处以UAExpert客户端为例,下载 UAExpert 客户端:https://www.unified-automation.com/downloads/opc-ua-clients.html +* 特性: + * OPC UA 将从 Sink 收到的设备信息,按照树形模型整理到 Objects folder 下的文件夹中。 + * 每个测点都被记录为一个变量节点,并记录当前数据库中的最新值。 + * OPC UA 无法删除数据或者改变数据类型的设置 +#### 3.1.1 准备工作 +1. 此处以UAExpert客户端为例,下载 UAExpert 客户端:https://www.unified-automation.com/downloads/opc-ua-clients.html 2. 安装 UAExpert,填写自身的证书等信息。 -#### 快速开始 - -1. 使用如下 sql,创建并启动 client-server 模式的 OPC UA Sink。详细语法参见上文:[IoTDB OPC Server语法](#语法) +#### 3.1.2 快速开始 +1. 使用如下 sql,启动 OPC UA 服务。详细语法参见上文:[IoTDB OPC Server语法](./Programming-OPC-UA_timecho.md#_2-1-语法) ```SQL create pipe p1 with sink ('sink'='opc-ua-sink'); @@ -141,9 +101,7 @@ create pipe p1 with sink ('sink'='opc-ua-sink'); insert into root.test.db(time, s2) values(now(), 2) ``` -​ 此处自动创建元数据开启。 - -3. 在 UAExpert 中配置 iotdb 的连接,其中 password 填写为上述参数配置中 sink.password 中设定的密码(此处以密码root为例): +3. 在 UAExpert 中配置 iotdb 的连接,其中 password 填写为上述参数配置中 sink.password 中设定的密码(此处用户名、密码以2.3小节示例中配置的 root/root 为例):
@@ -171,9 +129,26 @@ insert into root.test.db(time, s2) values(now(), 2) ### 3.2 Pub / Sub 模式 -#### 准备工作 +在这种模式下,IoTDB的流处理引擎通过 OPC UA Sink 向OPC UA 服务器(Server)发送数据变更事件。这些事件被发布到服务器的消息队列中,并通过事件节点 (Event Node) 进行管理。其他OPC UA客户端(Client)可以订阅这些事件节点,以便在数据变更时接收通知。 + +* 特性: + * 每个测点会被 OPC UA 包装成一个事件节点(EventNode)。 + * 相关字段及其对应含义如下: + + | 字段 | 含义 | 类型(Milo) | 示例 | + | ------------ | ------------------ | --------------- | ----------------------- | + | Time | 时间戳 | DateTime | 1698907326198 | + | SourceName | 测点对应完整路径 | String | root.test.opc.sensor0 | + | SourceNode | 测点数据类型 | NodeId | Int32 | + | Message | 数据 | LocalizedText | 3.0 | + + - Event 仅会发送给所有已经监听的客户端,客户端未连接则会忽略该 Event。 + - 如果数据被删除,信息则无法推送给客户端。 + + +#### 3.2.1 准备工作 -该代码位于 iotdb-example 包下的 [opc-ua-sink 文件夹](https://github.com/apache/iotdb/tree/rc/2.0.1/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua)中 +该代码位于 iotdb-example 包下的 [opc-ua-sink 文件夹](https://github.com/apache/iotdb/tree/master/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua)中 代码中包含: @@ -182,7 +157,7 @@ insert into root.test.db(time, s2) values(now(), 2) - Client 的配置及启动逻辑(ClientExampleRunner) - ClientTest 的父类(ClientExample) -### 3.3 快速开始 +#### 3.2.2 快速开始 使用步骤为: @@ -194,11 +169,10 @@ insert into root.a.b(time, c, d) values(now(), 1, 2); ​ 此处自动创建元数据开启。 -2. 使用如下 sql,创建并启动 Pub-Sub 模式的 OPC UA Sink。详细语法参见上文:[IoTDB OPC Server语法](#语法) +2. 使用如下 sql,创建并启动 Pub-Sub 模式的 OPC UA Sink。详细语法参见上文:[IoTDB OPC Server语法](./Programming-OPC-UA_timecho.md#_2-1-语法) ```SQL -create pipe p1 with sink ('sink'='opc-ua-sink', - 'sink.opcua.model'='pub-sub'); +create pipe p1 with sink ('sink'='opc-ua-sink', 'sink.opcua.model'='pub-sub'); start pipe p1; ``` diff --git a/src/zh/UserGuide/V1.3.x/API/Programming-OPC-UA_timecho.md b/src/zh/UserGuide/V1.3.x/API/Programming-OPC-UA_timecho.md index 861fc5851..917b211ee 100644 --- a/src/zh/UserGuide/V1.3.x/API/Programming-OPC-UA_timecho.md +++ b/src/zh/UserGuide/V1.3.x/API/Programming-OPC-UA_timecho.md @@ -21,52 +21,19 @@ # OPC UA 协议 -## OPC UA +## OPC UA 订阅数据 -OPC UA 是一种在自动化领域用于不同设备和系统之间进行通信的技术规范,用于实现跨平台、跨语言和跨网络的操作,为工业物联网提供一个可靠和安全的数据交换基础。IoTDB 中支持 OPC UA协议, IoTDB OPC Server 支持 Client/Server 和 Pub/Sub 两种通信模式。 +本功能支持用户以 OPC UA 协议从 IoTDB 中订阅数据,订阅数据的通信模式支持 Client/Server 和 Pub/Sub 两种。 -### OPC UA Client/Server 模式 +注意:本功能并非从外部 OPC Server 中采集数据写入 IoTDB -- **Client/Server 模式**:在这种模式下,IoTDB 的流处理引擎通过 OPC UA Sink 与 OPC UA 服务器(Server)建立连接。OPC UA 服务器在其地址空间(Address Space) 中维护数据,IoTDB可以请求并获取这些数据。同时,其他OPC UA客户端(Client)也能访问服务器上的数据。 +![](/img/opc-ua-new-1.png) -
- -
- - -- 特性: - - - OPC UA 将从 Sink 收到的设备信息,按照树形模型整理到 Objects folder 下的文件夹中。 - - 每个测点都被记录为一个变量节点,并记录当前数据库中的最新值。 - -### OPC UA Pub/Sub 模式 - -- **Pub/Sub 模式**:在这种模式下,IoTDB的流处理引擎通过 OPC UA Sink 向OPC UA 服务器(Server)发送数据变更事件。这些事件被发布到服务器的消息队列中,并通过事件节点 (Event Node) 进行管理。其他OPC UA客户端(Client)可以订阅这些事件节点,以便在数据变更时接收通知。 - -
- -
- -- 特性: - - - 每个测点会被 OPC UA 包装成一个事件节点(EventNode)。 - - - 相关字段及其对应含义如下: - - | 字段 | 含义 | 类型(Milo) | 示例 | - | :--------- | :--------------- | :------------ | :-------------------- | - | Time | 时间戳 | DateTime | 1698907326198 | - | SourceName | 测点对应完整路径 | String | root.test.opc.sensor0 | - | SourceNode | 测点数据类型 | NodeId | Int32 | - | Message | 数据 | LocalizedText | 3.0 | - - - Event 仅会发送给所有已经监听的客户端,客户端未连接则会忽略该 Event。 - -## IoTDB OPC Server 启动方式 +## OPC 服务启动方式 ### 语法 -创建该 Sink 的语法如下: +启动 OPC UA 协议的语法: ```SQL create pipe p1 @@ -89,7 +56,7 @@ create pipe p1 | sink.opcua.model | OPC UA 使用的模式 | String: client-server / pub-sub | 选填 | pub-sub | | sink.opcua.tcp.port | OPC UA 的 TCP 端口 | Integer: [0, 65536] | 选填 | 12686 | | sink.opcua.https.port | OPC UA 的 HTTPS 端口 | Integer: [0, 65536] | 选填 | 8443 | -| sink.opcua.security.dir | OPC UA 的密钥及证书目录 | String: Path,支持绝对及相对目录 | 选填 | iotdb 相关 DataNode 的 conf 目录下的 opc_security 文件夹 /
如无 iotdb 的 conf 目录(例如 IDEA 中启动 DataNode),则为用户主目录下的 iotdb_opc_security 文件夹 / | +| sink.opcua.security.dir | OPC UA 的密钥及证书目录 | String: Path,支持绝对及相对目录 | 选填 | iotdb 相关 DataNode 的 conf 目录下的 opc_security 文件夹 /``。
如无 iotdb 的 conf 目录(例如 IDEA 中启动 DataNode),则为用户主目录下的 iotdb_opc_security 文件夹 /`` | | sink.opcua.enable-anonymous-access | OPC UA 是否允许匿名访问 | Boolean | 选填 | true | | sink.user | 用户,这里指 OPC UA 的允许用户 | String | 选填 | root | | sink.password | 密码,这里指 OPC UA 的允许密码 | String | 选填 | root | @@ -106,20 +73,18 @@ start pipe p1; ### 使用限制 -1. **必须存在 DataRegion**:在 IoTDB 有 dataRegion 时,OPC UA 的服务器才会启动。因此,对于一个空的 IoTDB,需要写入一条数据,OPC UA 的服务器才有效。 -2. **需连接才有数据**:每一个订阅该服务器的客户端,不会收到 OPC Server 在连接之前写入IoTDB的数据。 - -3. **多 DataNode 会有分散发送 / 冲突问题**: - - - 对于有多个 dataRegion,且分散在不同 DataNode ip上的 IoTDB 集群,数据会在 dataRegion 的 leader 上分散发送。客户端需要对 DataNode ip 的配置端口分别监听。 - - - 建议在 1C1D 下使用该 OPC UA 服务器。 +1. 启动协议之后需要写入数据,才能建立连接,且仅能订阅建立连接之后的数据。 +2. 推荐在单机模式下使用。在分布式模式下,每一个 IoTDB DataNode 都作为一个独立的 OPC Server 提供数据,需要单独订阅。 -4. **不支持删除数据和修改测点类型:**在Client Server模式下,OPC UA无法删除数据或者改变数据类型的设置。而在Pub Sub模式下,如果数据被删除了,信息是无法推送给客户端的。 +## 两种通信模式示例 +### Client / Server 模式 -## IoTDB OPC Server 示例 +在这种模式下,IoTDB 的流处理引擎通过 OPC UA Sink 与 OPC UA 服务器(Server)建立连接。OPC UA 服务器在其地址空间(Address Space) 中维护数据,IoTDB可以请求并获取这些数据。同时,其他OPC UA客户端(Client)也能访问服务器上的数据。 -### Client / Server 模式 +* 特性: + * OPC UA 将从 Sink 收到的设备信息,按照树形模型整理到 Objects folder 下的文件夹中。 + * 每个测点都被记录为一个变量节点,并记录当前数据库中的最新值。 + * OPC UA 无法删除数据或者改变数据类型的设置 #### 准备工作 @@ -171,9 +136,27 @@ insert into root.test.db(time, s2) values(now(), 2) ### Pub / Sub 模式 +在这种模式下,IoTDB的流处理引擎通过 OPC UA Sink 向OPC UA 服务器(Server)发送数据变更事件。这些事件被发布到服务器的消息队列中,并通过事件节点 (Event Node) 进行管理。其他OPC UA客户端(Client)可以订阅这些事件节点,以便在数据变更时接收通知。 + +- 特性: + + - 每个测点会被 OPC UA 包装成一个事件节点(EventNode)。 + - 相关字段及其对应含义如下: + + | 字段 | 含义 | 类型(Milo) | 示例 | + | :--------- | :--------------- | :------------ | :-------------------- | + | Time | 时间戳 | DateTime | 1698907326198 | + | SourceName | 测点对应完整路径 | String | root.test.opc.sensor0 | + | SourceNode | 测点数据类型 | NodeId | Int32 | + | Message | 数据 | LocalizedText | 3.0 | + + - Event 仅会发送给所有已经监听的客户端,客户端未连接则会忽略该 Event。 + - 如果数据被删除,信息则无法推送给客户端。 + + #### 准备工作 -该代码位于 iotdb-example 包下的 [opc-ua-sink 文件夹](https://github.com/apache/iotdb/tree/rc/1.3.3/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua)中 +该代码位于 iotdb-example 包下的 [opc-ua-sink 文件夹](https://github.com/apache/iotdb/tree/rc/1.3.5/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua)中 代码中包含: @@ -182,7 +165,7 @@ insert into root.test.db(time, s2) values(now(), 2) - Client 的配置及启动逻辑(ClientExampleRunner) - ClientTest 的父类(ClientExample) -### 快速开始 +#### 快速开始 使用步骤为: diff --git a/src/zh/UserGuide/dev-1.3/API/Programming-OPC-UA_timecho.md b/src/zh/UserGuide/dev-1.3/API/Programming-OPC-UA_timecho.md index b0e9948b7..917b211ee 100644 --- a/src/zh/UserGuide/dev-1.3/API/Programming-OPC-UA_timecho.md +++ b/src/zh/UserGuide/dev-1.3/API/Programming-OPC-UA_timecho.md @@ -21,52 +21,19 @@ # OPC UA 协议 -## OPC UA +## OPC UA 订阅数据 -OPC UA 是一种在自动化领域用于不同设备和系统之间进行通信的技术规范,用于实现跨平台、跨语言和跨网络的操作,为工业物联网提供一个可靠和安全的数据交换基础。IoTDB 中支持 OPC UA协议, IoTDB OPC Server 支持 Client/Server 和 Pub/Sub 两种通信模式。 +本功能支持用户以 OPC UA 协议从 IoTDB 中订阅数据,订阅数据的通信模式支持 Client/Server 和 Pub/Sub 两种。 -### OPC UA Client/Server 模式 +注意:本功能并非从外部 OPC Server 中采集数据写入 IoTDB -- **Client/Server 模式**:在这种模式下,IoTDB 的流处理引擎通过 OPC UA Sink 与 OPC UA 服务器(Server)建立连接。OPC UA 服务器在其地址空间(Address Space) 中维护数据,IoTDB可以请求并获取这些数据。同时,其他OPC UA客户端(Client)也能访问服务器上的数据。 +![](/img/opc-ua-new-1.png) -
- -
- - -- 特性: - - - OPC UA 将从 Sink 收到的设备信息,按照树形模型整理到 Objects folder 下的文件夹中。 - - 每个测点都被记录为一个变量节点,并记录当前数据库中的最新值。 - -### OPC UA Pub/Sub 模式 - -- **Pub/Sub 模式**:在这种模式下,IoTDB的流处理引擎通过 OPC UA Sink 向OPC UA 服务器(Server)发送数据变更事件。这些事件被发布到服务器的消息队列中,并通过事件节点 (Event Node) 进行管理。其他OPC UA客户端(Client)可以订阅这些事件节点,以便在数据变更时接收通知。 - -
- -
- -- 特性: - - - 每个测点会被 OPC UA 包装成一个事件节点(EventNode)。 - - - 相关字段及其对应含义如下: - - | 字段 | 含义 | 类型(Milo) | 示例 | - | :--------- | :--------------- | :------------ | :-------------------- | - | Time | 时间戳 | DateTime | 1698907326198 | - | SourceName | 测点对应完整路径 | String | root.test.opc.sensor0 | - | SourceNode | 测点数据类型 | NodeId | Int32 | - | Message | 数据 | LocalizedText | 3.0 | - - - Event 仅会发送给所有已经监听的客户端,客户端未连接则会忽略该 Event。 - -## IoTDB OPC Server 启动方式 +## OPC 服务启动方式 ### 语法 -创建该 Sink 的语法如下: +启动 OPC UA 协议的语法: ```SQL create pipe p1 @@ -89,7 +56,7 @@ create pipe p1 | sink.opcua.model | OPC UA 使用的模式 | String: client-server / pub-sub | 选填 | pub-sub | | sink.opcua.tcp.port | OPC UA 的 TCP 端口 | Integer: [0, 65536] | 选填 | 12686 | | sink.opcua.https.port | OPC UA 的 HTTPS 端口 | Integer: [0, 65536] | 选填 | 8443 | -| sink.opcua.security.dir | OPC UA 的密钥及证书目录 | String: Path,支持绝对及相对目录 | 选填 | iotdb 相关 DataNode 的 conf 目录下的 opc_security 文件夹 /
如无 iotdb 的 conf 目录(例如 IDEA 中启动 DataNode),则为用户主目录下的 iotdb_opc_security 文件夹 / | +| sink.opcua.security.dir | OPC UA 的密钥及证书目录 | String: Path,支持绝对及相对目录 | 选填 | iotdb 相关 DataNode 的 conf 目录下的 opc_security 文件夹 /``。
如无 iotdb 的 conf 目录(例如 IDEA 中启动 DataNode),则为用户主目录下的 iotdb_opc_security 文件夹 /`` | | sink.opcua.enable-anonymous-access | OPC UA 是否允许匿名访问 | Boolean | 选填 | true | | sink.user | 用户,这里指 OPC UA 的允许用户 | String | 选填 | root | | sink.password | 密码,这里指 OPC UA 的允许密码 | String | 选填 | root | @@ -106,20 +73,18 @@ start pipe p1; ### 使用限制 -1. **必须存在 DataRegion**:在 IoTDB 有 dataRegion 时,OPC UA 的服务器才会启动。因此,对于一个空的 IoTDB,需要写入一条数据,OPC UA 的服务器才有效。 -2. **需连接才有数据**:每一个订阅该服务器的客户端,不会收到 OPC Server 在连接之前写入IoTDB的数据。 - -3. **多 DataNode 会有分散发送 / 冲突问题**: - - - 对于有多个 dataRegion,且分散在不同 DataNode ip上的 IoTDB 集群,数据会在 dataRegion 的 leader 上分散发送。客户端需要对 DataNode ip 的配置端口分别监听。 - - - 建议在 1C1D 下使用该 OPC UA 服务器。 +1. 启动协议之后需要写入数据,才能建立连接,且仅能订阅建立连接之后的数据。 +2. 推荐在单机模式下使用。在分布式模式下,每一个 IoTDB DataNode 都作为一个独立的 OPC Server 提供数据,需要单独订阅。 -4. **不支持删除数据和修改测点类型:**在Client Server模式下,OPC UA无法删除数据或者改变数据类型的设置。而在Pub Sub模式下,如果数据被删除了,信息是无法推送给客户端的。 +## 两种通信模式示例 +### Client / Server 模式 -## IoTDB OPC Server 示例 +在这种模式下,IoTDB 的流处理引擎通过 OPC UA Sink 与 OPC UA 服务器(Server)建立连接。OPC UA 服务器在其地址空间(Address Space) 中维护数据,IoTDB可以请求并获取这些数据。同时,其他OPC UA客户端(Client)也能访问服务器上的数据。 -### Client / Server 模式 +* 特性: + * OPC UA 将从 Sink 收到的设备信息,按照树形模型整理到 Objects folder 下的文件夹中。 + * 每个测点都被记录为一个变量节点,并记录当前数据库中的最新值。 + * OPC UA 无法删除数据或者改变数据类型的设置 #### 准备工作 @@ -171,9 +136,27 @@ insert into root.test.db(time, s2) values(now(), 2) ### Pub / Sub 模式 +在这种模式下,IoTDB的流处理引擎通过 OPC UA Sink 向OPC UA 服务器(Server)发送数据变更事件。这些事件被发布到服务器的消息队列中,并通过事件节点 (Event Node) 进行管理。其他OPC UA客户端(Client)可以订阅这些事件节点,以便在数据变更时接收通知。 + +- 特性: + + - 每个测点会被 OPC UA 包装成一个事件节点(EventNode)。 + - 相关字段及其对应含义如下: + + | 字段 | 含义 | 类型(Milo) | 示例 | + | :--------- | :--------------- | :------------ | :-------------------- | + | Time | 时间戳 | DateTime | 1698907326198 | + | SourceName | 测点对应完整路径 | String | root.test.opc.sensor0 | + | SourceNode | 测点数据类型 | NodeId | Int32 | + | Message | 数据 | LocalizedText | 3.0 | + + - Event 仅会发送给所有已经监听的客户端,客户端未连接则会忽略该 Event。 + - 如果数据被删除,信息则无法推送给客户端。 + + #### 准备工作 -该代码位于 iotdb-example 包下的 [opc-ua-sink 文件夹](https://github.com/apache/iotdb/tree/master/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua)中 +该代码位于 iotdb-example 包下的 [opc-ua-sink 文件夹](https://github.com/apache/iotdb/tree/rc/1.3.5/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua)中 代码中包含: @@ -182,7 +165,7 @@ insert into root.test.db(time, s2) values(now(), 2) - Client 的配置及启动逻辑(ClientExampleRunner) - ClientTest 的父类(ClientExample) -### 快速开始 +#### 快速开始 使用步骤为: diff --git a/src/zh/UserGuide/latest/API/Programming-OPC-UA_timecho.md b/src/zh/UserGuide/latest/API/Programming-OPC-UA_timecho.md index f37cfc625..eea7e97fd 100644 --- a/src/zh/UserGuide/latest/API/Programming-OPC-UA_timecho.md +++ b/src/zh/UserGuide/latest/API/Programming-OPC-UA_timecho.md @@ -21,52 +21,18 @@ # OPC UA 协议 -## 1. OPC UA +## 1. OPC UA 订阅数据 -OPC UA 是一种在自动化领域用于不同设备和系统之间进行通信的技术规范,用于实现跨平台、跨语言和跨网络的操作,为工业物联网提供一个可靠和安全的数据交换基础。IoTDB 中支持 OPC UA协议, IoTDB OPC Server 支持 Client/Server 和 Pub/Sub 两种通信模式。 +本功能支持用户以 OPC UA 协议从 IoTDB 中订阅数据,订阅数据的通信模式支持 Client/Server 和 Pub/Sub 两种。 -### 1.1 PC UA Client/Server 模式 +注意:本功能并非从外部 OPC Server 中采集数据写入 IoTDB -- **Client/Server 模式**:在这种模式下,IoTDB 的流处理引擎通过 OPC UA Sink 与 OPC UA 服务器(Server)建立连接。OPC UA 服务器在其地址空间(Address Space) 中维护数据,IoTDB可以请求并获取这些数据。同时,其他OPC UA客户端(Client)也能访问服务器上的数据。 - -
- -
- - -- 特性: - - - OPC UA 将从 Sink 收到的设备信息,按照树形模型整理到 Objects folder 下的文件夹中。 - - 每个测点都被记录为一个变量节点,并记录当前数据库中的最新值。 - -### 1.2 OPC UA Pub/Sub 模式 - -- **Pub/Sub 模式**:在这种模式下,IoTDB的流处理引擎通过 OPC UA Sink 向OPC UA 服务器(Server)发送数据变更事件。这些事件被发布到服务器的消息队列中,并通过事件节点 (Event Node) 进行管理。其他OPC UA客户端(Client)可以订阅这些事件节点,以便在数据变更时接收通知。 - -
- -
- -- 特性: - - - 每个测点会被 OPC UA 包装成一个事件节点(EventNode)。 - - - 相关字段及其对应含义如下: - - | 字段 | 含义 | 类型(Milo) | 示例 | - | :--------- | :--------------- | :------------ | :-------------------- | - | Time | 时间戳 | DateTime | 1698907326198 | - | SourceName | 测点对应完整路径 | String | root.test.opc.sensor0 | - | SourceNode | 测点数据类型 | NodeId | Int32 | - | Message | 数据 | LocalizedText | 3.0 | - - - Event 仅会发送给所有已经监听的客户端,客户端未连接则会忽略该 Event。 - -## 2. IoTDB OPC Server 启动方式 +![](/img/opc-ua-new-1.png) +## 2. OPC 服务启动方式 ### 2.1 语法 -创建该 Sink 的语法如下: +启动 OPC UA 协议的语法: ```SQL create pipe p1 @@ -83,16 +49,16 @@ create pipe p1 ### 2.2 参数 -| **参数** | **描述** | **取值范围** | **是否必填** | **默认值** | -| ---------------------------------- | ------------------------------ | -------------------------------- | ------------ |------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| sink | OPC UA SINK | String: opc-ua-sink | 必填 | | -| sink.opcua.model | OPC UA 使用的模式 | String: client-server / pub-sub | 选填 | pub-sub | -| sink.opcua.tcp.port | OPC UA 的 TCP 端口 | Integer: [0, 65536] | 选填 | 12686 | -| sink.opcua.https.port | OPC UA 的 HTTPS 端口 | Integer: [0, 65536] | 选填 | 8443 | -| sink.opcua.security.dir | OPC UA 的密钥及证书目录 | String: Path,支持绝对及相对目录 | 选填 | iotdb 相关 DataNode 的 conf 目录下的 opc_security 文件夹 /
如无 iotdb 的 conf 目录(例如 IDEA 中启动 DataNode),则为用户主目录下的 iotdb_opc_security 文件夹 / | -| sink.opcua.enable-anonymous-access | OPC UA 是否允许匿名访问 | Boolean | 选填 | true | -| sink.user | 用户,这里指 OPC UA 的允许用户 | String | 选填 | root | -| sink.password | 密码,这里指 OPC UA 的允许密码 | String | 选填 | TimechoDB@2021 //V2.0.6.x 之前默认密码为root | +| **参数** | **描述** | **​ 取值范围 ​** | **是否必填** | **默认值** | +| ------------------------------------ | -------------------------------- | ---------------------------------- | -------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------| +| sink | OPC UA SINK | String: opc-ua-sink | 必填 | | +| sink.opcua.model | OPC UA 使用的模式 | String: client-server / pub-sub | 选填 | client-server | +| sink.opcua.tcp.port | OPC UA 的 TCP 端口 | Integer: [0, 65536] | 选填 | 12686 | +| sink.opcua.https.port | OPC UA 的 HTTPS 端口 | Integer: [0, 65536] | 选填 | 8443 | +| sink.opcua.security.dir | OPC UA 的密钥及证书目录 | String: Path,支持绝对及相对目录 | 选填 | 1. iotdb 相关 DataNode 的 conf 目录下的 opc\_security 文件夹 / ``。2. 如无 iotdb 的 conf 目录(例如 IDEA 中启动 DataNode),则为用户主目录下的 iotdb\_opc\_security 文件夹 /``| +| sink.opcua.enable-anonymous-access | OPC UA 是否允许匿名访问 | Boolean | 选填 | true | +| sink.user | 用户,这里指 OPC UA 的允许用户 | String | 选填 | root | +| sink.password | 密码,这里指 OPC UA 的允许密码 | String | 选填 | TimechoDB@2021 (V2.0.6.x 之前默认密码为root ) | ### 2.3 示例 @@ -100,36 +66,30 @@ create pipe p1 create pipe p1 with sink ('sink' = 'opc-ua-sink', 'sink.user' = 'root', - 'sink.password' = 'TimechoDB@2021'); //V2.0.6.x 之前默认密码为root + 'sink.password' = 'TimechoDB@2021');//V2.0.6.x 之前默认密码为root start pipe p1; ``` ### 2.4 使用限制 +1. 启动协议之后需要写入数据,才能建立连接,且仅能订阅建立连接之后的数据。 +2. 推荐在单机模式下使用。在分布式模式下,每一个 IoTDB DataNode 都作为一个独立的 OPC Server 提供数据,需要单独订阅。 -1. **必须存在 DataRegion**:在 IoTDB 有 dataRegion 时,OPC UA 的服务器才会启动。因此,对于一个空的 IoTDB,需要写入一条数据,OPC UA 的服务器才有效。 -2. **需连接才有数据**:每一个订阅该服务器的客户端,不会收到 OPC Server 在连接之前写入IoTDB的数据。 - -3. **多 DataNode 会有分散发送 / 冲突问题**: - - - 对于有多个 dataRegion,且分散在不同 DataNode ip上的 IoTDB 集群,数据会在 dataRegion 的 leader 上分散发送。客户端需要对 DataNode ip 的配置端口分别监听。 - - - 建议在 1C1D 下使用该 OPC UA 服务器。 - -4. **不支持删除数据和修改测点类型:**在Client Server模式下,OPC UA无法删除数据或者改变数据类型的设置。而在Pub Sub模式下,如果数据被删除了,信息是无法推送给客户端的。 - -## 3. IoTDB OPC Server 示例 - +## 3. 两种通信模式示例 ### 3.1 Client / Server 模式 -#### 准备工作 +在这种模式下,IoTDB 的流处理引擎通过 OPC UA Sink 与 OPC UA 服务器(Server)建立连接。OPC UA 服务器在其地址空间(Address Space) 中维护数据,IoTDB可以请求并获取这些数据。同时,其他OPC UA客户端(Client)也能访问服务器上的数据。 -1. 此处以UAExpert客户端为例,下载 UAExpert 客户端:https://www.unified-automation.com/downloads/opc-ua-clients.html +* 特性: + * OPC UA 将从 Sink 收到的设备信息,按照树形模型整理到 Objects folder 下的文件夹中。 + * 每个测点都被记录为一个变量节点,并记录当前数据库中的最新值。 + * OPC UA 无法删除数据或者改变数据类型的设置 +#### 3.1.1 准备工作 +1. 此处以UAExpert客户端为例,下载 UAExpert 客户端:https://www.unified-automation.com/downloads/opc-ua-clients.html 2. 安装 UAExpert,填写自身的证书等信息。 -#### 快速开始 - -1. 使用如下 sql,创建并启动 client-server 模式的 OPC UA Sink。详细语法参见上文:[IoTDB OPC Server语法](#语法) +#### 3.1.2 快速开始 +1. 使用如下 sql,启动 OPC UA 服务。详细语法参见上文:[IoTDB OPC Server语法](./Programming-OPC-UA_timecho.md#_2-1-语法) ```SQL create pipe p1 with sink ('sink'='opc-ua-sink'); @@ -141,9 +101,7 @@ create pipe p1 with sink ('sink'='opc-ua-sink'); insert into root.test.db(time, s2) values(now(), 2) ``` -​ 此处自动创建元数据开启。 - -3. 在 UAExpert 中配置 iotdb 的连接,其中 password 填写为上述参数配置中 sink.password 中设定的密码(此处以密码root为例): +3. 在 UAExpert 中配置 iotdb 的连接,其中 password 填写为上述参数配置中 sink.password 中设定的密码(此处用户名、密码以2.3小节示例中配置的 root/root 为例):
@@ -171,9 +129,26 @@ insert into root.test.db(time, s2) values(now(), 2) ### 3.2 Pub / Sub 模式 -#### 准备工作 +在这种模式下,IoTDB的流处理引擎通过 OPC UA Sink 向OPC UA 服务器(Server)发送数据变更事件。这些事件被发布到服务器的消息队列中,并通过事件节点 (Event Node) 进行管理。其他OPC UA客户端(Client)可以订阅这些事件节点,以便在数据变更时接收通知。 + +* 特性: + * 每个测点会被 OPC UA 包装成一个事件节点(EventNode)。 + * 相关字段及其对应含义如下: + + | 字段 | 含义 | 类型(Milo) | 示例 | + | ------------ | ------------------ | --------------- | ----------------------- | + | Time | 时间戳 | DateTime | 1698907326198 | + | SourceName | 测点对应完整路径 | String | root.test.opc.sensor0 | + | SourceNode | 测点数据类型 | NodeId | Int32 | + | Message | 数据 | LocalizedText | 3.0 | + + - Event 仅会发送给所有已经监听的客户端,客户端未连接则会忽略该 Event。 + - 如果数据被删除,信息则无法推送给客户端。 + + +#### 3.2.1 准备工作 -该代码位于 iotdb-example 包下的 [opc-ua-sink 文件夹](https://github.com/apache/iotdb/tree/rc/2.0.1/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua)中 +该代码位于 iotdb-example 包下的 [opc-ua-sink 文件夹](https://github.com/apache/iotdb/tree/master/example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua)中 代码中包含: @@ -182,7 +157,7 @@ insert into root.test.db(time, s2) values(now(), 2) - Client 的配置及启动逻辑(ClientExampleRunner) - ClientTest 的父类(ClientExample) -### 3.3 快速开始 +#### 3.2.2 快速开始 使用步骤为: @@ -194,11 +169,10 @@ insert into root.a.b(time, c, d) values(now(), 1, 2); ​ 此处自动创建元数据开启。 -2. 使用如下 sql,创建并启动 Pub-Sub 模式的 OPC UA Sink。详细语法参见上文:[IoTDB OPC Server语法](#语法) +2. 使用如下 sql,创建并启动 Pub-Sub 模式的 OPC UA Sink。详细语法参见上文:[IoTDB OPC Server语法](./Programming-OPC-UA_timecho.md#_2-1-语法) ```SQL -create pipe p1 with sink ('sink'='opc-ua-sink', - 'sink.opcua.model'='pub-sub'); +create pipe p1 with sink ('sink'='opc-ua-sink', 'sink.opcua.model'='pub-sub'); start pipe p1; ```