public CreateHmiPresetConstantTagsTask(TiaPortal portal, TagFolder folder, ConstantLookup constants) { this.portal = portal; this.folder = folder; this.constants = constants; Description = "Update HMI preset constant table " + PRESET_CONSTANT_TABLE_NAME; }
public CreateHmiTagsFromBlockTask(TiaPortal portal, PlcBlock block, TagFolder folder, string function, ConstantLookup constants) { this.portal = portal; this.folder = folder; this.block = block; this.function = function; this.constants = constants; Description = "Update HMI tag table " + function + " for block " + block.Name; }
public HMItagBuilder(TiaPortal portal, PlcSoftware plc, HmiTarget hmi, ConstantLookup constants) { this.portal = portal; this.plc = plc; this.hmi = hmi; this.constants = constants; btn_run.Enabled = false; FindDB(); }
public static void SetPresetNames(XmlElement tag_element, ConstantLookup constants, string[] values) { ARRAY name_array = new ARRAY { MemberType = new STRUCT() }; MemberComponent name_tag = new MemberComponent("Names", name_array); SetPathValues(tag_element, name_tag, constants, values); }
public static void SetPresetColors(XmlElement tag_element, ConstantLookup constants, int[] values) { ARRAY name_array = new ARRAY { MemberType = new STRUCT() }; MemberComponent name_tag = new MemberComponent("Colors", name_array); var objs = values.Select <int, object>(x => (object)x).ToArray <object>(); SetPathValues(tag_element, name_tag, constants, objs); }
public static int[] GetPresetColors(XmlElement tag_element, ConstantLookup constants) { ARRAY name_array = new ARRAY(); MemberComponent name_tag = new MemberComponent("Colors", name_array); Array array = GetPathValues(tag_element, name_tag, constants); if (array.Rank != 1) { throw new Exception("Names tag must be one dimensional"); } return(FlattenArray <int>(array)); }
public static PathComponent InitializeArrayPath(PathComponent path, ConstantLookup constants) { PathComponent parent; if (path.Parent != null) { parent = InitializeArrayPath(path.Parent, constants); } else { parent = null; } if (path is IndexComponent) { IndexComponent index = (IndexComponent)path; int[] indices = new int[index.Indices.Count()]; for (int i = 0; i < indices.Count(); i++) { indices[i] = ((IntegerLiteral)((ARRAY)parent.Type).Limits[i].LowLimit).Value; } path = new IndexComponent(indices, index.Type, parent); } else { MemberComponent member = (MemberComponent)path; DataType type = member.Type; ARRAY array_type = path.Type as ARRAY; if (array_type != null) { ARRAY new_array_type = new ARRAY(); new_array_type.MemberType = array_type.MemberType; new_array_type.Limits = new ArrayLimits[array_type.Limits.Count]; for (int i = 0; i < new_array_type.Limits.Count(); i++) { new_array_type.Limits[i] = new ArrayLimits( new IntegerLiteral(array_type.Limits[i].LowLimit.ResolveInt(constants)), new IntegerLiteral(array_type.Limits[i].HighLimit.ResolveInt(constants))); } type = new_array_type; } path = new MemberComponent(member.Name, type, parent); } return(path); }
public int ResolveInt(ConstantLookup lookup) { if (this is IntegerLiteral i) { return(i.Value); } if (this is NamedConstant c) { return(lookup.IntegerLookup(c.Name)); } else { throw new Exception("Can only resolve named constants"); } }
private void btn_hmi_tags_Click(object sender, EventArgs e) { PlcSoftware plc = null; if (!find_plc(projectTreeView.Nodes, ref plc)) { MessageBox.Show("More than one PLC is selected"); return; } if (plc == null) { MessageBox.Show("No PLC is selected"); return; } HmiTarget hmi = null; if (!find_hmi(projectTreeView.Nodes, ref hmi)) { MessageBox.Show("More than one HMI device is selected"); return; } if (hmi == null) { MessageBox.Show("No HMI device is selected"); return; } ConstantLookup constants = new ConstantLookup(); try { constants.Populate(tiaPortal, plc); } catch (Exception ex) { MessageBox.Show("Failed to build lookup table for user constants: " + ex.Message); return; } HMItagBuilder hmi_tags = new HMItagBuilder(tiaPortal, plc, hmi, constants); hmi_tags.ShowDialog(); }
public static void SetPathValues(XmlElement tag_element, PathComponent path, ConstantLookup constants, object [] values) { List <Limits> limits = new List <Limits>(); XmlElement elem = GetPathElement(tag_element, ref limits, path, constants); int[] lengths = limits.Select(x => (x.High - x.Low + 1)).ToArray(); int[] lower = limits.Select(x => x.Low).ToArray(); if (limits.Count < values.Rank) { throw new Exception("Path " + path + " has " + limits.Count + " indices but the supplied values has " + values.Rank); } DataType value_type = DataTypeParser.Parse(elem.GetAttribute("Datatype"), out string _); if (value_type is ARRAY value_array) { value_type = value_array.MemberType; } int[] indices = new int[lengths.Count()]; int v_index = 0; SetStartValues(elem, values, value_type, indices, limits, 0, ref v_index); }
void UpdatePresetValues( PlcSoftware plcSoftware, Dictionary <string, PresetGroup> preset_groups) { ConstantLookup constants = new ConstantLookup(); constants.Populate(tiaPortal, plcSoftware); PlcBlockGroup preset_group = plcSoftware.BlockGroup.Groups.Find("Preset"); if (preset_group == null) { MessageBox.Show("No group named Preset found for PLC " + plcSoftware.Name); return; } foreach (string group_name in preset_groups.Keys) { string preset_db_name = "sDB_Preset_" + group_name; PlcBlock preset_db = preset_group.Blocks.Find(preset_db_name); if (preset_db == null) { MessageBox.Show("No block named " + preset_db_name + " found for PLC " + plcSoftware.Name); return; } XmlDocument doc; try { doc = TIAutils.ExportPlcBlockXML(preset_db); } catch (Exception ex) { MessageBox.Show("Failed to export block " + preset_db_name + ": " + ex.Message); return; } if (doc.DocumentElement.SelectSingleNode("/Document/SW.Blocks.GlobalDB//if:Section[@Name='Static']", XMLUtil.nameSpaces) is XmlElement static_elem) { var infos = preset_groups[group_name].presets; foreach (PresetInfo info in infos) { PresetValueParser.SetPresetValue(static_elem, info.tag.tagPath, constants, info.values); PresetValueParser.SetPresetEnabled(static_elem, info.tag.tagPath, constants, info.enabled); } PresetValueParser.SetPresetNames(static_elem, constants, preset_groups[group_name].preset_names); PresetValueParser.SetPresetColors(static_elem, constants, preset_groups[group_name].preset_colors); } else { MessageBox.Show("No static section found for " + preset_db_name); return; } try { var group = (Siemens.Engineering.SW.Blocks.PlcBlockGroup)preset_db.Parent; var name = group.Name; TIAutils.ImportPlcBlockXML(doc, group); } catch (Exception ex) { MessageBox.Show("Failed to import block " + preset_db_name + ": " + ex.Message); return; } } }
private void exportButton_Click(object sender, EventArgs e) { if (savePresetList.ShowDialog() == System.Windows.Forms.DialogResult.OK) { try { ConstantLookup constants = new ConstantLookup(); constants.Populate(tiaPortal, plcSoftware); Dictionary <string, List <PresetTag> > tag_groups = tagGroups(presetList); PlcBlockGroup plc_preset_group = plcSoftware.BlockGroup.Groups.Find("Preset"); if (plc_preset_group == null) { MessageBox.Show("No group named Preset found for PLC " + plcSoftware.Name); return; } Dictionary <string, PresetGroup> preset_groups = new Dictionary <string, PresetGroup>(); foreach (string group_name in tag_groups.Keys) { PresetGroup group = new PresetGroup(); string preset_db_name = "sDB_Preset_" + group_name; PlcBlock preset_db = plc_preset_group.Blocks.Find(preset_db_name); if (preset_db == null) { MessageBox.Show("No block named " + preset_db_name + " found for PLC " + plcSoftware.Name); return; } XmlDocument doc; try { doc = TIAutils.ExportPlcBlockXML(preset_db); } catch (Exception ex) { MessageBox.Show("Failed to export block " + preset_db_name + ": " + ex.Message); return; } if (doc.DocumentElement.SelectSingleNode("/Document/SW.Blocks.GlobalDB//if:Section[@Name='Static']", XMLUtil.nameSpaces) is XmlElement static_elem) { group.preset_names = PresetValueParser.GetPresetNames(static_elem, constants); group.preset_colors = PresetValueParser.GetPresetColors(static_elem, constants); group.presets = new List <PresetDocument.PresetInfo>(); var tags = tag_groups[group_name]; foreach (var tag in tags) { var values = PresetValueParser.GetPresetValue(static_elem, tag.tagPath, constants); var enabled = PresetValueParser.GetPresetEnabled(static_elem, tag.tagPath, constants); Console.WriteLine(tag.tagPath + ":" + (string.Join(",", values))); group.presets.Add(new PresetDocument.PresetInfo() { tag = tag, values = values, enabled = enabled }); } preset_groups[group_name] = group; } else { MessageBox.Show("No static section found for " + preset_db_name); return; } } PresetDocument.Save(savePresetList.FileName, preset_groups, cultureComboBox.SelectedItem.ToString()); } catch (Exception ex) { MessageBox.Show("Failed to export preset list: " + ex.Message); } } }
private void WriteButton_Click(object sender, EventArgs e) { if (task_dialog == null) { task_dialog = new TaskDialog(); } task_dialog.Clear(); Project proj = tiaPortal.Projects[0]; LanguageAssociation langs = proj.LanguageSettings.ActiveLanguages; string[] cultures = langs.Select(l => l.Culture.Name).ToArray(); string default_culture = proj.LanguageSettings.ReferenceLanguage.Culture.Name; foreach (PresetTagList.Row row in presetList) { row.Tag.labels.AddMissingCultures(cultures, default_culture); if (row.Tag.state_labels != null) { foreach (MultilingualText text in row.Tag.state_labels.Values) { text.AddMissingCultures(cultures, default_culture); } } } // Sort the groups into separate lists of tags Dictionary <string, List <PresetTag> > tag_groups = tagGroups(presetList); ConstantLookup constants = new ConstantLookup(); constants.Populate(tiaPortal, plcSoftware); // Create databases for all groups foreach (string group_name in tag_groups.Keys) { string db_name = PRESET_DB_PREFIX + group_name; string hmi_db_name = PRESET_HMI_DB_PREFIX + group_name; var tags = tag_groups[group_name]; string value_type_name = "PresetValueType_" + group_name; string enable_type_name = "PresetEnableType_" + group_name; task_dialog.AddTask(new CreatePresetTypesTask(tiaPortal, tags, typeGroup, value_type_name, enable_type_name)); string recall_block_name = "PresetRecall_" + group_name; task_dialog.AddTask(new CreatePresetRecallBlockTask(tiaPortal, tags, resultGroup, recall_block_name, value_type_name, enable_type_name)); string store_block_name = "PresetStore_" + group_name; string store_enabled_block_name = "PresetStoreEnabled_" + group_name; task_dialog.AddTask(new CreatePresetStoreBlockTask(tiaPortal, tags, resultGroup, store_block_name, store_enabled_block_name, value_type_name, enable_type_name)); } task_dialog.AddTask(new CreatePlcCompileTask(tiaPortal, plcSoftware)); foreach (HmiTarget hmi in hmiTargets) { // Create HMI tags TagFolder preset_tag_folder = hmi.TagFolder.Folders.Find("Preset"); if (preset_tag_folder != null) { task_dialog.AddTask(new CreateHmiPresetConstantTagsTask(tiaPortal, preset_tag_folder, constants)); } } // Create HMI for all groups foreach (string group_name in tag_groups.Keys) { var tags = tag_groups[group_name]; string db_name = PRESET_DB_PREFIX + group_name; string hmi_db_name = PRESET_HMI_DB_PREFIX + group_name; foreach (HmiTarget hmi in hmiTargets) { string popup_name = "PresetPopup_" + group_name; ScreenPopupFolder popup_folder = hmi.ScreenPopupFolder; ScreenPopup popup = popup_folder.ScreenPopups.Find(popup_name); if (popup == null) { task_dialog.AddTask(new MessageTask("Skipping preset group " + group_name + " for HMI " + hmi.Name, MessageLog.Severity.Info, "Assuming preset group " + group_name + " is not used by this HMI since the pop-up screen " + popup_name + " was not found")); continue; } String list_prefix = "PresetTextList_" + group_name + "_"; TextListComposition hmi_text_lists = hmi.TextLists; // Text list that are candidates for deletion List <String> delete_lists = new List <string>(); // Find all preset text lists foreach (var list in hmi_text_lists) { if (list.Name.StartsWith(list_prefix)) { delete_lists.Add(list.Name); } } // Create text lists int count = 1; foreach (PresetTag tag in tags) { if (tag.state_labels != null) { string list_name = list_prefix + count; delete_lists.Remove(list_name); // Don't delete this list task_dialog.AddTask(new CreateHmiTextListTask(tiaPortal, list_name, hmi_text_lists, tag.state_labels)); } count++; } // Delete old textlists task_dialog.AddTask(new DeleteHmiTextListTask(tiaPortal, list_prefix, hmi_text_lists, delete_lists)); // Get number of presets configured string count_entry_name = "PresetCount_" + group_name; ConstantLookup.Entry count_entry = constants.Lookup(count_entry_name); if (count_entry == null) { throw new Exception("Global constant " + count_entry_name + " not found"); } int nPresets = int.Parse(count_entry.value); Dictionary <int, MultilingualText> preset_names = new Dictionary <int, MultilingualText>(); // Create preset name list { for (int p = 1; p <= nPresets; p++) { string name_string = "<hmitag length='20' type='Text' name='PresetName_" + group_name + "_" + p + "'>Preset " + p + "</hmitag>"; MultilingualText text = new MultilingualText(); foreach (string c in cultures) { text.AddText(c, name_string); } preset_names.Add(p, text); } string list_name = "PresetNameList_" + group_name; task_dialog.AddTask(new CreateHmiTextListTask(tiaPortal, list_name, hmi_text_lists, preset_names)); } // Create HMI tags TagFolder preset_tag_folder = hmi.TagFolder.Folders.Find("Preset"); if (preset_tag_folder != null) { string table_name = "Preset_" + group_name; task_dialog.AddTask(new CreatePresetHmiTagsTask(tiaPortal, tags, preset_tag_folder, table_name, group_name, db_name, hmi_db_name, nPresets)); } else { MessageBox.Show("No HMI tag group name 'Preset' was found for HMI " + hmi.Name + ". No tag tables will be updated."); } // Load template screen ScreenTemplate obj_templ = hmi.ScreenTemplateFolder.ScreenTemplates.Find("ObjectTemplate"); if (obj_templ != null) { XmlDocument templates = TIAutils.ExportScreenTemplateXML(obj_templ); // Create popups task_dialog.AddTask(new CreatePresetScreenPopupTask(tiaPortal, tags, popup_folder, templates, popup_name, group_name)); } else { MessageBox.Show("No template screen named ObjectTemplate found for HMI " + hmi.Name + ". Some screens will not be updated."); } } } task_dialog.Show(); }
public static XmlElement GetPathElement(XmlElement tag_element, ref List <Limits> limits, PathComponent path, ConstantLookup constants) { XmlElement elem = tag_element; if (path.Parent != null) { elem = GetPathElement(tag_element, ref limits, path.Parent, constants); if (elem == null) { return(null); } } if (path is MemberComponent member_path) { if (!(elem.SelectSingleNode("./if:Member[@Name='" + member_path.Name + "'] | ./if:Sections/if:Section/if:Member[@Name='" + member_path.Name + "']", XMLUtil.nameSpaces) is XmlElement child_elem)) { throw new Exception("Unable to find path " + member_path + " in element " + (elem?.GetAttribute("Name") ?? "<Unknown>")); } DataType type = DataTypeParser.Parse(child_elem.GetAttribute("Datatype"), out string _); if (type is ARRAY array) { limits.AddRange(array.Limits.Select(x => new Limits() { Low = x.LowLimit.ResolveInt(constants), High = x.HighLimit.ResolveInt(constants) })); } return(child_elem); } else if (path is IndexComponent index_path) { limits.RemoveRange(limits.Count - index_path.Indices.Count(), index_path.Indices.Count()); limits.AddRange(index_path.Indices.Select(x => new Limits() { Low = x, High = x })); return(elem); } else { return(null); } }
public static void SetPresetEnabled(XmlElement tag_element, PathComponent path, ConstantLookup constants, bool?[] values) { ARRAY enable_array = new ARRAY { MemberType = new STRUCT() }; MemberComponent enable_tag = new MemberComponent("Enable", enable_array); PathComponent value_path = path.PrependPath(enable_tag); object [] obj_values = values.Select(x => (object)x).ToArray(); SetPathValues(tag_element, value_path, constants, obj_values); }
public static Array GetPathValues(XmlElement tag_element, PathComponent path, ConstantLookup constants) { List <Limits> limits = new List <Limits>(); XmlElement elem = GetPathElement(tag_element, ref limits, path, constants); XmlNodeList start_values = elem.SelectNodes(".//if:Subelement/if:StartValue", XMLUtil.nameSpaces); int[] lengths = limits.Select(x => (x.High - x.Low + 1)).ToArray(); int[] lower = limits.Select(x => x.Low).ToArray(); DataType value_type = DataTypeParser.Parse(elem.GetAttribute("Datatype"), out string _); if (value_type is ARRAY value_array) { value_type = value_array.MemberType; } Type array_type; if (value_type is BitString bits) { array_type = typeof(int); } else if (value_type is Integer) { array_type = typeof(int); } else if (value_type is Float) { array_type = typeof(double); } else if (value_type is BOOL) { array_type = typeof(bool); } else if (value_type is STRING) { array_type = typeof(string); } else { throw new NotImplementedException("Unhandled value type " + value_type.ToString()); } Array array = Array.CreateInstance(array_type, lengths, lower); foreach (XmlElement start_value in start_values) { string subpath = ((XmlElement)start_value.ParentNode).GetAttribute("Path"); int[] indices = subpath.Split(new char[] { ',' }).Select(x => int.Parse(x)).ToArray(); string value_str = start_value.InnerText.Trim(new char[1] { '\'' }); Object value = ParseValue(value_str, value_type); if (indices.Length != limits.Count) { throw new IndexOutOfRangeException("Wrong number of dimensions for " + path + " (expected " + limits.Count + " got " + indices.Length); } int i; // Check if indices are within limits for (i = 0; i < indices.Length; i++) { if (indices[i] < limits[i].Low || indices[i] > limits[i].High) { break; } } if (i == indices.Length) { array.SetValue(value, indices); } } return(array); }
public static object[] GetPresetValue(XmlElement tag_element, PathComponent path, ConstantLookup constants) { ARRAY preset_array = new ARRAY { MemberType = new STRUCT() }; MemberComponent preset_tag = new MemberComponent("Preset", preset_array); PathComponent value_path = path.PrependPath(preset_tag); Array array = GetPathValues(tag_element, value_path, constants); return(FlattenArray <object>(array)); }
public static void SetPresetValue(XmlElement tag_element, PathComponent path, ConstantLookup constants, object[] values) { ARRAY preset_array = new ARRAY { MemberType = new STRUCT() }; MemberComponent preset_tag = new MemberComponent("Preset", preset_array); PathComponent value_path = path.PrependPath(preset_tag); SetPathValues(tag_element, value_path, constants, values); }
public static bool?[] GetPresetEnabled(XmlElement tag_element, PathComponent path, ConstantLookup constants) { ARRAY enable_array = new ARRAY { MemberType = new STRUCT() }; MemberComponent enable_tag = new MemberComponent("Enable", enable_array); PathComponent value_path = path.PrependPath(enable_tag); Array array = GetPathValues(tag_element, value_path, constants); return(FlattenArray <bool?>(array)); }