cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Need help navigating or using the PTC Community? Contact the community team. X

Trigger Thingworx Flow BEFORE model load

GianVal
15-Moonstone

Trigger Thingworx Flow BEFORE model load

Hi, I set up a workflow to gather some data from Windchill PLM. Among these data, it will be the model pvz source for Vuforia Studio experience.

So, I want to trigger a thingworx flow that could update some source data (including the pvz file in the repository connected to the experience) before the model loading. In this way, the shown model can be the last possible version available on the thingworx repository, and consequently on windchill.

Is this possible? How to? 
many thanks.

 

1 ACCEPTED SOLUTION

Accepted Solutions

Finally worked!!!!

i set the converted file in this way

 

 

    let converted_file = 'data:image/pvz;base64,' + args.data[0].Content

 

 

and deleting "&colon" and adding the symbol " : "

Now I'm curious to know why it worked in this way 😄

 

View solution in original post

14 REPLIES 14
Suraj_Patil
15-Moonstone
(To:GianVal)

will u please elaborate more ?....what exactly you want to achieve?

GianVal
15-Moonstone
(To:Suraj_Patil)

From windchill, I want to pull some data to the thingworx repository. I know that this is feasible with thingworx flow. Among these data, there is the pvz graphic source for the vuforia experience. I want to trigger the thingworx flow from inside the vuforia experience so that I can update the source files in the thingworx repository (from which the experience takes data) before the model loads. in this way, the loaded model will be built with the last updated version of the pvz file available in the twx repo.

I hope I clarified the use case requirements. many thanks

Suraj_Patil
15-Moonstone
(To:GianVal)

i really dont know, how the pvz file in vuforia studio automaticatically update from thingworx repository. because as far as i know pvz file is view file once its created. how it will change automatically unless n untill you manually save n upload on thingwox and same for vuforia studio as well. i feels its not possible with above reasons, but latest updates on these softwares i m not aware about.

 

thanks.

Hi @GianVal , 

so far I understand your scenario here :

- you start a project - so it will loasd the start view - let say Home.js /view name here is not relevant

- now you want to update the model which is displayid in a model widget  possibly by new model which was updated in the repository. So means the pvz model file in the repository was in the meantime updated . Therefore this model should be downloaded on runtime and displayed in the modelwidget instead of the old model version.

Is that scenario what you want to implment?

Here I wnat to show one possible option:

-you can use a static model -pvz - just for the case that on you mobile device the connection to TWX is not working.

- add the LoadBinary service to the Studio External Data sectionsfrom the repository thing where the CAD models are saved

2022-01-26_10-16-43.jpg

- In the start.js /e.g. Home.js define the trigger for the LoadBinary servce complete event- some code like this:

 

 

//====================================================================
//this is called when  loaded $scope.SaveBinJsonToTwxRepository --> $scope.GetBinJsonFromTwxRepository
  $scope.$root.$on('LoadBinary-complete', function(event, args) { 
  console.log("LoadBinary-complete event"); //some logs
   console.log("name="+event.name) //some logs
   console.warn(args.data[0].Content);//some logs
 //convert the format from laoded data to resource property /src
  let converted_file= 'data:image/pvz;base64,'+args.data[0].Content
  console.warn(converted_file) //some log printed
//add now the loaded pvz data from repository to src modelWidget
    $scope.setWidgetProp('model-2','src',converted_file); $scope.$applyAsync();

});
//////
//call the server 
$scope.app.apprunMyTWXService= function(pars)
{
var TWXmodelID = 'CADtestRepository'
var serviceName='LoadBinary'
var parameters = pars
twx.app.fn.triggerDataService(TWXmodelID,serviceName, parameters);
}
//////////////////////////////////////////////////////////////
$scope.GetBinJsonFromTwxRepository = function(path) {
 $scope.$applyAsync(function() {
  console.log("calling GetBinJsonFromTwxRepository") 
   $scope.app.apprunMyTWXService( {"path": path} );}   ,500 );
//sample below how the rest API link should looks like
   //'https://pp-5555555559fd.portal.ptc.io/Thingworx/FileRepositories/CADtestRepository/test/blue_pump.pvz'

};

 

 

- call the Thingworx service on model load or when the loading of all widget are completely  e..g on after view enter event:

 

 

$scope.$on('$ionicView.afterEnter', function() {   
    GetBinJsonFromTwxRepository('/test/robot_test.pvz');  
   });
//will load the current versionof robot_test.pvz from repository

 

 

- I tested  this configuration and I  was able to verify that this will work in preview mode and on mobile (tested with ios i-pad 6 generation) - ok the requirment is that your TWX permissions are propperly set according to   http://support.ptc.com/help/vuforia/studio/en/#page/Studio_Help_Center%2FGrantUserPermissions.html and http://support.ptc.com/help/vuforia/studio/en/#page/Studio_Help_Center%2FAnonymousAccess.html%23  on the TWX server  and also added the CADtestRepository for the service LoadBinary  -visibility and service runtime execute permissions for the es-public-access-org

