private static bool GetUdtStructureFromSource(String udtName, out S7DataRow udtStructure) { bool completed = false; bool typeFailed = false; S7Block block = new S7Block(); udtStructure = new S7DataRow(udtName, S7DataRowType.UDT, block); while (!completed) { if (UdtReferenceBlocks.ContainsKey(udtName)) { udtStructure = UdtReferenceBlocks[udtName].Structure.DeepCopy(); completed = true; } else { bool result = PromptForMissingType(udtName); if (!result) { typeFailed = true; break; } } } return(typeFailed); }
/// <summary> /// With this Function you get the AWL Source of a Block, so that it can be imported into Step7 /// </summary> /// <param name="blkInfo">The BlockInfo from the Block you wish to get the Source of!</param> /// <returns></returns> public string GetSourceBlock(ProjectBlockInfo blkInfo, bool useSymbols = false) { StringBuilder retVal = new StringBuilder(); Block blk = GetBlock(blkInfo, new S7ConvertingOptions(Project.ProjectLanguage) { CombineDBOpenAndDBAccess = true, GenerateCallsfromUCs = true, ReplaceDBAccessesWithSymbolNames = useSymbols, ReplaceLokalDataAddressesWithSymbolNames = true, UseComments = true }); S7Block fblk = (S7Block)blk; return(fblk.GetSourceBlock(useSymbols)); }
/// <summary> /// Copy S7 block to the right. Returns true if right project structure changed (block added/removed) /// </summary> /// <param name="leftBlock"></param> /// <param name="rightBlock"></param> /// <param name="rightFolder"></param> /// <returns></returns> public bool CopyBlock(S7Block leftBlock, S7Block rightBlock, IS7Container rightFolder) { // Standard blocks FB/FC/DB bool bRes = false; if (leftBlock != null) { // Source block exists if (rightBlock != null) { // Target block also exists - copy! EventFire.Info("Copying S7 Block. Copying block to the right."); // Magic happened here. Deleting and re-creating block doesn't affect cache // Because new block somehow gets created with the same array index as the old one rightBlock.Remove(); leftBlock.Copy(rightBlock.Parent); EventFire.Info("Copying S7 Block. Done."); } else { if (rightFolder != null) { // Right block does not exists - create a new one EventFire.Info("Copying S7 Block. Right block does not exisits. Creating new block."); leftBlock.Copy(rightFolder); EventFire.Info("Copying S7 Block. Done."); // Just created a new block - need to update right cache // TODO: Smart cache update - only current folder bRes = true; } else { EventFire.Error("Copying S7 Block. Right block does not exisits. Can't find corresponding parent foder in the right Simatic project."); } } } else { // Source block does not exists - remove target block EventFire.Info("Copying S7 Block. Left block does not exists. Deleting right block."); rightBlock.Remove(); // TODO: Maybe we don't need to refresh cache? Verify // Just deleted a block - need to update cache bRes = true; EventFire.Info("Copying S7 Block. Done."); } return(bRes); }
/// <summary> /// Copy S7 block to the right. Returns true if right project structure changed (block added/removed) /// </summary> /// <param name="leftBlock"></param> /// <param name="rightBlock"></param> /// <param name="rightFolder"></param> /// <returns></returns> public bool CopyBlock(S7Block leftBlock, S7Block rightBlock, IS7Container rightFolder) { // Standard blocks FB/FC/DB bool bRes = false; if (leftBlock != null) { // Source block exists if (rightBlock != null) { // Target block also exists - copy! EventFire.Info("Copying S7 Block. Copying block to the right."); // Magic happened here. Deleting and re-creating block doesn't affect cache // Because new block somehow gets created with the same array index as the old one rightBlock.Remove(); leftBlock.Copy(rightBlock.Parent); EventFire.Info("Copying S7 Block. Done."); } else { if (rightFolder != null) { // Right block does not exists - create a new one EventFire.Info("Copying S7 Block. Right block does not exisits. Creating new block."); leftBlock.Copy(rightFolder); EventFire.Info("Copying S7 Block. Done."); // Just created a new block - need to update right cache // TODO: Smart cache update - only current folder bRes = true; } else { EventFire.Error("Copying S7 Block. Right block does not exisits. Can't find corresponding parent foder in the right Simatic project."); } } } else { // Source block does not exists - remove target block EventFire.Info("Copying S7 Block. Left block does not exists. Deleting right block."); rightBlock.Remove(); // TODO: Maybe we don't need to refresh cache? Verify // Just deleted a block - need to update cache bRes = true; EventFire.Info("Copying S7 Block. Done."); } return bRes; }
public void TestDB4() { var txt = "\r\n STRUCT \t\r\n X_KOORDINATE : ARRAY [0 .. 67, 0 .. 16, 1 .. 2 ] OF //X, Y, Z (Z1 = links, Z2 = rechts)\r\n INT ;\t\r\n END_STRUCT ;\t"; var par1 = new List <string>(); var fld = new BlocksOfflineFolder(); var blk = new S7Block(); var test = DotNetSiemensPLCToolBoxLibrary.PLCs.S7_xxx.MC7.Parameter.GetInterfaceOrDBFromStep7ProjectString(txt, ref par1, PLCBlockType .DB, false, fld, blk); var rw = test.Children[0] as S7DataRow; var callStr = rw.GetCallingString(); }
static public byte[] GetMC7(S7Block myCmd) { //if (myCmd.GetType() == typeof(PLCFunctionBlock)) // return GetMC7((PLCFunctionBlock) myCmd); List <byte> retVal = new List <byte>(); foreach (var myLine in ((S7FunctionBlock)myCmd).AWLCode) { if (((S7FunctionBlockRow)myLine).MC7 == null) { ((S7FunctionBlockRow)myLine).MC7 = GetMC7(((S7FunctionBlockRow)myLine)); } retVal.AddRange(((S7FunctionBlockRow)myLine).MC7); } return(retVal.ToArray()); }
private void BlockList_MouseDoubleClick(object sender, MouseButtonEventArgs e) { string nm = BlockList.SelectedItem.ToString(); if (dispatcherTimer != null) { dispatcherTimer.Stop(); } if (myDiag != null) { myDiag.Close(); myDiag = null; } myBlock = MC7Converter.GetAWLBlock(_myconn.PLCGetBlockInMC7(nm), 0, myblkFld); if (myBlock != null) { if (myBlock.BlockType == PLCBlockType.DB) { toppanel.ClearValue(HeightProperty); toppanel.ClearValue(DockPanel.DockProperty); textEditor.Visibility = System.Windows.Visibility.Collapsed; } else { toppanel.Height = 160; toppanel.SetValue(DockPanel.DockProperty, Dock.Top); textEditor.Visibility = System.Windows.Visibility.Visible; } textEditor.Text = myBlock.ToString(); blockName.Content = nm; Upload.IsEnabled = true; Optimize.IsEnabled = true; Diag.IsEnabled = true; if (myBlock.BlockType == PLCBlockType.DB) { myTree.DataContext = ((S7DataBlock)myBlock).Structure.Children; } else { myTree.DataContext = ((S7FunctionBlock)myBlock).Parameter.Children; } } }
public void TestDB2() { var txt = "\r\n STRUCT \t\r\n Fachkoordinate : ARRAY [0 .. 67, 1 .. 2 ] OF //X, Z (1 = links, 2 = rechts)\r\n STRUCT \t\r\n X : DINT ;\t\r\n END_STRUCT ;\t\r\n END_STRUCT ;\t"; var par1 = new List <string>(); var fld = new BlocksOfflineFolder(); var blk = new S7Block(); var test = DotNetSiemensPLCToolBoxLibrary.PLCs.S7_xxx.MC7.Parameter.GetInterfaceOrDBFromStep7ProjectString(txt, ref par1, PLCBlockType .DB, false, fld, blk); Assert.AreEqual(test.Children[0].Name, "Fachkoordinate"); Assert.AreEqual(((S7DataRow)test.Children[0]).ArrayStart[0], 0); Assert.AreEqual(((S7DataRow)test.Children[0]).ArrayStart[1], 1); Assert.AreEqual(((S7DataRow)test.Children[0]).ArrayStop[0], 67); Assert.AreEqual(((S7DataRow)test.Children[0]).ArrayStop[1], 2); Assert.AreEqual(((S7DataRow)test.Children[0]).ByteLength, 544); }
public void TestDB3() { var txt = "\r\n STRUCT \t\r\n X_KOORDINATE : ARRAY [0 .. 67, 0 .. 16, 1 .. 2 ] OF //X, Y, Z (Z1 = links, Z2 = rechts)\r\n INT ;\t\r\n END_STRUCT ;\t"; var par1 = new List <string>(); var fld = new BlocksOfflineFolder(); var blk = new S7Block(); var test = DotNetSiemensPLCToolBoxLibrary.PLCs.S7_xxx.MC7.Parameter.GetInterfaceOrDBFromStep7ProjectString(txt, ref par1, PLCBlockType .DB, false, fld, blk); Assert.AreEqual(test.Children[0].Name, "X_KOORDINATE"); Assert.AreEqual(test.Children[0].ArrayStart[0], 0); Assert.AreEqual(test.Children[0].ArrayStart[1], 0); Assert.AreEqual(test.Children[0].ArrayStart[2], 1); Assert.AreEqual(test.Children[0].ArrayStop[0], 67); Assert.AreEqual(test.Children[0].ArrayStop[1], 16); Assert.AreEqual(test.Children[0].ArrayStop[2], 2); Assert.AreEqual(test.Children[0].ByteLength, 4624); }
public void TestDB1() { var txt = "\r\n STRUCT \t\r\n DB_VAR : INT := 1;\t//vorläufige Platzhaltervariable\r\n aa : ARRAY [1 .. 8 ] OF BYTE ;\t\r\n bb : INT ;\t\r\n aa1 : INT ;\t\r\n END_STRUCT ;\t"; var par1 = new List <string>(); var fld = new BlocksOfflineFolder(); var blk = new S7Block(); var test = DotNetSiemensPLCToolBoxLibrary.PLCs.S7_xxx.MC7.Parameter.GetInterfaceOrDBFromStep7ProjectString(txt, ref par1, PLCBlockType .DB, false, fld, blk); Assert.AreEqual(test.Children[0].Name, "DB_VAR"); Assert.AreEqual(test.Children[1].Name, "aa"); Assert.AreEqual(test.Children[2].Name, "bb"); Assert.AreEqual(test.Children[3].Name, "aa1"); Assert.AreEqual(((S7DataRow)test.Children[0]).BlockAddress.ByteAddress, 0); Assert.AreEqual(((S7DataRow)test.Children[1]).BlockAddress.ByteAddress, 2); Assert.AreEqual(((S7DataRow)test.Children[2]).BlockAddress.ByteAddress, 10); Assert.AreEqual(((S7DataRow)test.Children[3]).BlockAddress.ByteAddress, 12); }
public void MergeBlocks(S7Block leftBlock, S7Block rightBlock) { // Standard FB/FC/DB // Should have both blocks if (leftBlock == null || rightBlock == null) { EventFire.Error("Merge S7 Blocks. Can't find block in the Simatic structure."); return; } EventFire.Info("Merge S7 Blocks. Generating right source."); if (!Directory.Exists(_RightSourceFilePath)) { Directory.CreateDirectory(_RightSourceFilePath); } String rightSourceFileName = _RightSourceFilePath + rightBlock.Name + ".awl"; rightBlock.GenerateSource(rightSourceFileName, S7GenerateSourceFlags.S7GSFDoOverwrite); EventFire.Info("Merge S7 Blocks. Generating left source."); if (!Directory.Exists(_LeftSourceFilePath)) { Directory.CreateDirectory(_LeftSourceFilePath); } String leftSourceFileName = _LeftSourceFilePath + leftBlock.Name + ".awl"; leftBlock.GenerateSource(leftSourceFileName, S7GenerateSourceFlags.S7GSFDoOverwrite); String mergedSourceFileName = _MergedSourceFilePath + rightBlock.Name + ".awl"; Process DiffProcess = new Process { StartInfo = new ProcessStartInfo { FileName = "TortoiseMerge.exe", Arguments = "/base:\"" + leftSourceFileName + "\" /mine:\"" + rightSourceFileName + "\" /merged:\"" + mergedSourceFileName + "\"" } }; DiffProcess.Start(); DiffProcess.WaitForExit(); if (File.Exists(mergedSourceFileName)) { S7SWItems s7swItems = rightBlock.Program.Next; for (int i = 1; i <= s7swItems.Count; i++) { if (((S7Container)s7swItems[i]).ConcreteType == S7ContainerType.S7SourceContainer) { IS7Source3 s7Source = (IS7Source3)s7swItems[i].Next.Add("Tmprc", S7SWObjType.S7Source, mergedSourceFileName); EventFire.Info("Merge S7 Blocks. Compiling block."); S7SWItems s7swReturn = s7Source.Compile(); IntPtr hwnd = (IntPtr)s7Source.AppWindowHandle; ShowWindow(hwnd, 6); // 0 = hide the window, 6 = minimize if (s7swReturn.Count <= 0) { // Something is not right - show edit window EventFire.Error("Merge S7 Blocks. Can't compile block, please resolve compilation errors."); ShowWindow(hwnd, 3); // 3 - maximize s7Source.Edit(); // Wait till they fixed it and close the window while (IsWindow(hwnd)) { ; } } else { // Close editor window EventFire.Info("Merge S7 Blocks. Compiled successfully."); //SendMessage(hwnd, 0x0112, 0xF060, 0); // 0xF060 = SC_CLOSE; 0x0112 = WM_SYSCOMMAND } // Remove the source s7Source.Remove(); // S7 editor doesn't like close message. Minimize it ShowWindow(hwnd, 6); break; } } } }
/// <summary> /// Parses the AWL Text and returns the S7Blocks /// </summary> /// <param name="AWL"></param> /// <param name="SymbolTable">Can be null</param> /// <returns></returns> public static List <S7Block> ParseAWL(string AWL, string SymbolTable) { var retVal = new List <S7Block>(); string txt = ""; string blockType = ""; string blockNumberOrName = ""; string blockRetValType = ""; bool startOfQuote = false; ParseStep step = ParseStep.ReadBlockType; S7DataRow akDataRow = null; S7Block akBlock = null; foreach (char c in AWL) { if (!startOfQuote && (c == ' ' || c == '\n' || c == '\r' || c == '=' || c == ':') || c == '"') { if (c == '"' && !startOfQuote) { startOfQuote = true; } else if (startOfQuote) { startOfQuote = false; } if (step == ParseStep.ReadBlockRetVal && txt != "" && txt != ":") //Header ohne RetVal { blockRetValType = ""; akBlock = CreateBlock(blockType, blockNumberOrName, blockRetValType); step = ParseStep.ParseHeaderRow; } if (step == ParseStep.ParseTitle && (c == '\n' || c == '\r')) { step = ParseStep.ParseHeaderRow; } if (txt != "") { switch (step) { case ParseStep.ReadBlockType: { blockType = txt.ToUpper(); step = ParseStep.ReadBlockNumberOrName; break; } case ParseStep.ReadBlockNumberOrName: { blockNumberOrName = txt; step = ParseStep.ReadBlockRetVal; break; } case ParseStep.ReadBlockRetVal: { step = ParseStep.ReadBlockRetValType; break; } case ParseStep.ReadBlockRetValType: { blockRetValType = txt; akBlock = CreateBlock(blockType, blockNumberOrName, blockRetValType); step = ParseStep.ParseHeaderRow; break; } case ParseStep.ParseHeaderRow: { switch (txt.ToUpper()) { case ("TITLE"): { step = ParseStep.ParseTitle; break; } case ("VERSION"): { step = ParseStep.ParseVersion; break; } case ("STRUCT"): { step = ParseStep.ParseStructure; break; } case ("BEGIN"): { step = ParseStep.ParseAWLCode; break; } case ("VAR_INPUT"): case ("VAR_OUTPUT"): case ("VAR_IN_OUT"): case ("VAR_TEMP"): { step = ParseStep.ParsePara; break; } default: { if (txt.StartsWith("{") && txt.EndsWith("}")) { akBlock.Attributes = ParseStep7Attribute(txt); } break; } } break; } case ParseStep.ParseTitle: { akBlock.Title = txt; step = ParseStep.ParseHeaderRow; break; } case ParseStep.ParseVersion: { akBlock.Version = txt; step = ParseStep.ParseHeaderRow; break; } } } txt = ""; } else { txt = txt + c; } } return(retVal); }
private static S7Block CreateBlock(string blockType, string blockNumber, string type) { S7Block akBlock = null; switch (blockType.ToUpper()) { case ("TYPE"): { akBlock = new S7DataBlock() { BlockType = DataTypes.PLCBlockType.UDT, BlockLanguage = PLCLanguage.DB }; } break; case ("DATA_BLOCK"): { akBlock = new S7DataBlock() { BlockType = DataTypes.PLCBlockType.DB, BlockLanguage = PLCLanguage.DB }; } break; case ("FUNCTION"): { akBlock = new S7FunctionBlock() { BlockType = DataTypes.PLCBlockType.FC, BlockLanguage = PLCLanguage.AWL }; S7DataRow parameterRoot = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, akBlock); S7DataRow parameterIN = new S7DataRow("IN", S7DataRowType.STRUCT, akBlock); S7DataRow parameterOUT = new S7DataRow("OUT", S7DataRowType.STRUCT, akBlock); S7DataRow parameterINOUT = new S7DataRow("IN_OUT", S7DataRowType.STRUCT, akBlock); S7DataRow parameterSTAT = new S7DataRow("STATIC", S7DataRowType.STRUCT, akBlock); S7DataRow parameterTEMP = new S7DataRow("TEMP", S7DataRowType.STRUCT, akBlock); parameterOUT.Add(new S7DataRow("RET_VAL", (S7DataRowType)Enum.Parse(typeof(S7DataRowType), type), akBlock)); parameterRoot.Children.Add(parameterIN); parameterRoot.Children.Add(parameterOUT); parameterRoot.Children.Add(parameterINOUT); parameterRoot.Children.Add(parameterSTAT); parameterRoot.Children.Add(parameterTEMP); } break; case ("FUNCTION_BLOCK"): { akBlock = new S7FunctionBlock() { BlockType = DataTypes.PLCBlockType.FB, BlockLanguage = PLCLanguage.AWL }; S7DataRow parameterRoot = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, akBlock); S7DataRow parameterIN = new S7DataRow("IN", S7DataRowType.STRUCT, akBlock); S7DataRow parameterOUT = new S7DataRow("OUT", S7DataRowType.STRUCT, akBlock); S7DataRow parameterINOUT = new S7DataRow("IN_OUT", S7DataRowType.STRUCT, akBlock); S7DataRow parameterTEMP = new S7DataRow("TEMP", S7DataRowType.STRUCT, akBlock); parameterRoot.Children.Add(parameterIN); parameterRoot.Children.Add(parameterOUT); parameterRoot.Children.Add(parameterINOUT); parameterRoot.Children.Add(parameterTEMP); } break; } return(akBlock); }
/*internal static S7DataRow GetInterface(int Start, int Count, byte[] BD, DataTypes.PLCBlockType blkTP, bool isInstanceDB, S7Block myBlk) * { * S7DataRow parameterRoot = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, myBlk); * S7DataRow parameterIN = new S7DataRow("IN", S7DataRowType.STRUCT, myBlk); * S7DataRow parameterOUT = new S7DataRow("OUT", S7DataRowType.STRUCT, myBlk); * S7DataRow parameterINOUT = new S7DataRow("IN_OUT", S7DataRowType.STRUCT, myBlk); * S7DataRow parameterSTAT = new S7DataRow("STATIC", S7DataRowType.STRUCT, myBlk); * S7DataRow parameterTEMP = new S7DataRow("TEMP", S7DataRowType.STRUCT, myBlk); * S7DataRow parameterRETVAL = new S7DataRow("RET_VAL", S7DataRowType.STRUCT, myBlk); * * * parameterRoot.Add(parameterIN); * parameterRoot.Add(parameterOUT); * parameterRoot.Add(parameterINOUT); * if (blkTP == DataTypes.PLCBlockType.FB || (blkTP == DataTypes.PLCBlockType.DB && isInstanceDB)) * parameterRoot.Add(parameterSTAT); * if (blkTP != DataTypes.PLCBlockType.DB) * parameterRoot.Add(parameterTEMP); * parameterRoot.Add(parameterRETVAL); * parameterRoot.ReadOnly = true; * * if (blkTP == DataTypes.PLCBlockType.DB && !isInstanceDB) * parameterRoot = parameterSTAT; * * //PLCDataRowsInterface retVal = new PLCDataRowsInterface(); * int INcnt = 0; * int OUTcnt = 0; * int IN_OUTcnt = 0; * int STATcnt = 0; * int TEMPcnt = 0; * int StackNr = 1; * * * int pos = Start + 4; * string parNm = ""; * * S7DataRow akParameter = parameterRoot; * * * while (pos <= (Start + Count)) * { * switch (BD[pos + 1]) * { * case 0x01: * case 0x09: //with start val * akParameter = parameterIN; * parNm = "IN"; * break; * case 0x02: * case 0x0A: //with start val * akParameter = parameterOUT; * parNm = "OUT"; * break; * case 0x03: * case 0x0b: //with start val * akParameter = parameterINOUT; * parNm = "IN_OUT"; * break; * case 0x04: * case 0x0C: //with start val * akParameter = parameterSTAT; * parNm = "STAT"; * break; * case 0x05: * akParameter = parameterTEMP; * parNm = "TEMP"; * break; * case 0x06: * akParameter = parameterRETVAL; * parNm = "RET_VAL"; * break; * } * * * pos += 2; * } * return parameterRoot; * }*/ //internal PLCDataRow GetInterfaceSubrows(PLCDataRow currRow) internal static void GetVarTypeEN(S7DataRow currPar, object startVal, byte b, bool Struct, bool Arry, string VarName, byte[] interfaceBytes, byte[] actualvalueBytes, ref int pos, ref List <string> ParaList, ref int StackNr, string VarNamePrefix, ref int VarCounter, ref int Valpos, S7Block myBlk) { int i, max, dim; S7DataRowType Result = S7DataRowType.BOOL; switch (b) { case 0x01: Result = S7DataRowType.BOOL; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x02: Result = S7DataRowType.BYTE; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x03: Result = S7DataRowType.CHAR; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x04: Result = S7DataRowType.WORD; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x05: Result = S7DataRowType.INT; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x06: Result = S7DataRowType.DWORD; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x07: Result = S7DataRowType.DINT; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x08: Result = S7DataRowType.REAL; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x09: Result = S7DataRowType.DATE; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x0A: Result = S7DataRowType.TIME_OF_DAY; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x0b: Result = S7DataRowType.TIME; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x0C: Result = S7DataRowType.S5TIME; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x0E: Result = S7DataRowType.DATE_AND_TIME; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x10: //Array... { dim = interfaceBytes[pos + 2]; List <int> arrStart = new List <int>(); List <int> arrStop = new List <int>(); for (i = 0; i <= dim - 1; i++) { arrStart.Add(BitConverter.ToInt16(interfaceBytes, pos + 3 + (i * 4))); arrStop.Add(BitConverter.ToInt16(interfaceBytes, pos + 5 + (i * 4))); } GetVarTypeEN(currPar, "", interfaceBytes[pos + 3 + (dim * 4)], true, true, VarName, interfaceBytes, actualvalueBytes, ref pos, ref ParaList, ref StackNr, VarNamePrefix, ref VarCounter, ref Valpos, myBlk); ((S7DataRow)currPar.Children[currPar.Children.Count - 1]).ArrayStart = arrStart; ((S7DataRow)currPar.Children[currPar.Children.Count - 1]).ArrayStop = arrStop; ((S7DataRow)currPar.Children[currPar.Children.Count - 1]).IsArray = true; pos += 3 + (dim * 4); } break; case 0x11: //Struct { if (Arry) { pos += 7; } Result = S7DataRowType.STRUCT; var akPar = new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { StartValue = startVal }; currPar.Add(akPar); VarCounter++; max = interfaceBytes[pos + 2] - 1; for (i = 0; i <= max; i++) { if ((interfaceBytes[pos + 3] == 0x11) || (interfaceBytes[pos + 3] == 0x10)) { pos += 3; if (Helper.IsWithStartVal(interfaceBytes[pos + 1])) { if (interfaceBytes[pos] != 0x10) //Datentyp == Array... { startVal = GetVarTypeVal(interfaceBytes[pos], actualvalueBytes, ref Valpos); } else { Valpos = Valpos + 6; startVal = GetVarTypeVal(interfaceBytes[pos + 3 + (interfaceBytes[pos + 2] * 4)], actualvalueBytes, ref Valpos); } } else { startVal = null; } GetVarTypeEN(akPar, startVal, interfaceBytes[pos], true, false, VarName + "." + VarNamePrefix + VarCounter.ToString(), interfaceBytes, actualvalueBytes, ref pos, ref ParaList, ref StackNr, VarNamePrefix, ref VarCounter, ref Valpos, myBlk); pos -= 3; } else { if (Helper.IsWithStartVal(interfaceBytes[pos + 4])) { if (interfaceBytes[pos] != 0x10) //Datentyp == Array... { startVal = GetVarTypeVal(interfaceBytes[pos + 3], actualvalueBytes, ref Valpos); } else { Valpos = Valpos + 6; startVal = GetVarTypeVal(interfaceBytes[pos + 6 + (interfaceBytes[pos + 2] * 4)], actualvalueBytes, ref Valpos); } } else { startVal = null; } GetVarTypeEN(akPar, startVal, interfaceBytes[pos + 3], true, false, VarName + "." + VarNamePrefix + VarCounter.ToString(), interfaceBytes, actualvalueBytes, ref pos, ref ParaList, ref StackNr, VarNamePrefix, ref VarCounter, ref Valpos, myBlk); } pos += 2; } if (Arry) { pos -= 7; } pos += 1; } break; case 0x13: { Result = S7DataRowType.STRING; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); if (Arry) { currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal, StringSize = interfaceBytes[pos + 9] }); } else { currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal, StringSize = interfaceBytes[pos + 2] }); } pos += 1; VarCounter++; } break; case 0x14: Result = S7DataRowType.POINTER; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x16: Result = S7DataRowType.ANY; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x17: Result = S7DataRowType.BLOCK_FB; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x18: Result = S7DataRowType.BLOCK_FC; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x19: Result = S7DataRowType.BLOCK_DB; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x1A: Result = S7DataRowType.BLOCK_SDB; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x1C: Result = S7DataRowType.COUNTER; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; case 0x1D: Result = S7DataRowType.TIMER; currPar.Add(new S7DataRow(VarNamePrefix + VarCounter.ToString(), Result, myBlk) { Value = startVal }); VarCounter++; break; //default: Result = "UNKNOWN (" + Convert.ToString(b) + ")"; break; } //if (!Struct || Arry) { ParaList.Add(VarName); //Result = Result + "(" + Convert.ToString(StackNr * 2) + ")"; StackNr = StackNr + 1; } //return Result; }
internal static S7DataRow GetInterfaceOrDBFromStep7ProjectString(string txt, ref List <String> ParaList, PLCBlockType blkTP, bool isInstanceDB, BlocksOfflineFolder myFld, S7Block myBlk, byte[] actualValues = null) { S7DataRow parameterRoot = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, myBlk); S7DataRow parameterRootWithoutTemp = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, myBlk); if (myBlk is S7FunctionBlock) { (myBlk as S7FunctionBlock).ParameterWithoutTemp = parameterRootWithoutTemp; } S7DataRow parameterIN = new S7DataRow("IN", S7DataRowType.STRUCT, myBlk); S7DataRow parameterOUT = new S7DataRow("OUT", S7DataRowType.STRUCT, myBlk); S7DataRow parameterINOUT = new S7DataRow("IN_OUT", S7DataRowType.STRUCT, myBlk); S7DataRow parameterSTAT = new S7DataRow("STATIC", S7DataRowType.STRUCT, myBlk); S7DataRow parameterTEMP = new S7DataRow("TEMP", S7DataRowType.STRUCT, myBlk); //S7DataRow parameterRETVAL = new S7DataRow("RET_VAL", S7DataRowType.STRUCT, myBlk); S7DataRow akDataRow = parameterRoot; parameterIN.isRootBlock = true; parameterOUT.isRootBlock = true; parameterINOUT.isRootBlock = true; parameterINOUT.isInOut = true; parameterSTAT.isRootBlock = true; parameterTEMP.isRootBlock = true; bool tempAdded = false; int Valpos = 0; if (txt == null) { if (blkTP != PLCBlockType.DB) { parameterRoot.Add(parameterTEMP); } return(parameterRoot); } //Todo: read the complete DB from mc5 code first, Read the containing UDTs, compare the UDTs with the Structs, if the UDTs and Structs are not Equal, marke the PLCDataRow as TimeStampConflict string[] rows = txt.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); S7DataRow lastrow = null; Dictionary <string, S7Block> blkHelpers = new Dictionary <string, S7Block>(); for (int n = 0; n < rows.Length; n++) // (string row in rows) { string rowTr = rows[n].Replace("\0", "").Trim(); int poscm = rowTr.IndexOf("\t//"); if (poscm <= 0) { poscm = rowTr.Length; } string switchrow = rowTr.Substring(0, poscm); string commnew = ""; if (poscm != rowTr.Length) { commnew = rowTr.Substring(poscm + 1); } if (rowTr.StartsWith("//")) { if (lastrow != null) { lastrow.Comment += rowTr; } else { if (commnew != null) { if (string.IsNullOrEmpty(akDataRow.Comment)) { akDataRow.Comment += rowTr; } else { akDataRow.Comment += "\r\n" + rowTr; } } } } else { switch (switchrow.Trim()) { case "VAR_INPUT": akDataRow = parameterIN; akDataRow.Comment = commnew; parameterRoot.Add(parameterIN); parameterRootWithoutTemp.Add(parameterIN); break; case "VAR_OUTPUT": akDataRow = parameterOUT; akDataRow.Comment = commnew; parameterRoot.Add(parameterOUT); parameterRootWithoutTemp.Add(parameterOUT); break; case "VAR_IN_OUT": akDataRow = parameterINOUT; akDataRow.Comment = commnew; parameterRoot.Add(parameterINOUT); parameterRootWithoutTemp.Add(parameterINOUT); break; case "VAR_TEMP": akDataRow = parameterTEMP; if (blkTP != PLCBlockType.DB) { tempAdded = true; parameterRoot.Add(parameterTEMP); } break; case "VAR": //Static Data on a FB akDataRow = parameterSTAT; parameterRoot.Add(parameterSTAT); parameterRootWithoutTemp.Add(parameterSTAT); break; case "END_STRUCT;": case "END_STRUCT ;": akDataRow = ((S7DataRow)akDataRow.Parent); break; case "STRUCT": case "END_VAR": case "": if (commnew != null) { if (string.IsNullOrEmpty(akDataRow.Comment)) { akDataRow.Comment += commnew; } else { akDataRow.Comment += "\r\n" + commnew; } } break; default: char oldChar = ' '; List <Step7Attribute> Step7Attributes = new List <Step7Attribute>(); string tmpName = ""; string tmpAttributeName = ""; string tmpAttributeValue = ""; string tmpType = ""; string tmpComment = ""; string tmpValue = ""; int parseZustand = 0; //0=ParName, 1=AttributeName, 6=AfterAttributeName, 2=AttributeValue, 3=Type, 4=Value, 7=InnerValue (without '), 5=Comment var p1 = rows[n].IndexOf(" OF "); int p2 = 0, p3 = 0; if (p1 > 0) { p2 = rows[n].IndexOf(";", p1); p3 = rows[n].IndexOf("//", p1); } //if (rows[n].Contains("ARRAY") && rows[n].Contains(" OF ") && !rows[n].Contains("\t\r")) // !rows[n].Contains("\t") if (rows[n].Contains("ARRAY") && rows[n].Contains(" OF ") && (!(p2 > p1 && (p2 < p3 || p3 < 0)) && !rows[n].Contains("\t\r"))) { if (rows.Length > n + 1) { if (rowTr.Contains("//")) { int pos = rowTr.IndexOf("//"); rowTr = rowTr.Substring(0, pos) + " " + rows[n + 1].Trim() + rowTr.Substring(pos); } else if (rowTr.Contains("OF STRUCT")) { } else if (rowTr[rowTr.Length - 1] != ';') { rowTr += " " + rows[n + 1].Trim(); } n++; } } for (int j = 0; j < rowTr.Length; j++) { char tmpChar = rowTr[j]; if (parseZustand == 0 && tmpChar == '{') { parseZustand = 1; } else if (parseZustand == 0 && tmpChar != ' ' && tmpChar != ':') { tmpName += tmpChar; } else if (parseZustand == 6 && tmpChar == '\'') { parseZustand = 2; } else if (parseZustand == 1 && tmpChar == ':' && rowTr[j + 1] == '=') { parseZustand = 6; j++; } else if (parseZustand == 1 && tmpChar != ' ' && tmpChar != ':' && tmpChar != '=' && tmpChar != '}' && tmpChar != '\'' && tmpChar != ';') { tmpAttributeName += tmpChar; } else if (parseZustand == 1 && tmpChar == '}') { parseZustand = 0; } else if (parseZustand == 0 && tmpChar == ':') { parseZustand = 3; } else if (parseZustand == 2 && tmpChar == '$') { tmpAttributeValue += rowTr[j + 1]; j++; } else if (parseZustand == 2 && tmpChar == '\'') { parseZustand = 1; Step7Attributes.Add(new Step7Attribute(tmpAttributeName, tmpAttributeValue)); tmpAttributeName = ""; tmpAttributeValue = ""; } else if (parseZustand == 2) { tmpAttributeValue += tmpChar; } //else if (parseZustand == 3 && tmpChar == ':') // parseZustand = 2; else if (parseZustand == 3 && tmpChar == ':' && rowTr[j + 1] == '=') { parseZustand = 4; j++; } else if ((parseZustand == 3 || parseZustand == 4) && tmpChar == '/' && rowTr[j + 1] == '/') { parseZustand = 5; j++; } else if (parseZustand == 4 && tmpChar == '\'') { tmpValue += tmpChar; parseZustand = 7; } else if (parseZustand == 7 && tmpChar == '$') { tmpValue += rowTr[j + 1]; j++; } else if (parseZustand == 7 && tmpChar == '\'') { tmpValue += tmpChar; parseZustand = 4; } else if (parseZustand == 3 && tmpChar != ';') { tmpType += tmpChar; } else if (parseZustand == 4 && tmpChar != ';' && tmpChar != ' ') { tmpValue += tmpChar; } else if (parseZustand == 7) { tmpValue += tmpChar; } else if (parseZustand == 5) { tmpComment += tmpChar; } } tmpType = tmpType.Trim().ToUpper(); S7DataRow addRW = new S7DataRow(tmpName, S7DataRowType.UNKNOWN, myBlk); lastrow = addRW; if (tmpType.Replace(" ", "").Contains("ARRAY[")) { List <int> arrayStart = new List <int>(); List <int> arrayStop = new List <int>(); int pos1 = tmpType.IndexOf("["); int pos2 = tmpType.IndexOf("]", pos1); string[] arrays = tmpType.Substring(pos1 + 1, pos2 - pos1 - 2).Split(','); foreach (string array in arrays) { string[] akar = array.Split(new string[] { ".." }, StringSplitOptions.RemoveEmptyEntries); arrayStart.Add(Convert.ToInt32(akar[0].Trim())); arrayStop.Add(Convert.ToInt32(akar[1].Trim())); } addRW.ArrayStart = arrayStart; addRW.ArrayStop = arrayStop; addRW.IsArray = true; tmpType = tmpType.Substring(pos2 + 5); } addRW.Comment = tmpComment.Replace("$'", "'").Replace("$$", "$"); if (Step7Attributes.Count > 0) { addRW.Attributes = Step7Attributes; } int akRowTypeNumber = 0; if (tmpType.Contains("SFB")) { addRW.DataType = S7DataRowType.SFB; akRowTypeNumber = Convert.ToInt32(tmpType.Substring(4)); string blkDesc = "SFB" + akRowTypeNumber.ToString(); S7FunctionBlock tmpBlk; if (blkHelpers.ContainsKey(blkDesc)) { tmpBlk = (S7FunctionBlock)blkHelpers[blkDesc]; } else { tmpBlk = ((S7FunctionBlock)myFld.GetBlock(blkDesc)); blkHelpers.Add(blkDesc, tmpBlk); } if (tmpBlk != null && tmpBlk.Parameter != null && tmpBlk.Parameter.Children != null) { addRW.AddRange(tmpBlk.ParameterWithoutTemp.DeepCopy().Children.Cast <S7DataRow>()); } } else if (tmpType.Contains("UDT")) { addRW.DataType = S7DataRowType.UDT; akRowTypeNumber = Convert.ToInt32(tmpType.Substring(4)); string blkDesc = "UDT" + akRowTypeNumber.ToString(); S7DataBlock tmpBlk; if (blkHelpers.ContainsKey(blkDesc)) { tmpBlk = (S7DataBlock)blkHelpers[blkDesc]; } else { tmpBlk = ((S7DataBlock)myFld.GetBlock(blkDesc)); blkHelpers.Add(blkDesc, tmpBlk); } if (tmpBlk != null && tmpBlk.Structure != null && tmpBlk.Structure.Children != null) { addRW.AddRange(((S7DataRow)tmpBlk.Structure).DeepCopy().Children.Cast <S7DataRow>()); } } else if (tmpType.Contains("BLOCK_FB")) { addRW.DataType = S7DataRowType.BLOCK_FB; //akRowTypeNumber = Convert.ToInt32(tmpType.Substring(3)); //PLCFunctionBlock tmpBlk = ((PLCFunctionBlock)myFld.GetBlock("FB" + akRowTypeNumber.ToString())); //if (tmpBlk != null && tmpBlk.Parameter != null && tmpBlk.Parameter.Children != null) // addRW.AddRange(tmpBlk.Parameter.Children); } else if (tmpType.Contains("FB")) { addRW.DataType = S7DataRowType.FB; akRowTypeNumber = Convert.ToInt32(tmpType.Substring(3)); string blkDesc = "FB" + akRowTypeNumber.ToString(); S7FunctionBlock tmpBlk; if (blkHelpers.ContainsKey(blkDesc)) { tmpBlk = (S7FunctionBlock)blkHelpers[blkDesc]; } else { tmpBlk = ((S7FunctionBlock)myFld.GetBlock(blkDesc)); blkHelpers.Add(blkDesc, tmpBlk); } if (tmpBlk != null && tmpBlk.Parameter != null && tmpBlk.Parameter.Children != null) { addRW.AddRange(tmpBlk.ParameterWithoutTemp.DeepCopy().Children.Cast <S7DataRow>()); } } else if (tmpType.Contains("STRING")) { addRW.DataType = S7DataRowType.STRING; int pos1 = tmpType.IndexOf("["); int pos2 = tmpType.IndexOf("]", pos1); addRW.StringSize = Convert.ToInt32(tmpType.Substring(pos1 + 1, pos2 - pos1 - 2)); } else { addRW.DataType = (S7DataRowType)Enum.Parse(typeof(S7DataRowType), tmpType.ToUpper()); } addRW.DataTypeBlockNumber = akRowTypeNumber; if (tmpValue != "") { //Todo: Startvalues bei arrays... //Mehrere Values... //TRUE,6(FALSE),TRUE,TRUE,7(FALSE) if (addRW.IsArray) { addRW.StartValue = tmpValue; } else { addRW.StartValue = Helper.StringValueToObject(tmpValue, addRW.DataType); } } else { if (!addRW.IsArray) { addRW.StartValue = Helper.DefaultValueForType(addRW.DataType); } } //if (actualValues != null) //{ // addRW.Value = GetVarTypeVal((byte)addRW.DataType, actualValues, ref Valpos); //} akDataRow.Add(addRW); ParaList.Add(tmpName); if (addRW.DataType == S7DataRowType.STRUCT) { akDataRow = addRW; } break; /* * Attributname kann nicht ' und } enthalten! * In Attribt Values * $$ zum ausmaskieren von $ * $' zum ausmaskieren von ' * * Beispielzeilen.... * // "ID { S7_co := 'agag'; S7_server1 := 'connection' }: INT ;\t// Connection ID 1..16" * // "LADDR { S7_co := 'agag'; S7_server1 := 'connection' }: WORD ;\t// Module address in hardware configuration" * // "RECV : ANY ;\t// Buffer for received data" * // "NDR : BOOL ;\t// Indicates whether new data were received" * // "aa { ff := '//ghghf}' }: BOOL ;" * // "bb : INT := 8888;" * // "P_1001 : ARRAY [0 .. 3 ] OF CHAR := '1', '0', '0', '1';" * // "aa : STRING [20 ] := 'deewedw';" * // "aa { dsfs := '' }: BOOL ;" * * //"res : ARRAY [1 .. 121 ] OF STRUCT" * // "P_AKL1 : ARRAY [0 .. 3 ] OF CHAR := 'A', 'K', 'L', '1';" */ } } } if (blkTP != PLCBlockType.DB && blkTP != PLCBlockType.UDT && tempAdded == false) { parameterRoot.Add(parameterTEMP); } if (actualValues != null) { int vPos = 0, bPos = 0; //FillActualValuesInDataBlock(parameterRoot, actualValues, ref vPos, ref bPos); } return(parameterRoot); }
/// <summary> /// With this Function you get the AWL Source of a Block, so that it can be imported into Step7 /// </summary> /// <param name="blkInfo">The BlockInfo from the Block you wish to get the Source of!</param> /// <returns></returns> public string GetSourceBlock(ProjectBlockInfo blkInfo) { StringBuilder retVal = new StringBuilder(); Block blk = GetBlock(blkInfo, new S7ConvertingOptions(Project.ProjectLanguage) { CombineDBOpenAndDBAccess = true, GenerateCallsfromUCs = true, ReplaceDBAccessesWithSymbolNames = false, ReplaceLokalDataAddressesWithSymbolNames = true, UseComments = true }); S7Block fblk = (S7Block)blk; S7FunctionBlock fcblk = null; if (blk is S7FunctionBlock) { fcblk = (S7FunctionBlock)blk; if (fcblk.BlockType == PLCBlockType.FC) { retVal.Append("FUNCTION " + blk.BlockName + " : VOID" + Environment.NewLine); } else { retVal.Append("FUNCTION_BLOCK " + blk.BlockName + Environment.NewLine); } } else { retVal.Append("DATA_BLOCK " + blk.BlockName + Environment.NewLine); } retVal.Append("TITLE =" + fblk.Title + Environment.NewLine); if (blk is S7FunctionBlock) { if (!String.IsNullOrEmpty(fcblk.Description)) { retVal.Append("//" + fcblk.Description.Replace(Environment.NewLine, Environment.NewLine + "//") + Environment.NewLine); } } if (!string.IsNullOrEmpty(fblk.Author)) { retVal.Append("AUTHOR : " + fblk.Author + Environment.NewLine); } if (!string.IsNullOrEmpty(fblk.Name)) { retVal.Append("NAME : " + fblk.Name + Environment.NewLine); } if (!string.IsNullOrEmpty(fblk.Version)) { retVal.Append("VERSION : " + fblk.Version + Environment.NewLine); } retVal.Append(Environment.NewLine); retVal.Append(Environment.NewLine); if (blk is S7DataBlock) { S7DataBlock dtaBlk = (S7DataBlock)fblk; if (dtaBlk.Structure.Children != null && !dtaBlk.IsInstanceDB) { retVal.Append(" STRUCT" + Environment.NewLine); retVal.Append(GetSubParas(dtaBlk.Structure, " ")); retVal.Append(" END_STRUCT ;" + Environment.NewLine); } else if (dtaBlk.IsInstanceDB) { retVal.Append(" FB " + dtaBlk.FBNumber + Environment.NewLine); } retVal.Append("BEGIN" + Environment.NewLine); retVal.Append("END_DATA_BLOCK" + Environment.NewLine); } else if (blk is S7FunctionBlock) { if (fcblk.Parameter.Children != null) { foreach (S7DataRow s7DataRow in fcblk.Parameter.Children) { string parnm = s7DataRow.Name; string ber = "VAR_" + parnm; if (parnm == "IN") { ber = "VAR_INPUT"; } else if (parnm == "OUT") { ber = "VAR_OUTPUT"; } else if (parnm == "STATIC") { ber = "VAR"; } retVal.Append(ber + Environment.NewLine); retVal.Append(GetSubParas(s7DataRow, " ")); retVal.Append("END_VAR" + Environment.NewLine); } } retVal.Append("BEGIN" + Environment.NewLine); foreach (Network network in fcblk.Networks) { retVal.Append("NETWORK" + Environment.NewLine); retVal.Append("TITLE = " + network.Name + Environment.NewLine); if (!String.IsNullOrEmpty(network.Comment)) { retVal.Append("//" + network.Comment.Replace(Environment.NewLine, Environment.NewLine + "//") + Environment.NewLine); } else { retVal.Append(Environment.NewLine); } foreach (S7FunctionBlockRow functionBlockRow in network.AWLCode) { if (functionBlockRow.ToString(false, false) == "") { retVal.Append(Environment.NewLine); } else { retVal.Append(functionBlockRow.ToString(false, true) + Environment.NewLine); } } } retVal.Append("END_FUNCTION"); } return(retVal.ToString()); }
public void MergeBlocks(S7Block leftBlock, S7Block rightBlock) { // Standard FB/FC/DB // Should have both blocks if (leftBlock == null || rightBlock == null) { EventFire.Error("Merge S7 Blocks. Can't find block in the Simatic structure."); return; } EventFire.Info("Merge S7 Blocks. Generating right source."); if (!Directory.Exists(_RightSourceFilePath)) Directory.CreateDirectory(_RightSourceFilePath); String rightSourceFileName = _RightSourceFilePath + rightBlock.Name + ".awl"; rightBlock.GenerateSource(rightSourceFileName, S7GenerateSourceFlags.S7GSFDoOverwrite); EventFire.Info("Merge S7 Blocks. Generating left source."); if (!Directory.Exists(_LeftSourceFilePath)) Directory.CreateDirectory(_LeftSourceFilePath); String leftSourceFileName = _LeftSourceFilePath + leftBlock.Name + ".awl"; leftBlock.GenerateSource(leftSourceFileName, S7GenerateSourceFlags.S7GSFDoOverwrite); String mergedSourceFileName = _MergedSourceFilePath + rightBlock.Name + ".awl"; Process DiffProcess = new Process { StartInfo = new ProcessStartInfo { FileName = "TortoiseMerge.exe", Arguments = "/base:\"" + leftSourceFileName + "\" /mine:\"" + rightSourceFileName + "\" /merged:\"" + mergedSourceFileName + "\"" } }; DiffProcess.Start(); DiffProcess.WaitForExit(); if (File.Exists(mergedSourceFileName)) { S7SWItems s7swItems = rightBlock.Program.Next; for (int i = 1; i <= s7swItems.Count; i++) { if (((S7Container)s7swItems[i]).ConcreteType == S7ContainerType.S7SourceContainer) { IS7Source3 s7Source = (IS7Source3)s7swItems[i].Next.Add("Tmprc", S7SWObjType.S7Source, mergedSourceFileName); EventFire.Info("Merge S7 Blocks. Compiling block."); S7SWItems s7swReturn = s7Source.Compile(); IntPtr hwnd = (IntPtr)s7Source.AppWindowHandle; ShowWindow(hwnd, 6); // 0 = hide the window, 6 = minimize if (s7swReturn.Count <= 0) { // Something is not right - show edit window EventFire.Error("Merge S7 Blocks. Can't compile block, please resolve compilation errors."); ShowWindow(hwnd, 3); // 3 - maximize s7Source.Edit(); // Wait till they fixed it and close the window while (IsWindow(hwnd)) ; } else { // Close editor window EventFire.Info("Merge S7 Blocks. Compiled successfully."); //SendMessage(hwnd, 0x0112, 0xF060, 0); // 0xF060 = SC_CLOSE; 0x0112 = WM_SYSCOMMAND } // Remove the source s7Source.Remove(); // S7 editor doesn't like close message. Minimize it ShowWindow(hwnd, 6); break; } } } }
static public byte[] GetMC7Block(S7Block myBlock) { byte[] retByte = AWLtoMC7.GetMC7(myBlock); return(retByte); }
/// <summary> /// Parse the Header and Footer information from an online MC7Code byte blob /// </summary> /// <param name="MC7Code">The online MC7 Code blob from the PLC</param> /// <param name="MnemoricLanguage">The Mnemoric that should be used when parsing the Blocks data</param> /// <returns></returns> internal static S7Block ParseBlockHeaderAndFooterFromMC7(byte[] MC7Code, MnemonicLanguage MnemoricLanguage) { S7Block retBlock = null; if (MC7Code != null) { //Parse Block type and prepare the Return block acordingly PLCBlockType BlockType = Helper.GetPLCBlockType(MC7Code[5]); if (BlockType == PLCBlockType.DB || BlockType == PLCBlockType.SDB) { retBlock = (S7Block) new S7DataBlock(); } else { retBlock = (S7Block) new S7FunctionBlock(); } /* * Description of a MC7 Block Header * * 0,1 = Signature ('pp') * 2 = Block Version * 3 = Block Attribute (.0 not unlinked, .1 standart block + know how protect, .3 know how protect, .5 not retain * 4 = Block Language * 5 = Block Type (a=DB, b=SDB) * 6,7 = Block Number * 8-11 = Block Length * 12-15 = Block Password * 16-21 = Last Modified * 22-27 = Last Interface Change * 28,29 = Interface length or DB Body (actual Values Part) length * 30,31 = Segment Table Length (Normaly 0 on a DB) (Length of networks!) * 32,33 = Local Data Length? (Normaly 0 on a DB) * 34,35 = MC7-Length or DB Body (definitions/initial values) */ /* * Description of a MC7 Block (Function - Block) * 36-xx = Header * xx+1, = 0x01 * xx+2,xx+3 = Again Block number, Zero on OB (but bytes swapped) * xx+4,xx+5 = Interface Length (from xx+6 to yy) * xx+6,xx+7 = Interface Blocks Count (In,Out,Satic,TMP etc) * 2 * xx+9-yy = Interface * yy+1-zz = Networks * */ /* * Description of a MC7 Block (Data - Block) * 36-xx = Header * xx+1, = 0x05 (DB) 0x10 (DI) * xx+2,xx+3 = Again Block Number or FB Number on a DI (but bytes swapped) * xx+4,xx+5 = Interface Length * xx+6,xx+7 = Interface Blocks Count (In,Out,Satic,TMP etc) * 2 * xx+8-yy = Interface * yy-zz = Start-Values */ //---------------------------------------------------------------------------------------------------- //Parse header data //---------------------------------------------------------------------------------------------------- retBlock.BlockVersion = Convert.ToString(MC7Code[2] - 1); //This is not the Block version from the Simatic Manager. It is unclar what data is stored in MC7Code[2] retBlock.BlockAttribute = (S7Block.S7BlockAtributes)MC7Code[3]; retBlock.BlockLanguage = (PLCLanguage)MC7Code[4]; // Enum.Parse(typeof(DataTypes.PLCLanguage), Helper.GetLang(MC7Code[4])); retBlock.MnemonicLanguage = (MnemonicLanguage)MnemoricLanguage; retBlock.BlockType = Helper.GetPLCBlockType(MC7Code[5]); retBlock.BlockNumber = (MC7Code[6] * 0x100) + MC7Code[7]; retBlock.Length = libnodave.getU32from(MC7Code, 8); retBlock.Password = new byte[] { MC7Code[12], MC7Code[13], MC7Code[14], MC7Code[15] }; retBlock.KnowHowProtection = (MC7Code[12] + MC7Code[13] + MC7Code[14] + MC7Code[15]) != 0; //if any of the Password bytes contains an non Zero value retBlock.LastCodeChange = Helper.GetDT(MC7Code[16], MC7Code[17], MC7Code[18], MC7Code[19], MC7Code[20], MC7Code[21]); retBlock.LastInterfaceChange = Helper.GetDT(MC7Code[22], MC7Code[23], MC7Code[24], MC7Code[25], MC7Code[26], MC7Code[27]); //---------------------------------------------------------------------------------------------------- //Parse Code and Data lengths //---------------------------------------------------------------------------------------------------- int InterfaceLength_or_DBActualValuesLength = libnodave.getU16from(MC7Code, 28); retBlock.SegmentTableSize = libnodave.getU16from(MC7Code, 30); //(Length of networks?) int LocalDataLength = libnodave.getU16from(MC7Code, 32); int MC7Length_or_DBBodyLength = libnodave.getU16from(MC7Code, 34); retBlock.InterfaceSize = InterfaceLength_or_DBActualValuesLength; retBlock.LocalDataSize = LocalDataLength; retBlock.CodeSize = MC7Length_or_DBBodyLength; retBlock.WorkMemorySize = retBlock.CodeSize + MC7Start_or_DBBodyStart; //in my tests(about 10 different blocks), this was alwasy 36 bytes more then the MC7 code size //---------------------------------------------------------------------------------------------------- //Parse footer data //---------------------------------------------------------------------------------------------------- //Old: int FooterStart = MC7Start_or_DBBodyStart + MC7Length_or_DBBodyLength + InterfaceLength_or_DBActualValuesLength + retBlock.SegmentTableSize; //Testing showed that the Footer always starts 36 bytes (footer lenght) before the end of the MC7 block. //so use this version, so that now there is no need for "GetAWLBlockBasicInfoFromBlockHeader" because its actually the same int FooterStart = MC7Code.Length - FooterLength; retBlock.Author = Helper.GetString(FooterStart + 0, 8, MC7Code); retBlock.Family = Helper.GetString(FooterStart + 8, 8, MC7Code); retBlock.Name = Helper.GetString(FooterStart + 16, 8, MC7Code); retBlock.Version = Helper.GetVersion(MC7Code[FooterStart + 24]); retBlock.CheckSum = libnodave.getU16from(MC7Code, FooterStart + 26); } return(retBlock); }
internal static S7Block GetAWLBlockBasicInfo(byte[] MC7Code, int MnemoricLanguage) { S7Block retBlock = null; if (MC7Code != null) { if ((MC7Code[5] == 0x0a) || (MC7Code[5] == 0x0b)) { retBlock = (S7Block) new S7DataBlock(); } else { retBlock = (S7Block) new S7FunctionBlock(); } /* * Description of a MC7 Block (Common) * * 0,1 = Signature ('pp') * 2 = Block Version * 3 = Block Attribute (.0 not unlinked, .1 standart block + know how protect, .3 know how protect, .5 not retain * 4 = Block Language * 5 = Block Type (a=DB, b=SDB) * 6,7 = Block Number * 8-11 = Block Length * 12-15 = Block Password * 16-21 = Last Modified * 22-27 = Last Interface Change * 28,29 = Interface length or DB Body (actual Values Part) length * 30,31 = Segment Table Length? (Normaly 0 on a DB) (Length of networks!) * 32,33 = Local Data Length? (Normaly 0 on a DB) * 34,35 = MC7-Length or DB Body (definitions/initial values) */ /* * Description of a MC7 Block (Function - Block) * 36-xx = AWL * xx+1, = 0x01 * xx+2,xx+3 = Again Block number, Zero on OB (but bytes swapped) * xx+4,xx+5 = Interface Length (from xx+6 to yy) * xx+6,xx+7 = Interface Blocks Count (In,Out,Satic,TMP etc) * 2 * xx+8,xx+9 = allways Zero * xx+10-yy = Interface * yy+1-zz = Networks * */ /* * Description of a MC7 Block (Data - Block) * 36-xx = AWL * xx+1, = 0x05 (DB) 0x10 (DI) * xx+2,xx+3 = Again Block Number or FB Number on a DI (but bytes swapped) * xx+4,xx+5 = Interface Length * xx+6-yy = Interface * yy-zz = Start-Values * xx = Nertworks */ retBlock.BlockVersion = Convert.ToString(MC7Code[2] - 1); //This is not the Block version from the Simatic Manager. It is unclar what data is stored in MC7Code[2] retBlock.BlockAttribute = (S7Block.S7BlockAtributes)MC7Code[3]; retBlock.BlockLanguage = (DataTypes.PLCLanguage)MC7Code[4]; // Enum.Parse(typeof(DataTypes.PLCLanguage), Helper.GetLang(MC7Code[4])); retBlock.MnemonicLanguage = (MnemonicLanguage)MnemoricLanguage; retBlock.BlockType = Helper.GetPLCBlockType(MC7Code[5]); retBlock.BlockNumber = (MC7Code[6] * 0x100) + MC7Code[7]; retBlock.Length = libnodave.getU32from(MC7Code, 8); retBlock.Password = new byte[] { MC7Code[12], MC7Code[13], MC7Code[14], MC7Code[15] }; retBlock.LastCodeChange = Helper.GetDT(MC7Code[16], MC7Code[17], MC7Code[18], MC7Code[19], MC7Code[20], MC7Code[21]); retBlock.LastInterfaceChange = Helper.GetDT(MC7Code[22], MC7Code[23], MC7Code[24], MC7Code[25], MC7Code[26], MC7Code[27]); int InterfaceLength_or_DBActualValuesLength = libnodave.getU16from(MC7Code, 28); retBlock.SegmentTableSize = libnodave.getU16from(MC7Code, 30); //(Length of networks?) int LocalDataLength = libnodave.getU16from(MC7Code, 32); int MC7Length_or_DBBodyLength = libnodave.getU16from(MC7Code, 34); retBlock.InterfaceSize = InterfaceLength_or_DBActualValuesLength; retBlock.LocalDataSize = LocalDataLength; retBlock.CodeSize = MC7Length_or_DBBodyLength; int FooterStart = MC7Start_or_DBBodyStart + MC7Length_or_DBBodyLength + InterfaceLength_or_DBActualValuesLength + retBlock.SegmentTableSize; retBlock.Author = Helper.GetString(FooterStart + 0, 8, MC7Code); retBlock.Family = Helper.GetString(FooterStart + 8, 8, MC7Code); retBlock.Name = Helper.GetString(FooterStart + 16, 8, MC7Code); retBlock.Version = Helper.GetVersion(MC7Code[FooterStart + 24]); retBlock.CheckSum = libnodave.getU16from(MC7Code, FooterStart + 26); } return(retBlock); }
// internal static S7DataRow GetInterface(byte[] interfaceBytes, byte[] actualvalueBytes, ref List <String> ParaList, DataTypes.PLCBlockType blkTP, bool isInstanceDB, S7Block myBlk) { S7DataRow parameterRoot = new S7DataRow("ROOTNODE", S7DataRowType.STRUCT, myBlk); S7DataRow parameterIN = new S7DataRow("IN", S7DataRowType.STRUCT, myBlk); S7DataRow parameterOUT = new S7DataRow("OUT", S7DataRowType.STRUCT, myBlk); S7DataRow parameterINOUT = new S7DataRow("IN_OUT", S7DataRowType.STRUCT, myBlk); S7DataRow parameterSTAT = new S7DataRow("STATIC", S7DataRowType.STRUCT, myBlk); S7DataRow parameterTEMP = new S7DataRow("TEMP", S7DataRowType.STRUCT, myBlk); S7DataRow parameterRETVAL = new S7DataRow("RET_VAL", S7DataRowType.STRUCT, myBlk); parameterRoot.Add(parameterIN); parameterRoot.Add(parameterOUT); parameterRoot.Add(parameterINOUT); if (blkTP == DataTypes.PLCBlockType.FB || (blkTP == DataTypes.PLCBlockType.DB && isInstanceDB)) { parameterRoot.Add(parameterSTAT); } if (blkTP != DataTypes.PLCBlockType.DB) { parameterRoot.Add(parameterTEMP); } parameterRoot.Add(parameterRETVAL); parameterRoot.ReadOnly = true; if (blkTP == DataTypes.PLCBlockType.DB && !isInstanceDB) { parameterRoot = parameterSTAT; } int INp = 0; int OUTp = 0; int IN_OUTp = 0; int STATp = 0; int TEMPp = 0; int StackNr = 1; int pos = 7; int Valpos = 0; S7DataRow akParameter = parameterRoot; ParaList.Clear(); while (pos <= (interfaceBytes.Length - 2)) // && pos < BD.Length - 2) //pos<BD.Length-2 was added so SDBs can be converted!! but is this needed? { object startVal; if (Helper.IsWithStartVal(interfaceBytes[pos + 1])) { if (interfaceBytes[pos] != 0x10) //Datentyp == Array... { startVal = GetVarTypeVal(interfaceBytes[pos], actualvalueBytes, ref Valpos); } else { Valpos = Valpos + 6; startVal = GetVarTypeVal(interfaceBytes[pos + 3 + (interfaceBytes[pos + 2] * 4)], actualvalueBytes, ref Valpos); } } else { startVal = null; } switch (interfaceBytes[pos + 1]) { case 0x01: case 0x09: { GetVarTypeEN(parameterIN, startVal, interfaceBytes[pos], false, false, "IN" + Convert.ToString(INp), interfaceBytes, actualvalueBytes, ref pos, ref ParaList, ref StackNr, "IN", ref INp, ref Valpos, myBlk); } break; case 0x02: case 0x0A: { GetVarTypeEN(parameterOUT, startVal, interfaceBytes[pos], false, false, "OUT" + Convert.ToString(OUTp), interfaceBytes, actualvalueBytes, ref pos, ref ParaList, ref StackNr, "OUT", ref OUTp, ref Valpos, myBlk); } break; case 0x03: case 0x0b: { GetVarTypeEN(parameterINOUT, startVal, interfaceBytes[pos], false, false, "IN_OUT" + Convert.ToString(IN_OUTp), interfaceBytes, actualvalueBytes, ref pos, ref ParaList, ref StackNr, "IN_OUT", ref IN_OUTp, ref Valpos, myBlk); } break; case 0x04: case 0x0C: { GetVarTypeEN(parameterSTAT, startVal, interfaceBytes[pos], false, false, "STAT" + Convert.ToString(STATp), interfaceBytes, actualvalueBytes, ref pos, ref ParaList, ref StackNr, "STAT", ref STATp, ref Valpos, myBlk); } break; case 0x05: { GetVarTypeEN(parameterTEMP, startVal, interfaceBytes[pos], false, false, "TEMP" + Convert.ToString(TEMPp), interfaceBytes, actualvalueBytes, ref pos, ref ParaList, ref StackNr, "TEMP", ref TEMPp, ref Valpos, myBlk); } break; case 0x06: { int tmp = 0; GetVarTypeEN(parameterRETVAL, startVal, interfaceBytes[pos], false, false, "RET_VAL", interfaceBytes, actualvalueBytes, ref pos, ref ParaList, ref StackNr, "RET_VAL", ref tmp, ref Valpos, myBlk); } break; /*default: * RETURNIntf = RETURNIntf + Convert.ToString(pos) + " UNKNOWN: " + * Convert.ToString(BD[pos + 1]) + " " + Convert.ToString(BD[pos]) + startVal + * "\r\n"; * break;*/ } pos += 2; } return(parameterRoot); }
public static S7Block GetAWLBlock(byte[] MC7Code, int MnemoricLanguage, S7ProgrammFolder prjBlkFld) { /* * string ttmp = ""; * for (int i = 0; i < MC7Code.Length; i++) * { * ttmp += MC7Code[i].ToString("X").PadLeft(2, '0'); * } * MessageBox.Show(ttmp); * Clipboard.SetText(ttmp); */ S7Block retBlock = null; if (MC7Code != null) { if ((MC7Code[5] == 0x0a) || (MC7Code[5] == 0x0b)) { retBlock = (S7Block) new S7DataBlock(); } else { retBlock = (S7Block) new S7FunctionBlock(); } const int MC7Start_or_DBBodyStart = 36; /* * Description of a MC7 Block (Common) * * 0,1 = Signature ('pp') * 2 = Block Version * 3 = Block Attribute (.0 not unlinked, .1 standart block + know how protect, .3 know how protect, .5 not retain * 4 = Block Language * 5 = Block Type (a=DB, b=SDB) * 6,7 = Block Number * 8-11 = Block Length * 12-15 = Block Password * 16-21 = Last Modified * 22-27 = Last Interface Change * 28,29 = Interface length or DB Body (actual Values Part) length * 30,31 = Segment Table Length? (Normaly 0 on a DB) (Length of networks!) * 32,33 = Local Data Length? (Normaly 0 on a DB) * 34,35 = MC7-Length or DB Body (definitions/initial values) */ /* * Description of a MC7 Block (Function - Block) * 36-xx = AWL * xx+1, = 0x01 * xx+2,xx+3 = Again Block number, Zero on OB (but bytes swapped) * xx+4,xx+5 = Interface Length (from xx+6 to yy) * xx+6,xx+7 = Interface Blocks Count (In,Out,Satic,TMP etc) * 2 * xx+8,xx+9 = allways Zero * xx+10-yy = Interface * yy+1-zz = Networks * */ /* * Description of a MC7 Block (Data - Block) * 36-xx = AWL * xx+1, = 0x05 (DB) 0x10 (DI) * xx+2,xx+3 = Again Block Number or FB Number on a DI (but bytes swapped) * xx+4,xx+5 = Interface Length * xx+6-yy = Interface * yy-zz = Start-Values * xx = Nertworks */ retBlock.BlockVersion = Convert.ToString(MC7Code[2] - 1); retBlock.BlockAttribute = Convert.ToString(MC7Code[3] - 1); retBlock.BlockLanguage = (DataTypes.PLCLanguage)MC7Code[4]; // Enum.Parse(typeof(DataTypes.PLCLanguage), Helper.GetLang(MC7Code[4])); retBlock.MnemonicLanguage = (MnemonicLanguage)MnemoricLanguage; retBlock.BlockType = Helper.GetPLCBlockType(MC7Code[5]); retBlock.BlockNumber = (MC7Code[6] * 0x100) + MC7Code[7]; retBlock.Length = libnodave.getU32from(MC7Code, 8); retBlock.Password = new byte[] { MC7Code[12], MC7Code[13], MC7Code[14], MC7Code[15] }; retBlock.LastCodeChange = Helper.GetDT(MC7Code[16], MC7Code[17], MC7Code[18], MC7Code[19], MC7Code[20], MC7Code[21]); retBlock.LastInterfaceChange = Helper.GetDT(MC7Code[22], MC7Code[23], MC7Code[24], MC7Code[25], MC7Code[26], MC7Code[27]); int InterfaceLength_or_DBActualValuesLength = libnodave.getU16from(MC7Code, 28); retBlock.SegmentTableSize = libnodave.getU16from(MC7Code, 30); //(Length of networks?) int LocalDataLength = libnodave.getU16from(MC7Code, 32); int MC7Length_or_DBBodyLength = libnodave.getU16from(MC7Code, 34); int IntfStart = MC7Start_or_DBBodyStart + MC7Length_or_DBBodyLength + 3; int IntfLength = BitConverter.ToUInt16(MC7Code, IntfStart) + 2; int IntfValStart = IntfStart + IntfLength + 2; retBlock.InterfaceSize = InterfaceLength_or_DBActualValuesLength; retBlock.LocalDataSize = LocalDataLength; retBlock.CodeSize = MC7Length_or_DBBodyLength; int FooterStart = MC7Start_or_DBBodyStart + MC7Length_or_DBBodyLength + InterfaceLength_or_DBActualValuesLength + retBlock.SegmentTableSize; retBlock.Author = Helper.GetString(FooterStart + 0, 8, MC7Code); retBlock.Family = Helper.GetString(FooterStart + 8, 8, MC7Code); retBlock.Name = Helper.GetString(FooterStart + 16, 8, MC7Code); retBlock.Version = Helper.GetVersion(MC7Code[FooterStart + 24]); if ((MC7Code[5] == 0x0a) || (MC7Code[5] == 0x0b)) { //Instance DB?? if (MC7Code[MC7Start_or_DBBodyStart + MC7Length_or_DBBodyLength] == 0x0a) { ((S7DataBlock)retBlock).IsInstanceDB = true; ((S7DataBlock)retBlock).FBNumber = BitConverter.ToUInt16(MC7Code, MC7Start_or_DBBodyStart + MC7Length_or_DBBodyLength + 1); } //((PLCDataBlock) retBlock).Structure = MC7toDB.GetDBInterface(IntfStart, IntfLength, AWLStart, IntfValStart, MC7Code); /*var interf = new byte[IntfLength]; * Array.Copy(MC7Code, IntfStart, interf, 0, IntfLength); * string wr = ""; * for (int i=0;i<interf.Length-1;i=i+2) * { * wr += interf[i+1].ToString("X").PadLeft(2, '0'); * wr += interf[i].ToString("X").PadLeft(2, '0'); * } * wr = wr;*/ List <string> tmp = new List <string>(); var interfaceBytes = new byte[IntfLength + 3]; var actualValues = new byte[MC7Length_or_DBBodyLength]; Array.Copy(MC7Code, IntfStart - 3, interfaceBytes, 0, IntfLength + 3); //-3 because of in the project file in the structere ssbpart is also the same structure with this 4 bytes!! Array.Copy(MC7Code, MC7Start_or_DBBodyStart, actualValues, 0, MC7Length_or_DBBodyLength); ((S7DataBlock)retBlock).StructureFromMC7 = Parameter.GetInterface(interfaceBytes, actualValues, ref tmp, retBlock.BlockType, ((S7DataBlock)retBlock).IsInstanceDB, retBlock); } else { var interfaceBytes = new byte[IntfLength + 3]; Array.Copy(MC7Code, IntfStart - 3, interfaceBytes, 0, IntfLength + 3); //-3 because of in the project file in the structere ssbpart is also the same structure with this 4 bytes!! List <string> ParaList = new List <string>(); ((S7FunctionBlock)retBlock).Parameter = Parameter.GetInterface(interfaceBytes, null, ref ParaList, retBlock.BlockType, false, retBlock); int[] Networks; Networks = NetWork.GetNetworks(MC7Start_or_DBBodyStart + MC7Length_or_DBBodyLength + InterfaceLength_or_DBActualValuesLength, MC7Code); ((S7FunctionBlock)retBlock).AWLCode = MC7toAWL.GetAWL(MC7Start_or_DBBodyStart, MC7Length_or_DBBodyLength - 2, MnemoricLanguage, MC7Code, Networks, ParaList, prjBlkFld); ((S7FunctionBlock)retBlock).Networks = NetWork.GetNetworksList((S7FunctionBlock)retBlock); } } return(retBlock); }