konimarti / opc

OPC DA client in Golang for monitoring and analyzing process data based on Windows COM.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issues with read-write synchronization and event notification

GhostCakeMaker opened this issue · comments

I have some questions, as follows:

  1. It seems that the Read and Write methods you provided are not synchronized. I have done some tests.
    image

  2. And you don't seem to have provided the DataChanged event.

@GhostCakeMaker thanks for your feedback.

Regarding your first issue, please provide some more data and information. Did you double-check that the OPC tag you want to write to allows a write operation? The following example with the Graybox OPC server demonstrates the read/write methods:

package main

import (
	"fmt"

	"github.com/konimarti/opc"
)

func main() {
	client, err := opc.NewConnection(
		"Graybox.Simulator",
		[]string{"localhost"},
		[]string{"storage.numeric.reg01"},
	)
	defer client.Close()

	if err != nil {
		panic(err)
	}

	// read reg01
	fmt.Println(client.ReadItem("storage.numeric.reg01"))

	// write to reg01
	fmt.Println(client.Write("storage.numeric.reg01", 66666))

	// read reg01 again
	fmt.Println(client.ReadItem("storage.numeric.reg01"))
}

And it produceds the following, correct output (manually initialized to 77777):

{77777 216 2019-12-20 08:58:36 +0000 UTC}
<nil>
{66666 216 2019-12-20 08:58:44 +0000 UTC}

Regarding your second point, if you would like to add this feature, please feel free to send me your pull request.

package main
/*
*OPC DA操作库: github.com/konimarti/opc
*测试发现,读写都是异步的
*没有实现DataChanged事件
*/
import (
"fmt"
"github.com/konimarti/opc"
)

func main() {
browser, _ := opc.CreateBrowser("Matrikon.OPC.Simulation.1", []string{"localhost"})
fmt.Println(browser.Name)
//opc.PrettyPrint(browser)
client, _ := opc.NewConnection("Matrikon.OPC.Simulation.1", []string{"localhost"}, []string{"Bucket Brigade.GoLang.Name"})
defer func() {
client.Close()
if err := recover(); err != nil {
fmt.Println(err)
}
}()
ReadAllPrint(client)
randInt := "77777"
errMsg := client.Write("Bucket Brigade.GoLang.Name", randInt)
fmt.Println("WRITE value:",randInt,"result:",errMsg)
//time.Sleep(500 * time.Millisecond)
ReadAllPrint(client)
}

func ReadAllPrint(conn opc.Connection) {
itemMap := conn.Read()
for _, v := range itemMap {
fmt.Println("READ value:", v.Value, "quality:", v.Quality, "timestamp:", v.Timestamp, "good:", v.Good())
}
}

I don't have a Matrikon OPC server installed to test it and I don't know how your tag "Bucket Brigade.GoLang.Name" is defined. The best is to test it with the known tags on the Graybox OPC server, so we share the same starting point. Did you try the example from above with Graybox?

For the first question, I used the Gray Opc you provided, which seems to be ok,but good is false.
image
However, the second question, DataChanged event do you provide again?

@GhostCakeMaker thanks for confirming that it works. The OPC quality value of 216 is "good - local override, value forced" according to the standard. I will change the code accordingly, so that it also returns true when Good() is called.
The DataChanged functionality is not implemented; however, if you want to add it, please feel free to do so. I'd appreciate it.