So here sample of the test - here is TWX service called by clicking on button on runtime in preview mode

2022-01-26_10-33-46.jpg

-In case that you want also call a service what will start the update proccess form Flow to repository - this could be done also be TWX service using the same mechnism as described here, but here possibly for the correct service you can post a  quesiton in the TWX development community - some thing like:

How to update a repository pvz model via TWX service from Windchill Thingworx Flow ... etc.

because this is some problem which more related to TWX dev group. Thanks.

I'm trying this solution, but something doesn't work. I set up the load binary service from VF studio.

GianVal_0-1643273651620.png

 

my repository is called ARepo and i changed the related parameters in your code. Can you find some mistakes?

 

 

$scope.$root.$on('LoadBinary-complete', function(event, args) {
    console.log("LoadBinary-complete event"); 
    console.log("name=" + event.name) 
    console.warn(args.data[0].Content); 
    let converted_file = 'data:image/pvz;base64,' + args.data[0].Content
    console.warn(converted_file) 
    $scope.setWidgetProp('model-1', 'src', converted_file);
    $scope.$applyAsync();

});
//////

$scope.app.apprunMyTWXService = function(pars) {
        var TWXmodelID = 'ARepo'
        var serviceName = 'LoadBinary'
        var parameters = pars
        twx.app.fn.triggerDataService(TWXmodelID, serviceName, parameters);
    }
    //////////////////////////////////////////////////////////////
$scope.GetBinJsonFromTwxRepository = function(path) {
    $scope.$applyAsync(function() {
        console.log("calling GetBinJsonFromTwxRepository")
        $scope.app.apprunMyTWXService({ "path": path });
    }, 500);

};

$scope.$on('$ionicView.afterEnter', function() {
    $scope.GetBinJsonFromTwxRepository('resource.pvz');
});

 

 

the complete path of the resource is

"/Thingworx/FileRepositories/ARepo/resource.pvz"

 

The log says

"twx-entity sent but no data for twx-entity has been set yet"

 

many thanks

Hi @GianVal ,

for example if you look in  the report e.g. in Thingworx you will see (as mentioned in your comment) here example for my environment :

/Thingworx/FileRepositories/CADtestRepository/test/blue_pump.pvz'
/Thingworx/FileRepositories/CADtestRepository/test/Illustrate-Annot_Brake-Explode.pvz

but if you click for example the link in the TWX UI  it  will also contain the TWX server - and should be :

 https://pp-XXXXXXXXXXX.portal.ptc.io/Thingworx/FileRepositories/CADtestRepository/test/blue_pump.pvz'
https://pp-XXXXXXXXXX.portal.ptc.io/Thingworx/FileRepositories/CADtestRepository/test/Illustrate-Annot_Brake-Explode.pvz

where https://pp-XXXXXXXXXXX.portal.ptc.io is here my  TWX server (ok some letter replaced by XXXX)

So means that you link requires also the Server URL s.e. https://yourServerURL//Thingworx/FileRepositories/ARepo/resource.pvz

You can see this url when you go to the service in your repository thing (GetFileListingWithLinks) and execute this service  for  particular folder. Then click on link and see the value in the browser

2022-01-27_11-14-55.jpg

 

ok thanks, so..where i have to put the entire link? Here?

 

$scope.$on('$ionicView.afterEnter', function() {
    $scope.GetBinJsonFromTwxRepository('https://THE LINK HERE?.pvz');
});

 

I tried but no result.

 

my code  what I verified that it worked is something like:

 

//////////////////////////////////////////////////////////////
$scope.GetBinJsonFromTwxRepository = function(path) {
 $scope.$applyAsync(function() {  
   $scope.app.apprunMyTWXService( {"path": path} );}   ,500 );
};

 

and I called it in button

 

GetBinJsonFromTwxRepository('/test/robot_test.pvz');

 

so means my previous statement was wrong! I am sorry. This full  link with server is the link what the GetFileListingWithLinks  will return. This syntax is required when we try to set the source directly e.g. binding between service all time and src of the modelWidget - but here is not used!  In the JavaCode example   the path argument in the LoadBinary service is called on the correct Thing and therefore It do not need the full URL but  only should use the relative folder location to the Thing . So in your case I will suggest

 

'/ARepo/resource.pvz'

/ARepo - the folder in the your repository Thing

I found a way to make it work. was an "async" js problem. anyway I can view the binary text the same as yours but I'm getting this error

 

"Error setting model URL on [model-1] due to [{}]"

Hi @GianVal ,

I do not know this error- so believe possibly some syntax in the generated string. Does this issue occur on mobile device or also in preview mode?  

