public static void Create(IEnumerable <IBlock> blocks, string path, PortalPlc parentPlc, WinccExportType exportType, TiaPortalVersion portalVersion) { if (blocks == null) { throw new ArgumentNullException(nameof(blocks)); } IEnumerable <DataBlock> dataBlocks; if ((dataBlocks = blocks.OfType <DataBlock>())?.Count() <= 0) { throw new ArgumentException("Blocks does not contain any valid DataBlocks.", nameof(blocks)); } WinccConfiguration.CreateInternal(dataBlocks, path, parentPlc, exportType, portalVersion); }
private static void CreateInternal(IEnumerable <DataBlock> dataBlocks, string path, PortalPlc parentPlc, WinccExportType exportType, TiaPortalVersion portalVersion) { if (path == null) { throw new ArgumentNullException(nameof(path)); } if (!FileHelpers.IsValidFilePath(path, ".xlsx")) { throw new ArgumentException(path + " is not a valid path.", nameof(path)); } var currentAlarmRow = 2; var currentTagRow = 2; string dataBlockName; var proTags = new List <string>(); using (var document = new ExcelPackage()) { var tagWorksheet = document.Workbook.Worksheets.Add(TagWorksheetName); var alarmWorksheet = document.Workbook.Worksheets.Add(AlarmWorksheetName); WinccConfiguration.WriteXlsxHeaders(document.Workbook, exportType, portalVersion); foreach (var db in dataBlocks) { dataBlockName = db.Name; db.CalcluateAddresses(parentPlc); foreach (var entry in db.Children) { ProcessDataEntry(alarmWorksheet, entry, string.Empty, new Address(), db.Name); } if (exportType != WinccExportType.Professional) { WriteComfortAdvancedTagRow(tagWorksheet, db, "HMI_Connection_1"); } } if (exportType == WinccExportType.Professional) { foreach (var tag in proTags) { WriteProfessionalTagRow(tagWorksheet, tag, "HMI_Connection_1"); } } using (Stream file = new FileStream(path, FileMode.Create)) { document.SaveAs(file); } } void ProcessDataEntry(ExcelWorksheet worksheet, DataEntry entry, string prependText, Address addressOffset, string prependTag = "") { string stackedComment; if (string.IsNullOrWhiteSpace(prependText)) { stackedComment = entry.Comment; } else if (prependText.EndsWith(" - ")) { stackedComment = prependText + entry.Comment; } else { stackedComment = prependText + " - " + entry.Comment; } string stackedTag; if (string.IsNullOrWhiteSpace(prependTag)) { stackedTag = entry.Name; } else if (prependText.EndsWith(".")) { stackedTag = prependTag + entry.Name; } else { stackedTag = prependTag + "." + entry.Name; } switch (entry.DataType) { case DataType.BOOL: var alarmNumber = currentAlarmRow - 1; var row = WinccConstants.GetAlarmRow(exportType, portalVersion); row[WinccExportField.Id] = alarmNumber.ToString(); row[WinccExportField.Name] = $"Discrete_alarm_{alarmNumber}"; row[WinccExportField.AlarmText] = stackedComment; row[WinccExportField.InfoText] = stackedComment; if (exportType == WinccExportType.Professional) { row[WinccExportField.TriggerTag] = stackedTag.Replace('.', '_'); proTags.Add(stackedTag); } else // WinCC Comfort/Advanced { row[WinccExportField.TriggerTag] = dataBlockName; row[WinccExportField.TriggerBit] = AddressToTriggerBit(addressOffset + entry.Address.Value).ToString(); } var column = 1; foreach (var item in row) { worksheet.Cells[currentAlarmRow, column].Style.Numberformat.Format = "@"; worksheet.Cells[currentAlarmRow, column++].Value = item; } currentAlarmRow++; break; case DataType.UDT: case DataType.STRUCT: entry.CalcluateAddresses(parentPlc); foreach (var newEntry in entry.Children) { ProcessDataEntry(worksheet, newEntry, stackedComment, addressOffset + entry.Address.Value, stackedTag); } break; case DataType.ARRAY: TagHelper.ResolveArrayChildren(entry, parentPlc); // write a new entry for each of the children foreach (var child in entry.Children) { ProcessDataEntry(worksheet, child, prependText, entry.Address.Value + addressOffset, stackedTag); } break; default: throw new SiemensException("Unsupported data type for WinCC alarms: " + entry.Name + ", " + entry.DataType.ToString()); } } void WriteComfortAdvancedTagRow(ExcelWorksheet worksheet, DataBlock dataBlock, string connectionName) { string dataType, address; var dbLength = dataBlock.CalculateSize(parentPlc).Byte; var wordLength = (int)Math.Ceiling(dbLength / 2.0); if (dbLength > 2) { dataType = $"Array [0..{wordLength - 1}] of Word"; address = $"%DB{dataBlock.Number}.DBX0.0"; } else { dataType = "Word"; address = $"%DB{dataBlock.Number}.DBW0"; wordLength = 0; } var row = WinccConstants.GetTagRow(exportType, portalVersion); row[WinccExportField.Name] = dataBlock.Name; row[WinccExportField.Connection] = connectionName; row[WinccExportField.DataType] = dataType; row[WinccExportField.Length] = ((wordLength + 1) * 2).ToString(); row[WinccExportField.Address] = address; var column = 1; foreach (var item in row) { worksheet.Cells[currentTagRow, column].Style.Numberformat.Format = "@"; worksheet.Cells[currentTagRow, column++].Value = item; } currentTagRow++; } void WriteProfessionalTagRow(ExcelWorksheet worksheet, string tag, string connectionName) { var row = WinccConstants.GetTagRow(exportType, portalVersion); row[WinccExportField.Name] = tag.Replace('.', '_'); row[WinccExportField.Connection] = connectionName; row[WinccExportField.PlcTag] = tag; var column = 1; foreach (var item in row) { worksheet.Cells[currentTagRow, column].Style.Numberformat.Format = "@"; worksheet.Cells[currentTagRow, column++].Value = item; } currentTagRow++; } int AddressToTriggerBit(Address address) { if (address.Byte % 2 == 0) { return((address.Byte + 1) * 8 + address.Bit); } else { return((address.Byte - 1) * 8 + address.Bit); } } }
public static void Create(IBlock block, string path, PortalPlc parentPlc, WinccExportType exportType, TiaPortalVersion portalVersion) { WinccConfiguration.Create(new[] { block }, path, parentPlc, exportType, portalVersion); }