Skip to content

duduyoyo/WebSocket4OPC

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WebSocket4OPC

Enable WebSocket in OPC DA/AE/HDA Server with JSON response - the FIRST TIME ever!

COM/DCOM was developed over two decades ago and served as the foundation for classic OPC servers. However, modern developers increasingly favor dynamic languages like Python and JavaScript for their simplicity and productivity, as opposed to the steep learning curve of COM/DCOM programming. Fortunately, with the widespread adoption of WebSocket across modern programming languages, it's now possible to bridge the gap between dynamic languages and legacy COM/DCOM technologies.

This innovative solution offers the best of all worlds by combining the strengths of its technology stack:

1. WebSocket — a standardized network protocol enabling cross-platform, full-duplex communication
2. Microsoft IIS — providing robust support for authorization, authentication, firewalls, certificates, and encryption
3. Classic OPC Servers — the most widely adopted standard in the industrial automation sector

Without the complexity, rigidity, and overhead of OPC UA, plant data can be delivered easily, securely, and reliably with this solution — whether on a desktop or mobile device.

Say goodbye to COM/DCOM — and Hello to the world's only all-in-one solution for accessing OPC DA/AE/HDA Data in your preferred language!

Benefits

.Fully support Python/JavaScript/Java/C#/C++/Swift etc — No OPC UA, No SDKs, No Hassles
.No COM/DCOM vulnerabilities or hardening concerns
.Built-in user authentication and authorization via IIS
.Secure connections with certificate-based HTTPS provided by IIS
.Data encryption handled by IIS for secure transmission
.Guaranteed cross-platform client support (Linux, Mac, Windows)
.No costly OPC corporate membership fees
.Simple, intuitive commands — no need for long REST API URLs
.Native mobile app development fully supported
.No need to read through 1,250 pages of OPC UA documentation
.No OPC UA certificate setup required
.No OPC UA firewall configuration needed
.No need to convert OPC DA to OPC UA, purely plant data delivered
.Remote host supported for Windows XP/7 (server 2003/2008) when WebSocket feature isn't available
.Ready for edge or gateway deployment - locally or remotely, no expensive custom hardware needed

Pre-requiste

1. It is strongly recommended to install the application on the same server where the classic OPC DA/AE/HDA server is running. If this is not feasible, the application can be installed on any compatible Windows machine with remote access to the OPC server. In such cases, a host entry must be configured in the configuration file located in the ProgramData folder. Take a reference here
2. Microsoft VC++ Runtim for X64 is required (download and install it here if not already present)
3. Ensure the WebSocket feature is enabled in IIS on the same server

Installation

Download all files from the server folder to your desired location. Open a command prompt with administrator privileges and navigate to your download folder. Run the command:

install.bat userAccount userPassword

Replace userAccount and userPassword with your own Windows credentials, ensuring the account has administrator privileges. These credentials are used only by IIS to configure a new application pool — they are neither stored nor used by this solution for any other purpose.

To verify the installation, open a browser (Chrome, Safari, or Edge) and navigate to the following URL: "http://localhost/OPC/websocket.html"

If installed in a multi-server environment, a configuration file located in the ProgramData folder allows you to specify the desired server using its ProgID.

Uninstallation

Run the uninstall.bat command in a Command Prompt with administrator privileges from your download folder.

