/// <summary>
        /// Checks, if the <c>sourceElements</c> can be used to pre-set instances for the rendering of
        /// the description/ form.
        /// If not, the display functionality will finally care about creating them.
        /// </summary>
        public void PresetInstancesBasedOnSource(AdminShell.SubmodelElementWrapperCollection sourceElements = null)
        {
            // access
            var desc = this.workingDesc as FormDescSubmodelElement;

            if (desc == null || desc.KeySemanticId == null || sourceElements == null)
            {
                return;
            }

            // Instances ready?
            if (this.SubInstances == null)
            {
                this.SubInstances = new List <FormInstanceBase>();
            }

            // maximum == 1?
            if (desc.Multiplicity == FormMultiplicity.ZeroToOne || desc.Multiplicity == FormMultiplicity.One)
            {
                var smw = sourceElements.FindFirstSemanticId(desc.KeySemanticId);
                if (smw != null && smw.submodelElement != null)
                {
                    var y = desc.CreateInstance(this, smw.submodelElement);
                    if (y != null)
                    {
                        this.SubInstances.Add(y);
                    }
                }
            }

            // maximum > 1?
            if (desc.Multiplicity == FormMultiplicity.ZeroToMany || desc.Multiplicity == FormMultiplicity.OneToMany)
            {
                foreach (var smw in sourceElements.FindAllSemanticId(desc.KeySemanticId))
                {
                    if (smw != null && smw.submodelElement != null)
                    {
                        var y = desc.CreateInstance(this, smw.submodelElement);
                        if (y != null)
                        {
                            this.SubInstances.Add(y);
                        }
                    }
                }
            }

            // prepare list of original source elements
            if (this.InitialSourceElements == null)
            {
                this.InitialSourceElements = new List <AdminShellV20.SubmodelElement>();
            }
            foreach (var inst in this.SubInstances)
            {
                if (inst != null && inst is FormInstanceSubmodelElement &&
                    (inst as FormInstanceSubmodelElement).sourceSme != null)
                {
                    this.InitialSourceElements.Add((inst as FormInstanceSubmodelElement).sourceSme);
                }
            }
        }
        /// <summary>
        /// Render the instance into a list (right now, exactly one!) of SubmodelElements.
        /// Might be overridden in subclasses.
        /// </summary>
        public virtual AdminShell.SubmodelElementWrapperCollection AddOrUpdateSmeToCollection(
            AdminShell.SubmodelElementWrapperCollection collectionNewElements,
            AdminShellPackageEnv packageEnv = null, bool addFilesToPackage = false)
        {
            // typically, there will be only one SME
            var res = new AdminShell.SubmodelElementWrapperCollection();

            // SME present?
            if (sme != null)
            {
                // process (will update existing elements)
                var doAdd = ProcessSmeForRender(packageEnv, addFilesToPackage, editSource: true);

                // still add?
                if (doAdd)
                {
                    // add to elements (this is the real transaction)
                    collectionNewElements.Add(AdminShell.SubmodelElementWrapper.CreateFor(sme));

                    // add to the tracing information for new elements
                    res.Add(AdminShell.SubmodelElementWrapper.CreateFor(sme));
                }
            }

            // OK
            return(res);
        }
        /// <summary>
        /// Render the list of form elements into a list of SubmodelElements.
        /// </summary>
        public AdminShell.SubmodelElementWrapperCollection AddOrUpdateDifferentElementsToCollection(
            AdminShell.SubmodelElementWrapperCollection elements,
            AdminShellPackageEnv packageEnv = null, bool addFilesToPackage = false)
        {
            // will be a list of newly added elements (for tracing)
            var res = new AdminShell.SubmodelElementWrapperCollection();

            // each description / instance pair
            foreach (var pair in this)
            {
                // ok, perform the actual add or update procedure
                var lst = pair.instances.AddOrUpdateSameElementsToCollection(elements, packageEnv, addFilesToPackage);

                // for newly added elements, shaping of idSHort might be required
                if (lst != null)
                {
                    foreach (var smw in lst)
                    {
                        // access
                        if (smw?.submodelElement?.idShort == null)
                        {
                            continue;
                        }

                        // check, if to make idShort unique?
                        FormInstanceHelper.MakeIdShortUnique(elements, smw.submodelElement);

                        // add to tracing
                        res.Add(smw);
                    }
                }
            }
            return(res);
        }
        /// <summary>
        /// Render the list of form elements into a list of SubmodelElements.
        /// </summary>
        public AdminShell.SubmodelElementWrapperCollection AddOrUpdateDifferentElementsToCollection(
            AdminShell.SubmodelElementWrapperCollection elements,
            AdminShellPackageEnv packageEnv = null,
            bool addFilesToPackage          = false,
            bool editSource = false)
        {
            // SM itself?
            if (this.sm != null && Touched && this.sourceSM != null && editSource)
            {
                if (this.sm.idShort != null)
                {
                    this.sourceSM.idShort = "" + this.sm.idShort;
                }
                if (this.sm.description != null)
                {
                    this.sourceSM.description = new AdminShell.Description(this.sm.description);
                }
            }

            // SM as a set of elements
            if (this.PairInstances != null)
            {
                return(this.PairInstances.AddOrUpdateDifferentElementsToCollection(
                           elements, packageEnv, addFilesToPackage));
            }
            return(null);
        }
