opc

package module
v0.3.2-0...-95e55d2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2020 License: MIT Imports: 10 Imported by: 0

README

OPC DA in Go

License GoDoc goreportcard

Read and write process and automation data in Go from an OPC server for monitoring and data analysis purposes (OPC DA protocol).

go get github.com/konimarti/opc

Usage

client, _ := opc.NewConnection(
	"Graybox.Simulator", 		// ProgId
	[]string{"localhost"}, 		// Nodes
	[]string{"numeric.sin.float"}, 	// Tags
)
defer client.Close()
client.ReadItem("numeric.sin.float")
browser, _ := opc.CreateBrowser(
	"Graybox.Simulator", 		// ProgId
	[]string{"localhost"}, 		// Nodes	
)
opc.PrettyPrint(browser)

Installation

  • go get github.com/konimarti/opc
Troubleshooting
  • OPC DA Automation Wrapper 2.02 should be installed on your system (OPCDAAuto.dll or gbda_aut.dll); the automation wrapper is usually shipped as part of the OPC Core Components of your OPC Server.
  • You can get the Graybox DA Automation Wrapper here. Follow the installation instruction for this wrapper.
  • Depending on whether your OPC server and automation wrapper are 32-bit or 64-bit, set the Go architecture correspondingly:
    • For 64-bit OPC servers and wrappers: DLL should be in C:\Windows\System32, use $ENV:GOARCH="amd64"
    • For 32-bit OPC servers and wrappers: DLL should be in C:\Windows\SysWOW64, use $ENV:GOARCH="386"
  • Make sure to have correct DCOM settings on your local and remote computers: Dcomcnfg.exe
Reporting Issues
  • If you find a bug in the code, please create an issue and suggest a solution how to fix it.
  • Issues that are related to connection problems are mostly because of a faulty installation of your OPC automation wrapper or some peculiarties of your specific setup and OPC installation. Since we cannot debug your specific situation, these issues will be directly closed.
Debugging
  • Add opc.Debug() before the opc.NewConnection call to print more debug-related information.
Testing
  • Start Graybox Simulator v1.8. This is a free OPC simulation server and require for testing this package. It can be downloaded here.
  • If you use the Graybox Simulator, set $GOARCH environment variable to "386", i.e. enter $ENV:GOARCH=386 in Powershell.
  • Test code with go test -v

Example

package main

import (
	"fmt"
	"github.com/konimarti/opc"
)

func main() {
	client, _ := opc.NewConnection(
		"Graybox.Simulator", // ProgId
		[]string{"localhost"}, //  OPC servers nodes
		[]string{"numeric.sin.int64", "numeric.saw.float"}, // slice of OPC tags
	)
	defer client.Close()

	// read single tag: value, quality, timestamp
	fmt.Println(client.ReadItem("numeric.sin.int64"))

	// read all added tags
	fmt.Println(client.Read())
}

with the following output:

{91 192 2019-06-21 15:23:08 +0000 UTC}
map[numeric.sin.int64:{91 192 2019-06-21 15:23:08 +0000 UTC} numeric.saw.float:{-36.42 192 2019-06-21 15:23:08 +0000 UTC
}]

Applications

opc-cli
  • opc-cli is a command-line interface to work with OPC servers: list available OPC servers, browse OPC tags on server, and read/write OPC tags.

  • Install it with go install github.com/konimarti/opc/cmds/opc-cli

    • List OPC servers on a specific node:

      $ opc-cli.exe list localhost
      Found 3 server(s) on 'localhost':
      Graybox.Simulator.1
      INAT TcpIpH1 OPC Server
      Prosys.OPC.Simulation
      
    • Browse OPC tags (in sub-branch):

      $ opc-cli.exe browse localhost Graybox.Simulator.1 textual
      textual
         - textual.color
         - textual.number
         - textual.random
         - textual.weekday
      
    • Write to OPC tag:

      $ opc-cli.exe write localhost Graybox.Simulator.1 options.sinfreq 0.01
      
    • Read OPC tags:

      $ opc-cli.exe read localhost Graybox.Simulator.1 options.sinfreq numeric.sin.float
      map[options.sinfreq:{0.05 192 2019-06-21 15:26:02 +0000 UTC} numeric.sin.float:{22.916641 192 2019-06-21 15:26:02 +0000 UTC}]
      
