Sfoglia il codice sorgente

added element for dynamic nodes, variable types, object types, server config

dstrutzenberger 10 mesi fa
parent
commit
f9d149cb74
4 ha cambiato i file con 290 aggiunte e 0 eliminazioni
  1. 191 0
      src/components/TheDynamics.vue
  2. 40 0
      src/ua/UAObjectType.ts
  3. 40 0
      src/ua/UAVariableType.ts
  4. 19 0
      src/util/ServerConfig.ts

+ 191 - 0
src/components/TheDynamics.vue

@@ -0,0 +1,191 @@
+<script setup lang="ts">
+import { useStore } from '@/util/store'
+import { computed, ref } from 'vue';
+import type { UABaseNode } from '@/ua/UABaseNode';
+import { ReferenceTypeIds } from '@/ua/opcua_node_ids';
+import type { UAReferenceType } from '@/ua/UAReferenceType';
+import { ObjectTypeIds } from '@/ua/opcua_node_ids';
+import type { UAObjectType } from '@/ua/UAObjectType';
+import { VariableTypeIds } from '@/ua/opcua_node_ids';
+import type { UAVariableType } from '@/ua/UAVariableType';
+import { UAReference } from '@/ua/UAReference';
+import { UAObject } from '@/ua/UAObject';
+import { UAVariable } from '@/ua/UAVariable';
+import {sconfig} from "@/util/ServerConfig"
+const store = useStore()
+
+const parentDialogOpen = ref(false);
+const node = computed(() => {
+  return store.selectedNode;
+
+});
+
+function clickNode(clickedNode: UABaseNode) {
+  //TODO: replace parent references
+  // node.value?.setParent(clickedNode, store.addressSpace?.findNode("ns=0;i="+ ReferenceTypeIds.HierarchicalReferences));
+  parentDialogOpen.value=false;
+}
+
+function filter(fnode: UABaseNode) {
+  if(node.value?.nodeClass==="Variable") {
+    if(fnode.nodeClass!="Object")
+      return true;
+  }
+  return false;
+}
+
+function getRefTypes():UABaseNode[] {
+  let list=(store.addressSpace?.getSubTreeAsList("ns=0;i="+ReferenceTypeIds.HierarchicalReferences)||[]) as UAReferenceType[];
+  list=list.filter((node) => node.isAbstract==false)
+  return list;
+}
+
+function getObjTypes(flag:any):UABaseNode[] {
+    let list = [];
+    if(flag){
+        list=(store.addressSpace?.getSubTreeAsList("ns=0;i=89")||[]) as UAVariableType[]; 
+    }else{
+        list=(store.addressSpace?.getSubTreeAsList("ns=0;i=88")||[]) as UAObjectType[];
+    }
+  list=list.filter((node) => node.isAbstract==false)
+  return list;
+}
+
+function defType(flag:any ):String{
+    let lab = "ObjectType";
+    if(flag){
+        lab = "VariableType";
+    }
+    return lab;
+}
+
+
+
+function getInstanceDecl(nid="ns=0;i=58"){
+  if(nid == "") nid = "ns=0;i=58";
+  let component_refs:String[] = [];
+  let res_man:any[] = [];
+  let res_opt:any[] = [];
+  let res:any[] = [];
+  let node =  (store.addressSpace?.findNode(nid)) as UABaseNode;
+  let refs = node.references;
+  let list = (store.addressSpace?.getSubTreeAsList("ns=0;i="+ReferenceTypeIds.Aggregates)||[]) as UABaseNode[];
+  list.forEach((item) => {
+    component_refs.push(item.browseName);
+  })
+  refs.forEach((item) => {
+    if(component_refs.includes(item.referenceType) && item.isForward){
+      let mr = "";
+      if(item.toNode.nodeClass == "Object"){
+        let i = item.toNode as UAObject;
+        mr = i.getModellingRule();
+      }else if(item.toNode.nodeClass == "Variable"){
+        let i = item.toNode as UAVariable;
+        mr = i.getModellingRule();
+      }
+      if(mr == "Mandatory"){
+        const newItem = { ref: item, checked: true, modellingRule:mr };
+        res_man.push(newItem);
+      }else{
+        const newItem = { ref: item, checked: false, modellingRule:mr };
+        res_opt.push(newItem);
+      }
+      res.push(res_man);
+      res.push(res_opt);
+    }
+  })
+  return res;
+}
+
+async function createDynamic() {
+  const blob = await store.addressSpace?.exportProject();
+  if ('dynamics' in sconfig){
+    sconfig.dynamics.push("hello");
+  }else{
+    sconfig.dynamics = [];
+  }
+   
+}
+
+
+
+
+const type_def = ref("")
+const checked = ref("")
+const type = ref("")
+const components = ref("")
+
+
+
+</script>
+
+<template>
+  <div class="card">
+    <div class="card-body" v-if="node != null">
+      <h5 class="card-title">Dynamic Node</h5>
+      <div class="card-text">
+        <div class="input-group mb-3">
+          <div class="input-group-prepend">
+            <span class="input-group-text" id="inputGroup-sizing-default">Parent Node</span>
+          </div>
+          <input readonly type="text" class="form-control" aria-label="Default"
+            aria-describedby="inputGroup-sizing-default" :value="node?.nodeId"> 
+        </div>
+        <div class="input-group mb-3">
+          <div class="input-group-prepend">
+            <span class="input-group-text" id="inputGroup-sizing-default">Reference</span>
+          </div>
+          <select class="form-select" aria-label="Default select example">
+            <option v-for="option in getRefTypes()" :value="option.nodeId.toString()" v-bind:key="option.nodeId.toString()">
+              {{ option.displayName }}
+            </option>
+          </select>
+        </div>
+        <div class="input-group mb-3">
+          <div class="input-group-prepend">
+            <input type="checkbox" id="checkbox" v-model="checked" />
+            <label for="checkbox">{{ defType(checked) }}</label>
+          </div>
+        </div>
+        <div class="input-group mb-3">
+          <div class="input-group-prepend">
+            <span class="input-group-text" id="inputGroup-sizing-default">Type Definition</span>
+          </div>
+          <select v-model="type" class="form-select" aria-label="Default select example">
+            <option v-for="option1 in getObjTypes(checked)" :value="option1.nodeId.toString()" v-bind:key="option1.nodeId.toString()">
+              {{ option1.displayName }}
+            </option>
+          </select>
+        </div>
+        <div class="input-group mb-3">
+          <ul class="no-bullets">Mandatory Components
+            <li v-for="todo in getInstanceDecl(type)[0]">
+              <input type="checkbox" id="checkbox-{{ todo.ref.toNode.displayName }}" v-model="todo.checked" :disabled="true">
+              <label for="checkbox-{{ todo.ref.toNode.displayName }}">{{ todo.ref.toNode.displayName }}</label>
+            </li>
+          </ul>
+        </div>
+        <div>
+          <ul class="no-bullets">Optional Components
+            <li v-for="todo1 in (getInstanceDecl(type)[1])">
+              <input type="checkbox" id="checkbox-digg" v-model="todo1.checked">
+              <label for="checkbox-digg">{{ todo1.ref.toNode.displayName }}</label>
+            </li>
+          </ul>
+        </div>
+        <div>
+          <button class="btn btn-light" @click.prevent="createDynamic()">Create</button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+
+<style scoped>
+  ul.no-bullets {
+  list-style-type: none;
+  margin: 0;
+  padding: 0;
+}
+</style>