Beispiel #5
0
        //
        // V11
        //

        private static void SearchForRelations(
            AdminShell.SubmodelElementWrapperCollection smwc,
            DocumentEntity.DocRelationType drt,
            AdminShell.Reference semId,
            DocumentEntity intoDoc)
        {
            // access
            if (smwc == null || semId == null || intoDoc == null)
            {
                return;
            }

            foreach (var re in smwc.FindAllSemanticIdAs <AdminShell.ReferenceElement>(semId,
                                                                                      AdminShellV20.Key.MatchMode.Relaxed))
            {
                // access
                if (re.value == null || re.value.Count < 1)
                {
                    continue;
                }

                // be a bit picky
                if (re.value.Last.type.ToLower().Trim() != AdminShell.Key.Entity.ToLower())
                {
                    continue;
                }

                // add
                intoDoc.Relations.Add(new Tuple <DocumentEntity.DocRelationType, AdminShellV20.Reference>(
                                          drt, re.value));
            }
        }
 /// <summary>
 /// Checks, if the <c>sourceElements</c> can be used to pre-set instances for the rendering
 /// of the description/ form.
 /// If not, the display functionality will finally care about creating them.
 /// </summary>
 public void PresetInstancesBasedOnSource(AdminShell.SubmodelElementWrapperCollection sourceElements = null)
 {
     if (this.PairInstances != null)
     {
         foreach (var pair in this.PairInstances)
         {
             pair?.instances?.PresetInstancesBasedOnSource(sourceElements);
         }
     }
 }
 /// <summary>
 /// Render the list of form elements into a list of SubmodelElements.
 /// </summary>
 public AdminShell.SubmodelElementWrapperCollection AddOrUpdateDifferentElementsToCollection(
     AdminShell.SubmodelElementWrapperCollection elements, AdminShellPackageEnv packageEnv = null,
     bool addFilesToPackage = false)
 {
     if (this.PairInstances != null)
     {
         return(this.PairInstances.AddOrUpdateDifferentElementsToCollection(
                    elements, packageEnv, addFilesToPackage));
     }
     return(null);
 }
        /// <summary>
        /// Build a new instance, based on the description data
        /// </summary>

        public override AdminShell.SubmodelElementWrapperCollection AddOrUpdateSmeToCollection(
            AdminShell.SubmodelElementWrapperCollection elements, AdminShellPackageEnv packageEnv = null,
            bool addFilesToPackage = false)
        {
            // SMEC as Refrable
            this.ProcessSmeForRender(packageEnv: null, addFilesToPackage: false, editSource: true);

            // SMEC as list of items
            if (this.PairInstances != null)
            {
                return(this.PairInstances.AddOrUpdateDifferentElementsToCollection(
                           elements, packageEnv, addFilesToPackage));
            }

            return(null);
        }
Beispiel #9
0
        private void DisplaySubmodel()
        {
            // show the edit panel
            OuterTabControl.SelectedItem = TabPanelEdit;

            // clear first
            ScrollViewerForm.Content = null;

            // test trivial access
            if (theOptions == null || theSubmodel == null)
            {
                return;
            }

            // identify the record
            // check for a record in options, that matches Submodel
            currentFormRecord = theOptions.MatchRecordsForSemanticId(theSubmodel.semanticId);
            if (currentFormRecord == null)
            {
                return;
            }

            // check form
            if (currentFormRecord.FormSubmodel == null || currentFormRecord.FormSubmodel.SubmodelElements == null)
            {
                return;
            }

            // initialize form
            formInUpdateMode     = true;
            updateSourceElements = theSubmodel.submodelElements;

            // take over existing data
            this.currentFormInst = new FormInstanceSubmodel(currentFormRecord.FormSubmodel);
            this.currentFormInst.InitReferable(currentFormRecord.FormSubmodel, theSubmodel);
            this.currentFormInst.PresetInstancesBasedOnSource(updateSourceElements);
            this.currentFormInst.outerEventStack = theEventStack;

            // bring it to the panel
            var elementsCntl = new FormListOfDifferentControl();

            elementsCntl.DataContext = this.currentFormInst;
            ScrollViewerForm.Content = elementsCntl;
        }
        /// <summary>
        /// Check if <c>smw.idShort</c>c> contains something like "{0:00}" and iterate index to make it unique
        /// </summary>
        public static void MakeIdShortUnique(
            AdminShell.SubmodelElementWrapperCollection collection, AdminShell.SubmodelElement sme)
        {
            // access
            if (collection == null || sme == null)
            {
                return;
            }

            // check, if to make idShort unique?
            if (sme.idShort.Contains("{0"))
            {
                var newIdShort = collection.IterateIdShortTemplateToBeUnique(sme.idShort, 999);
                if (newIdShort != null)
                {
                    sme.idShort = newIdShort;
                }
            }
        }
Beispiel #11
0
        public void CreateEmptyItemsFromSMEs(
            AdminShell.SubmodelElementWrapperCollection smwc,
            bool omitIecEclass = false)
        {
            if (smwc == null)
            {
                return;
            }

            foreach (var smw in smwc)
            {
                var sme = smw?.submodelElement;
                if (sme == null)
                {
                    continue;
                }

                // any
                var si = sme.semanticId?.GetAsExactlyOneKey()?.value;
                if (si != null)
                {
                    if (omitIecEclass && (si.StartsWith("0173") || si.StartsWith("0112")))
                    {
                        continue;
                    }

                    var item = new CstIdDictionaryItem()
                    {
                        semId  = si,
                        cstRef = ""
                    };
                    this.Add(item);
                }

                if (sme is AdminShell.SubmodelElementCollection smc)
                {
                    // SMC ? recurse!
                    CreateEmptyItemsFromSMEs(smc.value, omitIecEclass);
                }
            }
        }
        public AdminShell.SubmodelElementWrapperCollection GenerateDefault()
        {
            var res = new AdminShell.SubmodelElementWrapperCollection();

            foreach (var desc in this)
            {
                AdminShell.SubmodelElement sme = null;

                // generate element

                if (desc is FormDescProperty)
                {
                    sme = (desc as FormDescProperty).GenerateDefault();
                }
                if (desc is FormDescMultiLangProp)
                {
                    sme = (desc as FormDescMultiLangProp).GenerateDefault();
                }
                if (desc is FormDescFile)
                {
                    sme = (desc as FormDescFile).GenerateDefault();
                }
                if (desc is FormDescSubmodelElementCollection)
                {
                    sme = (desc as FormDescSubmodelElementCollection).GenerateDefault();
                }

                // multiplicity -> enumerate correctly
                FormInstanceHelper.MakeIdShortUnique(res, sme);

                if (sme != null)
                {
                    res.Add(sme);
                }
            }

            return(res);
        }
