6 Replies Latest reply on Jun 29, 2017 12:43 PM by pchung RSS
    kjans Newbie

    A simple end-to-end example, please...

    Hi,

     

    I am trying to learn Thingworx by creating a simple end-to-end example:


        IoTDevice --> POST gaugeValue(59) --> JSON/REST Thingworx --> Mashup --> GaugeWidget

     

    For example, an IoT device does a POST of JSON data to a RESTful Thingworx service…
    The JSON data contains a Value to be displayed in a Thingworx Mashup / Gauge Widget.

     

    Question: what is the simplest way to connect a data value received in a Thingworx
    Script to a Mashup / Widget?


    =========================================

    Details:

    I have done the following:


      - Created a Thing called "SmartThing" in Composer.


      - Created a Service called "RestListener" which accepts a "payload" with Type JSON.


      - In the body of the RestListener script is just the following two lines:


         logger.warn("Made it to the REST listener");
         logger.warn(payload.dataShape.fieldDefinitions.gaugeValue);


      - I can issue a POST from an IoT device containing the following JSON:
         {
           "dataShape": {
             "fieldDefinitions": {
               "gaugeValue": "42"
             }
           }
         }


      - The POST is to:
          http://<TW_HOST>/Thingworx/Things/SmartThing/Services/RestListener?postParameter=payload


      - I can see in the Thingworx log both the logger.warn statements; the second contains the
        correct value for gaugeValue...so the POST works and the script can read the data value.


      - I created a Mashup... named it "SmartThing"


      - I added a Panel and in the panel added a Gauge widget
         - Mashup
           - panel-1
             - gauge-2


      - How do I connect the "gaugeValue" in my script to update "gauge-2" in my Mashup...


    It seems like this should be simple...but I have spent hours trying with no success...


    Thanks for listening...

      • Re: A simple end-to-end example, please...
        pchung Collaborator

        You'll want to create a Thing (and best practice before that a ThingTemplate)  with a Property to hold the Gauge Value

        So let's say it's Pressure, you create a ThingTemplate with a Property called pressure. You also create that service in the Template

        have that service write the value to the property

        Now you can create any number of Things and your sensors can post to their matching Thing.

        In the mashup you can now use service like GetProperties / GetPropertyValues

         

        To extend this and scale this, you can first call a list of GetImplementingThings from your ThingTemplate and then use that in a List

        then use the selection to drive the value retrieval of an individual Thing

        • Re: A simple end-to-end example, please...
          wposner-2 Apprentice

          You first probably want to edit your service to return the actual payload value.  So change your result type to match whatever the value actually is and then set result=payload.datashape.fieldDinitions.guageValue;

           

          In right panel within composer when you have your mashup open, click the little plus sign.  When the window opens, search for your SmartThing thing then select your RestListener to add it to the service list.

           

          Drag the AllData from the results section of your service to your widget and bind it to the data parameter.

           

          You'll also probably want to add a refresh widget to your mashup since you've yet to construct your model to support the remote thing concept.  Drag the refresh event from the refresh widget to your RestListener Service in the mashup builder so that when the refresh event fires it gets whatever value the RestListener service returns.

            • Re: A simple end-to-end example, please...
              kjans Newbie

              Thanks for the reply...

               

              I've done the following:

               

                 - changed my RestListener definition to return a # NUMBER result

               

                 - added this code at the end of my RestListener:

                     var result = parseInt(payload.dataShape.fieldDefinitions.gaugeValue, 10);

                     logger.warn(result);

                     logger.warn(typeof result);

               

                 - In the Mashup

                   - Added SmartThing to the service list

                   - Dragged # result to the Gauge

                   - Bound to # Data

               

                 - Save'd

               

                 - View Mashup still doesn't show any value for the gauge...pressed Refresh, etc...

                 - The logger messages indicate that the correct value is being assigned to "result"

               

              Any suggestions...

                • Re: A simple end-to-end example, please...
                  wposner-2 Apprentice

                  Ahh...the Mashup Loaded Event!  You need to click on the workspace tab, select Mashup, and then from the little arrow that appears in the top left of the workspace, click on it, selected the Loaded event and drag that over to your service.  Now when the mashup loads, it will fire that service which should grab your data and update the gauge.

                    • Re: A simple end-to-end example, please...
                      kjans Newbie

                      Thanks again for your reply...

                       

                      It turns out that I can't have the Loaded or Refresh events invoke my RESTful Service directly...

                      It expects an input of JSON data... since the Loaded/Refresh events don't provide that, my Service reports an error.

                       

                      I have tried the following as a workaround...

                       

                      I create a Property "gaugeValue" in my Thing... type # NUMBER

                      In my RESTful Service handler, I update it like this:

                        Things["SmartThing"].gaugeValue = payload.dataShape.fieldDefinitions.gaugeValue;

                       

                      I created a new Service named GetGaugeValue...

                      It returns a # NUMBER

                      It contains:

                         logger.warn("In GetGaugeValue");

                         var result = Things["SmartThing"].gaugeValue;

                         logger.warn(result);

                       

                      If I "test" this Service from the Composer, it gets the last value that was updated via the RESTful POST...

                       

                      I then went back to my Mashup...

                      I removed the old wiring..

                      I wired the GetGaugeValue Service to my Gauge # Data

                      I added an "Auto Refresh" Widget and wired it to my Service

                      I wired the Mashup's Loaded event to the Service

                       

                      View Mashup...

                      I can see my logger.warn statements from the GetGauageValue Service periodically appearing in the log with the latest value...

                      so the Load/Refresh widget is working...

                      But...the Gauge still does not show any value...

                       

                      Can I wire directly from a Service to a Widget?

                      When I "test" my service, I get an option to create a "DataShape"...do I need an intermediate DataShape?

                       

                      Thanks