Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents
minLevel3
outlinetrue
stylenone

Widget Connector
width480
urlhttp://youtube.com/watch?v=YbQtm-Z1V7c
height360

...

Hardware Setup

In order to run the tutorial, you need to set up the hardware. You can find detailed instructions here.

Write a ThingFacet, Workflow and Device Logic (Message Transformation)

Write a ThingFacet 

To abstract the interactions with the temperature/humidity sensors setup in the previous section, we create a TempFacetSerial ThingFacet. 

...

titleThingFacet

...

Go to page

 

We add two types of attributes in this ThingFacet (1) parameters required to make a protocol specific invocation (2) attribute(s) to store the information received from the sensor. For the purpose of this tutorial we have protocol specific parameters as (Unit, Peripheral, InterfacePort, Interface, etc). Temperature Value will be stored in numeric TempValue Parameter. 

Code Block
languagexml
titleTempFacetSerial attributes
linenumberstrue
<ThingFacet Name="TempFacetSerial">
	<String Name="TempValue"/>
    <String Name="Unit" default="Celsius"/>
	<String Name="Peripheral"/>
    <String Name="InterfacePort"/>
    <String Name="Interface"/>
    <String Name="UniqueId" default="56789"/>
    <String Name="Baudrate"/>
    <String Name="Format" default="ascii"/>
    <String Name="Operation"/>
    <String Name="Payload"/>
	...
</ThingFacet>

Write a Action with Workflow

The next step in ThingFacet is writing a Action which contains a workflow responsible for making external protocol specific call and store the output in the appropriate ThingFacet attribute.  An important decision while writing Action is correct protocol selection. See the /wiki/spaces/TQLDocs/pages/1179871 in the Working with Things section. For this serial sensor we need the perif:// protocol handler, which is part of the TQLEngine.

1. Write an Action name as SerialReadAction

Code Block
languagexml
titleSerialReadAction
linenumberstrue
<ThingFacet Name="TempFacetSerial">
	...
	<Action Name="SerialReadAction">
		...
	</Action>
</ThingFacet>

...

titleAction

...

Go to page

 

2. Create a Workflow within the Action, with one single continuous running Task and waiting for the Event with its ActionArgument.

...

titleWorkflow

...

Go to page

...

titleWorkflow structure

...

Go to page

...

languagexml
titleWorkflow
linenumberstrue

...

Image Added

Philip Hue is a system of 4 components:

  1. Apps – These are ways to control the lights to make them do smart things. 
  2. Bridge – This is used to enable your smart bulbs to communicate with each other and the Portal via the internet. The main set of APIs are those offered by the bridge. These allow you to control all settings of the lights in your system. These APIs require direct access to your bridge so you’ll only be able to access them when your app and bridge are on the same local network.
  3. Portal – This is a web based control panel which connects your home to the internet. It delivers control commands from outside and keeps your software in the bridge up-to-date. The portal presents a utility API to help you discover the address of your bridge.
  4. Lights – This is the output of the system. These smart bulbs contain 3 types of LED specifically chosen to produce a range of colors and intensities. Lights create a mesh network with each other which enables each light to pass on messages to the next extending the range and making everything more robust. They are connected to the bridge via an open standards protocol called ZigBee Light Link.

We will be controlling the lights using Philip Bridge HTTP APIs.

Philip Bridge HTTP Requests

http://10.0.2.16/api/newdeveloper/lights

Request Name: Get the list of lights