Beispiel #13
0
        private void ButtonTabPanels_Click(object sender, RoutedEventArgs e)
        {
            if (sender == ButtonCreateDoc)
            {
                // show the edit panel
                OuterTabControl.SelectedItem = TabPanelEdit;
                ButtonAddUpdateDoc.Content   = "Add";

                //// TODO (MIHO, 2020-09-29): if the V1.1 template works and is adopted, the old
                //// V1.0 shall be removed completely (over complicated) */
                //// make a template description for the content (remeber it)
                var desc = theOptions.FormVdi2770;
                if (desc == null)
                {
                    desc = DocumentShelfOptions.CreateVdi2770TemplateDesc(theOptions);
                }

                // latest version (from resources)
                if (this.CheckBoxLatestVersion.IsChecked == true)
                {
                    desc = DocumentShelfOptions.CreateVdi2770v11TemplateDesc();
                }

                this.currentFormDescription = desc;
                formInUpdateMode            = false;
                updateSourceElements        = null;

                // take over existing data
                this.currentFormInst = new FormInstanceSubmodelElementCollection(null, currentFormDescription);
                this.currentFormInst.PresetInstancesBasedOnSource(updateSourceElements);
                this.currentFormInst.outerEventStack = theEventStack;

                // bring it to the panel
                var elementsCntl = new FormListOfDifferentControl();
                elementsCntl.ShowHeader  = false;
                elementsCntl.DataContext = this.currentFormInst;
                ScrollViewerForm.Content = elementsCntl;
            }

            if (sender == ButtonAddUpdateDoc)
            {
                // add
                if (this.currentFormInst != null && this.currentFormDescription != null &&
                    thePackage != null &&
                    theOptions != null && theOptions.SemIdDocument != null &&
                    theSubmodel != null)
                {
                    // on this level of the hierarchy, shall a new SMEC be created or shall
                    // the existing source of elements be used?
                    AdminShell.SubmodelElementWrapperCollection currentElements = null;
                    if (formInUpdateMode && updateSourceElements != null)
                    {
                        currentElements = updateSourceElements;
                    }
                    else
                    {
                        currentElements = new AdminShell.SubmodelElementWrapperCollection();
                    }

                    // create a sequence of SMEs
                    try
                    {
                        this.currentFormInst.AddOrUpdateDifferentElementsToCollection(
                            currentElements, thePackage, addFilesToPackage: true);
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "when adding Document");
                    }

                    // the InstSubmodel, which started the process, should have a "fresh" SMEC available
                    // make it unique in the Documentens Submodel
                    var newSmc = this.currentFormInst?.sme as AdminShell.SubmodelElementCollection;

                    // if not update, put them into the Document's Submodel
                    if (!formInUpdateMode && currentElements != null && newSmc != null)
                    {
                        // make newSmc unique in the cotext of the Submodel
                        FormInstanceHelper.MakeIdShortUnique(theSubmodel.submodelElements, newSmc);

                        // add the elements
                        newSmc.value = currentElements;

                        // add the whole SMC
                        theSubmodel.Add(newSmc);
                    }

#if __may_be_not__
                    // save directly to ensure consistency
                    try
                    {
                        if (thePackage.Filename != null)
                        {
                            thePackage.SaveAs(thePackage.Filename);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (theLogger != null)
                        {
                            theLogger.Log(
                                $"Saving package {thePackage.Filename} failed for adding Document " +
                                $"and gave: {ex.Message}");
                        }
                    }
#endif
                }
                else
                {
                    Log.Error("Preconditions for adding Document not met.");
                }

                // change back
                OuterTabControl.SelectedItem = TabPanelList;

                // re-display
                ParseSubmodelToListItems(
                    this.theSubmodel, this.theOptions, theViewModel.TheSelectedDocClass,
                    theViewModel.TheSelectedLanguage, theViewModel.TheSelectedListType);

                // re-display also in Explorer
                var evt = new AasxPluginResultEventRedrawAllElements();
                if (theEventStack != null)
                {
                    theEventStack.PushEvent(evt);
                }
            }

            if (sender == ButtonCancel)
            {
                OuterTabControl.SelectedItem = TabPanelList;
            }

            if (sender == ButtonFixCDs)
            {
                // check if CDs are present
                var theDefs = new AasxPredefinedConcepts.DefinitionsVDI2770.SetOfDefsVDI2770(
                    new AasxPredefinedConcepts.DefinitionsVDI2770());
                var theCds = theDefs.GetAllReferables().Where(
                    (rf) => { return(rf is AdminShell.ConceptDescription); }).ToList();

                // v11
                if (CheckBoxLatestVersion.IsChecked == true)
                {
                    theCds = AasxPredefinedConcepts.VDI2770v11.Static.GetAllReferables().Where(
                        (rf) => { return(rf is AdminShell.ConceptDescription); }).ToList();
                }

                if (theCds.Count < 1)
                {
                    Log.Error(
                        "Not able to find appropriate ConceptDescriptions in pre-definitions. " +
                        "Aborting.");
                    return;
                }

                // check for Environment
                var env = this.thePackage?.AasEnv;
                if (env == null)
                {
                    Log.Error(
                        "Not able to access AAS environment for set of Submodel's ConceptDescriptions. Aborting.");
                    return;
                }

                // be safe?
                if (MessageBoxResult.Yes != MessageBox.Show(
                        "Add missing ConceptDescriptions to the AAS?", "Question",
                        MessageBoxButton.YesNo, MessageBoxImage.Warning))
                {
                    return;
                }

                // ok, check
                int nr = 0;
                foreach (var x in theCds)
                {
                    var cd = x as AdminShell.ConceptDescription;
                    if (cd == null || cd.identification == null)
                    {
                        continue;
                    }
                    var cdFound = env.FindConceptDescription(cd.identification);
                    if (cdFound != null)
                    {
                        continue;
                    }
                    // ok, add
                    var newCd = new AdminShell.ConceptDescription(cd);
                    env.ConceptDescriptions.Add(newCd);
                    nr++;
                }

                // ok
                Log.Info("In total, {0} ConceptDescriptions were added to the AAS environment.", nr);
            }

            if (sender == ButtonCreateEntity)
            {
                // show the edit panel
                OuterTabControl.SelectedItem = TabPanelEntity;
            }

            if (sender == ButtonCancelEntity)
            {
                OuterTabControl.SelectedItem = TabPanelList;
            }

            if (sender == ButtonAddEntity &&
                this.theSubmodel != null &&
                TextBoxEntityIdShort.Text.Trim().HasContent())
            {
                // add entity
                this.theSubmodel.SmeForWrite.CreateSMEForCD <AdminShell.Entity>(
                    AasxPredefinedConcepts.VDI2770v11.Static.CD_DocumentedEntity,
                    idShort: "" + TextBoxEntityIdShort.Text.Trim(),
                    addSme: true);

                // switch back
                OuterTabControl.SelectedItem = TabPanelList;

                // re-display also in Explorer
                var evt = new AasxPluginResultEventRedrawAllElements();
                if (theEventStack != null)
                {
                    theEventStack.PushEvent(evt);
                }
            }
        }
        private void ButtonTabPanels_Click(object sender, RoutedEventArgs e)
        {
            if (sender == ButtonCreateDoc)
            {
                // show the edit panel
                OuterTabControl.SelectedItem = TabPanelEdit;
                ButtonAddUpdateDoc.Content   = "Add";

                // make a template description for the content (remeber it)
                var desc = theOptions.FormVdi2770;
                if (desc == null)
                {
                    desc = DocumentShelfOptions.CreateVdi2770TemplateDesc(theOptions);
                }

                this.currentFormDescription = desc;
                formInUpdateMode            = false;
                updateSourceElements        = null;

                // take over existing data
                this.currentFormInst = new FormInstanceSubmodelElementCollection(null, currentFormDescription);
                this.currentFormInst.PresetInstancesBasedOnSource(updateSourceElements);

                // bring it to the panel
                var elementsCntl = new FormListOfDifferentControl();
                elementsCntl.ShowHeader  = false;
                elementsCntl.DataContext = this.currentFormInst;
                ScrollViewerForm.Content = elementsCntl;
            }

            if (sender == ButtonAddUpdateDoc)
            {
                // add
                if (this.currentFormInst != null && this.currentFormDescription != null &&
                    thePackage != null &&
                    theOptions != null && theOptions.SemIdDocument != null &&
                    theSubmodel != null)
                {
                    // on this level of the hierarchy, shall a new SMEC be created or shall
                    // the existing source of elements be used?
                    AdminShell.SubmodelElementWrapperCollection currentElements = null;
                    if (formInUpdateMode && updateSourceElements != null)
                    {
                        currentElements = updateSourceElements;
                    }
                    else
                    {
                        currentElements = new AdminShell.SubmodelElementWrapperCollection();
                    }

                    // create a sequence of SMEs
                    try
                    {
                        this.currentFormInst.AddOrUpdateDifferentElementsToCollection(
                            currentElements, thePackage, addFilesToPackage: true);
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "when adding Document");
                    }

                    // the InstSubmodel, which started the process, should have a "fresh" SMEC available
                    // make it unique in the Documentens Submodel
                    var newSmc = this.currentFormInst?.sme as AdminShell.SubmodelElementCollection;

                    // if not update, put them into the Document's Submodel
                    if (!formInUpdateMode && currentElements != null && newSmc != null)
                    {
                        // make newSmc unique in the cotext of the Submodel
                        FormInstanceHelper.MakeIdShortUnique(theSubmodel.submodelElements, newSmc);

                        // add the elements
                        newSmc.value = currentElements;

                        // add the whole SMC
                        theSubmodel.Add(newSmc);
                    }

#if __may_be_not__
                    // save directly to ensure consistency
                    try
                    {
                        if (thePackage.Filename != null)
                        {
                            thePackage.SaveAs(thePackage.Filename);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (theLogger != null)
                        {
                            theLogger.Log(
                                $"Saving package {thePackage.Filename} failed for adding Document " +
                                $"and gave: {ex.Message}");
                        }
                    }
#endif
                }
                else
                {
                    Log.Error("Preconditions for adding Document not met.");
                }

                // change back
                OuterTabControl.SelectedItem = TabPanelList;

                // re-display
                ParseSubmodelToListItems(
                    this.theSubmodel, this.theOptions, theViewModel.TheSelectedDocClass,
                    theViewModel.TheSelectedLanguage, theViewModel.TheSelectedListType);

                // re-display also in Explorer
                var evt = new AasxPluginResultEventRedrawAllElements();
                if (theEventStack != null)
                {
                    theEventStack.PushEvent(evt);
                }
            }

            if (sender == ButtonCancel)
            {
                OuterTabControl.SelectedItem = TabPanelList;
            }
        }