+ 40 - 0
src/ua/UAObjectType.ts

@@ -0,0 +1,40 @@
+import { XMLElem } from "@/util/XmlElem";
+import type { NamespaceTable } from "./NameSpaceTable";
+import { UABaseNode, type UABaseNodeOptions } from "./UABaseNode";
+
+export class UAObjectType extends UABaseNode{
+    public isAbstract: boolean;
+
+    constructor(options: UAObjectTypeOptions) {
+        super(options)
+        this.isAbstract=options.isAbstract||false;
+    }
+
+    static  fromXML(xmlObjType: any): UAObjectType{
+        const bn=super.fromXML(xmlObjType)
+        return new UAObjectType({nodeId: bn.nodeId, 
+                            browseName: bn.browseName, 
+                            displayName: bn.displayName,
+                            references: bn.references,
+                            isAbstract: xmlObjType['@_IsAbstract']==='true'});
+    }
+
+    toXML(lnst:NamespaceTable, gnst:NamespaceTable): XMLElem {
+        const nid=UABaseNode.localNodeId(this.nodeId, lnst, gnst);
+        const elem =new XMLElem('UAObjectType');
+        elem.attr('NodeId', nid.toString())
+            .attr('BrowseName', this.browseName)
+            .attr('IsAbstract', this.isAbstract)
+            .elem('DisplayName', this.displayName);
+        const refs=elem.add(new XMLElem('References'))
+        for(const ref of this.references) {
+            if(ref.fromNode.nodeId.toString()==this.nodeId.toString()) //on load resolveReferences() duplicates references to both sides. skip them for export
+                refs.add(ref.toXML(lnst, gnst));
+        }
+        return elem;
+    }
+}
+
+export interface UAObjectTypeOptions extends UABaseNodeOptions{
+    isAbstract?: boolean
+}

