Skip to content

Commit fb4618e

Browse files
committed
PlcTagDTL: Change Value from byte-array to DateTime plus Nanosecond field
1 parent 8ea8087 commit fb4618e

File tree

1 file changed

+72
-21
lines changed

1 file changed

+72
-21
lines changed

src/S7CommPlusDriver/ClientApi/PlcTag.cs

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)