Beispiel #15
0
        public void TableAddPropertyRows_Recurse(
            ConceptModelZveiTechnicalData theDefs, string defaultLang, AdminShellPackageEnv package,
            Table table, AdminShell.SubmodelElementWrapperCollection smwc, int depth = 0)
        {
            // access
            if (table == null || smwc == null)
            {
                return;
            }

            // make a RowGroup
            var currentRowGroup = new TableRowGroup();

            table.RowGroups.Add(currentRowGroup);

            // go element by element
            foreach (var smw in smwc)
            {
                // access
                if (smw?.submodelElement == null)
                {
                    continue;
                }
                var sme = smw.submodelElement;

                // prepare information about displayName, semantics unit
                var semantics = "-";
                var unit      = "";
                // make up property name (1)
                var dispName       = "" + sme.idShort;
                var dispNameWithCD = dispName;

                // make up semantics
                if (sme.semanticId != null)
                {
                    if (sme.semanticId.Matches(theDefs.CD_SemanticIdNotAvailable.GetSingleKey()))
                    {
                        semantics = "(not available)";
                    }
                    else
                    {
                        // the semantics display
                        semantics = "" + sme.semanticId.ToString(2);

                        // find better property name (2)
                        var cd = package?.AasEnv?.FindConceptDescription(sme.semanticId);
                        if (cd != null)
                        {
                            // unit?
                            unit = "" + cd.GetIEC61360()?.unit;

                            // names
                            var dsn = cd.GetDefaultShortName(defaultLang);
                            if (dsn != "")
                            {
                                dispNameWithCD = dsn;
                            }

                            var dpn = cd.GetDefaultPreferredName(defaultLang);
                            if (dpn != "")
                            {
                                dispNameWithCD = dpn;
                            }
                        }
                    }
                }

                // make up even better better property name (3)
                var descDef = "" + sme.description?.langString?.GetDefaultStr(defaultLang);
                if (descDef.HasContent())
                {
                    dispName       = descDef;
                    dispNameWithCD = dispName;
                }

                // special function?
                if (sme is AdminShell.SubmodelElementCollection &&
                    true == sme.semanticId?.Matches(theDefs.CD_MainSection.GetSingleKey()))
                {
                    // finalize current row group??
                    ;

                    // Main Section
                    var cell = NewTableCellPara("" + dispName, null, "ParaStyleSectionMain", columnSpan: 3,
                                                padding: new Thickness(5 * depth, 0, 0, 0));

                    // add cell (to a new row group)
                    currentRowGroup = new TableRowGroup();
                    table.RowGroups.Add(currentRowGroup);
                    var tr = new TableRow();
                    currentRowGroup.Rows.Add(tr);
                    tr.Cells.Add(cell);

                    // recurse into that (again, new group)
                    TableAddPropertyRows_Recurse(
                        theDefs, defaultLang, package, table,
                        (sme as AdminShell.SubmodelElementCollection).value, depth + 1);

                    // start new group
                    currentRowGroup = new TableRowGroup();
                    table.RowGroups.Add(currentRowGroup);
                }
                else
                if (sme is AdminShell.SubmodelElementCollection &&
                    true == sme.semanticId?.Matches(theDefs.CD_SubSection.GetSingleKey()))
                {
                    // finalize current row group??
                    ;

                    // Sub Section
                    var cell = NewTableCellPara("" + dispName, null, "ParaStyleSectionSub", columnSpan: 3,
                                                padding: new Thickness(5 * depth, 0, 0, 0));

                    // add cell (to a new row group)
                    currentRowGroup = new TableRowGroup();
                    table.RowGroups.Add(currentRowGroup);
                    var tr = new TableRow();
                    currentRowGroup.Rows.Add(tr);
                    tr.Cells.Add(cell);

                    // recurse into that
                    TableAddPropertyRows_Recurse(
                        theDefs, defaultLang, package, table,
                        (sme as AdminShell.SubmodelElementCollection).value, depth + 1);

                    // start new group
                    currentRowGroup = new TableRowGroup();
                    table.RowGroups.Add(currentRowGroup);
                }
                else
                if (sme is AdminShell.Property || sme is AdminShell.MultiLanguageProperty || sme is AdminShell.Range)
                {
                    // make a row (in current group)
                    var tr = new TableRow();
                    currentRowGroup.Rows.Add(tr);

                    // add cells
                    tr.Cells.Add(NewTableCellPara(dispNameWithCD, "CellStylePropertyLeftmost", "ParaStyleProperty",
                                                  padding: new Thickness(5 * depth, 0, 0, 0)));
                    tr.Cells.Add(NewTableCellPara(semantics, "CellStylePropertyOther", "ParaStyleProperty"));
                    tr.Cells.Add(NewTableCellPara("" + sme.ValueAsText(defaultLang) + " " + unit,
                                                  "CellStylePropertyOther", "ParaStyleProperty"));
                }
            }

            // finalize current row group??
            ;
        }
