@@ -16,6 +16,7 @@ import {
1616import { ExternalControlProgramNode } from './external-control-program.node' ;
1717import { URCAP_ID , VENDOR_ID } from 'src/generated/contribution-constants' ;
1818import { ExternalControlApplicationNode } from '../external-control-application/external-control-application.node' ;
19+ import { v4 as uuidv4 } from 'uuid' ;
1920
2021const createProgramNodeLabel = async ( node : ExternalControlProgramNode ) : Promise < AdvancedTranslatedProgramLabel > => {
2122 const api = new ProgramBehaviorAPI ( self ) ;
@@ -38,22 +39,35 @@ const createProgramNode = async (): Promise<ExternalControlProgramNode> => {
3839 const applicationNode = await api . applicationService . getApplicationNode ( 'universal-robots-external-control-external-control-application' ) as ExternalControlApplicationNode ;
3940 return ( {
4041 type : 'universal-robots-external-control-external-control-program' ,
41- version : '1.0 .0' ,
42+ version : '1.1 .0' ,
4243 lockChildren : false ,
4344 allowsChildren : false ,
45+ parameters : {
46+ nodeHash : uuidv4 ( )
47+ }
4448 } ) ;
4549} ;
4650
4751export const fetchBackendJson = async ( port : number , robotIP : string , api : ProgramBehaviorAPI ) : Promise < any > => {
4852 const url = api . getContainerContributionURL ( VENDOR_ID , URCAP_ID , 'external-control-backend' , 'rest-api' ) ;
4953 const backendUrl = `${ location . protocol } //${ url } /${ port } /${ robotIP } ` ;
54+ console . log ( "backendUrl" , backendUrl ) ;
5055 const response = await fetch ( backendUrl ) ;
56+ console . log ( "response" , response ) ;
5157 if ( ! response . ok ) {
5258 throw new Error ( `Backend error: ${ response . status } ` ) ;
5359 }
5460 return await response . json ( ) ;
5561} ;
5662
63+ export const isThisNodeTheFirstUrcapNodeInTree = async ( node : ExternalControlProgramNode , api : ProgramBehaviorAPI ) : Promise < boolean > => {
64+ const listOfUrcapNodesInTree = ( await api . programTreeService . getContributedNodeInstancesForURCap ( ) )
65+ const filteredListOfUrcapNodesInTree = listOfUrcapNodesInTree . filter ( node => ! node . node . isSuppressed && node . node . type === 'universal-robots-external-control-external-control-program' )
66+ const sortedListOfUrcapNodesInTree = filteredListOfUrcapNodesInTree . sort ( ( a , b ) => a . node . parameters ?. nodeHash . localeCompare ( b . node . parameters . nodeHash ) )
67+
68+ return sortedListOfUrcapNodesInTree . length > 0 && sortedListOfUrcapNodesInTree [ 0 ] . node . parameters ?. nodeHash === node . parameters ?. nodeHash ;
69+ }
70+
5771const generateScriptCodeBefore = async ( node : ExternalControlProgramNode , ScriptContext : ScriptContext ) : Promise < ScriptBuilder > => {
5872 const api = new ProgramBehaviorAPI ( self ) ;
5973 const applicationNode = await api . applicationService . getApplicationNode ( 'universal-robots-external-control-external-control-application' ) as ExternalControlApplicationNode ;
@@ -73,17 +87,26 @@ const generateScriptCodeBefore = async (node: ExternalControlProgramNode, Script
7387const generateScriptCodeAfter = ( node : ExternalControlProgramNode ) : OptionalPromise < ScriptBuilder > => new ScriptBuilder ( ) ;
7488
7589const generatePreambleScriptCode = async ( node : ExternalControlProgramNode , ScriptContext : ScriptContext ) : Promise < ScriptBuilder > => {
90+ console . log ( 'generatePreambleScriptCode' ) ;
7691 const api = new ProgramBehaviorAPI ( self ) ;
77- const applicationNode = await api . applicationService . getApplicationNode ( 'universal-robots-external-control-external-control-application' ) as ExternalControlApplicationNode ;
78- const port = applicationNode . port ;
79- const robotIP = applicationNode . robotIP ;
92+
8093 const builder = new ScriptBuilder ( ) ;
81- try {
82- const json = await fetchBackendJson ( port , robotIP , api ) ;
83- builder . addRaw ( json . preamble || '' ) ;
84- } catch ( e ) {
94+
95+ if ( await isThisNodeTheFirstUrcapNodeInTree ( node , api ) ) {
96+ // Fetch the preamble from the backend
97+ const applicationNode = await api . applicationService . getApplicationNode ( 'universal-robots-external-control-external-control-application' ) as ExternalControlApplicationNode ;
98+ const port = applicationNode . port ;
99+ const robotIP = applicationNode . robotIP ;
100+ try {
101+ const json = await fetchBackendJson ( port , robotIP , api ) ;
102+ builder . addRaw ( json . preamble || '' ) ;
103+ } catch ( e ) {
104+ builder . addRaw ( '' ) ;
105+ }
106+ } else {
85107 builder . addRaw ( '' ) ;
86108 }
109+
87110 return builder ;
88111} ;
89112
@@ -105,7 +128,21 @@ const allowChildInsert = (node: ProgramNode, childType: string): OptionalPromise
105128
106129const allowedInsert = ( insertionContext : InsertionContext ) : OptionalPromise < boolean > => true ;
107130
108- const nodeUpgrade = ( loadedNode : ProgramNode ) : ProgramNode => loadedNode ;
131+ const nodeUpgrade = ( loadedNode : ProgramNode ) : ProgramNode => {
132+ const upgradedNode = { ...loadedNode } ;
133+
134+ // Ensure parameters object exists
135+ if ( ! upgradedNode . parameters ) {
136+ upgradedNode . parameters = { } ;
137+ }
138+
139+ // Add nodeHash if missing
140+ if ( ! upgradedNode . parameters . nodeHash ) {
141+ upgradedNode . parameters . nodeHash = uuidv4 ( ) ;
142+ }
143+
144+ return upgradedNode ;
145+ } ;
109146
110147const behaviors : ProgramBehaviors = {
111148 programNodeLabel : createProgramNodeLabel ,
0 commit comments