Usage

  1. DA commands

    1.1 Browse

    "browse" - Display all child tags at the top level of the DA server

    "browse:tagID" - Display all child tags under a specific tag of the DA server

    "browse:tagID -countsInPagenation -pageNumber" - Display a paginated subset of child tags under a specific tag in the DA server. For example, if there are 10,000 child tags under a specific tag, the command "browse: tagID -2000 -3" will display only 2,000 child tags (from the 4,000th to the 5,999th) corresponding to page 3 in the DA server

    JSON returns {"parentNodeID":[{"n": "tagName1", "i": "tagID1", "b": 1}, {"n": "tagName2", "i": "tagID2", "b": 0}, ...]}
    (parentNodeID - parent node id or "" at top level, n - name, i - ID, b - branch)

    When command "browse: Random" is sent, response will be like

    1.2 Read

    "read: tagID1, tagID2, ..."- Read the latest values of tags from the DA server

    JSON returns {"DA":[{"i": "tagID1", "v": "20.308", "t": 1643759756112, "q": 192}, {"i": "tagID2", "v": "4", "t": 1643769859342, "q": 192}, ...]}
    (i - ID, v - value, t - time stamp in milliseconds of epoch UTC, q - quality)

    When command "read: Random.Real4, Random.Int2" is sent, response will be like

    1.3 Write

    "write: tagID1 -value1; tagID2 -value2; ..." - Write tag values to the DA server. It is strongly recommended not to use this command in a production environment with Internet access. Please contact the developer to obtain a production version without this command.

    No JSON return but writing status (success/failure) will be reported as info. Use read command to verify writing's success

    When command "write: Bucket Brigade.Int2 -34; Random.Int2 -12" is sent, response will be like

    1.4 Subscribe

    "subscribe: tagID1, tagID2, ..." - Add tags to be monitored on the DA server and receive updates whenever new values are available

    JSON returns {"DA":[{"i": "tagID1", "v": "20.308", "t": 1643759756112, "q": 192}, {"i": "tagID2", "v": "4", "t": 1643769859342, "q": 192}, ...]}
    (i - ID, v - value, t - time stamp in milliseconds of epoch UTC, q - quality)

    When command "subscribe:Saw-toothed Waves.Int1,Saw-toothed Waves.Int2" is sent, response will be like

    1.5 Unsubscribe

    "unsubscribe" - Remove all monitored tags from the DA server

    "unsubscribe: tagID1, tagID2, ..." - Remove the specific monitored tags from the DA server

  2. HDA commands

    2.1 Browse

    "browseHDA" - Display all child tags at the top level of the HDA server

    "browseHDA:tagID" - Display all child tags under a specific tag in the HDA server

    "browseHDA:tagID -countsInPagenation -pageNumber" - Display a paginated subset of child tags for a specific tag in the HDA server. For example, if there are a total of 10,000 child tags under a specific tag, the command "browseHDA: tagID -2000 -3" will display 2,000 child tags (from the 4,000th to the 5,999th) corresponding to the 3rd page in the HDA server.

JSON returns {"parentNodeID":[{"n": "tagName1", "i": "tagID1", "b": 1}, {"n": "tagName2", "i": "tagID2", "b": 0}, ...]}
(parentNodeID - parent node id or "" at top level, n - name, i - ID, b - branch)

When command "browseHDA: Random" is sent, response will be like

2.2 ReadRaw

"readRaw: tagID1, tagID2,..., tagIDx -startTimeStamp -endTimeStamp" - Read historical raw data of tags based on specified start and end timestamps

JSON returns {"HDA":[{"tagID1":[{"v":"24201","t":1665632091123,"q":262336}, {"v":"19168","t":1665632092334,"q":262336},...]}, {"tagID2":[{"v":"24","t":1665632091445,"q":262336}, {"v":"168","t":1665632092667,"q":262336},...]}]}
(v - value, t - time stamp in milliseconds of epoch UTC, q - quality which need be parsed with OPC HDA and DA masks to have results like Raw/Interpolated and Good/Bad)

When command "readRaw: Saw-toothed Waves.Int1,Saw-toothed Waves.Int2 -1672977528112 -1672977529338" is sent, response will be like

2.3 ReadAtTime

"readAtTime: tagID1, tagID2, ..., tagIDx -timeStamp1 -timsStamp2 -timeStampX" - Read historical tags' values based on various timestamps

JSON returns {"HDA":[{"tagID1":[{"v":"24201","t":1665632091231,"q":262336}, {"v":"19168","t":1665632092354,"q":262336},...]}, {"tagID2":[{"v":"24","t":1665632091341,"q":262336}, {"v":"168","t":1665632092321,"q":262336},...]}]}
(v - value, t - time stamp in milliseconds of epoch UTC, q - quality which need be parsed with OPC HDA and DA masks to have results like Raw/Interpolated and Good/Bad)

When command "readAtTime: Saw-toothed Waves.Int1,Saw-toothed Waves.Int2 -1672978265112 -1672978266338" is sent, response will be like