Beispiel #16
0
        private void ButtonTabPanels_Click(object sender, RoutedEventArgs e)
        {
            if (sender == ButtonUpdate)
            {
                // add
                if (this.currentFormInst != null &&
                    thePackage != null &&
                    theOptions != null &&
                    theSubmodel != null)
                {
                    // on this level of the hierarchy, shall a new SMEC be created or shall
                    // the existing source of elements be used?
                    AdminShell.SubmodelElementWrapperCollection currentElements = null;
                    if (formInUpdateMode && updateSourceElements != null)
                    {
                        currentElements = updateSourceElements;
                    }
                    else
                    {
                    }

                    // create a sequence of SMEs
                    try
                    {
                        this.currentFormInst.AddOrUpdateDifferentElementsToCollection(
                            currentElements, thePackage, addFilesToPackage: true, editSource: true);
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "when adding Document");
                    }

#if __may_be_not__
                    // save directly to ensure consistency
                    try
                    {
                        if (thePackage.Filename != null)
                        {
                            thePackage.SaveAs(thePackage.Filename);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (theLogger != null)
                        {
                            theLogger.Log(
                                $"Saving package {thePackage.Filename} failed for adding Document " +
                                $"and gave: {ex.Message}");
                        }
                    }
#endif
                }
                else
                {
                    Log.Error("Preconditions for adding entities from GenericForm not met.");
                }

                // re-display
                DisplaySubmodel();

                // re-display also in Explorer
                var evt = new AasxPluginResultEventRedrawAllElements();
                if (theEventStack != null)
                {
                    theEventStack.PushEvent(evt);
                }
            }

            if (sender == ButtonFixCDs)
            {
                // check if CDs are present
                if (currentFormRecord == null || currentFormRecord.ConceptDescriptions == null ||
                    currentFormRecord.ConceptDescriptions.Count < 1)
                {
                    Log.Error(
                        "Not able to find appropriate ConceptDescriptions in the GeneralForm option records. " +
                        "Aborting.");
                    return;
                }

                // check for Environment
                var env = this.thePackage?.AasEnv;
                if (env == null)
                {
                    Log.Error(
                        "Not able to access AAS environment for set of Submodel's ConceptDescriptions. Aborting.");
                    return;
                }

                // be safe?
                if (MessageBoxResult.Yes != MessageBox.Show(
                        "Add missing ConceptDescriptions to the AAS?", "Question",
                        MessageBoxButton.YesNo, MessageBoxImage.Warning))
                {
                    return;
                }

                // ok, check
                int nr = 0;
                foreach (var cd in currentFormRecord.ConceptDescriptions)
                {
                    if (cd == null || cd.identification == null)
                    {
                        continue;
                    }
                    var cdFound = env.FindConceptDescription(cd.identification);
                    if (cdFound != null)
                    {
                        continue;
                    }
                    // ok, add
                    var newCd = new AdminShell.ConceptDescription(cd);
                    env.ConceptDescriptions.Add(newCd);
                    nr++;
                }

                // ok
                Log.Info("In total, {0} ConceptDescriptions were added to the AAS environment.", nr);
            }
        }