Code Block
titleGet Lights JSON
linenumberstrue
{
    "1": {
        "state": {
            "on": true,
            "bri": 144,
            "hue": 13088,
            "sat": 212,
            "effect": "none",
            "xy": [
                0.5128,
                0.4147
            ],
            "ct": 467,
            "alert": "none",
         	<Event name=  "Argumentcolormode": as="ActionArgument"/>
			...hs",
          	</Task> 	</Workflow>
</Action>

Here we used three modifiers for this workflow. Limit = "1" means there can be at most one instance of this workflow waiting. Live = "1" means there can be at most one instance of this workflow running. Timeout ="-1" means this workflow will never be timed out. We used a modifier while = "true" with the Task to make the workflow running in a continuous loop, because it needs to run repeatedly, not just once. For more details, refer to workflow modifiers and the lifecycle of a workflow.

The task will be activated by the event handler Event called ActionArgument. "ActionArgument" is the event generated whenever the attribute(s) associated with this Action is modified (See Associate Action with a ThingFacet Attribute). ActionArgument carries all the current values of the ThingFacet attributes, which can be used in the task if needed.

 

...

titleActionArgument

...

Go to page

3. Invoke PERIF call: Method of PERIF is GET. We use Invoke modifier Get for this purpose. The parameters required PERIF are passed as part of <Message> and <Value>. More details of the perif:// handler are in the Working with Things Section.

Code Block
languagexml
titleInvoke serial handler
linenumberstrue
<Invoke name="InvokeSerialRead" waitFor="Argument" get="perif://">
    <Message> "reachable": true
        },
        "type": "Extended color light",
        "name": "Hue Lamp 1",
        "modelid": "LCT001",
        "uniqueid": "00:17:88:01:00:b6:c6:f0-0b",
        "swversion": "66009663",
        "pointsymbol": {
            "1": "none",
            "2": "none",
            "3": "none",
            "4": "none",
             <Value>"5": "none",
            <InterfacePort>"6"[%:Event.Argument.interfacePort.Value:%]": "none",
             </InterfacePort>"7": "none",
            <Baudrate>"8"[%:Event.Argument.Baudrate.Value:%]"</Baudrate>: "none"
        }
   <Interface>"[%:Event.Argument.Interface.Value:%]"</Interface> },
    "2": {
        <UniqueId>"state"[%:Event.Argument.UniqueId.Value:%]"</UniqueId>: {
            <Operation>"on"[%:Event.Argument.Operation.Value:%]"</Operation>: true,
            <format>"bri"[%:Event.Argument.Format.Value:%]"</format>: 144,
            <Payload>"hue"[%:Event.Argument.Payload.Value:%]"</Payload>: 13088,
            "sat": 212,
            "effect": "none",
            <Peripheral>"xy"[%:Event.Argument.Peripheral.Value:%]"</Peripheral>: [
        </Value>     </Message>
</Invoke>

Here Invoke gets the attribute values that the Event ActionArgument (or Argument) carries. It uses them as the parameter values for the PERIF by substitution. For example, 

<Baudrate>"[%:Event.Argument.baudrate.Value:%]"</Baudrate>

means replacing the value of Message.Value.Baudrate with the value of Event.Argument.baudrate.Value.

Value substitution (rather than assignment) is very common in TQL, given that it is a declarative language. The notation [%: is part of the /wiki/spaces/TEACH/pages/21170773. More details on /wiki/spaces/TEACH/pages/21170773 can be found in the Developer's Guide.

4. Process the message received from the sensor

Code Block
languagexml
titleMessage parsing using TP and XPath
<Output Name="Result" As="ActionResult">
	<Value>
    	<TempValue>
        	[%:Invoke.InvokeSerialRead.Message.Value:%]
    	</TempValue>
	</Value>
</Output>

Here we used an XPath statement to pass the message. Alternatively, you can use Javascript. An example of using JavaScript for message processing within an Action can be found in another tutorial here.

Jira Legacy
showSummaryfalse
serverJIRA (mqidentity.atlassian.net)
serverId77fb3325-4051-36d9-bcc7-761f62050707
keyDOCS-14

...

Associate Action with a ThingFacet Attribute

We will now have to associate a ThingFacet Attribute (TempValue) with the Action using the KnownBy modifier. When TempValue is "KnownBy" SerialReadAction, any TempValue value changes will activate the SerialReadAction.

Code Block
languagexml
titleAttribute TempValue
linenumberstrue
<ThingFacet Name="TempFacetSerial">
	...
	<String Name="TempValue" update="auto" KnownBy="SerialReadAction"/>
</ThingFacet>

...

titleActionable attributes

...

Go to page

The attribute modifier update= "auto" makes sure that once the action associated with this attribute is triggered, its workflow continues to run and wait for subsequent sensor events (not just the first event). This modifier is only used with actionable attributes. For more details, refer to Automatic Action trigger.

Combining ThingFacet with a ThingModel

Finally, in order to use ThingFacet we have to combine it with a ThingModel. We define ThingModel to contain only a unique system identifier.

Code Block
languagexml
titleThingModel TempSensor
linenumberstrue
<ThingModel Name="TempSensor" combines="TempFacetSerial">
	<Sid Name="sensorId"/>
</ThingModel>

...

titleModels

...

Go to page

...

titleThingModels

...

Go to page

 

Only when the TempSensor ThingModel "combines" TempFacetSerial, can TempFacetSerial be instantiated within the TempSensor and accessible by TQL queries. TempSensor will inherit all the attributes from TempFacetSerial, in addition to its own attributes. The ThingFacet TempFacetSerial hence serves as a reusable component.

More details on the use of "combines" can be found here. Information on Sid can be found here.

Deploy and test via queries and subscriptions

Export, import and deploy

Once the models are built in a TQLStudio project, you can export the project. The URL of the Zip file containing the content of your project will be sent over to your email account. Once you have downloaded the engine – launch the TQLEngine User Interface in the browser and select Import Project. You can copy the URL from Export Project Email and hit import button. Go to ThingSpaces and Deploy the project.

...

titleDeploy and instantiate

...

Go to page

Instantiation

Here we use a query to instantiate the sensor, creating 1 instance of the TempSensor ThingModel. In the query, we first use "DeleteAll" to delete all the current instances of the TempSensor, if there are any. The Save will save the values into the corresponding model attributes  (inherited from the ThingFacet). These values provide the runtime parameters for the perif:// handler, as well as providing an update of the TempValue actionable attribute ($Null ( )), which will trigger the associated action SerialReadAction.

Code Block
languagexml
titleSensor instantiation
linenumberstrue
<Query>
	<DeleteAll format="version,current">
    	<TempSensor>
      		<sensorId ne=""/>
    	</TempSensor>
  	</DeleteAll>
  	<Save format="version,current">
    	<!-- This will read -->
    	<TempSensor>
      		<Peripheral>serial</Peripheral>
      		<Baudrate>9600</Baudrate>
      		<InterfacePort>/dev/cu.usbserial-AL01C1HO</InterfacePort>
      		<Interface>serial</Interface>
      		<Format>ascii</Format>
      		<Operation>receive</Operation>
      		<UniqueId>76522</UniqueId>
      		<Payload>$Null()</Payload>
      		<TempValue>$Null()</TempValue>
    	</TempSensor>
  	</Save>
</Query>

Query and subscription

Now we can try a simple Find Query to get sensor values

Code Block
languagexml
titleFind TempSensor query
linenumberstrue
<Query>
    <Find format="version,current">
        <TempSensor>   0.5128,
                0.4147
            ],
            "ct": 467,
            "alert": "none",
            "colormode": "ct",
            "reachable": true
        },
        "type": "Extended color light",
        "name": "Hue Lamp 2",
        "modelid": "LCT001",
        "uniqueid": "00:17:88:01:00:b9:38:7c-0b",
        "swversion": "66009663",
        "pointsymbol": {
            "1": "none",
            "2": "none",
            "3": "none",
            "4": "none",
            "5": "none",
            "6": "none",
            "7": "none",
            "8": "none"
        }
    },
    "3": {
        "state": {
            "on": true,
            "bri": 144,
            "hue": 13088,
            "sat": 212,
            "effect": "none",
            "xy": [
                0.5128,
                0.4147
            ],
            "ct": 467,
            <sensorId ne="" />"alert": "none",
         </TempSensor>   "colormode":  </Find>
</Query>

You will see the result from the RESULTS window:

Code Block
languagexml
titleFind TempSensor query result
linenumberstrue
collapsetrue
<Find Status="Success" Format="version,current">"hs",
        <Result>    "reachable": true
   <TempSensor>     },
       <sensorId>KLHEPDF7AAAAUAABB4JDTW4S</sensorId>
    "type": "Extended color light",
        <interfacePort Value="/dev/cu.usbserial-A7030IWB" Version="1"/>
    "name": "Hue Lamp 3",
       <payload Value="modelid": Version="1LCT001"/>,
        "uniqueid": "00:17:88:01:00:b9:38:5c-0b",
  <peripheral Value="serial" Version="1"/>    "swversion": "66009663",
       <interface Value="serialpointsymbol" Version="1"/>
: {
           <operation Value="receive1": Version="1none"/>,
            <tempValue Value="2": Version="1none"/>,
            <baudrate Value="115200" Version="1"/>
"3": "none",
            "4": "none",
           <uniqueId Value="765225": Version="1none"/>
,
           <format Value="ascii6": Version="1"/>none",
            "7": "none",
   </TempSensor>     </Result> </Find>

 

 

...

titleQueries

...

Go to page

 

To subscribe to changes, use subscription is registered by through a query (query, create)

 

...

languagexml
titleSubscribe to temperature sensor
linenumberstrue

...

 

...

  "8": "none"
 

...

       }
 

...

 

...

 

...

 

...

Or you can subscribe to the specific attribute of the model.

Code Block
languagexml
titleSubscribe to temperature sensor attribute
linenumberstrue
<Topic>Atomiton.Sensor.TempSensor.tempValue</Topic>
<Topic>Atomiton.Sensor.TempSensor.*</Topic>

The Label is the string that will be attached to every message you receive from this subscription. Here we give an sid to this instance of the subscription.

Hardware Setup

Image Removed

Philip Hue is a system of 4 components:

  1. Apps – These are ways to control the lights to make them do smart things. 
  2. Bridge – This is used to enable your smart bulbs to communicate with each other and the Portal via the internet. The main set of APIs are those offered by the bridge. These allow you to control all settings of the lights in your system. These APIs require direct access to your bridge so you’ll only be able to access them when your app and bridge are on the same local network.
  3. Portal – This is a web based control panel which connects your home to the internet. It delivers control commands from outside and keeps your software in the bridge up-to-date. The portal presents a utility API to help you discover the address of your bridge.
  4. Lights – This is the output of the system. These smart bulbs contain 3 types of LED specifically chosen to produce a range of colors and intensities. Lights create a mesh network with each other which enables each light to pass on messages to the next extending the range and making everything more robust. They are connected to the bridge via an open standards protocol called ZigBee Light Link.

We will be controlling the lights using Philip Bridge HTTP APIs.

Philip Bridge HTTP Requests

http://10.0.2.16/api/newdeveloper/lights

Request Name: Get the list of lights

Code Block
titleGet Lights JSON
linenumberstrue
{
    "1": {
        "state": {
            "on": true,
            "bri": 144,
            "hue": 13088,
            "sat": 212,
            "effect": "none",
            "xy": [
                0.5128,
                0.4147
            ],
            "ct": 467,
            "alert": "none",
            "colormode": "hs",
            "reachable": true}
}

Request Name:  Change the state of Light

http://10.0.2.16/api/newdeveloper/lights/1/state

Code Block
titleGet Lights JSON
linenumberstrue
{"on":true}

Write a ThingFacet, Workflow and Device Logic (Message Transformation)

Write a ThingFacet 

To abstract the interactions with the temperature/humidity sensors setup in the previous section, we create a TempFacetSerial ThingFacet. 

Expand
titleThingFacet
Info

Include Page
ThingFacets
ThingFacets

Go to page

 

We add two types of attributes in this ThingFacet (1) parameters required to make a protocol specific invocation (2) attribute(s) to store the information received from the sensor. For the purpose of this tutorial we have protocol specific parameters as (Unit, Peripheral, InterfacePort, Interface, etc). Temperature Value will be stored in numeric TempValue Parameter. 

Code Block
languagexml
titleTempFacetSerial attributes
linenumberstrue
<ThingFacet Name="TempFacetSerial">
	<String Name="TempValue"/>
    <String Name="Unit" default="Celsius"/>
	<String Name="Peripheral"/>
    <String Name="InterfacePort"/>
    <String Name="Interface"/>
    <String Name="UniqueId" default="56789"/>
    <String Name="Baudrate"/>
    <String Name="Format" default="ascii"/>
    <String Name="Operation"/>
    <String Name="Payload"/>
	...
</ThingFacet>

Write a Action with Workflow

The next step in ThingFacet is writing a Action which contains a workflow responsible for making external protocol specific call and store the output in the appropriate ThingFacet attribute.  An important decision while writing Action is correct protocol selection. See the /wiki/spaces/TQLDocs/pages/1179871 in the Working with Things section. For this serial sensor we need the perif:// protocol handler, which is part of the TQLEngine.

1. Write an Action name as SerialReadAction

Code Block
languagexml
titleSerialReadAction
linenumberstrue
<ThingFacet Name="TempFacetSerial">
	...
	<Action Name="SerialReadAction">
		...
	</Action>
</ThingFacet>
Expand
titleAction
Info

Include Page
Actions
Actions

Go to page

 

2. Create a Workflow within the Action, with one single continuous running Task and waiting for the Event with its ActionArgument.

Expand
titleWorkflow
Info

Include Page
Workflows
Workflows

Go to page

Expand
titleWorkflow structure
Info

Include Page
Structure of a workflow
Structure of a workflow

Go to page

Code Block
languagexml
titleWorkflow
linenumberstrue
<Action Name="SerialReadAction">
	<Workflow Limit="1" Live="1" Timeout="-1">
    	<Task name="Main" while="true">
        },
  	<Event name="Argument" as="ActionArgument"/>
			...
     "type": "Extended color light",
        "name": "Hue Lamp 1",
        "modelid": "LCT001",
        "uniqueid": "00:17:88:01:00:b6:c6:f0-0b",
        "swversion": "66009663",
        "pointsymbol": {
    	</Task>
	</Workflow>
</Action>

Here we used three modifiers for this workflow. Limit = "1" means there can be at most one instance of this workflow waiting. Live = "1" means there can be at most one instance of this workflow running. Timeout ="-1" means this workflow will never be timed out. We used a modifier while = "true" with the Task to make the workflow running in a continuous loop, because it needs to run repeatedly, not just once. For more details, refer to workflow modifiers and the lifecycle of a workflow.

The task will be activated by the event handler Event called ActionArgument. "ActionArgument" is the event generated whenever the attribute(s) associated with this Action is modified (See Associate Action with a ThingFacet Attribute). ActionArgument carries all the current values of the ThingFacet attributes, which can be used in the task if needed.

 

Expand
titleActionArgument
Info

Include Page
ActionArgument
ActionArgument

Go to page

3. Invoke PERIF call: Method of PERIF is GET. We use Invoke modifier Get for this purpose. The parameters required PERIF are passed as part of <Message> and <Value>. More details of the perif:// handler are in the Working with Things Section.

Code Block
languagexml
titleInvoke serial handler
linenumberstrue
<Invoke name="InvokeSerialRead" waitFor="Argument" get="perif://">
    <Message>
       "1": "none", <Value>
            <InterfacePort>"2": "none",
            "3": "none",[%:Event.Argument.interfacePort.Value:%]"
            "4": "none",</InterfacePort>
            "5": "none",<Baudrate>"[%:Event.Argument.Baudrate.Value:%]"</Baudrate>
            "6": "none",<Interface>"[%:Event.Argument.Interface.Value:%]"</Interface>
            "7": "none",<UniqueId>"[%:Event.Argument.UniqueId.Value:%]"</UniqueId>
            "8": "none"
     <Operation>"[%:Event.Argument.Operation.Value:%]"</Operation>
  }     },     "2": {
        "state": {<format>"[%:Event.Argument.Format.Value:%]"</format>
             "on": true,<Payload>"[%:Event.Argument.Payload.Value:%]"</Payload>
             "bri": 144,<Peripheral>"[%:Event.Argument.Peripheral.Value:%]"</Peripheral>
             "hue": 13088,</Value>
             "sat": 212,
            "effect": "none",</Message>
</Invoke>

Here Invoke gets the attribute values that the Event ActionArgument (or Argument) carries. It uses them as the parameter values for the PERIF by substitution. For example, 

<Baudrate>"[%:Event.Argument.baudrate.Value:%]"</Baudrate>

means replacing the value of Message.Value.Baudrate with the value of Event.Argument.baudrate.Value.

Value substitution (rather than assignment) is very common in TQL, given that it is a declarative language. The notation [%: is part of the /wiki/spaces/TEACH/pages/21170773. More details on /wiki/spaces/TEACH/pages/21170773 can be found in the Developer's Guide.

4. Process the message received from the sensor

Code Block
languagexml
titleMessage parsing using TP and XPath
<Output Name="Result" As="ActionResult">
	<Value>
    	<TempValue>
        	[%:Invoke.InvokeSerialRead.Message.Value:%]
   "xy": [
                0.5128,
                0.4147
            ],
            "ct": 467,
            "alert": "none",
            "colormode": "ct",
            "reachable": true
        },
        "type": "Extended color light",
        "name": "Hue Lamp 2",
        "modelid": "LCT001",
        "uniqueid": "00:17:88:01:00:b9:38:7c-0b",
        "swversion": "66009663",
        "pointsymbol": {
            "1": "none",
            "2": "none",
            "3": "none",
            "4": "none",
            "5": "none",
            "6": "none",
            "7": "none",
            "8": "none"
        }
    },
    "3": {
        "state": {
            "on": true,
            "bri": 144,
            "hue": 13088,
            "sat": 212,
            "effect": "none",
            "xy": [
                0.5128, 	</TempValue>
	</Value>
</Output>

Here we used an XPath statement to pass the message. Alternatively, you can use Javascript. An example of using JavaScript for message processing within an Action can be found in another tutorial here.

Jira Legacy
showSummaryfalse
serverJIRA (mqidentity.atlassian.net)
serverId77fb3325-4051-36d9-bcc7-761f62050707
keyDOCS-14

Anchor
Associate Action with a ThingFacet Attribute
Associate Action with a ThingFacet Attribute

Associate Action with a ThingFacet Attribute

We will now have to associate a ThingFacet Attribute (TempValue) with the Action using the KnownBy modifier. When TempValue is "KnownBy" SerialReadAction, any TempValue value changes will activate the SerialReadAction.

Code Block
languagexml
titleAttribute TempValue
linenumberstrue
<ThingFacet Name="TempFacetSerial">
	...
	<String Name="TempValue" update="auto" KnownBy="SerialReadAction"/>
</ThingFacet>
Expand
titleActionable attributes
Info

Include Page
Actionable attributes
Actionable attributes

Go to page

The attribute modifier update= "auto" makes sure that once the action associated with this attribute is triggered, its workflow continues to run and wait for subsequent sensor events (not just the first event). This modifier is only used with actionable attributes. For more details, refer to Automatic Action trigger.

Combining ThingFacet with a ThingModel

Finally, in order to use ThingFacet we have to combine it with a ThingModel. We define ThingModel to contain only a unique system identifier.

Code Block
languagexml
titleThingModel TempSensor
linenumberstrue
<ThingModel Name="TempSensor" combines="TempFacetSerial">
	<Sid Name="sensorId"/>
</ThingModel>
Expand
titleModels
Info

Include Page
Models
Models

Go to page

Expand
titleThingModels
Info

Include Page
ThingModels
ThingModels

Go to page

 

Only when the TempSensor ThingModel "combines" TempFacetSerial, can TempFacetSerial be instantiated within the TempSensor and accessible by TQL queries. TempSensor will inherit all the attributes from TempFacetSerial, in addition to its own attributes. The ThingFacet TempFacetSerial hence serves as a reusable component.

More details on the use of "combines" can be found here. Information on Sid can be found here.

Deploy and test via queries and subscriptions

Export, import and deploy

Once the models are built in a TQLStudio project, you can export the project. The URL of the Zip file containing the content of your project will be sent over to your email account. Once you have downloaded the engine – launch the TQLEngine User Interface in the browser and select Import Project. You can copy the URL from Export Project Email and hit import button. Go to ThingSpaces and Deploy the project.

Expand
titleDeploy and instantiate
Info

Include Page
Deploy and instantiate
Deploy and instantiate

Go to page

Instantiation

Here we use a query to instantiate the sensor, creating 1 instance of the TempSensor ThingModel. In the query, we first use "DeleteAll" to delete all the current instances of the TempSensor, if there are any. The Save will save the values into the corresponding model attributes  (inherited from the ThingFacet). These values provide the runtime parameters for the perif:// handler, as well as providing an update of the TempValue actionable attribute ($Null ( )), which will trigger the associated action SerialReadAction.

Code Block
languagexml
titleSensor instantiation
linenumberstrue
<Query>
	<DeleteAll format="version,current">
    	<TempSensor>
      		<sensorId ne=""/>
    	</TempSensor>
  	</DeleteAll>
  	<Save format="version,current">
    	<!-- This will read -->
    	<TempSensor>
      		<Peripheral>serial</Peripheral>
      		<Baudrate>9600</Baudrate>
      		<InterfacePort>/dev/cu.usbserial-AL01C1HO</InterfacePort>
      		<Interface>serial</Interface>
      		<Format>ascii</Format>
      		<Operation>receive</Operation>
      		<UniqueId>76522</UniqueId>
      		<Payload>$Null()</Payload>
      		<TempValue>$Null()</TempValue>
    	</TempSensor>
  	</Save>
</Query>

Query and subscription

Now we can try a simple Find Query to get sensor values

Code Block
languagexml
titleFind TempSensor query
linenumberstrue
<Query>
    <Find format="version,current">
        <TempSensor>
       0.4147     <sensorId    ne="" />
   ],     </TempSensor>
       "ct": 467,
            "alert": "none",</Find>
</Query>

You will see the result from the RESULTS window:

Code Block
languagexml
titleFind TempSensor query result
linenumberstrue
collapsetrue
<Find Status="Success" Format="version,current">
    <Result>
       "colormode": "hs", <TempSensor>
            "reachable": true<sensorId>KLHEPDF7AAAAUAABB4JDTW4S</sensorId>
         },   <interfacePort Value="/dev/cu.usbserial-A7030IWB" Version="1"/>
   "type": "Extended color light",      <payload   "name": "Hue Lamp 3",Value="" Version="1"/>
            <peripheral Value="modelidserial": Version="LCT001",1"/>
            <interface Value="uniqueidserial": "00:17:88:01:00:b9:38:5c-0b",
 Version="1"/>
      "swversion": "66009663",      <operation   "pointsymbol": {Value="receive" Version="1"/>
            <tempValue Value="1": Version="none1",/>
            <baudrate Value="2115200": Version="none1",/>
            <uniqueId Value="376522": Version="none1",/>
            <format Value="4ascii": Version="none1",/>
        </TempSensor>
    "5": "none",
            "6": "none",
</Result>
</Find>

 

 

Expand
titleQueries
Info

Include Page
Queries
Queries

Go to page

 

To subscribe to changes, use subscription is registered by through a query (query, create)

 

Code Block
languagexml
titleSubscribe to temperature sensor
linenumberstrue
<Query Storage='TqlSubscription'>
    <Save>
        <TqlSubscription Label='TempSensor' 

...

sid='20'>
            <Topic>Atomiton.Sensor.TempSensor.tempValue</Topic>
 

...

 

...

      

...

</TqlSubscription>
   

...

Request Name:  Change the state of Light

http://10.0.2.16/api/newdeveloper/lights/1/state

...

titleGet Lights JSON
linenumberstrue

...

 </Save>
</Query>

Or you can subscribe to the specific attribute of the model.

Code Block
languagexml
titleSubscribe to temperature sensor attribute
linenumberstrue
<Topic>Atomiton.Sensor.TempSensor.tempValue</Topic>
<Topic>Atomiton.Sensor.TempSensor.*</Topic>

The Label is the string that will be attached to every message you receive from this subscription. Here we give an sid to this instance of the subscription.

Hardware Setup

Queries

Code Block
languagexml
titleFind Lights
linenumberstrue
 <Query>
  <Find format="all">
    <PhilipLightModel>
      <LightNumber eq="1"/>
    </PhilipLightModel>
  </Find>
</Query>

...