Community Tip - Learn all about the Community Ranking System, a fun gamification element of the PTC Community. X
Hello, I used the tutorial from this site to install the MQTT Extension from the Marketplace to my installation. Everything works fine.
For my purpose I need to transmit additional Information in the MQTT messages such as timestamp, senderID etc. I use JSON Format for the messages. Doing so I cant simply use the MQTT Extension to subscribe to a topic and directly save the messages to the ValueStream or whatever else. I would need a service that is called everytime a new message is received from the subscribed topics and that manages decoding the JSON etc.
Is there a service that is called everytime a message is received? Or how can I create one?
Thanks a lot
Solved! Go to Solution.
The "Not Authorized for Service Invoke" error indicates that the user performing the action does not have the necessary permission to run the service in question. Easiest way to resolve the problem is to add a run time permission for the user / group that will be running these actions granting Service Execute on the entity in question. You can do this either as a specific service, or as a overall grant to Service Execute.
On the WeatherStationMQTT thing:
- Select Permissions > Run Time
- To grant full Service Execute Permissions, type a group or user name in the topmost box (All properties, events, services), then select the green circle under Service Execute
- To only grant Service Execute permissions on the service in question, type in the name of the service in the bottom box (Property, Service, Event Overrides), then type in a user or group in the new box that appears for the selected service.
Occasionally you may have to grant permissions to the SuperUser or System user to work around this, though that is usually only in cases where a user context cannot be determined.
If you have bound your topic to a property, you can use a Subscription to the DataChange event for that property to run services. (Note, there may be a bug with DataChange events on Infotables; the infotable only triggers the event if a row is added or deleted, so a string would be better)
With the subscription in place, you could then process your request, parse the JSON, etc. each time the topic changes.
Hey Jeremy, thanks for the answer. I tried using a Subscription on the datachange event. I created a property "TemperatureMQTT" which subscribes to the MQTT Topic. I then created a Subscription for the datachange event of this property which should write the processed value via me.UpdatePropertyValues into another property "Temperature" that contains only the number values.
I get the error:
Error processing local event: Execution error in service script [WeatherStationMQTT TemperatureSubscriber.DataChange] : Wrapped com.thingworx.common.exceptions.InvalidRequestException: Not authorized for ServiceInvoke on UpdatePropertyValues in WeatherStationMQTT Cause: Not authorized for ServiceInvoke on UpdatePropertyValues in WeatherStationMQTT
and nothing is written to the other property. Is it somehow not allowed to write to an other property than that the subscription is from? How can this be done?
Hi Nicolas Jourdan,
Create a Separate (Non MQTT) Thing for the number property and try to update the same.
Thanks,
Ankit Gupta
The "Not Authorized for Service Invoke" error indicates that the user performing the action does not have the necessary permission to run the service in question. Easiest way to resolve the problem is to add a run time permission for the user / group that will be running these actions granting Service Execute on the entity in question. You can do this either as a specific service, or as a overall grant to Service Execute.
On the WeatherStationMQTT thing:
- Select Permissions > Run Time
- To grant full Service Execute Permissions, type a group or user name in the topmost box (All properties, events, services), then select the green circle under Service Execute
- To only grant Service Execute permissions on the service in question, type in the name of the service in the bottom box (Property, Service, Event Overrides), then type in a user or group in the new box that appears for the selected service.
Occasionally you may have to grant permissions to the SuperUser or System user to work around this, though that is usually only in cases where a user context cannot be determined.
Thank you this works perfectly
Hi Jeremy,
I am trying to accomplish the same task, have gone through the various tutorial to setup my MQTT connection and I have already set my permissions for the thing template and thing. However I still cannot complete the data change subscription event between the property subscribing to the topic and my other created property.
Could this be a configuration issue within Thingworx or could it be the message sent by my gateway? I am able to see the JSON object from the MQTT property.
Any feedback would be appreciated.
Christian Acosta
Hello Christian:
When you say that you aren't able to complete the data change subscription event, is the event itself not firing, or are you getting an error reported as a result of some action that the subscription is taking? Is the Data Change event keyed off of an MQTT mapped property?
If you have any error messages reported in ApplicationLog, ScriptLog or ErrorLog that might be relevant, it would be useful for troubleshooting this type of problem.
Thank you for the response Jeremy.
The warning I found I am receiving is:
11:00:56 WARN - runtime not configured for conversion of "[object Object]" from "JSON" to "STRING"
Can you perhaps provide some insight on this warning?
Thank you very much!
If you are attempting to print out a JSON object, or to convert it from JSON to string, you often need to wrap it in JSON.stringify(jsonObject). The message you are getting seems to imply that you're attempting a JSON to String conversion.
It's possible that this message is coming from code you might be using to debug this problem and may not actually be related to the problem at hand, but at the very least, this should be a starting point for this specific message.
Hi Jeremy,
I managed to eliminate the warning from above and am not receiving any other errors or warnings in the log so at this point I think my data change is just not firing.
How could I verify this?
Any insight would be much appreciated, thank you!
Best thing to do is to temporarily set up a logging line in your subscription for the data change event that you're watching.
logger.warn("Entered DataChange for Thing <>");
This will log a line to the ScriptLog each time the data change event is called on the thing in question. It can be verbose and shouldn't be left in place beyond debugging, but if you're not seeing the line, it could also indicate that the event you're expecting is not actually firing.
Inserted the "logger" line in the same subscription as shown above, and verified that the temp property is changing, and I am not seeing the line in the script log. And again, run time instance permissions have been changed.
Could this have anything to do with the message coming in from my MQTT device or would this still be a configuration issue in ThingWorx?
That change is on a Thing Template, and based on the name it's not clear what template you're using (Connection, Subscriber or MQTT, though I'd guess the latter). For this to work, you need to have your subscription subscribing to the Data Change event on a MQTT_Subscriber derived Thing (not Thing Template!) that is configured for the appropriate connection.
Yes, I am using the MQTT template. And I have changed my data change subscription to occur on the Thing with the MQTT_Master Template rather than the actual template and the event is still not firing.
Images below show my edited configurations. I even used the line you provided me with a Data change event for my MQTT devices last connection time, and upon multiple value changes still did not display the message on the script logger.
Take a look at this youtube video, describing exactly what you want to reach:
Minute 7:00 ++
Thanks for the video. This works fine. I also want to use the timestamp from the JSON for my valuestream in case the data transmission is not synchronous. For everyone that wants to achieve the same you can use this JS snippet in the subscription:
var decodedValue = eventData.newValue.value;
var createITParams = { infoTableName : "InfoTable", dataShapeName : "NamedVTQ" };
var properties = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape(createITParams);
var row = new Object();
row.name = decodedValue.topic;
row.value = decodedValue.data;
row.time = decodedValue.timestamp;
properties.AddRow(row);
me.UpdatePropertyValues({ values: properties });