I checked the project and used following code - simplified version:

  1.  to start the service
    //////////////////////////////////////////////////////////////
    $scope.LoadBinaryFileFromTwxRepository = function(path) {
      console.log("calling LoadFileFromTwxRepository")
      var TWXmodelID   = 'CADtestRepository';  //this the FileRepository Thing
      var serviceName  = 'LoadBinary'; // this is the service name
      var parameters   =  {"path":path} ;  // this is the parameters Json 
    //TWX parameter name  + parameter value
      twx.app.fn.triggerDataService(TWXmodelID,serviceName, parameters);
      $scope.$applyAsync();               
    };
    ​

      alternative is here another version using the broatcast method and Thing name - here "CADtestRepository" is the name of the repository thing which contains the pvz files. Here in the example I have a folder /test  where I uploaded the pvz file. - Used the TWX upload widget 

    //////////////////////////////////////////////////////////////
    $scope.LoadFileFromTwxRepositoryBC = function(path) {
     $scope.$applyAsync(function() {
     $rootScope.$broadcast('app.mdl.CADtestRepository.svc.LoadBinary',
                              {"path":path}
                             );}   ,500 );    
    };

     it is important that the Thing e.g.  (CADtestRepoistory) is added on the right side in External data section. Also the service LoadBinary should be  added to External Data section:

  2. To call the service mentioned in the sample code above we need to call e.g.
    $scope.LoadFileFromTwxRepository('/test/robot_test.pvz');
    //or
    $scope.LoadFileFromTwxRepositoryBC('/test/robot_test.pvz');​
  3.  The menthod is called asyncronously so we  need to devine a listener which will be called when the service finished. So , in the listener call back function we need to  set the received data to the modelWidget property. The listener should be defined before we call the service. Also as mentioned in 2.) Thing and service should be added in the external data section and the TWX permissions should allow access:
    //======================================================
    $scope.$root.$on('LoadBinary-complete', function(event, args) { 
    console.log("LoadBinary-complete event");
    console.log("name="+event.name)
    let modelWidgetName='model-1'
    let converted_file= 'data:image/pvz;base64,'+args.data[0].Content
    console.warn(converted_file) // here if you want to check the content to print
    $scope.setWidgetProp(modelWidgetName,'src',converted_file); $scope.$applyAsync();
    });
    //////////////////////////////////////////////////////////////​

I perfectly understood the functions' purpose and tried with the second "broadcast" method, but the same result.

I do not know.

 

Thank you

 

 

 

@GianVal , yes seems that  there is an issue which I need to check more detailed , respectively to discuss with dev team. I found that on some location it will not work. On my preview installation it works but fine but on others will not - different  ES and windows machine. So need to verify what is the difference. Possible there is some encode and blob convert. required .. need to check it more detailed next week . I  will provide a  feedback when I find the root cause.

Finally worked!!!!

i set the converted file in this way

 

 

    let converted_file = 'data:image/pvz;base64,' + args.data[0].Content

 

 

and deleting "&colon" and adding the symbol " : "

Now I'm curious to know why it worked in this way 😄

 

Yes the syntax was a little incorrect! I checked older code and found that I used this syntax for json but it seems not to  be much sensitive and was working with this error- no issue. So, it seems that PVZ format have an issue.

I found that when I generate the svg format dynamically, it required the correct syntax and otherwise it will not work. So found following code:

 

 

 

 

 

 

scope.svg_ret1 = function(imgWidget, height,color1,color2,color3,width1,width2,width3) {
  var txtL=""
   
   var width=(width1+width2+width3)
      var xmlsrc='<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'
      xmlsrc=xmlsrc+'<svg xmlns="http://www.w3.org/2000/svg" height="'+height+'" width="'+ width+'">\n'
      xmlsrc=xmlsrc+'<rect x="0" y="0" width="'+width1+'" height="'+height+'" style="fill:'+color1+'"/>\n'
       var x= width1
      xmlsrc=xmlsrc+'<rect x="'+x+'" y="0" width="'+width2+'" height="'+height+'" style="fill:'+color2+'"/>\n'
          x= width1+width2
      xmlsrc=xmlsrc+'<rect x="'+x+'" y="0" width="'+width3+'" height="' +height+'" style="fill:'+color3+'"/>\n'
    
      xmlsrc=xmlsrc+'</svg>'

 console.log('here  $scope.view.wdg['+imgWidget+'].src=')
     console.warn('data&colon;image/svg+xml;base64,'+xmlsrc)
      
  $scope.view.wdg[imgWidget].imgsrc='data:' +'image/svg+xml;base64,'+btoa(xmlsrc);
}

 

 

 

 

 

 

the code above will generate a SVG graphic file dynamically and then it will convert it to base64 format. Here we can see the exact syntax - 

 

 

 

 

 

let convert= "data:" +"image/ "+<type>+";base64," +btoa(xmlText);

 

 

the SVG file is first created to xml (ansi text) and then via btoa will converted to base64 format.

In case that file is obtained via request - here the service call - and the listener callback for the service complete event - the data is received already in base64 format. The text prefix is only required so that the property will "know" that the value is set to base64 / other option is to use the download link (asci text)

I belive the error with the syntax is comming from sum publi

shing to html where it was automaticaly converted by editor... here I am wrorte in this editor data:     but it make automaticaly data@colon&; --- not idea how to post the correct ....  so that issue was caused by some automatic syntax

Top Tags