TheDynamics.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <script setup lang="ts">
  2. import { useStore } from '@/store'
  3. import { computed, ref, watch } from 'vue';
  4. import { UABaseNode } from '@/ua/UABaseNode';
  5. import { ObjectIds, ReferenceTypeIds } from '@/ua/opcua_node_ids';
  6. import type { UAReferenceType } from '@/ua/UAReferenceType';
  7. import type { UAVariableType } from '@/ua/UAVariableType';
  8. import { type DynamicNodeData} from '@/ua/DynamicNode';
  9. import { storeToRefs } from 'pinia';
  10. const store = useStore();
  11. const { selectedNode} = storeToRefs(store)
  12. const nameSpaceName = computed(() => {
  13. if(!selectedNode.value)
  14. return "";
  15. let nsIdx=selectedNode.value.nodeId.namespace;
  16. return store.addressSpace?.nst.getUri(nsIdx);
  17. })
  18. let opt: DynamicNodeData = {
  19. ident: "...",
  20. namespaceUri:"MyNamespace",
  21. parentNodeId: "MyNodeId",
  22. checkInterval:100,
  23. nodeClass:"Object",
  24. typeNodeId:"ns=0;i=88",
  25. name:"...",
  26. startIndex:0
  27. };
  28. const dynNode = ref(opt);
  29. const checked = ref("")
  30. const typedef = ref("")
  31. watch(selectedNode, async (newNode, _oldNode) => {
  32. if(!newNode)
  33. return;
  34. let dynConfig=store.serverConfig.configData.dynamics?.find((d) => {d.parentNodeId==newNode.nodeId.toString()})||{}
  35. dynNode.value=dynConfig;
  36. //TODO: what id does/should typedef hold?
  37. typedef.value=newNode.nodeId.toString();
  38. })
  39. function getRefTypes():UABaseNode[] {
  40. let list=(store.addressSpace?.getSubTreeAsList("ns=0;i="+ReferenceTypeIds.HierarchicalReferences)||[]) as UAReferenceType[];
  41. list=list.filter((node) => node.isAbstract==false)
  42. return list;
  43. }
  44. function getObjTypes(nid: string):UABaseNode[] {
  45. const list=(store.addressSpace?.getSubTreeAsList(nid)||[]) as UAVariableType[];
  46. return list.filter((node) => node.isAbstract==false)
  47. }
  48. function getInstanceDecl(nid: string, mrType: string){
  49. const aggregates = (store.addressSpace?.getSubTreeAsList("ns=0;i="+ReferenceTypeIds.Aggregates)||[]) as UABaseNode[];
  50. let aggStrings:String[] = [];
  51. aggregates.forEach((item) => {
  52. aggStrings.push(item.browseName);
  53. })
  54. let node = (store.addressSpace?.findNode(nid)) as UABaseNode;
  55. let res:string[] = [];
  56. node.references.forEach((item) => {
  57. if(aggStrings.includes(item.referenceType) && item.isForward){
  58. let mr = item.toNode.getModellingRule()||"";
  59. if(mr == mrType){
  60. res.push(item.toNode.browseName||"");
  61. }
  62. }
  63. })
  64. return res;
  65. }
  66. function getNodeVersion(nid:string){
  67. let node = (store.addressSpace?.findNode(nid)) as UABaseNode;
  68. if(!node)
  69. return "";
  70. let refs = node.references;
  71. refs.forEach((ref)=>{
  72. if(ref.toNode.browseName == "NodeVersion" && ref.isForward){
  73. return ref.toNode.nodeId.toString()
  74. }else if(ref.fromNode.browseName == "NodeVersion" && !ref.isForward){
  75. return ref.fromNode.nodeId.toString()
  76. }
  77. })
  78. }
  79. function okPressed() {
  80. store.serverConfig.addDynamic(dynNode.value);
  81. }
  82. defineExpose({ okPressed })
  83. </script>
  84. <template>
  85. <div class="card">
  86. <div class="card-body" v-if="selectedNode != null">
  87. <h5 class="card-title">Dynamic Node</h5>
  88. <div class="card-text">
  89. <div class="input-group mb-3">
  90. <div class="input-group-prepend">
  91. <span class="input-group-text" id="inputGroup-sizing-default">Parent Node</span>
  92. </div>
  93. <input type="text" class="form-control" aria-label="Default"
  94. aria-describedby="inputGroup-sizing-default" v-model="selectedNode.nodeId" disabled>
  95. </div>
  96. <div class="input-group mb-3">
  97. <div class="input-group-prepend">
  98. <span class="input-group-text" id="inputGroup-sizing-default">Namespace</span>
  99. </div>
  100. <input type="text" class="form-control" aria-label="Default" aria-describedby="inputGroup-sizing-default" v-model="nameSpaceName" disabled>
  101. </div>
  102. <div class="input-group mb-3">
  103. <div class="input-group-prepend">
  104. <span class="input-group-text" id="inputGroup-sizing-default">Name Dynamic Definition</span>
  105. </div>
  106. <input type="text" class="form-control" aria-label="Default"
  107. aria-describedby="inputGroup-sizing-default" v-model="dynNode.name">
  108. </div>
  109. <div class="input-group mb-3">
  110. <div class="input-group-prepend">
  111. <span class="input-group-text" id="inputGroup-sizing-default">Update Interval in ms</span>
  112. </div>
  113. <input type="text" class="form-control" aria-label="Default"
  114. aria-describedby="inputGroup-sizing-default" v-model="dynNode.checkInterval">
  115. </div>
  116. <div class="input-group mb-3">
  117. <div class="input-group-prepend">
  118. <span class="input-group-text" id="inputGroup-sizing-default">NodeVersion</span>
  119. </div>
  120. <input type="text" class="form-control" aria-label="Default"
  121. aria-describedby="inputGroup-sizing-default" :value="getNodeVersion(selectedNode.nodeId.toString())" disabled>
  122. </div>
  123. <div class="input-group mb-3">
  124. <div class="input-group-prepend">
  125. <span class="input-group-text" id="inputGroup-sizing-default">Reference</span>
  126. </div>
  127. <select class="form-select" aria-label="Default select example">
  128. <option v-for="option in getRefTypes()" :value="option.nodeId.toString()" v-bind:key="option.nodeId.toString()">
  129. {{ option.browseName }}
  130. </option>
  131. </select>
  132. </div>
  133. <div class="input-group mb-3">
  134. <div class="input-group-prepend">
  135. <span class="input-group-text" id="inputGroup-sizing-default">Ident</span>
  136. </div>
  137. <input type="text" class="form-control" aria-label="Default"
  138. aria-describedby="inputGroup-sizing-default" v-model="dynNode.ident">
  139. </div>
  140. <div class="input-group mb-3">
  141. <div class="input-group-prepend">
  142. <input type="checkbox" id="checkbox" v-model="checked" />
  143. <label for="checkbox">{{ checked?"ObjectType":"VariableType" }}</label>
  144. </div>
  145. </div>
  146. <div class="input-group mb-3">
  147. <div class="input-group-prepend">
  148. <span class="input-group-text" id="inputGroup-sizing-default">Type Definition</span>
  149. </div>
  150. <select v-model="typedef" class="form-select" aria-label="Default select example" >
  151. <option v-for="option1 in getObjTypes('ns=0;i='+ ObjectIds.VariableTypesFolder)" :value="option1.nodeId.toString()" v-bind:key="option1.nodeId.toString()">
  152. {{ option1.browseName }}
  153. </option>
  154. </select>
  155. </div>
  156. <div class="input-group mb-3">
  157. <ul class="no-bullets"><b>Mandatory Components</b>
  158. <li v-for="item of getInstanceDecl(typedef, 'Mandatory')" v-bind:key = item>
  159. <input type="checkbox" id="checkbox-digg-{{ item }}" :checked="true" :disabled="true">
  160. <label for="checkbox-digg-{{ item}}">{{ item}}</label>
  161. </li>
  162. </ul>
  163. </div>
  164. <div>
  165. <ul class="no-bullets"><b>Optional Components</b>
  166. <li v-for="(item1) of getInstanceDecl(typedef, 'Optional')" v-bind:key = item1>
  167. <input type="checkbox" id="checkbox-digg-{{ item1 }}" :value="item1">
  168. <label for="checkbox-digg-{{ item1 }}">{{ item1 }}</label>
  169. </li>
  170. </ul>
  171. </div>
  172. </div>
  173. </div>
  174. </div>
  175. </template>
  176. <style scoped>
  177. ul.no-bullets {
  178. list-style-type: none;
  179. margin: 0;
  180. padding: 0;
  181. }
  182. </style>@/store