Beispiel #17
0
        private void PublishSingleValues_ChangeItem(
            AasEventMsgEnvelope ev,
            AdminShell.ReferableRootInfo ri,
            AdminShell.KeyList startPath,
            AasPayloadStructuralChangeItem ci)
        {
            // trivial
            if (ev == null || ci == null || startPath == null)
            {
                return;
            }

            // only specific reasons
            if (!(ci.Reason == AasPayloadStructuralChangeItem.ChangeReason.Create ||
                  ci.Reason == AasPayloadStructuralChangeItem.ChangeReason.Modify))
            {
                return;
            }

            // need a payload
            if (ci.Path == null || ci.Data == null)
            {
                return;
            }

            var dataRef = ci.GetDataAsReferable();

            // give this to (recursive) function
            var messages = new List <MqttApplicationMessage>();

            if (dataRef is AdminShell.SubmodelElement dataSme)
            {
                var smwc = new AdminShell.SubmodelElementWrapperCollection(dataSme);
                smwc.RecurseOnSubmodelElements(null, null, (o, parents, sme) =>
                {
                    // assumption is, the sme is now "leaf" of a SME-hierarchy
                    if (sme is AdminShell.IEnumerateChildren)
                    {
                        return;
                    }

                    // value of the leaf
                    var valStr = sme.ValueAsText();

                    // build a complete path of keys
                    var path    = startPath + ci.Path + parents.ToKeyList() + sme?.ToKey();
                    var pathStr = path.BuildIdShortPath();

                    // publish
                    if (_diaData.LogDebug)
                    {
                        _logger?.Info("Publish single value (create/ update)");
                    }
                    messages.Add(
                        new MqttApplicationMessageBuilder()
                        .WithTopic(GenerateTopic(
                                       _diaData.EventTopic, defaultIfNull: "SingleValue",
                                       aasIdShort: ri?.AAS?.idShort, aasId: ri?.AAS?.identification,
                                       smIdShort: ri?.Submodel?.idShort, smId: ri?.Submodel?.identification,
                                       path: pathStr))
                        .WithPayload(valStr)
                        .WithExactlyOnceQoS()
                        .WithRetainFlag(_diaData.MqttRetain)
                        .Build());
                });
            }

            // publish these
            // convert to synchronous behaviour
            int count = 0;

            foreach (var msg in messages)
            {
                count++;
                _mqttClient.PublishAsync(msg).GetAwaiter().GetResult();
            }
            LogStatus(incSingleValue: count);
        }
Beispiel #18
0
        private static void RecurseExportAsTemplate(
            AdminShell.SubmodelElementWrapperCollection smwc, FormDescListOfElement tels,
            AdminShell.AdministrationShellEnv env = null, AdminShell.ListOfConceptDescriptions cds = null)
        {
            // access
            if (smwc == null || tels == null)
            {
                return;
            }

            // over all elems
            foreach (var smw in smwc)
            {
                if (smw != null && smw.submodelElement != null)
                {
                    FormDescSubmodelElement tsme = null;
                    if (smw.submodelElement is AdminShell.Property p)
                    {
                        tsme = new FormDescProperty(
                            "" + p.idShort, FormMultiplicity.One, p.semanticId?.GetAsExactlyOneKey(),
                            "" + p.idShort, valueType: p.valueType);
                    }
                    if (smw.submodelElement is AdminShell.MultiLanguageProperty mlp)
                    {
                        tsme = new FormDescMultiLangProp(
                            "" + mlp.idShort, FormMultiplicity.One, mlp.semanticId?.GetAsExactlyOneKey(),
                            "" + mlp.idShort);
                    }
                    if (smw.submodelElement is AdminShell.File fl)
                    {
                        tsme = new FormDescFile(
                            "" + fl.idShort, FormMultiplicity.One, fl.semanticId?.GetAsExactlyOneKey(),
                            "" + fl.idShort);
                    }
                    if (smw.submodelElement is AdminShell.ReferenceElement rf)
                    {
                        tsme = new FormDescReferenceElement(
                            "" + rf.idShort, FormMultiplicity.One, rf.semanticId?.GetAsExactlyOneKey(),
                            "" + rf.idShort);
                    }
                    if (smw.submodelElement is AdminShell.SubmodelElementCollection smec)
                    {
                        tsme = new FormDescSubmodelElementCollection(
                            "" + smec.idShort, FormMultiplicity.One, smec.semanticId?.GetAsExactlyOneKey(),
                            "" + smec.idShort);
                    }

                    if (tsme != null)
                    {
                        // take over directly
                        tsme.PresetCategory = smw.submodelElement.category;

                        // Qualifers
                        var qs = smw.submodelElement.qualifiers;

                        var q = qs?.FindType("FormTitle");
                        if (q != null)
                        {
                            tsme.FormTitle = "" + q.value;
                        }

                        q = qs?.FindType("FormInfo");
                        if (q != null)
                        {
                            tsme.FormInfo = "" + q.value;
                        }

                        q = qs?.FindType("EditIdShort");
                        if (q != null)
                        {
                            tsme.FormEditIdShort = q.value.Trim().ToLower() == "true";
                        }

                        q = qs?.FindType("EditDescription");
                        if (q != null)
                        {
                            tsme.FormEditDescription = q.value.Trim().ToLower() == "true";
                        }

                        q = qs?.FindType("Multiplicity");
                        if (q != null)
                        {
                            foreach (var m in (FormMultiplicity[])Enum.GetValues(typeof(FormMultiplicity)))
                            {
                                if (("" + q.value) == Enum.GetName(typeof(FormMultiplicity), m))
                                {
                                    tsme.Multiplicity = m;
                                }
                            }
                        }

                        q = qs?.FindType("PresetValue");
                        if (q != null && tsme is FormDescProperty)
                        {
                            (tsme as FormDescProperty).presetValue = "" + q.value;
                        }

                        q = qs?.FindType("PresetMimeType");
                        if (q != null && tsme is FormDescFile)
                        {
                            (tsme as FormDescFile).presetMimeType = "" + q.value;
                        }

                        q = qs?.FindType("FormChoices");
                        if (q != null && q.value.HasContent() && tsme is FormDescProperty fdprop)
                        {
                            var choices = q.value.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                            if (choices != null && choices.Length > 0)
                            {
                                fdprop.comboBoxChoices = choices;
                            }
                        }

                        // adopt presetIdShort
                        if (tsme.Multiplicity == FormMultiplicity.ZeroToMany ||
                            tsme.Multiplicity == FormMultiplicity.OneToMany)
                        {
                            tsme.PresetIdShort += "{0:00}";
                        }

                        // Ignore this element
                        q = qs?.FindType("FormIgnore");
                        if (q != null)
                        {
                            continue;
                        }
                    }

                    if (tsme != null)
                    {
                        tels.Add(tsme);
                    }

                    // in any case, check for CD
                    if (env != null && cds != null && smw?.submodelElement?.semanticId?.Keys != null)
                    {
                        var masterCd = env.FindConceptDescription(smw?.submodelElement?.semanticId?.Keys);
                        if (masterCd != null && masterCd.identification != null)
                        {
                            // already in cds?
                            var copyCd = cds.Find(masterCd.identification);
                            if (copyCd == null)
                            {
                                // add clone
                                cds.Add(new AdminShell.ConceptDescription(masterCd));
                            }
                        }
                    }

                    // recurse
                    if (smw.submodelElement is AdminShell.SubmodelElementCollection)
                    {
                        RecurseExportAsTemplate(
                            (smw.submodelElement as AdminShell.SubmodelElementCollection).value,
                            (tsme as FormDescSubmodelElementCollection).value, env, cds);
                    }
                }
            }
        }
        private void RecurseOnSme(
            AdminShell.SubmodelElementWrapperCollection smwc,
            CstIdObjectBase presetId,
            string presetClassType,
            CstPropertyRecord.ListOfProperty propRecs)
        {
            // access
            if (smwc == null)
            {
                return;
            }

            // create a class def
            CstClassDef.ClassDefinition clsdef;
            if (presetId != null)
            {
                clsdef = new CstClassDef.ClassDefinition(presetId);
            }
            else
            {
                clsdef = new CstClassDef.ClassDefinition(GenerateCustomId("CLS"));
            }
            clsdef.ClassType = presetClassType;

            // add the class def (to have the following classes below)
            ClassDefs.AddIfUnique(clsdef);

            // values
            for (int smcMode = 0; smcMode < 2; smcMode++)
            {
                foreach (var smw in smwc)
                {
                    // trivial
                    var sme = smw?.submodelElement;
                    if (sme == null)
                    {
                        continue;
                    }

                    // is SMC? .. ugly contraption to have first all Properties, then all SMCs
                    var smc = sme as AdminShell.SubmodelElementCollection;
                    if ((smcMode == 0 && smc != null) ||
                        (smcMode == 1 && smc == null))
                    {
                        continue;
                    }

                    // check, if ConceptDescription exists ..
                    var cd = _env?.AasEnv.FindConceptDescription(sme.semanticId);

                    // try to take over as much information from the pure SME as possible
                    var    semid   = sme.semanticId.GetAsExactlyOneKey()?.value;
                    string refStr  = null;
                    string refName = null;
                    if (semid != null)
                    {
                        // standardized ID?
                        if (semid.StartsWith("0173") || semid.StartsWith("0112"))
                        {
                            refStr = semid;
                        }

                        // already known, fixed id?
                        var it = _knownIdStore?.FindStringSemId(semid);
                        if (it != null)
                        {
                            if (it.cstRef != null)
                            {
                                refStr = it.cstRef;
                            }
                            if (it.cstId != null)
                            {
                                refStr = it.cstId.ToRef();
                            }
                            if (it.preferredName != null)
                            {
                                refName = it.preferredName;
                            }
                        }
                    }

                    // prepare a prop def & data type
                    CstPropertyDef.PropertyDefinition tmpPd = null;
                    string tmpDt = null;
                    if (refStr != null)
                    {
                        // make it
                        var bo = CstIdObjectBase.Parse(refStr);
                        tmpPd = new CstPropertyDef.PropertyDefinition(bo);

                        // more info
                        tmpPd.Name = "" + sme.idShort;
                        if (sme.description != null)
                        {
                            tmpPd.Remark = sme.description.GetDefaultStr("en");
                        }

                        if (sme is AdminShell.Property prop)
                        {
                            tmpDt = prop.valueType;
                        }

                        // more info
                        if (cd != null)
                        {
                            var ds61360 = cd.IEC61360Content;
                            if (ds61360 != null)
                            {
                                if (ds61360.definition != null)
                                {
                                    tmpPd.Definition = ds61360.definition.GetDefaultStr("en");
                                }

                                var dst = ds61360.dataType?.Trim().ToUpper();
                                if (ds61360 == null && dst != null)
                                {
                                    tmpDt = dst;
                                }
                            }
                        }

                        // default
                        if (!tmpDt.HasContent())
                        {
                            tmpDt = "STRING";
                        }
                    }

                    if (smc != null)
                    {
                        // SMC

                        // make a reference property def
                        // the property itself needs to have an ALTERED ID, to be not ídentical with
                        if (tmpPd != null)
                        {
                            // class id
                            tmpPd.ID = "BLPRP_" + tmpPd.ID;

                            // will be a reference to the intended class
                            tmpPd.DataType = new CstPropertyDef.DataType()
                            {
                                Type           = "Reference",
                                BlockReference = "" + refStr
                            };

                            // rest of attributes
                            tmpPd.ObjectType = "02";
                            tmpPd.Status     = "Released";

                            // add
                            PropertyDefs.AddIfUnique(tmpPd);
                        }

                        // create a new class attribute (with reference to ALTERED ID!)
                        var attr = new CstClassDef.ClassAttribute()
                        {
                            Type      = "Property",
                            Reference = tmpPd?.ToRef() ?? "NULL"
                        };
                        clsdef.ClassAttributes.AddIfUnique(attr);

                        // start new list of property values, embedded in a PropertyRecord
                        var rec = new CstPropertyRecord.PropertyRecord();
                        var lop = new CstPropertyRecord.ListOfProperty();
                        rec.ClassDefinition = refStr;
                        rec.Properties      = lop;
                        var pr = new CstPropertyRecord.Property()
                        {
                            ID         = tmpPd.ToRef(),
                            Name       = "" + smc.idShort,
                            ValueProps = rec
                        };

                        // execute the following, only if twice the same ID in proprety records
                        // (for blocks are allowed)
                        var addBlockRec = true;
                        if (DoNotAddMultipleBlockRecordsWithSameIds &&
                            propRecs.FindExisting(pr) != null)
                        {
                            addBlockRec = false;
                        }

                        // ok?
                        if (addBlockRec)
                        {
                            if (propRecs != null)
                            {
                                propRecs.Add(pr);
                            }

                            // recursion, but as Block
                            // TODO (MIHO, 2021-05-28): extend Parse() to parse also ECLASS, IEC CDD
                            var blockId = CstIdObjectBase.Parse(refStr);
                            blockId.Name = refName;
                            RecurseOnSme(smc.value, blockId, "Block", lop);
                        }
                    }
                    else
                    {
                        // normal case .. Property or so

                        // create a new class attribute
                        var attr = new CstClassDef.ClassAttribute()
                        {
                            Type      = "Property",
                            Reference = refStr
                        };
                        clsdef.ClassAttributes.AddIfUnique(attr);

                        // make a "normal" property definition
                        if (tmpPd != null)
                        {
                            // use data type?
                            if (tmpDt != null)
                            {
                                tmpPd.DataType = new CstPropertyDef.DataType()
                                {
                                    Type = AasxCstUtils.ToPascalCase(tmpDt)
                                }
                            }
                            ;

                            tmpPd.ObjectType = "02";
                            tmpPd.Status     = "Released";
                            PropertyDefs.AddIfUnique(tmpPd);
                        }

                        // make a prop rec
                        var pr = new CstPropertyRecord.Property()
                        {
                            ValueStr = sme.ValueAsText(),
                            ID       = refStr,
                            Name     = "" + sme.idShort
                        };
                        if (propRecs != null)
                        {
                            propRecs.Add(pr);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Render the form description and adds or updates its instances into a list of SubmodelElements.
        /// </summary>
        public AdminShell.SubmodelElementWrapperCollection AddOrUpdateSameElementsToCollection(
            AdminShell.SubmodelElementWrapperCollection elements, AdminShellPackageEnv packageEnv = null,
            bool addFilesToPackage = false)
        {
            // access
            var res = new AdminShell.SubmodelElementWrapperCollection();

            if (this.SubInstances == null || this.workingDesc == null)
            {
                return(null);
            }

            // over all instances
            foreach (var ins in this.SubInstances)
            {
                // access
                if (!(ins is FormInstanceSubmodelElement))
                {
                    continue;
                }

                // only touched?
                if (!(ins is FormInstanceSubmodelElementCollection) && !ins.Touched)
                {
                    continue;
                }

                // this is not very nice: distinguish between SMECs und SMEs
                if (!(this.workingDesc is FormDescSubmodelElementCollection))
                {
                    var lst1 = (ins as FormInstanceSubmodelElement).AddOrUpdateSmeToCollection(
                        elements, packageEnv, addFilesToPackage);

                    // for monitoring purpose
                    res.AddRange(lst1);
                }
                else
                {
                    // Special case: SMEC

                    // the Same-Instance was already prepared, however it needs to be eventually
                    // filled with the new elements
                    var smecInst   = ins as FormInstanceSubmodelElementCollection;
                    var sourceSmec = smecInst?.sourceSme as AdminShell.SubmodelElementCollection;

                    AdminShell.SubmodelElementWrapperCollection newElems = null;
                    bool addMode = false;
                    if (sourceSmec == null)
                    {
                        // will become a NEW SMEC !
                        newElems = new AdminShell.SubmodelElementWrapperCollection();
                        addMode  = true;
                    }
                    else
                    {
                        // will be added to an existing SMEC
                        newElems = sourceSmec.value;
                        addMode  = false;
                    }

                    var lst = (ins as FormInstanceSubmodelElement).AddOrUpdateSmeToCollection(
                        newElems, packageEnv, addFilesToPackage);

                    if (newElems != null && newElems.Count > 0)
                    {
                        var smec = smecInst?.sme as AdminShell.SubmodelElementCollection;

                        // really add a new instances of the SMEC
                        if (addMode && smecInst != null && smec != null)
                        {
                            // add
                            if (smec.value == null)
                            {
                                smec.value = new AdminShellV20.SubmodelElementWrapperCollection();
                            }
                            smec.value.AddRange(newElems);

                            // make smec unique
                            FormInstanceHelper.MakeIdShortUnique(elements, smec);

                            // to (outer) elements
                            elements.Add(smec);
                        }

                        // for monitoring purpose
                        res.AddRange(lst);
                    }
                }
            }

            // now, check if original SMEs are missing in the Instances and have therefore be removed
            // (kind of post-mortem analysis)
            if (this.InitialSourceElements != null)
            {
                foreach (var ise in this.InitialSourceElements)
                {
                    // exclude trivial cases
                    if (ise == null)
                    {
                        continue;
                    }

                    // manually search
                    var found = false;
                    foreach (var ins in this.SubInstances)
                    {
                        if (ins != null && ins is FormInstanceSubmodelElement &&
                            (ins as FormInstanceSubmodelElement).sourceSme == ise)
                        {
                            found = true;
                        }
                    }

                    // if not foudnd, DELETE original element
                    if (!found)
                    {
                        elements.Remove(ise);
                    }
                }
            }

            // ok
            return(res);
        }