OPCAPI
  • Application to expose OPC tags with a JSON REST API.

    • Install the app: go install github.com/konimarti/opc/cmds/opcapi

    • Create config file:

      [config]
      allow_write = false
      allow_add = true
      allow_remove = true
      
      [opc]
      server = "Graybox.Simulator"
      nodes = [ "localhost" ]
      tags = [ "numeric.sin.float", "numeric.saw.float" ]
      
      
    • Run app:

      $ opcapi.exe -conf api.conf -addr ":4444"
      
    • Access API:

      • Get tags:
        $ curl.exe -X GET localhost:4444/tags
        {"numeric.saw.float":-21.41,"numeric.sin.float":62.303356}
        
      • Add tag:
        $ curl.exe -X POST -d '["numeric.triangle.float"]' localhost:4444/tag
        {"result": "created"}
        
      • Remove tag:
        $ curl.exe -X DELETE localhost:4444/tag/numeric.triangle.float
        {"result": "removed"}
        
OPCFLUX
  • Application to write OPC data directly to InfluxDB.

    • Install the app: go install github.com/konimarti/opc/cmds/opcflux

    • Create InfluxDB database "test"

    • Create config file: Put OPC tags in []. This is required for the expression evaluation. Any calculation can be performed that can evaluated.

      ---
      server: "Graybox.Simulator"
      nodes: ["localhost", "127.0.0.1"]
      monitoring: ""
      influx:
       addr: "http://localhost:8086"
       database: test
       precision: s
      measurements: 
       numeric:
         - tags: {type: sin}
           fields: {float: "[numeric.sin.float]", int: "[numeric.sin.int32]"}
         - tags: {type: saw}
           fields: {float: "[numeric.saw.float]", int: "[numeric.saw.int32]"}
         - tags: {type: calculation}
           fields: {float: "[numeric.triangle.float] / [numeric.triangle.int32]"}
       textual:
         - tags: {type: color}
           fields: {text: "[textual.color]", brown: "[textual.color] == 'Brown'"}        
         - tags: {type: weekday}
           fields: {text: "[textual.weekday]"}        
      
    • Run app: opcflux.exe -conf influx.yml -rate 1s

Credits

This software package has been developed for and is in production at Kalkfabrik Netstal.

Documentation

Index

Constants

View Source
const (
	//OPCDataSource defines constants for Sources when reading data from OPC:
	//Default implementation is OPCCache.
	//From the cache
	OPCCache int32 = 1
	//From the device
	OPCDevice int32 = 2

	//OPCQuality defines the quality of the OPC items:
	//Bad
	OPCQualityBad int16 = 0
	//Good
	OPCQualityGood          int16 = 192
	OPCQualityGoodButForced int16 = 216
	//Maks
	OPCQualityMask int16 = 192
	//Uncertain
	OPCQualityUncertain int16 = 64

	//OPCServerState defines the state of the server:
	//Disconnected
	OPCDisconnected int32 = 6
	//Failed
	OPCFailed int32 = 2
	//Noconfig
	OPCNoconfig int32 = 3
	//Running
	OPCRunning int32 = 1
	//Suspended
	OPCSuspended int32 = 4
	//Test
	OPCTest int32 = 5
)

Variables

This section is empty.

Functions

func CollectTags

func CollectTags(tree *Tree) []string

CollectTags traverses tree and collects all tags in string slice

func Debug

func Debug()

Debug will set the logger to print to stderr

func PrettyPrint

func PrettyPrint(tree *Tree)

PrettyPrint prints tree in a nice format

func SetLogWriter

func SetLogWriter(w io.Writer)

SetLogWriter sets a user-defined writer for logger

func StartMonitoring

func StartMonitoring(port string)

StartMonitoring exposes /metrics to Prometheus

Types

type Collector

type Collector interface {
	Get(string) (interface{}, bool)
	Sync(Connection, time.Duration) io.Closer
}

Collector interface

func NewDataModel

func NewDataModel() Collector

NewDataModel returns an OPC Data struct.

type Connection

type Connection interface {
	Add(...string) int
	Remove(string)
	Read() map[string]Item
	ReadItem(string) Item
	Tags() []string
	Write(string, interface{}) error
	Close()
}

Connection represents the interface for the connection to the OPC server.

type Item

type Item struct {
	Value     interface{}
	Quality   int16
	Timestamp time.Time
}

Item stores the result of an OPC item from the OPC server.

func (*Item) Good

func (i *Item) Good() bool

Good checks the quality of the Item

type Leaf

type Leaf struct {
	Name string
	Tag  string
}

Leaf contains the OPC tag and forms part of the Tree struct for the OPC browser

type Tree

type Tree struct {
	Name     string
	Parent   *Tree
	Branches []*Tree
	Leaves   []Leaf
}

Tree creates an OPC browser representation

func ExtractBranchByName

func ExtractBranchByName(tree *Tree, name string) *Tree

ExtractBranchByName return substree with name

Directories

Path Synopsis
cmds

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL