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

Community Tip - You can Bookmark boards, posts or articles that you'd like to access again easily! X

How to create Things and Things template by code

fmanniti
9-Granite

How to create Things and Things template by code

There's something I don't understand:
I would like to create my thing by code on eclipse instead of by composer.

I can't find a tutorial which explain how to do this. Would you have a link?

26 REPLIES 26

Hi Fabio,

I've never did it from Java extension, but you should be able to call Resources["EntityServices"].CreateThing service from Java side.

Carles.

Yes, but what you are talking about is inside thing services, isn't it?

I mean, I have this "issue": I have a thing template with 1000 things child I can't just create them one by one so I was thinking about a java extension.

What I've done so far is:

Create the Thing template: MyThingTemplate

Create a Thing builder: MyThingBuilder.

Inside MyThingBuilder there is a subscription at thing start


for(i=1; i<1001; i++){

     var paramsTH = {

       name: "myThing_"+i,

       thingTemplateName: 'MyThingTemplate',

       tags: tags

     };

     Resources["EntityServices"].CreateThing(paramsTH);

}

I know that this works. My only issue is that this is not the smartest way to do this.

I don't see why you need an extension to do this, you can perfectly do with a helper thing ( MyThingBuilder ) it's totally correct.

What I don't know it's why you should bind this service to the Thing Start event, this service should be called only once, then you can perfectly call it by hand. If you want to be more Pro, you can build a Helper Thing which initializes all you system, which triggers any Initialization process the First time only.

Ok, the reason is quite stupid: I understood how to use subscriptions to event (like Thing Start event) but I don't know how to call a service once.

Let's say I write a service and I call it "CreateMyThings". It has no input and no output.

The script is the same of my subscription (which I posted above).

Now is my issue: how do I call my service in MyThingBuilder to create my things?

I know it's a quite stupid question but I'm trying to figure it out my leaks little by little.

Wait... sorry I've just did it.

Ok, never mind (feel so embarrassed )

With the Composer, you have a Test button next to the service name

tags value couldn't accepted as String value like "FlowserveDemo". I think there is typecasting required. I am getting following error while executing: Wrapped java.lang.Exception: Unable To Convert From java.lang.String to TAGS Cause: Unable To Convert From java.lang.String to TAGS.

Could you please help me out?

In the first places I think that the tag you are trying to type doesn't exist.

You should first create your model tag then you can add it.

You may also go to see the log files, it will explain a little better your problem

Model tag "FlowserveDemo" is already created. I am getting error Wrapped java.lang.Exception: Unable To Convert From java.lang.String to TAGS Cause: Unable To Convert From java.lang.String to TAGS. while executing service that contain following script code:

for(i=4; i<7; i++){ 

 

     var paramsTH = { 

       name: "Asset"+i, 

       thingTemplateName: 'PumpTemplate',

         tags: 'FlowserveDemo'

     }; 

     Resources["EntityServices"].CreateThing(paramsTH); 

Please give me solution.

You must indent the tag with the ModelTag name, something like "MyModelTagDictionaryName:MyTag"

You wrote it wrong.

It's supposed to be something like this

var tags = [

            {vocabulary:"<yourVocabulary>",vocabularyTerm:'FlowserveDemo'},

              {... if you have more tags ...}

        ];

var params = {

            name: "Asset"+i,

            thingTemplateName: 'PumpTemplate',

            tags: tags

        };

Thanks a lot.

I wrote following script and issue is resolved.

for(i=4; i<7; i++){ 

 

     var paramsTH = { 

       name: "Asset"+i, 

       thingTemplateName: 'PumpTemplate',

         tags: 'Applications:FlowserveDemo'

     }; 

     Resources["EntityServices"].CreateThing(paramsTH); 

} .

Now I have another query:

Through code how can I map properties of dynamically creating things (Asset1, Asset2,Asset3......) to properties of a remote things (RemoteAsset1, RemoteAsset2, RemoteAsset3,........)?

(Actually all properties is defined in a ThingShape: 'PumpShape' and 'PumpShape' is bind to 'PumpTemplate as a implemented shape' and our all creating things implement ThingTemplate: 'PumpTemplate' as shown in above example)

If PumpTemplate it's based on a RemoteThing template and on the remote edge side the remote properties exists then you just need to use own service SetRemotePropertyBinding

I have taken Generic as base thing Template of PumpTemplate.

Suppose there are some properties in PumpShape like Pressure1, Pressure2, Temperature1, Temperature2, Vibration1, Vibration2, Vibration3. and PumpShape is implemented shape in PumpTemplate.

So could you please give me some code of snippet to mapping these properties to remote thing's properties while creating thing dynamically by code using SetRemotePropertyBinding.

Remote Property Binding only works for a RemoteThing Entity, if PumpTemplate isn't a RemoteThing then you can't.

You will need another thing which it's RemoteThing and has the REmoteBIndings, and then Localy Bind from that RemoteThing to PumpTemplate based Thing.

Suppose base thing Template of PumpTemplate is RemoteThing.

Now what code of snippet I have to add for mapping properties of PumpTemplate to remote simulator edge's properties after following code:

for(i=4; i<7; i++){ 

 

     var paramsTH = { 

       name: "Asset"+i, 

       thingTemplateName: 'PumpTemplate',

         tags: 'Applications:FlowserveDemo'

     }; 

     Resources["EntityServices"].CreateThing(paramsTH); 

}

some properties in PumpShape like Pressure1, Pressure2, Temperature1, Temperature2, Vibration1, Vibration2, Vibration3.

var props = {

            propertyName: '<Property You Want to link>',

            sourceThingName: <Name of the source thing>,

            sourcePropertyName: '<Name of the property of the source thing you want to link>'

        };

Things[<your remote thing name>].SetLocalPropertyBinding(props);

your given example is not described enough what I asked. So please check my query again and let me know solution accordingly and give me code also for the same

This is what I got:
you have two types of things:

Asset and RemoteAsset

They both have a property called Temperature.

You want that the value for property Temperature for RemoteAsset, is written also in Temperature for Asset, did I get it right?

Yes, mostly you got i.

Mapping of Properties should be happen at the creation of things.

For Example:

for(i=1; i<4; i++){

     var paramsTH = {

       name: "Asset"+i,

       thingTemplateName: 'PumpTemplate',

         tags: 'Applications:FlowserveDemo'

     };

     Resources["EntityServices"].CreateThing(paramsTH);

} .

Here Asset1, Asset2 and Asset3 things are creating by code so i want mapping of properties after creation of Asset thing by code. Actually I don't want to map properties manually means Go to properties link - > Manage Binding -> then map. I want everything by code dynamically.

So please let me know what line of code I have to insert after code snippet above.

Then the code is the one I wrote to you

for(i=1; i<4; i++){

     var thingName = "Asset_"+i;

     var remThingName = "RemoteAsset_"+i;

   

     var paramsRemoteThing = {

            name: remThingName ,

            thingTemplateName: 'RemoteThingTemplate',

            tags: 'Applications:FlowserveDemo'

        };

     Resources["EntityServices"].CreateThing(paramsRemoteThing);

     var paramsThing = {

            name: thingName ,

            thingTemplateName: 'Template',

            tags: 'Applications:FlowserveDemo'

        };

     Resources["EntityServices"].CreateThing(paramsThing);

     Things[remThingName].EnableThing();

     Things[remThingName].RestartThing();

     Things[thingName].EnableThing();

     Things[thingName].RestartThing();

     var params = {

          propertyName: 'RemoteThing_Temperature',

          sourceThingName: thingName,

          sourcePropertyName: 'Thing_Temperature'

     };

     Things[remThingName].SetLocalPropertyBinding(params);

}

Thanks a lot. your given example is helpful.

Now I want to map multiple properties to my remote thing. I use paramsRem variable as Array.  I am getting error Wrapped java.lang.Exception: Remote_Asset_1 does not have a property named [null] while executing below snippet of code.

Please let me know following lines of code will work or not:

var paramsRem = [

        {propertyName: 'Temperature1', sourcePropertyName: 'Temperature1'},

        {propertyName: 'Temperature2', sourcePropertyName: 'Temperature2'},

        {propertyName: 'Temperature3', sourcePropertyName: 'Temperature3'},

            {propertyName: 'Vibration1', sourcePropertyName: 'Vibration1'},

            {propertyName: 'Vibration2', sourcePropertyName: 'Vibration2'},

            {propertyName: 'Vibration3', sourcePropertyName: 'Vibration3'},

            {propertyName: 'Pressure1', sourcePropertyName: 'Pressure1'},

            {propertyName: 'Pressure2', sourcePropertyName: 'Pressure2'},

            {propertyName: 'Flow', sourcePropertyName: 'Flow'}

        ]

Things[remThingName].SetRemotePropertyBinding(paramsRem);

only one at a time.

Yes, it's as Carles said. You have to do it only one property per time

var params = {

          propertyName: 'RemoteThing_<firstProperty>',

          sourceThingName: thingName,

          sourcePropertyName: 'Thing_<firstProperty>'

    };

Things[remThingName].SetLocalPropertyBinding(params);

var params = {

          propertyName: 'RemoteThing_<secondProperty>',

          sourceThingName: thingName,

          sourcePropertyName: 'Thing_<secondProperty>'

    };

Things[remThingName].SetLocalPropertyBinding(params);

...

It could be faster if you loop an array

var properties = ['<firstProperty>', '<secondProperty>', '...'];

for(var prop in properties){

    var params = {

              propertyName: prop,

              sourceThingName: thingName,

              sourcePropertyName: prop

        };

    Things[remThingName].SetLocalPropertyBinding(params);

}

obviously RemoteThing properties and Thing properties must have the same name, unless you don't make and array object

var properties = [

     {thing: '<firstProperty>',  remThing: '<remFirstProperty>'},

     {thing: '<secondProperty>',  remThing: '<remSecondProperty>'}

]

Thank you so much.

Now I have another query.

Actually value of each Asset's properties is updated in some interval. So I would like to know about

How can we display date and time in the grid at which Asset's properties value is updated recently?

For that you need a stream.

1) you create a stream (and a datashape) with the fields you need

2) you make a subscription to each thing (or to the template) for which any data changing you add a stream entry

3) In your grid you will bind the stream service "GetStreamEntriesWithData()".

Top Tags