@@ -1629,18 +1629,54 @@ public override string ToString()
16291629
16301630 public class PlcTagDTL : PlcTag
16311631 {
1632- // TODO: Unify all date / time datatypes
1633- private byte [ ] m_Value ;
1632+ private DateTime m_Value ;
1633+ private uint m_ValueNanosecond ;
16341634
1635- public byte [ ] Value
1635+ public DateTime Value
16361636 {
1637- get { return m_Value ; }
1638- set { m_Value = value ; }
1637+ get
1638+ {
1639+ return m_Value ;
1640+ }
1641+
1642+ set
1643+ {
1644+ if ( value >= new DateTime ( 1970 , 1 , 1 ) && value <= new DateTime ( 2262 , 4 , 11 , 23 , 47 , 16 ) )
1645+ {
1646+ m_Value = value ;
1647+ }
1648+ else
1649+ {
1650+ throw new ArgumentOutOfRangeException ( "Value" , "DateTime must be >= 1970-01-01 and <= 2262-04-11 23:47:16" ) ;
1651+ }
1652+ }
16391653 }
16401654
1655+ public uint ValueNanosecond
1656+ {
1657+ get
1658+ {
1659+ return m_ValueNanosecond ;
1660+ }
1661+
1662+ set
1663+ {
1664+ if ( value <= 999999999 )
1665+ {
1666+ m_ValueNanosecond = value ;
1667+ }
1668+ else
1669+ {
1670+ throw new ArgumentOutOfRangeException ( "Value" , "Nanosecond must be <= 999999999" ) ;
1671+ }
1672+ }
1673+ }
1674+
1675+ public UInt64 DTLInterfaceTimestamp = 0x10ff4ad6dfd5774c ; // Oct 23, 2008 16:38:30.406829900 UTC. Should be used from first browse method (or read) and set correctly
1676+
16411677 public PlcTagDTL ( string name , ItemAddress address , uint softdatatype ) : base ( name , address , softdatatype )
16421678 {
1643- m_Value = new byte [ 12 ] ;
1679+ Value = new DateTime ( 1970 , 1 , 1 ) ;
16441680 }
16451681
16461682 public override void ProcessReadResult ( object valueObj , ulong error )
@@ -1661,12 +1697,19 @@ public override void ProcessReadResult(object valueObj, ulong error)
16611697 // 6: MINUTE, USInt
16621698 // 7: SECOND, USInt
16631699 // 8, 9, 10, 11: NANOSECOND, UDInt
1664- if ( struct_val . GetValue ( ) == 33554499 )
1700+
1701+ // Use the default timestamp, or refresh it from browsing the plc, or from reading dtl first
1702+ DTLInterfaceTimestamp = struct_val . PackedStructInterfaceTimestamp ;
1703+
1704+ if ( struct_val . GetValue ( ) == 0x02000043 )
16651705 {
1666- var elem = struct_val . GetStructElement ( 33554499 ) ;
1706+ var elem = struct_val . GetStructElement ( 0x02000043 ) ;
16671707 if ( elem . GetType ( ) == typeof ( ValueByteArray ) )
16681708 {
1669- Value = ( ( ValueByteArray ) elem ) . GetValue ( ) ;
1709+ var barr = ( ( ValueByteArray ) elem ) . GetValue ( ) ;
1710+ int year = ( int ) barr [ 0 ] * 256 + ( int ) barr [ 1 ] ;
1711+ ValueNanosecond = ( uint ) barr [ 8 ] * 16777216 + ( uint ) barr [ 9 ] * 65536 + ( uint ) barr [ 10 ] * 256 + ( uint ) barr [ 11 ] ;
1712+ Value = new DateTime ( year , barr [ 2 ] , barr [ 3 ] , barr [ 5 ] , barr [ 6 ] , barr [ 7 ] ) ;
16701713 Quality = PlcTagQC . TAG_QUALITY_GOOD ;
16711714 }
16721715 else
@@ -1687,21 +1730,29 @@ public override void ProcessReadResult(object valueObj, ulong error)
16871730
16881731 public override PValue GetWriteValue ( )
16891732 {
1690- // TODO! This won't work, because ValueStruct can't handle to serialize a packed struct
1691- //var struct_val = new ValueStruct(33554499);
1692- //struct_val.AddStructElement(33554499, new ValueByteArray(Value));
1693- //return struct_val;
1694- return null ;
1733+ var struct_val = new ValueStruct ( 0x02000043 ) ; // 0x02000043 = TI_LIB.SimpleType.67 -> DTL Systemdatatype
1734+ struct_val . PackedStructInterfaceTimestamp = DTLInterfaceTimestamp ;
1735+ var barr = new byte [ 12 ] ;
1736+ barr [ 0 ] = ( byte ) ( Value . Year >> 8 ) ;
1737+ barr [ 1 ] = ( byte ) Value . Year ;
1738+ barr [ 2 ] = ( byte ) Value . Month ;
1739+ barr [ 3 ] = ( byte ) Value . Day ;
1740+ barr [ 4 ] = 0 ; // Weekday, don't set
1741+ barr [ 5 ] = ( byte ) Value . Hour ;
1742+ barr [ 6 ] = ( byte ) Value . Minute ;
1743+ barr [ 7 ] = ( byte ) Value . Second ;
1744+ barr [ 8 ] = ( byte ) ( ValueNanosecond >> 24 ) ;
1745+ barr [ 9 ] = ( byte ) ( ValueNanosecond >> 16 ) ;
1746+ barr [ 10 ] = ( byte ) ( ValueNanosecond >> 8 ) ;
1747+ barr [ 11 ] = ( byte ) ( ValueNanosecond ) ;
1748+ struct_val . AddStructElement ( 0x02000043 , new ValueByteArray ( barr ) ) ;
1749+ return struct_val ;
16951750 }
16961751
16971752 public override string ToString ( )
16981753 {
16991754 string fmt ;
1700- int year = ( int ) Value [ 0 ] * 256 + ( int ) Value [ 1 ] ;
1701- uint ns = ( uint ) Value [ 8 ] * 16777216 + ( uint ) Value [ 9 ] * 65536 + ( uint ) Value [ 10 ] * 256 + ( uint ) Value [ 11 ] ;
1702-
1703- DateTime dt = new DateTime ( year , Value [ 2 ] , Value [ 3 ] , Value [ 5 ] , Value [ 6 ] , Value [ 7 ] ) ;
1704-
1755+ uint ns = ValueNanosecond ;
17051756 if ( ( ns % 1000 ) > 0 )
17061757 {
17071758 fmt = "{0}.{1:D09}" ;
@@ -1718,9 +1769,9 @@ public override string ToString()
17181769 }
17191770 else
17201771 {
1721- return dt . ToString ( ) ;
1772+ return Value . ToString ( ) ;
17221773 }
1723- return String . Format ( fmt , dt . ToString ( ) , ns ) ;
1774+ return String . Format ( fmt , Value . ToString ( ) , ns ) ;
17241775 }
17251776 }
17261777}
0 commit comments