/LibNoDaveConnectionLibrary/Communication/PLCTag.cs

http://siemensplctoolboxlib.codeplex.com · C# · 1955 lines · 1766 code · 106 blank · 83 comment · 449 complexity · 42a50eec8ae6be44ecb2180cf581f8cc MD5 · raw file

  1. /*
  2. This implements a high level Wrapper between libnodave.dll and applications written
  3. in MS .Net languages.
  4. This ConnectionLibrary was written by Jochen Kuehner
  5. * http://jfk-solutuions.de/
  6. *
  7. * Thanks go to:
  8. * Steffen Krayer -> For his work on MC7 decoding and the Source for his Decoder
  9. * Zottel -> For LibNoDave
  10. WPFToolboxForSiemensPLCs is free software; you can redistribute it and/or modify
  11. it under the terms of the GNU Library General Public License as published by
  12. the Free Software Foundation; either version 2, or (at your option)
  13. any later version.
  14. WPFToolboxForSiemensPLCs is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. GNU General Public License for more details.
  18. You should have received a copy of the GNU Library General Public License
  19. along with Libnodave; see the file COPYING. If not, write to
  20. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22. using System;
  23. using System.Collections;
  24. using System.Collections.Generic;
  25. using System.ComponentModel;
  26. using System.Globalization;
  27. using System.Text;
  28. using System.Text.RegularExpressions;
  29. using System.Xml.Serialization;
  30. using DotNetSiemensPLCToolBoxLibrary.Communication.LibNoDave;
  31. using DotNetSiemensPLCToolBoxLibrary.DataTypes;
  32. using DotNetSiemensPLCToolBoxLibrary.General;
  33. using DotNetSiemensPLCToolBoxLibrary.PLCs.S7_xxx.MC7;
  34. namespace DotNetSiemensPLCToolBoxLibrary.Communication
  35. {
  36. #if !IPHONE
  37. [System.ComponentModel.Editor(typeof(PLCTagUITypeEditor), typeof(System.Drawing.Design.UITypeEditor))]
  38. #endif
  39. [Serializable]
  40. public class PLCTag: INotifyPropertyChanged
  41. {
  42. internal bool raiseValueChangedEvenWhenNoChangeHappened;
  43. private string _valueName;
  44. /// <summary>
  45. /// This is a Property wich addresses the values you've read with a Name
  46. /// </summary>
  47. public String ValueName
  48. {
  49. get { return _valueName; }
  50. set { _valueName = value;
  51. NotifyPropertyChanged("ValueName");
  52. }
  53. }
  54. private int _byteAddress;
  55. public int ByteAddress
  56. {
  57. get { return _byteAddress; }
  58. set { _byteAddress = value;
  59. NotifyPropertyChanged("ByteAddress"); NotifyPropertyChanged("S7FormatAddress");
  60. }
  61. }
  62. private int _bitAddress;
  63. public int BitAddress
  64. {
  65. get { return _bitAddress; }
  66. set { _bitAddress = value;
  67. _bitAddress = _bitAddress > 7 ? 7 : _bitAddress;
  68. _bitAddress = _bitAddress < 0 ? 0 : _bitAddress;
  69. NotifyPropertyChanged("BitAddress"); NotifyPropertyChanged("S7FormatAddress");
  70. }
  71. }
  72. private bool isSymbolicAccessKeyTag;
  73. public bool IsSymbolicAccessKeyTag
  74. {
  75. get
  76. {
  77. return this.isSymbolicAccessKeyTag;
  78. }
  79. set
  80. {
  81. this.isSymbolicAccessKeyTag = value;
  82. if (!value)
  83. symbolicAccessKey = null;
  84. NotifyPropertyChanged("SymbolicAccessKey");
  85. NotifyPropertyChanged("IsSymbolicAccessKeyTag");
  86. NotifyPropertyChanged("S7FormatAddress");
  87. }
  88. }
  89. private string symbolicAccessKey;
  90. public string SymbolicAccessKey
  91. {
  92. get
  93. {
  94. return this.symbolicAccessKey;
  95. }
  96. set
  97. {
  98. this.symbolicAccessKey = value;
  99. if (!string.IsNullOrEmpty(value))
  100. isSymbolicAccessKeyTag = true;
  101. NotifyPropertyChanged("SymbolicAccessKey");
  102. NotifyPropertyChanged("IsSymbolicAccessKeyTag");
  103. NotifyPropertyChanged("S7FormatAddress");
  104. }
  105. }
  106. //For Tags used with Full Symbolic in TIA Portal
  107. private bool _itemDoesNotExist;
  108. [XmlIgnore]
  109. public virtual bool ItemDoesNotExist
  110. {
  111. get { return _itemDoesNotExist; }
  112. set
  113. {
  114. if (_itemDoesNotExist != value)
  115. {
  116. _itemDoesNotExist = value;
  117. NotifyPropertyChanged("ItemDoesNotExist");
  118. NotifyPropertyChanged("ValueAsString");
  119. }
  120. }
  121. }
  122. public PLCTag()
  123. { }
  124. public PLCTag(PLCTag oldTag)
  125. {
  126. if (oldTag != null)
  127. {
  128. this.TagDataSource = oldTag.TagDataSource;
  129. this.TagDataType = oldTag.TagDataType;
  130. this.ByteAddress = oldTag.ByteAddress;
  131. this.BitAddress = oldTag.BitAddress;
  132. this.ArraySize = oldTag.ArraySize;
  133. this.DataTypeStringFormat = oldTag.DataTypeStringFormat;
  134. this.DataBlockNumber = oldTag.DataBlockNumber;
  135. this.Controlvalue = oldTag.Controlvalue;
  136. this.DontSplitValue = oldTag.DontSplitValue;
  137. }
  138. }
  139. /// <summary>
  140. /// The initalizationString can be a PLC Address like: "DB100.DBW2" or a init String like: "User,DB100.DBW2,Word,Decimal"
  141. /// </summary>
  142. /// <param name="initalizationString"></param>
  143. public PLCTag(string initalizationString)
  144. {
  145. if (initalizationString.Contains(","))
  146. {
  147. string[] values = initalizationString.Split(',');
  148. this.ValueName = values[0];
  149. this.ChangeAddressFromString(values[1]);
  150. if (values.Length > 2) this.ChangeDataTypeFromString(values[2]);
  151. if (values.Length > 3) this.ChangeDataTypeStringFormatFromString(values[3]);
  152. }
  153. else
  154. {
  155. var low = initalizationString.ToLower();
  156. if (low.StartsWith("p#"))
  157. {
  158. if (low.Contains("bool")) this.TagDataType = TagDataType.Bool;
  159. else if (low.Contains("byte")) this.TagDataType = TagDataType.Byte;
  160. else if (low.Contains("dword")) this.TagDataType = TagDataType.Dword;
  161. else if (low.Contains("word")) this.TagDataType = TagDataType.Word;
  162. else if (low.Contains("dint")) this.TagDataType = TagDataType.Dint;
  163. else if (low.Contains("int")) this.TagDataType = TagDataType.Int;
  164. else if (low.Contains("time_of_day")) this.TagDataType = TagDataType.TimeOfDay;
  165. else if (low.Contains("date")) this.TagDataType = TagDataType.Date;
  166. else if (low.Contains("s5time")) this.TagDataType = TagDataType.S5Time;
  167. else if (low.Contains("real")) this.TagDataType = TagDataType.Float;
  168. else if (low.Contains("time")) this.TagDataType = TagDataType.Time;
  169. }
  170. this.ChangeAddressFromString(initalizationString);
  171. }
  172. }
  173. private int _datablockNumber = 1;
  174. public int DataBlockNumber
  175. {
  176. get
  177. {
  178. if (this.TagDataSource == MemoryArea.Datablock || this.TagDataSource == MemoryArea.InstanceDatablock)
  179. return _datablockNumber > 0 ? _datablockNumber : 1;
  180. else
  181. return 0;
  182. }
  183. set { _datablockNumber = value;
  184. NotifyPropertyChanged("DataBlockNumber"); NotifyPropertyChanged("S7FormatAddress");
  185. }
  186. }
  187. private MemoryArea tagDataSource = MemoryArea.Datablock;
  188. public MemoryArea TagDataSource
  189. {
  190. get
  191. {
  192. return this.tagDataSource;
  193. }
  194. set
  195. {
  196. this.tagDataSource = value;
  197. if (value == MemoryArea.Timer || value == MemoryArea.Counter)
  198. if (this.TagDataType != TagDataType.Bool && this.TagDataType != TagDataType.Int && this.TagDataType != TagDataType.Word && this.TagDataType != TagDataType.S5Time && this.TagDataType != TagDataType.BCDWord)
  199. this.tagDataType = value == MemoryArea.Timer ? TagDataType.S5Time : TagDataType.Int;
  200. NotifyPropertyChanged("TagDataSource"); NotifyPropertyChanged("S7FormatAddress");
  201. }
  202. }
  203. private TagDisplayDataType _dataTypeStringFormat = TagDisplayDataType.Bool;
  204. public TagDisplayDataType DataTypeStringFormat
  205. {
  206. get
  207. {
  208. switch (this.TagDataType)
  209. {
  210. case TagDataType.Bool:
  211. if (_dataTypeStringFormat != TagDisplayDataType.Bool && _dataTypeStringFormat != TagDisplayDataType.Binary)
  212. return TagDisplayDataType.Bool;
  213. return _dataTypeStringFormat;
  214. case TagDataType.S5Time:
  215. case TagDataType.Time:
  216. if (_dataTypeStringFormat != TagDisplayDataType.TimeSpan && _dataTypeStringFormat != TagDisplayDataType.S5Time && _dataTypeStringFormat != TagDisplayDataType.Time)
  217. return TagDisplayDataType.TimeSpan;
  218. return _dataTypeStringFormat;
  219. case TagDataType.Date:
  220. if (_dataTypeStringFormat != TagDisplayDataType.DateTime && _dataTypeStringFormat != TagDisplayDataType.S7Date)
  221. return TagDisplayDataType.S7Date;
  222. return _dataTypeStringFormat;
  223. case TagDataType.TimeOfDay:
  224. if (_dataTypeStringFormat != TagDisplayDataType.DateTime && _dataTypeStringFormat != TagDisplayDataType.S7TimeOfDay)
  225. return TagDisplayDataType.S7TimeOfDay;
  226. return _dataTypeStringFormat;
  227. case TagDataType.DateTime:
  228. if (_dataTypeStringFormat != TagDisplayDataType.DateTime && _dataTypeStringFormat != TagDisplayDataType.S7DateTime)
  229. return TagDisplayDataType.DateTime;
  230. return _dataTypeStringFormat;
  231. case TagDataType.String:
  232. case TagDataType.CharArray:
  233. return TagDisplayDataType.String;
  234. case TagDataType.Int:
  235. case TagDataType.Dint:
  236. case TagDataType.Byte:
  237. case TagDataType.SByte:
  238. case TagDataType.Word:
  239. case TagDataType.Dword:
  240. case TagDataType.BCDByte:
  241. case TagDataType.BCDWord:
  242. case TagDataType.BCDDWord:
  243. if (_dataTypeStringFormat != TagDisplayDataType.Decimal && _dataTypeStringFormat != TagDisplayDataType.Hexadecimal && _dataTypeStringFormat != TagDisplayDataType.Float && _dataTypeStringFormat != TagDisplayDataType.Binary && _dataTypeStringFormat != TagDisplayDataType.Pointer && _dataTypeStringFormat != TagDisplayDataType.String)
  244. return TagDisplayDataType.Decimal;
  245. return _dataTypeStringFormat;
  246. case TagDataType.Float:
  247. if (_dataTypeStringFormat != TagDisplayDataType.Decimal && _dataTypeStringFormat != TagDisplayDataType.Hexadecimal && _dataTypeStringFormat != TagDisplayDataType.Float && _dataTypeStringFormat != TagDisplayDataType.Binary)
  248. return TagDisplayDataType.Float;
  249. return _dataTypeStringFormat;
  250. case TagDataType.ByteArray:
  251. return TagDisplayDataType.ByteArray;
  252. }
  253. return TagDisplayDataType.Decimal;
  254. }
  255. set { _dataTypeStringFormat = value; NotifyPropertyChanged("DataTypeStringFormat"); NotifyPropertyChanged("Value"); NotifyPropertyChanged("ValueAsString"); }
  256. }
  257. private TagDataType tagDataType;
  258. public virtual TagDataType TagDataType
  259. {
  260. get
  261. {
  262. return this.tagDataType;
  263. }
  264. set
  265. {
  266. if (value == TagDataType.Struct)
  267. return;
  268. //if (value == TagDataType.DateTime)
  269. // ArraySize = 1;
  270. else if (value != TagDataType.Bool)
  271. _bitAddress = 0;
  272. //else if (value == TagDataType.CharArray || value == TagDataType.ByteArray || value == TagDataType.String)
  273. // ArraySize = _internalGetSize();
  274. if (this.tagDataSource == MemoryArea.Timer || this.tagDataSource == MemoryArea.Counter)
  275. {
  276. if (value != TagDataType.Bool && value != TagDataType.Int && value != TagDataType.Word && value != TagDataType.S5Time && value != TagDataType.BCDWord)
  277. this.tagDataType = this.TagDataSource == MemoryArea.Timer ? TagDataType.S5Time : TagDataType.Int;
  278. else
  279. this.tagDataType = value;
  280. }
  281. else
  282. this.tagDataType = value;
  283. NotifyPropertyChanged("TagDataType");
  284. NotifyPropertyChanged("S7FormatAddress");
  285. NotifyPropertyChanged("DataTypeStringFormat");
  286. NotifyPropertyChanged("ReadByteSize");
  287. NotifyPropertyChanged("ArraySize");
  288. }
  289. }
  290. //For a List of old Values...
  291. protected List<Object> _oldvalues;
  292. [XmlIgnore]
  293. public List<Object> OldValues
  294. {
  295. get { return _oldvalues; }
  296. }
  297. protected int _backupvaluescount = 0;
  298. public int BackupValuesCount
  299. {
  300. get
  301. {
  302. return _backupvaluescount;
  303. }
  304. set
  305. {
  306. _backupvaluescount = value;
  307. if (value > 0 && _oldvalues == null)
  308. _oldvalues = new List<object>();
  309. else if (value == 0)
  310. _oldvalues = null;
  311. NotifyPropertyChanged("BackupValuesCount");
  312. }
  313. }
  314. private bool _dontSplitValue = true;
  315. /// <summary>
  316. /// This Tag can not be splittet into more then one PDU (if there are a few rest Bytes in a PDU aviable)
  317. /// --> If this is set, the Tag is not allowed to be bigger!
  318. /// This bit should be set in all Tags wich are used for indirect Addressing! (Becaus eit could be you read 2 bytes of a double, then the value chages in the plc, then you read the rest!)
  319. /// This is also used when Writing the Value, and when set, it is not splitted. When the Value is bigger then a PDU, an error occurs
  320. /// </summary>
  321. public virtual bool DontSplitValue
  322. {
  323. get { return _dontSplitValue; }
  324. set { _dontSplitValue = value; NotifyPropertyChanged("DontSplitValue"); }
  325. }
  326. private int _arraySize = 1;
  327. /// <summary>
  328. /// Only valid (and used!) with String, CharArray and ByteArray Type!
  329. /// </summary>
  330. public int ArraySize
  331. {
  332. get
  333. {
  334. //if (TagDataType== TagDataType.String || TagDataType==TagDataType.CharArray|| TagDataType==TagDataType.ByteArray)
  335. return _arraySize;
  336. //return 1;
  337. }
  338. set
  339. {
  340. _arraySize = value == 0 ? 1 : value;
  341. NotifyPropertyChanged("ArraySize");
  342. NotifyPropertyChanged("S7FormatAddress");
  343. NotifyPropertyChanged("ReadByteSize");
  344. }
  345. }
  346. #region Read Write Value of the TAG
  347. /// <summary>
  348. /// Helper Property to Set the Value, because the Setter of the normal Value Sets Control Value!
  349. /// </summary>
  350. protected internal virtual Object _setValueProp
  351. {
  352. set
  353. {
  354. _value = value;
  355. if (_value == null)
  356. {
  357. NotifyPropertyChanged("Value");
  358. NotifyPropertyChanged("ValueAsString");
  359. if (ValueChanged != null) ValueChanged(this, new ValueChangedEventArgs(_oldvalue, _value));
  360. _oldvalue = _value;
  361. }
  362. else
  363. {
  364. if (!_value.Equals(_oldvalue) || raiseValueChangedEvenWhenNoChangeHappened)
  365. {
  366. NotifyPropertyChanged("Value");
  367. NotifyPropertyChanged("ValueAsString");
  368. if (ValueChanged != null) ValueChanged(this, new ValueChangedEventArgs(_oldvalue, _value));
  369. if (MaximumReached != null && _value is IComparable && ((IComparable)_value).CompareTo(Maximum) >= 0) MaximumReached(this, new LimitReachedEventArgs(_oldvalue, Maximum));
  370. if (MinimumReached != null && _value is IComparable && ((IComparable)_value).CompareTo(Minimum) <= 0) MinimumReached(this, new LimitReachedEventArgs(_oldvalue, Minimum));
  371. _oldvalue = _value;
  372. }
  373. if (BackupValuesCount > 0 && _oldvalues != null)
  374. {
  375. _oldvalues.Add(_value);
  376. if (_oldvalues.Count - _backupvaluescount > 0) _oldvalues.RemoveRange(0, _oldvalues.Count - _backupvaluescount);
  377. NotifyPropertyChanged("OldValues");
  378. }
  379. }
  380. }
  381. }
  382. protected Object _value;
  383. private Object _oldvalue;
  384. /// <summary>
  385. /// Value of the Tag. The Setter of this Property sets Controlvalue, because the Tag firstly got this Value when it's written!
  386. /// </summary>
  387. public virtual Object Value
  388. {
  389. get { return _value; }
  390. set
  391. {
  392. if (_controlvalue == null || !_controlvalue.Equals(value))
  393. {
  394. _controlvalue = value;
  395. NotifyPropertyChanged("Controlvalue");
  396. }
  397. }
  398. }
  399. public void ClearValue()
  400. {
  401. _value = null;
  402. _oldvalue = null;
  403. }
  404. [XmlIgnore]
  405. public String ValueAsString
  406. {
  407. get { return GetValueAsString(); }
  408. set
  409. {
  410. ParseControlValueFromString((String) value);
  411. NotifyPropertyChanged("ControlValueAsString");
  412. }
  413. }
  414. protected Object _controlvalue;
  415. public virtual Object Controlvalue
  416. {
  417. get { return _controlvalue; }
  418. set
  419. {
  420. if (_controlvalue == null || !_controlvalue.Equals(value))
  421. {
  422. _controlvalue = value;
  423. //_oldvalue = null;
  424. NotifyPropertyChanged("Controlvalue");
  425. NotifyPropertyChanged("ControlValueAsString");
  426. }
  427. }
  428. }
  429. [XmlIgnore]
  430. public String ControlValueAsString
  431. {
  432. get { return Controlvalue != null ? GetValueAsString(_controlvalue) : null; }
  433. set
  434. {
  435. ParseControlValueFromString((String)value);
  436. NotifyPropertyChanged("ControlValueAsString");
  437. }
  438. }
  439. #endregion
  440. [XmlIgnore]
  441. public string S7FormatAddress
  442. {
  443. get
  444. {
  445. int aksz = _internalGetSize();
  446. StringBuilder ret = new StringBuilder();
  447. if (aksz == 3 || (aksz > 4 && this.TagDataSource != MemoryArea.Timer && this.TagDataSource != MemoryArea.Counter))
  448. ret.Append("P#");
  449. if (this.TagDataSource == MemoryArea.Datablock || this.TagDataSource == MemoryArea.InstanceDatablock)
  450. {
  451. if (this.TagDataSource == MemoryArea.InstanceDatablock)
  452. ret.Append("DI");
  453. else
  454. ret.Append("DB");
  455. ret.Append(this.DataBlockNumber);
  456. ret.Append(".");
  457. if (this.TagDataSource == MemoryArea.InstanceDatablock)
  458. ret.Append("DI");
  459. else
  460. ret.Append("DB");
  461. if (this.TagDataType == TagDataType.Bool || aksz == 3 || aksz > 4)
  462. ret.Append("X");
  463. }
  464. switch (this.TagDataSource)
  465. {
  466. case MemoryArea.Inputs:
  467. ret.Append("E");
  468. break;
  469. case MemoryArea.Outputs:
  470. ret.Append("A");
  471. break;
  472. case MemoryArea.Flags:
  473. ret.Append("M");
  474. break;
  475. case MemoryArea.Timer:
  476. ret.Append("T");
  477. break;
  478. case MemoryArea.Counter:
  479. ret.Append("Z");
  480. break;
  481. case MemoryArea.LocalData:
  482. ret.Append("L");
  483. break;
  484. case MemoryArea.PreviousLocalData:
  485. ret.Append("V");
  486. break;
  487. }
  488. if (this.TagDataType == TagDataType.Bool && ArraySize < 2)
  489. {
  490. ret.Append(ByteAddress);
  491. if (this.TagDataSource != MemoryArea.Timer && this.TagDataSource != MemoryArea.Counter)
  492. {
  493. ret.Append(".");
  494. ret.Append(BitAddress);
  495. }
  496. }
  497. else if (this.TagDataSource != MemoryArea.Counter && this.TagDataSource != MemoryArea.Timer)
  498. {
  499. if (aksz == 3 || aksz > 4)
  500. {
  501. ret.Append(ByteAddress);
  502. ret.Append(".");
  503. ret.Append(BitAddress);
  504. ret.Append(" BYTE ");
  505. ret.Append(_internalGetSize().ToString());
  506. }
  507. else if (aksz == 4)
  508. {
  509. ret.Append("D");
  510. ret.Append(ByteAddress);
  511. }
  512. else if (aksz == 1)
  513. {
  514. ret.Append("B");
  515. ret.Append(ByteAddress);
  516. }
  517. else
  518. {
  519. ret.Append("W");
  520. ret.Append(ByteAddress);
  521. }
  522. }
  523. else
  524. {
  525. ret.Append(ByteAddress);
  526. }
  527. if (isSymbolicAccessKeyTag)
  528. {
  529. ret.Append(" (" + symbolicAccessKey + ")");
  530. }
  531. return ret.ToString();
  532. }
  533. set
  534. {
  535. ChangeAddressFromString(value);
  536. NotifyPropertyChanged("SymbolicAccessKey");
  537. NotifyPropertyChanged("S7FormatAddress");
  538. NotifyPropertyChanged("ReadByteSize");
  539. NotifyPropertyChanged("ArraySize");
  540. }
  541. }
  542. public string GetControlValueAsString()
  543. {
  544. return GetValueAsString(this.Controlvalue);
  545. }
  546. public void ParseControlValueFromString(string myValue)
  547. {
  548. string myValueStrip = myValue.ToLower().Trim();
  549. switch (this.TagDataType)
  550. {
  551. case TagDataType.S5Time:
  552. case TagDataType.Time:
  553. if (myValueStrip.Contains("t#") || myValueStrip.Contains("s5t#"))
  554. {
  555. Controlvalue = Helper.GetTimespanFromS5TimeorTime(myValue);
  556. }
  557. else
  558. {
  559. TimeSpan ret;
  560. TimeSpan.TryParse(myValue, out ret);
  561. Controlvalue = ret;
  562. }
  563. break;
  564. case TagDataType.BCDWord:
  565. case TagDataType.Int:
  566. if (myValueStrip.Contains("w#16#") || myValueStrip.Contains("dw#16#"))
  567. {
  568. Controlvalue = Convert.ToInt16(Helper.GetIntFromHexString(myValue));
  569. }
  570. else if (myValue.StartsWith("2#"))
  571. {
  572. Controlvalue = Convert.ToInt16(Helper.GetIntFromBinString(myValue));
  573. }
  574. else
  575. {
  576. Int16 ret;
  577. Int16.TryParse(myValue, out ret);
  578. Controlvalue = ret;
  579. }
  580. break;
  581. case TagDataType.BCDDWord:
  582. case TagDataType.Dint:
  583. if (myValueStrip.Contains("w#16#") || myValueStrip.Contains("dw#16#"))
  584. Controlvalue = Convert.ToInt32(Helper.GetIntFromHexString(myValue));
  585. else if (myValue.StartsWith("2#"))
  586. Controlvalue = Convert.ToInt32(Helper.GetIntFromBinString(myValue));
  587. else
  588. try
  589. {
  590. if (!string.IsNullOrEmpty(myValue))
  591. Controlvalue = Int32.Parse(myValue);
  592. } catch (Exception) {}
  593. break;
  594. case TagDataType.Byte:
  595. if (myValueStrip.Contains("w#16#") || myValueStrip.Contains("dw#16#"))
  596. {
  597. Controlvalue = Convert.ToByte(Helper.GetUIntFromHexString(myValue));
  598. }
  599. else if (myValue.StartsWith("2#"))
  600. {
  601. Controlvalue = Convert.ToByte(Helper.GetIntFromBinString(myValue));
  602. }
  603. else
  604. {
  605. Byte ret;
  606. Byte.TryParse(myValue, out ret);
  607. Controlvalue = ret;
  608. }
  609. break;
  610. case TagDataType.BCDByte:
  611. case TagDataType.SByte:
  612. if (myValueStrip.Contains("w#16#") || myValueStrip.Contains("dw#16#"))
  613. {
  614. Controlvalue = Convert.ToSByte(Helper.GetIntFromHexString(myValue));
  615. }
  616. else if (myValue.StartsWith("2#"))
  617. {
  618. Controlvalue = Convert.ToSByte(Helper.GetIntFromBinString(myValue));
  619. }
  620. else
  621. {
  622. SByte ret;
  623. SByte.TryParse(myValue, out ret);
  624. Controlvalue = ret;
  625. }
  626. break;
  627. case TagDataType.Word:
  628. if (myValueStrip.Contains("w#16#") || myValueStrip.Contains("dw#16#"))
  629. {
  630. Controlvalue = Convert.ToUInt16(Helper.GetUIntFromHexString(myValue));
  631. }
  632. else if (myValue.StartsWith("2#"))
  633. {
  634. Controlvalue = Convert.ToUInt16(Helper.GetIntFromBinString(myValue));
  635. }
  636. else
  637. {
  638. UInt16 ret;
  639. UInt16.TryParse(myValue, out ret);
  640. Controlvalue = ret;
  641. }
  642. break;
  643. case TagDataType.Dword:
  644. if (myValueStrip.Contains("w#16#") || myValueStrip.Contains("dw#16#"))
  645. {
  646. Controlvalue = Convert.ToUInt32(Helper.GetUIntFromHexString(myValue));
  647. }
  648. else if (myValue.StartsWith("2#"))
  649. {
  650. Controlvalue = Convert.ToUInt32(Helper.GetIntFromBinString(myValue));
  651. }
  652. else
  653. {
  654. UInt32 ret;
  655. UInt32.TryParse(myValue, out ret);
  656. Controlvalue = ret;
  657. }
  658. break;
  659. case TagDataType.Bool:
  660. if (myValue=="1")
  661. Controlvalue = true;
  662. else if (myValue=="0")
  663. Controlvalue = false;
  664. else
  665. {
  666. bool bvalue;
  667. bool.TryParse(myValue, out bvalue);
  668. Controlvalue = bvalue;
  669. }
  670. break;
  671. case TagDataType.String:
  672. case TagDataType.CharArray:
  673. Controlvalue = myValue;
  674. break;
  675. case TagDataType.DateTime:
  676. case TagDataType.Date:
  677. case TagDataType.TimeOfDay:
  678. if (myValueStrip.StartsWith("d#"))
  679. Controlvalue = Helper.GetDateTimeFromDateString(myValue);
  680. else if (myValueStrip.StartsWith("tod#"))
  681. Controlvalue = Helper.GetDateTimeFromTimeOfDayString(myValue);
  682. else if (myValueStrip.StartsWith("dt#"))
  683. Controlvalue = Helper.GetDateTimeFromDateAndTimeString(myValue);
  684. else if (!string.IsNullOrEmpty(myValue))
  685. try
  686. {
  687. if (!string.IsNullOrEmpty(myValue))
  688. Controlvalue = DateTime.Parse(myValue);
  689. }
  690. catch (Exception) { }
  691. break;
  692. case TagDataType.ByteArray:
  693. {
  694. if (myValueStrip.Length > 2 && myValueStrip[0] == '{' && myValueStrip[myValueStrip.Length - 1] == '}')
  695. myValueStrip = myValueStrip.Substring(1, myValueStrip.Length - 2);
  696. string[] vals = myValueStrip.Split(',');
  697. byte[] wrt = new byte[vals.Length];
  698. int i = 0;
  699. foreach (string val in vals)
  700. {
  701. try
  702. {
  703. wrt[i++] = Convert.ToByte(val);
  704. }
  705. catch (Exception)
  706. { }
  707. }
  708. Controlvalue = wrt;
  709. }
  710. break;
  711. case TagDataType.Float:
  712. {
  713. Single val;
  714. Controlvalue = Single.TryParse(myValue, out val);
  715. Controlvalue = val;
  716. }
  717. break;
  718. /*
  719. * case TagDataType.TimeOfDay:
  720. case TagDataType.Float:
  721. */
  722. }
  723. }
  724. private string GetValueAsString(object myValue)
  725. {
  726. if (myValue != null)
  727. {
  728. switch (this.TagDataType)
  729. {
  730. case TagDataType.String:
  731. case TagDataType.CharArray:
  732. return myValue.ToString();
  733. case TagDataType.ByteArray:
  734. {
  735. StringBuilder sb = new StringBuilder();
  736. sb.Append("{");
  737. foreach (Byte bt in ((System.Byte[])myValue))
  738. {
  739. if (sb.Length > 1) sb.Append(";");
  740. sb.Append(bt.ToString());
  741. }
  742. sb.Append("}");
  743. return sb.ToString();
  744. }
  745. case TagDataType.S5Time:
  746. case TagDataType.Time:
  747. case TagDataType.Bool:
  748. case TagDataType.DateTime:
  749. case TagDataType.Date:
  750. case TagDataType.TimeOfDay:
  751. case TagDataType.Int:
  752. case TagDataType.Dint:
  753. case TagDataType.Byte:
  754. case TagDataType.SByte:
  755. case TagDataType.Word:
  756. case TagDataType.Dword:
  757. case TagDataType.Float:
  758. case TagDataType.BCDByte:
  759. case TagDataType.BCDWord:
  760. case TagDataType.BCDDWord:
  761. if (ArraySize < 2)
  762. {
  763. return this.GetValueAsStringInternal(myValue);
  764. }
  765. else
  766. {
  767. string ret = "";
  768. var ienumer = myValue as IEnumerable;
  769. if (ienumer != null)
  770. {
  771. var enumer = ienumer.GetEnumerator();
  772. for (int i = 0; i < ArraySize; i++)
  773. {
  774. if (enumer.MoveNext())
  775. {
  776. if (ret != "") ret += ";";
  777. ret += this.GetValueAsStringInternal(enumer.Current);
  778. }
  779. }
  780. return ret;
  781. }
  782. }
  783. break;
  784. }
  785. }
  786. return "";
  787. }
  788. private string GetValueAsStringInternal(object myValue)
  789. {
  790. if (myValue != null)
  791. {
  792. switch (this.TagDataType)
  793. {
  794. case TagDataType.S5Time:
  795. {
  796. if (DataTypeStringFormat == TagDisplayDataType.S5Time)
  797. {
  798. var bt = new byte[2];
  799. libnodave.putS5Timeat(bt, 0, (TimeSpan)myValue);
  800. return Helper.GetS5Time(bt[0], bt[1]);
  801. }
  802. return ((TimeSpan)myValue).ToString();
  803. }
  804. case TagDataType.Time:
  805. {
  806. var tm = (TimeSpan)myValue;
  807. var ret = new StringBuilder("T#");
  808. if (tm.TotalMilliseconds < 0) ret.Append("-");
  809. if (tm.Days != 0) ret.Append(tm.Days + "D");
  810. if (tm.Hours != 0) ret.Append(tm.Hours + "H");
  811. if (tm.Minutes != 0) ret.Append(tm.Minutes + "M");
  812. if (tm.Seconds != 0) ret.Append(tm.Seconds + "S");
  813. if (tm.Milliseconds != 0) ret.Append(tm.Milliseconds + "MS");
  814. return ret.ToString();
  815. }
  816. case TagDataType.Bool:
  817. if (DataTypeStringFormat == TagDisplayDataType.Binary)
  818. {
  819. if (((bool)myValue) == true)
  820. return "1";
  821. return "0";
  822. }
  823. return myValue.ToString();
  824. case TagDataType.DateTime:
  825. case TagDataType.Date:
  826. case TagDataType.TimeOfDay:
  827. if (DataTypeStringFormat == TagDisplayDataType.S7DateTime)
  828. {
  829. DateTime ak = (DateTime) myValue;
  830. StringBuilder sb = new StringBuilder();
  831. sb.Append("DT#");
  832. sb.Append(ak.Year.ToString().Substring(2));
  833. sb.Append("-");
  834. sb.Append(ak.Month);
  835. sb.Append("-");
  836. sb.Append(ak.Day);
  837. sb.Append("-");
  838. sb.Append(ak.Hour);
  839. sb.Append(":");
  840. sb.Append(ak.Minute);
  841. sb.Append(":");
  842. sb.Append(ak.Second);
  843. sb.Append(".");
  844. sb.Append(ak.Millisecond.ToString().PadRight(3, '0'));
  845. return sb.ToString();
  846. }
  847. else if (DataTypeStringFormat == TagDisplayDataType.S7Date)
  848. {
  849. DateTime ak = (DateTime)myValue;
  850. StringBuilder sb = new StringBuilder();
  851. sb.Append("D#");
  852. sb.Append(ak.Year);
  853. sb.Append("-");
  854. sb.Append(ak.Month);
  855. sb.Append("-");
  856. sb.Append(ak.Day);
  857. return sb.ToString();
  858. }
  859. else if (DataTypeStringFormat == TagDisplayDataType.S7TimeOfDay)
  860. {
  861. DateTime ak = (DateTime)myValue;
  862. StringBuilder sb = new StringBuilder();
  863. sb.Append("TOD#");
  864. sb.Append(ak.Hour);
  865. sb.Append(":");
  866. sb.Append(ak.Minute);
  867. sb.Append(":");
  868. sb.Append(ak.Second);
  869. sb.Append(".");
  870. sb.Append(ak.Millisecond.ToString().PadRight(3, '0'));
  871. return sb.ToString();
  872. }
  873. return myValue.ToString();
  874. case TagDataType.Int:
  875. case TagDataType.Dint:
  876. case TagDataType.Byte:
  877. case TagDataType.SByte:
  878. case TagDataType.Word:
  879. case TagDataType.Dword:
  880. case TagDataType.Float:
  881. case TagDataType.BCDByte:
  882. case TagDataType.BCDWord:
  883. case TagDataType.BCDDWord:
  884. IFormattable val = myValue as IFormattable ?? 0;
  885. switch (DataTypeStringFormat)
  886. {
  887. case TagDisplayDataType.String:
  888. switch (this.TagDataType)
  889. {
  890. case TagDataType.Int:
  891. return Encoding.ASCII.GetString(BitConverter.GetBytes((Int16)myValue));
  892. case TagDataType.Dint:
  893. return Encoding.ASCII.GetString(BitConverter.GetBytes((Int32)myValue));
  894. case TagDataType.Byte:
  895. return Encoding.ASCII.GetString(new []{(Byte)myValue});
  896. case TagDataType.SByte:
  897. return Encoding.ASCII.GetString(new[] { BitConverter.GetBytes((SByte)myValue)[0] });
  898. case TagDataType.Word:
  899. return Encoding.ASCII.GetString(BitConverter.GetBytes((UInt16)myValue));
  900. case TagDataType.Dword:
  901. return Encoding.ASCII.GetString(BitConverter.GetBytes((UInt32)myValue));
  902. case TagDataType.Float:
  903. return Encoding.ASCII.GetString(BitConverter.GetBytes((Single)myValue));
  904. case TagDataType.BCDByte:
  905. return Encoding.ASCII.GetString(BitConverter.GetBytes((Byte)myValue));
  906. case TagDataType.BCDWord:
  907. return Encoding.ASCII.GetString(BitConverter.GetBytes((UInt16)myValue));
  908. case TagDataType.BCDDWord:
  909. return Encoding.ASCII.GetString(BitConverter.GetBytes((UInt32)myValue));
  910. }
  911. break;
  912. case TagDisplayDataType.Pointer:
  913. return "P#" + (Convert.ToInt32(myValue) / 8).ToString() + "." + (Convert.ToInt32(myValue) % 8).ToString();
  914. break;
  915. case TagDisplayDataType.Hexadecimal:
  916. string ad = "";
  917. switch (_internalGetSize())
  918. {
  919. case 1:
  920. ad = "B#16#";
  921. break;
  922. case 2:
  923. ad = "W#16#";
  924. break;
  925. case 4:
  926. ad = "DW#16#";
  927. break;
  928. }
  929. return ad + val.ToString("X", NumberFormatInfo.CurrentInfo).PadLeft(_internalGetSize() * 2, '0');
  930. case TagDisplayDataType.Binary:
  931. byte[] bt = new byte[] { };
  932. switch (this.TagDataType)
  933. {
  934. case TagDataType.Int:
  935. bt = BitConverter.GetBytes((Int16)myValue);
  936. break;
  937. case TagDataType.Dint:
  938. bt = BitConverter.GetBytes((Int32)myValue);
  939. break;
  940. case TagDataType.Byte:
  941. bt = new byte[] { (byte)myValue };
  942. break;
  943. case TagDataType.SByte:
  944. bt = new byte[] { (byte)myValue };
  945. break;
  946. case TagDataType.Word:
  947. bt = BitConverter.GetBytes((UInt16)myValue);
  948. break;
  949. case TagDataType.Dword:
  950. bt = BitConverter.GetBytes((UInt32)myValue);
  951. break;
  952. case TagDataType.Float:
  953. bt = BitConverter.GetBytes((float)myValue);
  954. break;
  955. case TagDataType.BCDByte:
  956. bt = BitConverter.GetBytes((byte)myValue);
  957. break;
  958. case TagDataType.BCDWord:
  959. bt = BitConverter.GetBytes((Int16)myValue);
  960. break;
  961. case TagDataType.BCDDWord:
  962. bt = BitConverter.GetBytes((Int32)myValue);
  963. break;
  964. }
  965. string ret = "";
  966. foreach (byte b in bt)
  967. {
  968. if (ret != "") ret = "_" + ret;
  969. ret = libnodave.dec2bin(b).Substring(0, 4) + "_" + libnodave.dec2bin(b).Substring(4, 4) + ret;
  970. }
  971. return "2#" + ret;
  972. }
  973. return val.ToString();
  974. }
  975. }
  976. return "";
  977. }
  978. public string GetValueAsString()
  979. {
  980. if (ItemDoesNotExist)
  981. return "Item does not exist on the PLC!";
  982. return GetValueAsString(this.Value);
  983. }
  984. public override string ToString()
  985. {
  986. string old = "";
  987. if (_oldvalues != null)
  988. {
  989. old = " -- Old-Values: ";
  990. foreach (var oldvalue in _oldvalues)
  991. {
  992. old += oldvalue.ToString() + ",";
  993. }
  994. old += "";
  995. }
  996. if (Value != null)
  997. {
  998. return S7FormatAddress + " = " + GetValueAsString() + old;
  999. }
  1000. return S7FormatAddress;
  1001. }
  1002. public void ChangeAddressFromString(String newPlcAddress)
  1003. {
  1004. var plcAddress = newPlcAddress;
  1005. if (plcAddress.Contains("("))
  1006. {
  1007. var pos = newPlcAddress.IndexOf('(');
  1008. plcAddress = newPlcAddress.Substring(0, pos);
  1009. symbolicAccessKey = newPlcAddress.Substring(pos + 1, newPlcAddress.Length - pos - 2);
  1010. isSymbolicAccessKeyTag = true;
  1011. }
  1012. if (plcAddress.StartsWith("%"))
  1013. plcAddress = plcAddress.Substring(1);
  1014. try
  1015. {
  1016. if (!string.IsNullOrEmpty(plcAddress))
  1017. {
  1018. plcAddress = plcAddress.Trim();
  1019. if (plcAddress.Length > 1 && plcAddress.Substring(0, 2).ToLower() == "p#")
  1020. {
  1021. string[] myPlcAddress = plcAddress.ToLower().Replace("byte", " byte ").Replace(" ", " ").Replace("p#", "").Split(' ');
  1022. BitAddress = 0;
  1023. if (!myPlcAddress[0].Contains("db"))
  1024. {
  1025. this.DataBlockNumber = 0;
  1026. var tmp = myPlcAddress[0].Split('.')[0];
  1027. if (tmp.Contains("e") || tmp.Contains("i"))
  1028. this.TagDataSource = MemoryArea.Inputs;
  1029. else if (tmp.Contains("a") || tmp.Contains("q"))
  1030. this.TagDataSource = MemoryArea.Outputs;
  1031. else if (tmp.Contains("l"))
  1032. this.TagDataSource = MemoryArea.LocalData;
  1033. else if (tmp.Contains("v"))
  1034. this.TagDataSource = MemoryArea.PreviousLocalData;
  1035. else if (tmp.Contains("m"))
  1036. this.TagDataSource = MemoryArea.Flags;
  1037. else if (tmp.Contains("t"))
  1038. this.TagDataSource = MemoryArea.Timer;
  1039. else if (tmp.Contains("z") || tmp.Contains("c"))
  1040. this.TagDataSource = MemoryArea.Counter;
  1041. ByteAddress = Convert.ToInt32(Regex.Replace(myPlcAddress[0].Split('.')[0], "[a-z]", ""));
  1042. }
  1043. else
  1044. {
  1045. this.TagDataSource = MemoryArea.Datablock;
  1046. this.DataBlockNumber = Convert.ToInt32(myPlcAddress[0].Split('.')[0].Replace("db", ""));
  1047. ByteAddress = Convert.ToInt32(myPlcAddress[0].Split('.')[1].Replace("dbx", ""));
  1048. }
  1049. ArraySize = Convert.ToInt32(myPlcAddress[2]);
  1050. var tsize = 1;
  1051. switch (myPlcAddress[1])
  1052. {
  1053. case "word":
  1054. case "int":
  1055. case "date":
  1056. case "s5time":
  1057. tsize = 2;
  1058. break;
  1059. case "real":
  1060. case "dword":
  1061. case "dint":
  1062. case "time":
  1063. case "time_of_day":
  1064. tsize = 4;
  1065. break;
  1066. }
  1067. var baseS = _internalGetBaseTypeSize();
  1068. if (baseS > 0) ArraySize = ArraySize / baseS;
  1069. ArraySize = ArraySize * tsize;
  1070. //if (this.TagDataType != TagDataType.ByteArray && this.TagDataType != TagDataType.CharArray && this.TagDataType != TagDataType.String && this.TagDataType != TagDataType.DateTime)
  1071. // this.TagDataType = TagDataType.ByteArray;
  1072. //if (ArraySize != 8 && this.TagDataType == TagDataType.DateTime)
  1073. // this.TagDataType = TagDataType.ByteArray;
  1074. if (this.TagDataType == TagDataType.String)
  1075. ArraySize -= 2;
  1076. }
  1077. else
  1078. {
  1079. string[] myPlcAddress = plcAddress.ToUpper().Trim().Replace(" ", "").Split('.');
  1080. if (myPlcAddress.Length >= 2 && (myPlcAddress[0].Contains("DB") || myPlcAddress[0].Contains("DI")))
  1081. {
  1082. this.TagDataSource = MemoryArea.Datablock;
  1083. this.DataBlockNumber = Convert.ToInt32(myPlcAddress[0].Replace("DB", "").Replace("DI", "").Trim());
  1084. if (myPlcAddress[1].Contains("DBW"))
  1085. {
  1086. if (this.TagDataType == TagDataType.String || this.TagDataType == TagDataType.CharArray || this.TagDataType == TagDataType.ByteArray)
  1087. ArraySize = 2;
  1088. else
  1089. ArraySize = 1;
  1090. if (this._internalGetSize() != 2)
  1091. this.TagDataType = TagDataType.Word;
  1092. }
  1093. else if (myPlcAddress[1].Contains("DBB"))
  1094. {
  1095. ArraySize = 1;
  1096. if (this.TagDataType == TagDataType.Bool || this._internalGetSize() != 1)
  1097. this.TagDataType = TagDataType.Byte;
  1098. }
  1099. else if (myPlcAddress[1].Contains("DBD"))
  1100. {
  1101. if (this.TagDataType == TagDataType.String || this.TagDataType == TagDataType.CharArray || this.TagDataType == TagDataType.ByteArray)
  1102. ArraySize = 4;
  1103. else
  1104. ArraySize = 1;
  1105. if (this._internalGetSize() != 4)
  1106. this.TagDataType = TagDataType.Dword;
  1107. }
  1108. else if (myPlcAddress[1].Contains("DBX"))
  1109. {
  1110. ArraySize = 1;
  1111. this.TagDataType = TagDataType.Bool;
  1112. if (myPlcAddress.Length > 2)
  1113. this.BitAddress = Convert.ToInt32(myPlcAddress[2]);
  1114. else
  1115. this.BitAddress = 0;
  1116. }
  1117. this.ByteAddress = Convert.ToInt32(myPlcAddress[1].Replace("DBW", "").Replace("DBD", "").Replace("DBX", "").Replace("DBB", "").Trim());
  1118. }
  1119. else
  1120. {
  1121. if (myPlcAddress[0].Contains("E") || myPlcAddress[0].Contains("I"))
  1122. this.TagDataSource = MemoryArea.Inputs;
  1123. else if (myPlcAddress[0].Contains("A") || myPlcAddress[0].Contains("Q"))
  1124. this.TagDataSource = MemoryArea.Outputs;
  1125. else if (myPlcAddress[0].Contains("M"))
  1126. this.TagDataSource = MemoryArea.Flags;
  1127. else if (myPlcAddress[0].Contains("T"))
  1128. this.TagDataSource = MemoryArea.Timer;
  1129. else if (myPlcAddress[0].Contains("Z") || myPlcAddress[0].Contains("C"))
  1130. this.TagDataSource = MemoryArea.Counter;
  1131. if (myPlcAddress[0].Contains("W"))
  1132. {
  1133. if (this.TagDataType == TagDataType.String || this.TagDataType == TagDataType.CharArray || this.TagDataType == TagDataType.ByteArray)
  1134. ArraySize = 2;
  1135. else
  1136. ArraySize = 1;
  1137. if (_internalGetSize() != 2)
  1138. this.TagDataType = TagDataType.Int;
  1139. }
  1140. else if (myPlcAddress[0].Contains("DBB"))
  1141. {
  1142. ArraySize = 1;
  1143. if (this.TagDataType == TagDataType.Bool || this._internalGetSize() != 1)
  1144. this.TagDataType = TagDataType.Byte;
  1145. }
  1146. else if (myPlcAddress[0].Contains("D"))
  1147. {
  1148. if (this.TagDataType == TagDataType.String || this.TagDataType == TagDataType.CharArray || this.TagDataType == TagDataType.ByteArray)
  1149. ArraySize = 4;
  1150. else
  1151. ArraySize = 1;
  1152. if (_internalGetSize() != 4)
  1153. this.TagDataType = TagDataType.Dint;
  1154. }
  1155. else if (myPlcAddress[0].Contains("B"))
  1156. {
  1157. ArraySize = 1;
  1158. if (this.TagDataType == TagDataType.Bool || this._internalGetSize() != 1)
  1159. this.TagDataType = TagDataType.Byte;
  1160. }
  1161. else if (!myPlcAddress[0].Contains("T") && !myPlcAddress[0].Contains("Z"))
  1162. {
  1163. ArraySize = 1;
  1164. this.TagDataType = TagDataType.Bool;
  1165. if (myPlcAddress.Length >= 2)
  1166. this.BitAddress = Convert.ToInt32(myPlcAddress[1]);
  1167. else
  1168. this.BitAddress = 0;
  1169. }
  1170. else if (myPlcAddress[0].Contains("T"))
  1171. {
  1172. ArraySize = 1;
  1173. this.TagDataType = TagDataType.S5Time;
  1174. }
  1175. else if (myPlcAddress[0].Contains("Z") || myPlcAddress[0].Contains("C"))
  1176. {
  1177. ArraySize = 1;
  1178. this.TagDataType = TagDataType.Int;
  1179. }
  1180. else
  1181. {
  1182. ArraySize = 1;
  1183. if (_internalGetSize() != 1)
  1184. this.TagDataType = TagDataType.Bool;
  1185. }
  1186. this.ByteAddress = Convert.ToInt32(Regex.Replace(myPlcAddress[0].ToLower(), "[a-z]", "").Trim());
  1187. if (this.TagDataType == TagDataType.String)
  1188. ArraySize -= 2;
  1189. }
  1190. }
  1191. }
  1192. }
  1193. catch(Exception)
  1194. {
  1195. if (plcAddress!=null)
  1196. if (plcAddress.ToLower().Contains("p#"))
  1197. {
  1198. this.TagDataType = TagDataType.ByteArray;
  1199. this.ArraySize = 10;
  1200. }
  1201. }
  1202. }
  1203. public void ChangeDataTypeFromString(String datatype)
  1204. {
  1205. if (!string.IsNullOrEmpty(datatype))
  1206. {
  1207. TagDataType tp = TagDataType.Word;
  1208. datatype = datatype.ToLower().Trim().Replace(" ", "");
  1209. switch (datatype)
  1210. {
  1211. case "bool":
  1212. tp = TagDataType.Bool;
  1213. break;
  1214. case "word":
  1215. tp = TagDataType.Word;
  1216. break;
  1217. case "int":
  1218. case "integer":
  1219. tp = TagDataType.Int;
  1220. break;
  1221. case "dword":
  1222. tp = TagDataType.Dword;
  1223. break;
  1224. case "dint":
  1225. tp = TagDataType.Dint;
  1226. break;
  1227. case "byte":
  1228. tp = TagDataType.Byte;
  1229. break;
  1230. case "sbyte":
  1231. tp = TagDataType.SByte;
  1232. break;
  1233. case "string":
  1234. tp = TagDataType.String;
  1235. break;
  1236. case "time":
  1237. tp = TagDataType.Time;
  1238. break;
  1239. case "s5time":
  1240. tp = TagDataType.S5Time;
  1241. break;
  1242. case "timeofday":
  1243. tp = TagDataType.TimeOfDay;
  1244. break;
  1245. case "date":
  1246. tp = TagDataType.Date;
  1247. break;
  1248. case "bcdbyte":
  1249. case "bcd":
  1250. tp = TagDataType.BCDByte;
  1251. break;
  1252. case "bcdword":
  1253. tp = TagDataType.BCDWord;
  1254. break;
  1255. case "bcddword":
  1256. tp = TagDataType.BCDDWord;
  1257. break;
  1258. case "datetime":
  1259. case "dateandtime":
  1260. tp = TagDataType.DateTime;
  1261. break;
  1262. case "char":
  1263. case "chararray":
  1264. tp = TagDataType.CharArray;
  1265. break;
  1266. case "bytearray":
  1267. tp = TagDataType.ByteArray;
  1268. break;
  1269. case "float":
  1270. case "real":
  1271. tp = TagDataType.Float;
  1272. break;
  1273. }
  1274. this.TagDataType = tp;
  1275. }
  1276. }
  1277. public void ChangeDataTypeStringFormatFromString(String datatype)
  1278. {
  1279. if (!string.IsNullOrEmpty(datatype))
  1280. {
  1281. TagDisplayDataType tp = TagDisplayDataType.Decimal;
  1282. datatype = datatype.ToLower().Trim().Replace(" ", "");
  1283. switch (datatype.Replace(" ", "").Replace("_", "").Trim())
  1284. {
  1285. case "decimal":
  1286. case "dec":
  1287. tp = TagDisplayDataType.Decimal;
  1288. break;
  1289. case "hexadecimal":
  1290. case "hex":
  1291. tp = TagDisplayDataType.Hexadecimal;
  1292. break;
  1293. case "binary":
  1294. case "bin":
  1295. tp = TagDisplayDataType.Binary;
  1296. break;
  1297. case "pointer":
  1298. tp = TagDisplayDataType.Pointer;
  1299. break;
  1300. case "bool":
  1301. tp = TagDisplayDataType.Bool;
  1302. break;
  1303. case "byte":
  1304. case "bytearray":
  1305. tp = TagDisplayDataType.ByteArray;
  1306. break;
  1307. case "datetime":
  1308. tp = TagDisplayDataType.DateTime;
  1309. break;
  1310. case "date":
  1311. case "s7date":
  1312. tp = TagDisplayDataType.S7Date;
  1313. break;
  1314. case "s7timeofday":
  1315. case "timeofday":
  1316. tp = TagDisplayDataType.S7TimeOfDay;
  1317. break;
  1318. case "float":
  1319. case "real":
  1320. tp = TagDisplayDataType.Float;
  1321. break;
  1322. case "s5time":
  1323. tp = TagDisplayDataType.S5Time;
  1324. break;
  1325. case "s7datetime":
  1326. case "dateandtime":
  1327. tp = TagDisplayDataType.S7DateTime;
  1328. break;
  1329. case "string":
  1330. case "strg":
  1331. tp = TagDisplayDataType.String;
  1332. break;
  1333. case "time":
  1334. case "s7time":
  1335. tp = TagDisplayDataType.Time;
  1336. break;
  1337. case "timespan":
  1338. tp = TagDisplayDataType.TimeSpan;
  1339. break;
  1340. }
  1341. this.DataTypeStringFormat = tp;
  1342. }
  1343. }
  1344. public static PLCTag GetPLCTagFromString(String plcAddress)
  1345. {
  1346. PLCTag retValue = new PLCTag();
  1347. retValue.ChangeAddressFromString(plcAddress);
  1348. return retValue;
  1349. }
  1350. public bool LimitControlValuesRange { get; set; }
  1351. internal virtual void _putControlValueIntoBuffer(byte[] buff, int startpos)
  1352. {
  1353. if (this.ArraySize == 1 || this.TagDataType == TagDataType.String || this.TagDataType == TagDataType.ByteArray)
  1354. {
  1355. _putControlValueIntoBuffer(buff, startpos, Controlvalue);
  1356. }
  1357. else
  1358. {
  1359. int n = 0;
  1360. foreach (var ctlVal in (IEnumerable)Controlvalue)
  1361. {
  1362. _putControlValueIntoBuffer(buff, startpos + (n * this._internalGetBaseTypeSize()), ctlVal);
  1363. n++;
  1364. if (n >= ArraySize) break;
  1365. }
  1366. }
  1367. }
  1368. internal virtual void _putControlValueIntoBuffer(byte[] buff, int startpos, object ctlValue)
  1369. {
  1370. if (ctlValue != null)
  1371. switch (this.TagDataType)
  1372. {
  1373. case TagDataType.Word:
  1374. libnodave.putU16at(buff, startpos, Convert.ToUInt16(ctlValue));
  1375. break;
  1376. case TagDataType.String:
  1377. libnodave.putS7Stringat(buff, startpos, ctlValue.ToString(), ArraySize);
  1378. break;
  1379. case TagDataType.CharArray:
  1380. libnodave.putStringat(buff, startpos, ctlValue.ToString(), ArraySize);
  1381. break;
  1382. case TagDataType.ByteArray:
  1383. {
  1384. byte[] tmp = (byte[])ctlValue;
  1385. for (int n = 0; n < ArraySize; n++)
  1386. {
  1387. if (n > tmp.Length)
  1388. buff[startpos + n] = 0x00;
  1389. else
  1390. buff[startpos + n] = tmp[n];
  1391. }
  1392. }
  1393. break;
  1394. case TagDataType.Bool:
  1395. bool tmp1 = false;
  1396. tmp1 = Convert.ToBoolean(ctlValue);
  1397. buff[startpos] = Convert.ToByte(tmp1);
  1398. break;
  1399. case TagDataType.Byte:
  1400. buff[startpos] = Convert.ToByte(ctlValue);
  1401. break;
  1402. case TagDataType.SByte:
  1403. buff[startpos] = (Byte)Convert.ToSByte(ctlValue);
  1404. break;
  1405. case TagDataType.Time:
  1406. libnodave.putTimeat(buff, startpos, (TimeSpan)ctlValue);
  1407. break;
  1408. case TagDataType.TimeOfDay:
  1409. libnodave.putTimeOfDayat(buff, startpos, (DateTime)ctlValue);
  1410. break;
  1411. case TagDataType.BCDByte:
  1412. libnodave.putBCD8at(buff, startpos, Convert.ToInt32(ctlValue));
  1413. break;
  1414. case TagDataType.Int:
  1415. libnodave.putS16at(buff, startpos, Convert.ToInt16(ctlValue));
  1416. break;
  1417. case TagDataType.S5Time:
  1418. //if (Controlvalue.GetType() == typeof(TimeSpan))
  1419. libnodave.putS5Timeat(buff, startpos, (TimeSpan)ctlValue);
  1420. //else
  1421. // libnodave.putS5Timeat(buff, startpos, TimeSpan.Parse(Controlvalue.ToString()));
  1422. break;
  1423. case TagDataType.BCDWord:
  1424. libnodave.putBCD16at(buff, startpos, Convert.ToInt32(ctlValue));
  1425. break;
  1426. case TagDataType.BCDDWord:
  1427. libnodave.putBCD32at(buff, startpos, Convert.ToInt32(ctlValue));
  1428. break;
  1429. case TagDataType.Dint:
  1430. libnodave.putS32at(buff, startpos, Convert.ToInt32(ctlValue));
  1431. break;
  1432. case TagDataType.Dword:
  1433. libnodave.putU32at(buff, startpos, Convert.ToUInt32(ctlValue));
  1434. break;
  1435. case TagDataType.Float:
  1436. libnodave.putFloatat(buff, startpos, Convert.ToSingle(ctlValue));
  1437. break;
  1438. case TagDataType.DateTime:
  1439. //if (Controlvalue.GetType() == typeof(DateTime))
  1440. libnodave.putDateTimeat(buff, startpos, (DateTime)ctlValue);
  1441. //else
  1442. // libnodave.putDateTimeat(buff, startpos, Convert.ToDateTime(Controlvalue));
  1443. break;
  1444. case TagDataType.Date:
  1445. //if (Controlvalue.GetType() == typeof(DateTime))
  1446. libnodave.putDateat(buff, startpos, (DateTime)ctlValue);
  1447. //else
  1448. // libnodave.putDateTimeat(buff, startpos, Convert.ToDateTime(Controlvalue));
  1449. break;
  1450. }
  1451. }
  1452. /// <summary>
  1453. /// This Parses the PLCTag From a Byte Array
  1454. /// this is used, when the Tag is not Read via my Functions, but the PLCTags are used as Wrapper
  1455. /// </summary>
  1456. /// <param name="buff"></param>
  1457. /// <param name="startpos"></param>
  1458. public void ParseValueFromByteArray(byte[] buff, int startpos)
  1459. {
  1460. _readValueFromBuffer(buff, startpos);
  1461. }
  1462. internal virtual void _readValueFromBuffer(byte[] buff, int startpos)
  1463. {
  1464. switch (this.TagDataType)
  1465. {
  1466. case TagDataType.String:
  1467. {
  1468. var sb = new StringBuilder();
  1469. int size = ArraySize > buff[startpos + 1] ? buff[startpos+1] : ArraySize;
  1470. for (var n = 2; n < size+2; n++)
  1471. sb.Append((char) buff[n + startpos]);
  1472. _setValueProp = sb.ToString();
  1473. }
  1474. break;
  1475. case TagDataType.CharArray:
  1476. {
  1477. var sb = new StringBuilder();
  1478. for (var n = 0; n < ((buff.Length - startpos) < ArraySize ? buff.Length - startpos : ArraySize); n++)
  1479. sb.Append((char)buff[n + startpos]);
  1480. _setValueProp = sb.ToString();
  1481. }
  1482. break;
  1483. case TagDataType.ByteArray:
  1484. {
  1485. var val = new Byte[ArraySize];
  1486. Array.Copy(buff, startpos, val, 0, ArraySize);
  1487. /*
  1488. for (var n = 0; n < ArraySize; n++)
  1489. val[n] = buff[n + startpos];
  1490. */
  1491. _setValueProp = val;
  1492. }
  1493. break;
  1494. case TagDataType.Bool:
  1495. case TagDataType.Byte:
  1496. case TagDataType.SByte:
  1497. case TagDataType.Time:
  1498. case TagDataType.Date:
  1499. case TagDataType.TimeOfDay:
  1500. case TagDataType.Word:
  1501. case TagDataType.BCDByte:
  1502. case TagDataType.Int:
  1503. case TagDataType.S5Time:
  1504. case TagDataType.BCDWord:
  1505. case TagDataType.BCDDWord:
  1506. case TagDataType.Dint:
  1507. case TagDataType.Dword:
  1508. case TagDataType.Float:
  1509. case TagDataType.DateTime:
  1510. {
  1511. if (ArraySize<2)
  1512. {
  1513. switch (this.TagDataType)
  1514. {
  1515. case TagDataType.Bool:
  1516. _setValueProp = libnodave.getBit(buff[startpos], BitAddress);
  1517. break;
  1518. case TagDataType.Byte:
  1519. _setValueProp = buff[startpos];
  1520. break;
  1521. case TagDataType.SByte:
  1522. _setValueProp = libnodave.getS8from(buff, startpos);
  1523. break;
  1524. case TagDataType.Time:
  1525. _setValueProp = libnodave.getTimefrom(buff, startpos);
  1526. break;
  1527. case TagDataType.Date:
  1528. _setValueProp = libnodave.getDatefrom(buff, startpos);
  1529. break;
  1530. case TagDataType.TimeOfDay:
  1531. _setValueProp = libnodave.getTimeOfDayfrom(buff, startpos);
  1532. break;
  1533. case TagDataType.Word:
  1534. _setValueProp = libnodave.getU16from(buff, startpos);
  1535. break;
  1536. case TagDataType.BCDByte:
  1537. _setValueProp = libnodave.getBCD8from(buff, startpos);
  1538. break;
  1539. case TagDataType.Int:
  1540. _setValueProp = libnodave.getS16from(buff, startpos);
  1541. break;
  1542. case TagDataType.S5Time:
  1543. _setValueProp = libnodave.getS5Timefrom(buff, startpos);
  1544. break;
  1545. case TagDataType.BCDWord:
  1546. _setValueProp = libnodave.getBCD16from(buff, startpos);
  1547. break;
  1548. case TagDataType.BCDDWord:
  1549. _setValueProp = libnodave.getBCD32from(buff, startpos);
  1550. break;
  1551. case TagDataType.Dint:
  1552. _setValueProp = libnodave.getS32from(buff, startpos);
  1553. break;
  1554. case TagDataType.Dword:
  1555. _setValueProp = libnodave.getU32from(buff, startpos);
  1556. break;
  1557. case TagDataType.Float:
  1558. _setValueProp = libnodave.getFloatfrom(buff, startpos);
  1559. break;
  1560. case TagDataType.DateTime:
  1561. _setValueProp = libnodave.getDateTimefrom(buff, startpos);
  1562. break;
  1563. }
  1564. }
  1565. else
  1566. {
  1567. switch (this.TagDataType)
  1568. {
  1569. case TagDataType.Bool:
  1570. {
  1571. var values = new List<bool>();
  1572. var akBit = BitAddress;
  1573. var akbyte = startpos;
  1574. for (int n = 0; n < ArraySize; n++)
  1575. {
  1576. values.Add(libnodave.getBit(buff[akbyte], akBit));
  1577. akBit++;
  1578. if (akBit>7)
  1579. {
  1580. akBit = 0;
  1581. akbyte++;
  1582. }
  1583. }
  1584. _setValueProp = values.ToArray();
  1585. break;
  1586. }
  1587. case TagDataType.Byte:
  1588. {
  1589. var values = new List<Byte>();
  1590. var mSize = _internalGetBaseTypeSize();
  1591. for (int n = 0; n < ArraySize; n++)
  1592. values.Add(buff[startpos + n * mSize]);
  1593. _setValueProp = values.ToArray();
  1594. break;
  1595. }
  1596. case TagDataType.SByte:
  1597. {
  1598. var values = new List<SByte>();
  1599. var mSize = _internalGetBaseTypeSize();
  1600. for (int n = 0; n < ArraySize; n++)
  1601. values.Add(libnodave.getS8from(buff, startpos + n * mSize));
  1602. _setValueProp = values.ToArray();
  1603. break;
  1604. }
  1605. case TagDataType.Time:
  1606. {
  1607. var values = new List<TimeSpan>();
  1608. var mSize = _internalGetBaseTypeSize();
  1609. for (int n = 0; n < ArraySize; n++)
  1610. values.Add(libnodave.getTimefrom(buff, startpos + n * mSize));
  1611. _setValueProp = values.ToArray();
  1612. break;
  1613. }
  1614. case TagDataType.Date:
  1615. {
  1616. var values = new List<DateTime>();
  1617. var mSize = _internalGetBaseTypeSize();
  1618. for (int n = 0; n < ArraySize; n++)
  1619. values.Add(libnodave.getDatefrom(buff, startpos + n * mSize));
  1620. _setValueProp = values.ToArray();
  1621. break;
  1622. }
  1623. case TagDataType.TimeOfDay:
  1624. {
  1625. var values = new List<DateTime>();
  1626. var mSize = _internalGetBaseTypeSize();
  1627. for (int n = 0; n < ArraySize; n++)
  1628. values.Add(libnodave.getTimeOfDayfrom(buff, startpos + n * mSize));
  1629. _setValueProp = values.ToArray();
  1630. break;
  1631. }
  1632. case TagDataType.Word:
  1633. {
  1634. var values = new List<UInt16>();
  1635. var mSize = _internalGetBaseTypeSize();
  1636. for (int n = 0; n < ArraySize; n++)
  1637. values.Add(libnodave.getU16from(buff, startpos + n * mSize));
  1638. _setValueProp = values.ToArray();
  1639. break;
  1640. }
  1641. case TagDataType.BCDByte:
  1642. {
  1643. var values = new List<int>();
  1644. var mSize = _internalGetBaseTypeSize();
  1645. for (int n = 0; n < ArraySize; n++)
  1646. values.Add(libnodave.getBCD8from(buff, startpos + n * mSize));
  1647. _setValueProp = values.ToArray();
  1648. break;
  1649. }
  1650. case TagDataType.Int:
  1651. {
  1652. var values = new List<Int16>();
  1653. var mSize = _internalGetBaseTypeSize();
  1654. for (int n = 0; n < ArraySize; n++)
  1655. values.Add(libnodave.getS16from(buff, startpos + n * mSize));
  1656. _setValueProp = values.ToArray();
  1657. break;
  1658. }
  1659. case TagDataType.S5Time:
  1660. {
  1661. var values = new List<TimeSpan>();
  1662. var mSize = _internalGetBaseTypeSize();
  1663. for (int n = 0; n < ArraySize; n++)
  1664. values.Add(libnodave.getS5Timefrom(buff, startpos + n * mSize));
  1665. _setValueProp = values.ToArray();
  1666. break;
  1667. }
  1668. case TagDataType.BCDWord:
  1669. {
  1670. var values = new List<Int32>();
  1671. var mSize = _internalGetBaseTypeSize();
  1672. for (int n = 0; n < ArraySize; n++)
  1673. values.Add(libnodave.getBCD16from(buff, startpos + n * mSize));
  1674. _setValueProp = values.ToArray();
  1675. break;
  1676. }
  1677. case TagDataType.BCDDWord:
  1678. {
  1679. var values = new List<Int32>();
  1680. var mSize = _internalGetBaseTypeSize();
  1681. for (int n = 0; n < ArraySize; n++)
  1682. values.Add(libnodave.getBCD32from(buff, startpos + n * mSize));
  1683. _setValueProp = values.ToArray();
  1684. break;
  1685. }
  1686. case TagDataType.Dint:
  1687. {
  1688. var values = new List<Int32>();
  1689. var mSize = _internalGetBaseTypeSize();
  1690. for (int n = 0; n < ArraySize; n++)
  1691. values.Add(libnodave.getS32from(buff, startpos + n * mSize));
  1692. _setValueProp = values.ToArray();
  1693. break;
  1694. }
  1695. case TagDataType.Dword:
  1696. {
  1697. var values = new List<UInt32>();
  1698. var mSize = _internalGetBaseTypeSize();
  1699. for (int n = 0; n < ArraySize; n++)
  1700. values.Add(libnodave.getU32from(buff, startpos + n * mSize));
  1701. _setValueProp = values.ToArray();
  1702. break;
  1703. }
  1704. case TagDataType.Float:
  1705. {
  1706. var values = new List<float>();
  1707. var mSize = _internalGetBaseTypeSize();
  1708. for (int n = 0; n < ArraySize; n++)
  1709. values.Add(libnodave.getFloatfrom(buff, startpos + n * mSize));
  1710. _setValueProp = values.ToArray();
  1711. break;
  1712. }
  1713. case TagDataType.DateTime:
  1714. {
  1715. var values = new List<DateTime>();
  1716. var mSize = _internalGetBaseTypeSize();
  1717. for (int n = 0; n < ArraySize; n++)
  1718. values.Add(libnodave.getDateTimefrom(buff, startpos + n * mSize));
  1719. _setValueProp = values.ToArray();
  1720. break;
  1721. }
  1722. }
  1723. }
  1724. }
  1725. break;
  1726. }
  1727. }
  1728. [XmlIgnore]
  1729. public int ReadByteSize { get { return _internalGetSize(); } }
  1730. internal virtual int _internalGetSize()
  1731. {
  1732. switch (this.TagDataType)
  1733. {
  1734. case TagDataType.String:
  1735. return ArraySize + 2;
  1736. case TagDataType.CharArray:
  1737. case TagDataType.ByteArray:
  1738. return ArraySize;
  1739. case TagDataType.Byte:
  1740. case TagDataType.SByte:
  1741. case TagDataType.BCDByte:
  1742. case TagDataType.Word:
  1743. case TagDataType.BCDWord:
  1744. case TagDataType.Int:
  1745. case TagDataType.S5Time:
  1746. case TagDataType.Date:
  1747. case TagDataType.Dint:
  1748. case TagDataType.Dword:
  1749. case TagDataType.Time:
  1750. case TagDataType.TimeOfDay:
  1751. case TagDataType.Float:
  1752. case TagDataType.BCDDWord:
  1753. case TagDataType.DateTime:
  1754. return _internalGetBaseTypeSize() * ArraySize;
  1755. case TagDataType.Bool:
  1756. {
  1757. var akbyte = 1;
  1758. var akBit = BitAddress;
  1759. for (int i = 0; i < ArraySize; i++)
  1760. {
  1761. if (akBit > 7)
  1762. {
  1763. akbyte++;
  1764. akBit = 0;
  1765. }
  1766. akBit++;
  1767. }
  1768. return akbyte;
  1769. }
  1770. }
  1771. return 0;
  1772. }
  1773. internal virtual int _internalGetBaseTypeSize()
  1774. {
  1775. switch (this.TagDataType)
  1776. {
  1777. case TagDataType.Byte:
  1778. case TagDataType.SByte:
  1779. case TagDataType.BCDByte:
  1780. return 1;
  1781. case TagDataType.Word:
  1782. case TagDataType.BCDWord:
  1783. case TagDataType.Int:
  1784. case TagDataType.S5Time:
  1785. case TagDataType.Date:
  1786. return 2;
  1787. case TagDataType.Dint:
  1788. case TagDataType.Dword:
  1789. case TagDataType.Time:
  1790. case TagDataType.TimeOfDay:
  1791. case TagDataType.Float:
  1792. case TagDataType.BCDDWord:
  1793. return 4;
  1794. case TagDataType.DateTime:
  1795. return 8;
  1796. }
  1797. return 0;
  1798. }
  1799. #region Events for Tag Checking
  1800. private bool _raiseValueChangedOnFirstRead = true;
  1801. public bool RaiseValueChangedOnFirstRead
  1802. {
  1803. get { return _raiseValueChangedOnFirstRead; }
  1804. set { _raiseValueChangedOnFirstRead = value; }
  1805. }
  1806. public delegate void ValueChangedEventHandler(PLCTag Sender, ValueChangedEventArgs e);
  1807. public class ValueChangedEventArgs
  1808. {
  1809. public ValueChangedEventArgs(object OldValue, object NewValue)
  1810. {
  1811. this.OldValue = OldValue;
  1812. this.NewValue = NewValue;
  1813. }
  1814. public object OldValue;
  1815. public object NewValue;
  1816. }
  1817. public event ValueChangedEventHandler ValueChanged;
  1818. public object Maximum { get; set; }
  1819. public object Minimum { get; set; }
  1820. public delegate void LimitReachedEventHandler(PLCTag Sender, LimitReachedEventArgs e);
  1821. public class LimitReachedEventArgs
  1822. {
  1823. public LimitReachedEventArgs(object Value, object Limit)
  1824. {
  1825. this.Value = Value;
  1826. this.Limit = Limit;
  1827. }
  1828. public object Value;
  1829. public object Limit;
  1830. }
  1831. public event LimitReachedEventHandler MaximumReached;
  1832. public event LimitReachedEventHandler MinimumReached;
  1833. #endregion
  1834. #region PropertyChanged
  1835. public event PropertyChangedEventHandler PropertyChanged;
  1836. protected void NotifyPropertyChanged(String info)
  1837. {
  1838. if (PropertyChanged != null)
  1839. {
  1840. PropertyChanged(this, new PropertyChangedEventArgs(info));
  1841. }
  1842. }
  1843. #endregion
  1844. }
  1845. }