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

Community Tip - Did you get called away in the middle of writing a post? Don't worry you can find your unfinished post later in the Drafts section of your profile page. X

AddDynamicSubscription help

jmay1
5-Regular Member

AddDynamicSubscription help

Can someone please explain this service to me? I am trying to be able to create subscriptions from a mashup and this seems to be the closest thing I have to work with but I want the ability to add them at a template level, which I would think is what this service meant by "dynamic" but it has a thingName parameter so what exactly does this do? And what is the serviceName parameter for? Is that a service that will execute when the subscription is triggered?
Thanks for the help!

7 REPLIES 7
costinb
8-Gravel
(To:jmay1)

Hi Jenna,

The service you mentioned above will help you add a subscription dynamically for a Thing. I believe it is called "dynamic" because you do not add it in the Composer, you just use some code to add it at Runtime. With this service you cannot add subscriptions at thingTemplate level.

In regards to the parameter, thingName refers to the thing to which you are subscribing to (if you are subscribing to your own event, you don't need to modify it, just leave it undefined), eventName is the event you are subscribing to and it is mandatory, propertyName (in case the event is a DataChange, Alert on a specific property, you need to mention it) and the serviceName is the actual service (code) that would be executed once the event is fired. This is also mandatory.

One important thing to mention is that with this service you have the possibility to add on the fly 'in-memory' subscriptions, which means that after a server restart, the subscriptions will be deleted.

I hope this info was useful. Let me know if you have further questions.

Costin

jmay1
5-Regular Member
(To:costinb)

Is there anyway to add subscriptions at template level during run time?

costinb
8-Gravel
(To:jmay1)

Hi Jenna,

The indicated way to add a subscription is at ThingTemplate level, but why is it necessary to add them dynamically at runtime? Normally, these subscriptions are defined in the Composer and as new Things based on that template are created, they will inherit the subscription.

There is no straight solution for this, but I can show how you can add a subscription to a template dynamically, at runtime, by leveraging the ThingWorx REST API. Basically, it is the same request that it would be made if you had defined the subscription in the Composer, only you can use a snippet to "put" the JSON to the server, instead of the browser doing that for you.

Assume you have a thing template called SimpleThingTemplate and you want to subscribe to a Timer5s Timer event in order to execute some code (in my simple example, I just log something in the Script log). The service used in this case is PutJSON in order to make an HTTP(s) PUT request to the server. Nor all parameters are necessary, but the body of the request is very large. I have highlighted the important parts.

In order for the request to be successfully completed, you need a form of authentication. For testing purposes, I used a username and a password but normally you should use an application key. The result of the service execution is irrelevant so you can eliminate the var result at the last line.

Other than that, you need just to pass the URL and the JSON request content like below.

You can test this and let me know whether you have additional questions.

Costin

var requestContent = {

    "entityType":"ThingTemplates",

    "effectiveThingPackage":"ConfiguredThing",

    "thingShape":

    {"propertyDefinitions":{

    },

    "subscriptions":

     {"Timer5s:Timer":

      {"enabled":true,"source":"Timer5s","eventName":"Timer","serviceImplementation":

       {"allowOverride":false,"description":"","name":"Timer5s:Timer","configurationTables":

        {"Script":{"description":"","isMultiRow":false,"name":"Script",

                   "dataShape":{"description":"","name":"","fieldDefinitions":{"code":

                                                                               {"baseType":"STRING","description":"code","name":"code","aspects":{

                                                                               },"ordinal":0}

                                                                              }}

                   ,

                   "rows":[{"code":"logger.warn(\"subscription added\");\n"}

                          ]}

        },"handlerName":"Script"}

      }}

     ,

     "eventDefinitions":{

     },

     "serviceImplementations":{

     },

     "serviceMappings":{

     },

     "serviceDefinitions":{

     }}  ,

    "thingTemplate":"GenericThing",

    "name":"SimpleTestTemplate",

    "id":"SimpleTestTemplate"

};// JSON

var params = {

    proxyScheme: undefined /* STRING */,

    headers: undefined /* JSON */,

    ignoreSSLErrors: undefined /* BOOLEAN */,

    useNTLM: undefined /* BOOLEAN */,

    workstation: undefined /* STRING */,

    useProxy: undefined /* BOOLEAN */,

    withCookies: undefined /* BOOLEAN */,

    proxyHost: undefined /* STRING */,

   url: "http://localhost/Thingworx/ThingTemplates/SimpleTestTemplate?reason=subscriptions%20%3A%20New%20subscription%20%3A%20Source%20updated%2C%20Code%20Updated%2C%20Timer5s%3ATimer%20%3A%20New%20subscription%2C%20Subscription%20Added%0A" /* STRING */,

    content: requestContent /* JSON */,

    timeout: undefined /* NUMBER */,

    proxyPort: undefined /* INTEGER */,

    password: "admin" /* STRING */,

    domain: undefined /* STRING */,

    username: "Administrator" /* STRING */

};

// result: JSON

var result = Resources["ContentLoaderFunctions"].PutJSON(params);

jmay1
5-Regular Member
(To:costinb)

Thank you. I will most certainly have some questions about this once I try it out.

To answer your question, the reason why I need to create a subscription dynamically, is that one of my requirements is to have a mashup that allows the end user to create alerts and alarms (emails) for those alerts. The user needs to define who is contacted when a selected property reaches a user-defined threshold.

Hi!

I tried your solution and it works perfectly. The problem is that the properties and services of the thing template, for which the subscription is created, are deleted on the process.

Does anyone have any idea to avoid this situation, and keep all thing template data after the subscription is created using this process?

Thank you!

Good day @jmay1@joao_espadanal and @costinb,

 

I am looking for similar functionality to add subscriptions on properties dynamically as described by @jmay1 (Did you manage to find a way to do this?)

 

But I am having two issue.  The one issue is the replacement of all of the subscriptions and adding just the one that was last defined (as described by @joao_espadanal - Did you manage to find a solution to this?).

 

And secondly: how do you define the property on which the "Alert" subscription should be? I have tried a couple of changes on the code provided by @costinb, but have yet to succeed?

 

Thank you,

Johan Bester

 

 

 

 

amittal-3
13-Aquamarine
(To:jbester)

Hello All,

I would also need some help on this topic about AddDynamicSubscription. So, AddDynamicSubscription service when called looks something like this - 

 

var params = {
	propertyName: undefined /* STRING */,
	thingName: undefined /* THINGNAME */,
	eventName: undefined /* STRING */,
	serviceName: undefined /* STRING */
};
me.AddDynamicSubscription(params);

My requirement is to pass a custom service, say "testService", which has couple of input parameters. To visualise better, when I call my service, it looks something like -

var params = {
	propertyName: undefined /* STRING */,
        propertyValue: undefined /* NUMBER */
};
me.testService(params);

So how do I specify my "testService" (along with the required parameters for the "testService") in the serviceName field of AddDynamicSubscription? As I can see there is no such provision to pass parameters to the service.

Any help on this issue would be appreciated.

Thanks in advance

Aditya Mittal

 

Top Tags