2.4 ReadModified

"readModified: tagID1, tagID2,..., tagIDx -startTimeStamp -endTimeStamp" - Read tags' modified historical values based on specified start and end timestamps

JSON returns {"HDA":[{"tagID1":[{"v":"24201","t":1665632091231,"q":262336}, {"v":"19168","t":1665632092354,"q":262336},...]}, {"tagID2":[{"v":"24","t":1665632091341,"q":262336}, {"v":"168","t":1665632092321,"q":262336},...]}]}
(v - value, t - time stamp in milliseconds of epoch UTC, q - quality which need be parsed with OPC HDA and DA masks to have results like Raw/Interpolated and Good/Bad)

2.5 ReadProcessed

"readProcessed: tagID1, tagID2,..., tagIDx -startTimeStamp -endTimeStamp -intervalInMilliseconds -aggregate" - Read tags' processed historical values based on specified start and end timestamps, using a defined interval and one of the aggregate methods listed below (vendor-specific methods not included)

JSON returns {"HDA":[{"tagID1":[{"v":"24201","t":1665632091231,"q":262336}, {"v":"19168","t":1665632092354,"q":262336},...]}, {"tagID2":[{"v":"24","t":1665632091341,"q":262336}, {"v":"168","t":1665632092321,"q":262336},...]}]}
(v - value, t - time stamp in milliseconds of epoch UTC, q - quality which need be parsed with OPC HDA and DA masks to have results like Raw/Interpolated and Good/Bad)

When command "readProcessed: random.Int1,random.Int4 -1705350325000 -1705350425000 -5000 -10" is sent, response will be like

2.6 InsertReplace<p>

"insertReplace: tagID1 -value -timeStamp -quality;tagID2 -value -timeStamp -quality;..." - Insert or replace tag historical data and quality values at specific timestamps (in epoch milliseconds)

No JSON returns except an operation status message

When command "insertReplace: Bucket Brigade.Int1 -234 -1710719956000 -192; Bucket Brigade.Int4 -567 -1710720852000 -192" is sent, response will be like

2.7 DeleteAtTime

"deleteAtTime: tagID1, tagID2,..., tagIDX -timeStamp1 -timeStamp2 ... -timeStampX" - Delete tags' historical values based on specified timestamps (in epoch milliseconds)

No JSON returns except an operation status message

When command "deleteAtTime: Write Error.Int1, Bucket Brigade.Int1 -1713118247000 -1713116556000" is sent, response will be like

  1. AE commands

    3.1 Subscribe

    "subscribeAE" - Receive notifications for alarms and events

    JSON returns {"AE":[{"s":"tagName1","m":"tagName1 Deviation is Low","c":"DEVIATION","sc":"LO","t":1643760803334,"q":192,"tp":4,"ec":2,"st":200,"a":1,"at":""}, {"s":"tagName2","m":"tagName2 Limit is Normal","c":"PVLEVEL","sc":"HIHI","t":1643760808112,"q":192,"tp":4,"ec":1,"st":500,"a":1,"at":""}]}
    (s - source, m - message, c - condition, sc - sub condition, t - time stamp in milliseconds of epoch UTC, q - quality, tp - type, ec - category, st - severity, a - acknowledgement, at - actor)

    When command "subscribeAE" is sent, response will be like

    3.2 Unsubscribe

    "unsubscribeAE" - Remove notifications for alarms and events

  2. Disconnect

    "disconnect" - Close the connection to the server

  3. Help

    "help" or "?" - Display all supported commands and their usage

Sample code output

Sample code for various languages (Python, Swift, C#, C++, Java) is available in the client folder

Python

Swift

RecordIt-C32C9C56-5A8F-4BDE-B100-E520E731FCEC.mp4

C#

C++

Java

Roadmap

- Full-fledged open source native client for iOS and partners/contributors are welcome

Service

- Consultation available for any edge design involving connections to OPC Classic servers
- Customization available upon request

Related contribution

OLEDB4OPC, the fastest way to transfer OPC data to database!

WebSocket4Fragment, a unique way to handle WebSocket fragment explicitly in run time!

About

Liberate and access plant data anywhere, any way!

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published