+ 40 - 0
src/ua/UAVariableType.ts

@@ -0,0 +1,40 @@
+import { XMLElem } from "@/util/XmlElem";
+import type { NamespaceTable } from "./NameSpaceTable";
+import { UABaseNode, type UABaseNodeOptions } from "./UABaseNode";
+
+export class UAVariableType extends UABaseNode{
+    public isAbstract: boolean;
+
+    constructor(options: UAVariableTypeOptions) {
+        super(options)
+        this.isAbstract=options.isAbstract||false;
+    }
+
+    static  fromXML(xmlObjType: any): UAVariableType{
+        const bn=super.fromXML(xmlObjType)
+        return new UAVariableType({nodeId: bn.nodeId, 
+                            browseName: bn.browseName, 
+                            displayName: bn.displayName,
+                            references: bn.references,
+                            isAbstract: xmlObjType['@_IsAbstract']==='true'});
+    }
+
+    toXML(lnst:NamespaceTable, gnst:NamespaceTable): XMLElem {
+        const nid=UABaseNode.localNodeId(this.nodeId, lnst, gnst);
+        const elem =new XMLElem('UAVariableType');
+        elem.attr('NodeId', nid.toString())
+            .attr('BrowseName', this.browseName)
+            .attr('IsAbstract', this.isAbstract)
+            .elem('DisplayName', this.displayName);
+        const refs=elem.add(new XMLElem('References'))
+        for(const ref of this.references) {
+            if(ref.fromNode.nodeId.toString()==this.nodeId.toString()) //on load resolveReferences() duplicates references to both sides. skip them for export
+                refs.add(ref.toXML(lnst, gnst));
+        }
+        return elem;
+    }
+}
+
+export interface UAVariableTypeOptions extends UABaseNodeOptions{
+    isAbstract?: boolean
+}

+ 19 - 0
src/util/ServerConfig.ts

@@ -0,0 +1,19 @@
+
+export let sconfig:any = {
+    buildInfo:{
+		manufacturerName:"Emco GmbH",
+		productName: "EMCO OPC UA Server",
+		softwareVersion: "1.0.0"
+		},
+	serverInfo: {
+				applicationUri: "EMCO_OPCUA",
+				productUri: "EMCO_OPCUA",
+				applicationName: { "text": "EMCO_OPCUA", "locale": "en" }
+			}
+};
+
+
+
+//Check wether key is already present  with if(key in sconfig)
+
+