TheDynamics.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. async function createDynamic() {
  80. //dynNode.namespaceUri = nameSpaceName.value;
  81. //dynNode.parentNodeId = selectedNode.value?.nodeId.toString();
  82. // dynNode.value.typeNodeId = typedef.value.toString();
  83. // console.log(dynNode);
  84. //console.log(c_man);
  85. //console.log(c_opt.value);
  86. // console.log(dynNode.value.dynamicNodeData.optionals)
  87. // console.log(dynNode.value.o_check)
  88. //dynNode = new DynamicNode(opt);
  89. /*
  90. const blob = await store.addressSpace?.exportProject();
  91. if ('dynamics' in sconfig){
  92. sconfig.dynamics.push("hello");
  93. }else{
  94. sconfig.dynamics = [];
  95. }
  96. */
  97. }
  98. function okPressed() {
  99. store.serverConfig.addDynamic(dynNode.value);
  100. }
  101. defineExpose({ okPressed })
  102. </script>
  103. <template>
  104. <div class="card">
  105. <div class="card-body" v-if="selectedNode != null">
  106. <h5 class="card-title">Dynamic Node</h5>
  107. <div class="card-text">
  108. <div class="input-group mb-3">
  109. <div class="input-group-prepend">
  110. <span class="input-group-text" id="inputGroup-sizing-default">Parent Node</span>
  111. </div>
  112. <input type="text" class="form-control" aria-label="Default"
  113. aria-describedby="inputGroup-sizing-default" v-model="selectedNode.nodeId" disabled>
  114. </div>
  115. <div class="input-group mb-3">
  116. <div class="input-group-prepend">
  117. <span class="input-group-text" id="inputGroup-sizing-default">Namespace</span>
  118. </div>
  119. <input type="text" class="form-control" aria-label="Default" aria-describedby="inputGroup-sizing-default" v-model="nameSpaceName" disabled>
  120. </div>
  121. <div class="input-group mb-3">
  122. <div class="input-group-prepend">
  123. <span class="input-group-text" id="inputGroup-sizing-default">Name Dynamic Definition</span>
  124. </div>
  125. <input type="text" class="form-control" aria-label="Default"
  126. aria-describedby="inputGroup-sizing-default" v-model="dynNode.name">
  127. </div>
  128. <div class="input-group mb-3">
  129. <div class="input-group-prepend">
  130. <span class="input-group-text" id="inputGroup-sizing-default">Update Interval in ms</span>
  131. </div>
  132. <input type="text" class="form-control" aria-label="Default"
  133. aria-describedby="inputGroup-sizing-default" v-model="dynNode.checkInterval">
  134. </div>
  135. <div class="input-group mb-3">
  136. <div class="input-group-prepend">
  137. <span class="input-group-text" id="inputGroup-sizing-default">NodeVersion</span>
  138. </div>
  139. <input type="text" class="form-control" aria-label="Default"
  140. aria-describedby="inputGroup-sizing-default" :value="getNodeVersion(selectedNode.nodeId.toString())" disabled>
  141. </div>
  142. <div class="input-group mb-3">
  143. <div class="input-group-prepend">
  144. <span class="input-group-text" id="inputGroup-sizing-default">Reference</span>
  145. </div>
  146. <select class="form-select" aria-label="Default select example">
  147. <option v-for="option in getRefTypes()" :value="option.nodeId.toString()" v-bind:key="option.nodeId.toString()">
  148. {{ option.browseName }}
  149. </option>
  150. </select>
  151. </div>
  152. <div class="input-group mb-3">
  153. <div class="input-group-prepend">
  154. <span class="input-group-text" id="inputGroup-sizing-default">Ident</span>
  155. </div>
  156. <input type="text" class="form-control" aria-label="Default"
  157. aria-describedby="inputGroup-sizing-default" v-model="dynNode.ident">
  158. </div>
  159. <div class="input-group mb-3">
  160. <div class="input-group-prepend">
  161. <input type="checkbox" id="checkbox" v-model="checked" />
  162. <label for="checkbox">{{ checked?"ObjectType":"VariableType" }}</label>
  163. </div>
  164. </div>
  165. <div class="input-group mb-3">
  166. <div class="input-group-prepend">
  167. <span class="input-group-text" id="inputGroup-sizing-default">Type Definition</span>
  168. </div>
  169. <select v-model="typedef" class="form-select" aria-label="Default select example" >
  170. <option v-for="option1 in getObjTypes('ns=0;i='+ ObjectIds.VariableTypesFolder)" :value="option1.nodeId.toString()" v-bind:key="option1.nodeId.toString()">
  171. {{ option1.browseName }}
  172. </option>
  173. </select>
  174. </div>
  175. <div class="input-group mb-3">
  176. <ul class="no-bullets"><b>Mandatory Components</b>
  177. <li v-for="item of getInstanceDecl(typedef, 'Mandatory')" v-bind:key = item>
  178. <input type="checkbox" id="checkbox-digg-{{ item }}" :checked="true" :disabled="true">
  179. <label for="checkbox-digg-{{ item}}">{{ item}}</label>
  180. </li>
  181. </ul>
  182. </div>
  183. <div>
  184. <ul class="no-bullets"><b>Optional Components</b>
  185. <li v-for="(item1) of getInstanceDecl(typedef, 'Optional')" v-bind:key = item1>
  186. <input type="checkbox" id="checkbox-digg-{{ item1 }}" :value="item1">
  187. <label for="checkbox-digg-{{ item1 }}">{{ item1 }}</label>
  188. </li>
  189. </ul>
  190. </div>
  191. </div>
  192. </div>
  193. </div>
  194. </template>
  195. <style scoped>
  196. ul.no-bullets {
  197. list-style-type: none;
  198. margin: 0;
  199. padding: 0;
  200. }
  201. </style>@/store