private ValueValidationInfo DIValidationInfo(SmartComponent smartComponent, DynamicProperty property, object newValue) { int diNumber = -1; int.TryParse(Right(property.Name, property.Name.Length - 11), out diNumber); if ((diNumber >= 0) && (diNumber < bDIO_AddressIsValid[(int)IO.Input].Length)) { bDIO_AddressIsValid[(int)IO.Input][diNumber] = false; S7Client.S7DataItem item = new S7Client.S7DataItem(); if (!GetS7DataItem((string)newValue, ref item)) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } if (item.WordLen != S7Consts.S7WLBit) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } if ((item.Area != S7Consts.S7AreaPA) && (item.Area != S7Consts.S7AreaMK) && (item.Area != S7Consts.S7AreaDB) ) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } bDIO_AddressIsValid[(int)IO.Input][diNumber] = true; return(ValueValidationInfo.Valid); } else { return(new ValueValidationInfo(ValueValidationResult.InvalidProject)); } }
/// <summary> /// Called when the value of an I/O signal value has changed. /// </summary> /// <param name="component"> Component that owns the changed signal. </param> /// <param name="changedSignal"> Changed signal. </param> public override void OnIOSignalValueChanged(SmartComponent component, IOSignal changedSignal) { if (changedSignal.Name == "Connect") { //Mark sure client is initialized before connect. CheckClientAndValues(component); if (((int)changedSignal.Value != 0) && bCanConnect) { Connect(component); } else { Disconnect(component); } } if ((changedSignal.Name == "Read") && ((int)changedSignal.Value != 0)) { Read(component); } if (changedSignal.Name.Contains("GO_")) { if (client.Connected) { int offset = -1; int.TryParse(Right(changedSignal.Name, changedSignal.Name.Length - 3), out offset); if (offset >= 0) { S7Client.S7DataItem item = new S7Client.S7DataItem(); if (GetS7DataItem((string)component.Properties["GO_FirstByteAddress"].Value, ref item)) { item.Start += offset; byte[] b = new byte[1]; byte.TryParse((string)changedSignal.Value.ToString(), out b[0]); int result = 0x01700000; // S7Consts.errCliInvalidBlockType switch (item.Area) { case 0x81: result = client.EBWrite(item.Start, 1, b); //S7Consts.S7AreaPE break; case 0x83: result = client.MBWrite(item.Start, 1, b); //S7Consts.S7AreaMK break; case 0x84: result = client.DBWrite(item.DBNumber, item.Start, 1, b); //S7Consts.S7AreaDB break; } ShowResult(component, result); } } } } }
/// <summary> /// Read all GI from PLC. /// </summary> /// <param name="component"></param> private void Read(SmartComponent component) { if (client.Connected) { S7MultiVar reader = new S7MultiVar(client); bool allDI_OK = true; int diCount = (int)component.Properties["DI_Number"].Value; List <byte[]> list = new List <byte[]>(); for (int i = 0; i < diCount; ++i) { S7Client.S7DataItem item = new S7Client.S7DataItem(); allDI_OK &= GetS7DataItem((string)component.Properties["DI_Address_" + i.ToString()].Value, ref item); if (allDI_OK) { byte[] b = new byte[1]; list.Add(b); if (!reader.Add(item.Area, item.WordLen, item.DBNumber, item.Start, item.Amount, ref b)) { ShowResult(component, 0x00200000); // S7Consts.errCliInvalidParams } } } if (allDI_OK && (diCount > 0)) { int result = 0x01700000; // S7Consts.errCliInvalidBlockType result = reader.Read(); ShowResult(component, result); if (result == 0) { for (int i = 0; i < diCount; ++i) { ShowResult(component, reader.Results[i]); string giName = "DI_" + i.ToString(); if (component.IOSignals.Contains(giName)) { byte[] b = list[i]; component.IOSignals[giName].Value = ((int)b[0] != 0 ? 1 : 0); } } } } } }
/// <summary> /// Read all DI from PLC. /// </summary> /// <param name="smartComponent"></param> private void Read(SmartComponent smartComponent) { if (client.Connected) { S7MultiVar reader = new S7MultiVar(client); bool allDO_OK = true; int doCount = (int)smartComponent.Properties["DO_Number"].Value; List <byte[]> listBuffers = new List <byte[]>(); for (int i = 0; i < doCount; ++i) { S7Client.S7DataItem item = new S7Client.S7DataItem(); allDO_OK &= GetS7DataItem((string)smartComponent.Properties["DO_Address_" + i.ToString()].Value, ref item); if (allDO_OK) { byte[] buffer = new byte[1]; listBuffers.Add(buffer); if (!reader.Add(item.Area, item.WordLen, item.DBNumber, item.Start, item.Amount, ref buffer)) { LogError(smartComponent, S7Consts.errCliInvalidParams); } } } if (allDO_OK && (doCount > 0)) { int err = S7Consts.errCliInvalidBlockType; err = reader.Read(); LogError(smartComponent, err); if (err == 0) { for (int i = 0; i < doCount; ++i) { LogError(smartComponent, reader.Results[i]); string diName = "DO_" + i.ToString(); if (smartComponent.IOSignals.Contains(diName)) { byte[] buffer = listBuffers[i]; smartComponent.IOSignals[diName].Value = ((int)buffer[0] != 0 ? 1 : 0); } } } } } }
/// <summary> /// Called when the value of an I/O signal value has changed. /// </summary> /// <param name="component"> Component that owns the changed signal. </param> /// <param name="changedSignal"> Changed signal. </param> public override void OnIOSignalValueChanged(SmartComponent component, IOSignal changedSignal) { if (changedSignal.Name == "Connect") { //Make sure client is initialized before connect. CheckClientAndValues(component); if (((int)changedSignal.Value != 0) && bCanConnect) { Connect(component); } else { Disconnect(component); } } if ((changedSignal.Name == "Read") && ((int)changedSignal.Value != 0)) { Read(component); } if (changedSignal.Name.Contains("DO_")) { if (client.Connected) { int doNumber = -1; int.TryParse(Right(changedSignal.Name, changedSignal.Name.Length - 3), out doNumber); if (doNumber >= 0) { S7Client.S7DataItem item = new S7Client.S7DataItem(); if (GetS7DataItem((string)component.Properties["DO_Address_" + doNumber.ToString()].Value, ref item)) { byte[] b = new byte[1]; byte.TryParse(changedSignal.Value.ToString(), out b[0]); int result = 0x01700000; // S7Consts.errCliInvalidBlockType result = client.WriteArea(item.Area, item.DBNumber, item.Start, item.Amount, item.WordLen, b); ShowResult(component, result); } } } } }
/// <summary> /// Read all GI from PLC. /// </summary> /// <param name="component"></param> private void Read(SmartComponent component) { if (client.Connected) { int giCount = (int)component.Properties["GI_ByteNumber"].Value; S7Client.S7DataItem item = new S7Client.S7DataItem(); if (GetS7DataItem((string)component.Properties["GI_FirstByteAddress"].Value, ref item) && (giCount > 0)) { byte[] b = new byte[giCount]; int result = 0x01700000; // S7Consts.errCliInvalidBlockType switch (item.Area) { case 0x82: result = client.ABRead(item.Start, giCount, b); //S7Consts.S7AreaPA break; case 0x83: result = client.MBRead(item.Start, giCount, b); //S7Consts.S7AreaMK break; case 0x84: result = client.DBRead(item.DBNumber, item.Start, giCount, b); //S7Consts.S7AreaDB break; } ShowResult(component, result); if (result == 0) { for (int i = 0; i < giCount; ++i) { string giName = "GI_" + i.ToString(); if (component.IOSignals.Contains(giName)) { component.IOSignals[giName].Value = (int)b[i]; } } } } } }
/// <summary> /// Populate S7DataItem struct depends name (ex: MB500). /// </summary> /// <param name="name">Name of data.</param> /// <param name="item">Struct to be populated.</param> /// <returns>True if name is in good syntax.</returns> private bool GetS7DataItem(string name, ref S7Client.S7DataItem item) { string strName = name.ToUpper(); if (string.IsNullOrEmpty(strName)) { return(false); } if (strName.Substring(0, 1) == "M") { item.Area = S7Consts.S7AreaMK; if (strName.Length < 2) //Mx0 || M0. { return(false); } item.WordLen = GetWordLength(strName.Substring(1, 1)); string strOffset = Right(strName, strName.Length - (item.WordLen == S7Consts.S7WLBit ? 1 : 2)); int offset; if (!int.TryParse(strOffset, out offset)) { return(false); } item.Start = offset; } else if ((strName.Substring(0, 1) == "A") || (strName.Substring(0, 1) == "Q")) { item.Area = S7Consts.S7AreaPA; if (strName.Length < 2) //Ax0 || A0. { return(false); } item.WordLen = GetWordLength(strName.Substring(1, 1)); string strOffset = Right(strName, strName.Length - (item.WordLen == S7Consts.S7WLBit ? 1 : 2)); int offset; if (!int.TryParse(strOffset, out offset)) { return(false); } item.Start = offset; } else if ((strName.Substring(0, 1) == "E") || (strName.Substring(0, 1) == "I")) { item.Area = S7Consts.S7AreaPE; if (strName.Length < 2) //Ex0 || E0. { return(false); } item.WordLen = GetWordLength(strName.Substring(1, 1)); string strOffset = Right(strName, strName.Length - (item.WordLen == S7Consts.S7WLBit ? 1 : 2)); int offset; if (!int.TryParse(strOffset, out offset)) { return(false); } item.Start = offset; } else if ((strName.Length >= 2) && (strName.Substring(0, 2) == "DB")) { item.Area = S7Consts.S7AreaDB; if (strName.Length < 3) //DB0 { return(false); } string strDBNumber = Right(strName, strName.Length - 2); strDBNumber = Left(strDBNumber, strDBNumber.IndexOf(".") == -1 ? strDBNumber.Length : strDBNumber.IndexOf(".")); int dbNumber; if (!int.TryParse(strDBNumber, out dbNumber)) { return(false); } item.DBNumber = dbNumber; int index = strName.IndexOf(".DB"); if ((index < 0) || (strName.Length < (index + 4))) //.DBx { return(false); } item.WordLen = GetWordLength(strName.Substring(index + 3, 1)); string strOffset = Right(strName, strName.Length - index - 4); //.DBx = 4 int offset; if (!int.TryParse(strOffset, out offset)) { return(false); } item.Start = offset; } else { return(false); } return(true); }
/// <summary> /// Called to validate the value of a dynamic property with the CustomValidation attribute. /// </summary> /// <param name="component">Component that owns the changed property.</param> /// <param name="property">Property that owns the value to be validated.</param> /// <param name="newValue">Value to validate.</param> /// <returns>Result of the validation. </returns> public override ValueValidationInfo QueryPropertyValueValid(SmartComponent component, DynamicProperty property, object newValue) { bCanConnect = false; if (property.Name == "PLC_Addr") { bPLC_AddrIsValid = false; System.Net.IPAddress ip; if (!System.Net.IPAddress.TryParse((string)newValue, out ip)) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } bPLC_AddrIsValid = true; } if (property.Name == "GI_FirstByteAddress") { bGI_FirstByteAddressIsValid = false; S7Client.S7DataItem item = new S7Client.S7DataItem(); if (!GetS7DataItem((string)newValue, ref item)) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } if (item.WordLen != S7Consts.S7WLByte) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } if ((item.Area != S7Consts.S7AreaPA) && (item.Area != S7Consts.S7AreaMK) && (item.Area != S7Consts.S7AreaDB) ) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } bGI_FirstByteAddressIsValid = true; } if (property.Name == "GO_FirstByteAddress") { bGO_FirstByteAddressIsValid = false; S7Client.S7DataItem item = new S7Client.S7DataItem(); if (!GetS7DataItem((string)newValue, ref item)) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } if (item.WordLen != S7Consts.S7WLByte) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } if ((item.Area != S7Consts.S7AreaPE) && (item.Area != S7Consts.S7AreaMK) && (item.Area != S7Consts.S7AreaDB) ) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } bGO_FirstByteAddressIsValid = true; } bCanConnect = bPLC_AddrIsValid; bCanConnect &= bGI_FirstByteAddressIsValid || ((int)component.Properties["GI_ByteNumber"].Value == 0); bCanConnect &= bGO_FirstByteAddressIsValid || ((int)component.Properties["GO_ByteNumber"].Value == 0); component.IOSignals["Connect"].UIVisible = bCanConnect; return(ValueValidationInfo.Valid); }
/// <summary> /// Called to validate the value of a dynamic property with the CustomValidation attribute. /// </summary> /// <param name="component">Component that owns the changed property.</param> /// <param name="property">Property that owns the value to be validated.</param> /// <param name="newValue">Value to validate.</param> /// <returns>Result of the validation. </returns> public override ValueValidationInfo QueryPropertyValueValid(SmartComponent component, DynamicProperty property, object newValue) { bCanConnect = false; if (property.Name == "PLC_Addr") { bPLC_AddrIsValid = false; System.Net.IPAddress ip; if (!System.Net.IPAddress.TryParse((string)newValue, out ip)) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } bPLC_AddrIsValid = true; } if (property.Name.StartsWith("DI_Address_")) { int diNumber = -1; int.TryParse(Right(property.Name, property.Name.Length - 11), out diNumber); if ((diNumber >= 0) && (diNumber < bDI_AddressIsValid.Length)) { bDI_AddressIsValid[diNumber] = false; S7Client.S7DataItem item = new S7Client.S7DataItem(); if (!GetS7DataItem((string)newValue, ref item)) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } if (item.WordLen != S7Consts.S7WLBit) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } if ((item.Area != S7Consts.S7AreaPA) && (item.Area != S7Consts.S7AreaMK) && (item.Area != S7Consts.S7AreaDB) ) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } bDI_AddressIsValid[diNumber] = true; } else { return(new ValueValidationInfo(ValueValidationResult.InvalidProject)); } } if (property.Name.StartsWith("DO_Address_")) { int doNumber = -1; int.TryParse(Right(property.Name, property.Name.Length - 11), out doNumber); if ((doNumber >= 0) && (doNumber < bDO_AddressIsValid.Length)) { bDO_AddressIsValid[doNumber] = false; S7Client.S7DataItem item = new S7Client.S7DataItem(); if (!GetS7DataItem((string)newValue, ref item)) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } if (item.WordLen != S7Consts.S7WLBit) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } if ((item.Area != S7Consts.S7AreaPE) && (item.Area != S7Consts.S7AreaMK) && (item.Area != S7Consts.S7AreaDB) ) { return(new ValueValidationInfo(ValueValidationResult.InvalidSyntax)); } bDO_AddressIsValid[doNumber] = true; } else { return(new ValueValidationInfo(ValueValidationResult.InvalidProject)); } } bCanConnect = bPLC_AddrIsValid; for (int i = 0; i < bDI_AddressIsValid.Length; ++i) { bCanConnect &= bDI_AddressIsValid[i] || ((int)component.Properties["DI_Number"].Value == 0); } for (int i = 0; i < bDO_AddressIsValid.Length; ++i) { bCanConnect &= bDO_AddressIsValid[i] || ((int)component.Properties["DO_Number"].Value == 0); } component.IOSignals["Connect"].UIVisible = bCanConnect; return(ValueValidationInfo.Valid); }