opcua icon indicating copy to clipboard operation
opcua copied to clipboard

Proposal: support additional time encoding formats

Open magiconair opened this issue 2 years ago • 2 comments

Some PLCs do not support encoding timestamps with millisecond precision or higher precision in DateTime variables. The workaround is to either send RFC3339Nano formatted strings or to encode an LTIME in an int64 or uint64.

We could support this in gopcua through struct tags, e.g.

type Data struct {
    T1 time.Time `opcua:"type=int64,format=epoch-ms"`  // int64 with unix epoch ms
    T2 time.Time `opcua:"type=uint64,format=ltime-ns"` // uint64 with LTIME ns
    T2 time.Time `opcua:"type=string,format=2006-01-02T15:04:05.999999999Z07:00"` // string with RFC 3339Nano format
}

We could also auto-detect the type and only specify the format.

type Data struct {
    T1 time.Time `opcua:"format=epoch-ms"` // int64 with unix epoch ms
    T2 time.Time `opcua:"format=ltime-ns"` // uint64 with LTIME ns
    T2 time.Time `opcua:"format=2006-01-02T15:04:05.999999999Z07:00"` // string with RFC 3339Nano format
}

Would this be useful?

magiconair avatar Apr 11 '22 13:04 magiconair

@kung-foo ^^

magiconair avatar Apr 11 '22 13:04 magiconair

where are we using struct tags? Internally at Intelecy are doing something similar. Example (structs defined via protobufs but same output as above):

message KepwareTagProperties {
  string name                     = 1 [(gogoproto.moretags) = "opc-ua:\"_Name\""];
  string address                  = 2 [(gogoproto.moretags) = "opc-ua:\"_Address\""];
  string description              = 3 [(gogoproto.moretags) = "opc-ua:\"_Description\""];
  string raw_data_type            = 4 [(gogoproto.moretags) = "opc-ua:\"_RawDataType\""];
  bool scaling_clamp_high         = 5 [(gogoproto.moretags) = "opc-ua:\"_ScalingClampHigh\""];
  bool scaling_clamp_low          = 6 [(gogoproto.moretags) = "opc-ua:\"_ScalingClampLow\""];
  double scaling_raw_high         = 7 [(gogoproto.moretags) = "opc-ua:\"_ScalingRawHigh\""];
  double scaling_raw_low          = 8 [(gogoproto.moretags) = "opc-ua:\"_ScalingRawLow\""];
  string scaling_scaled_data_type = 9 [(gogoproto.moretags) = "opc-ua:\"_ScalingScaledDataType\""];
  double scaling_scaled_high      = 10 [(gogoproto.moretags) = "opc-ua:\"_ScalingScaledHigh\""];
  double scaling_scaled_low       = 11 [(gogoproto.moretags) = "opc-ua:\"_ScalingScaledLow\""];
  string scaling_type             = 12 [(gogoproto.moretags) = "opc-ua:\"_ScalingType\""];
  string scaling_units            = 13 [(gogoproto.moretags) = "opc-ua:\"_ScalingUnits\""];
}

kung-foo avatar Apr 21 '22 13:04 kung-foo