Table of Contents |
---|
minLevel | 3 |
---|
outline | true |
---|
style | none |
---|
|
Widget Connector |
---|
width | 480 |
---|
url | http://youtube.com/watch?v=YbQtm-Z1V7c |
---|
height | 360 |
---|
|
Hardware Setup
Philip Hue is a system of 4 components:
...
Request Name: Change the state of Light
http://10.0.2.16/api/newdeveloper/lights/1/state
Code Block |
---|
title | Get Lights JSON |
---|
linenumbers | true |
---|
|
{"on":true} |
...
To abstract the interactions with the temperature/humidity sensors setup in the previous sectionPhilip Light Bulbs, we create a TempFacetSerial ThingFacetPhilipLightFacet ThingFacet.
We add two types of attributes in this ThingFacet (1) parameters
- Parameters required to make a protocol specific
...
- invocation
Attributes to store the information received from the
...
light.
There are two important patterns for look for:
- The response from GetLights is a complex hierarchical response.
- Parameterizing the Protocol Parameters instead of attributes of a ThingFacet
Let's create response structure using Types (Def) to match to the response of Lights
Code Block |
---|
language | xml |
---|
title | TempFacetSerial attributesPhilipLightState Definition |
---|
linenumbers | true |
---|
|
<ThingFacet<Def Name="TempFacetSerialPhilipLightState">
<String <Boolean Name="TempValueOn"/>
<String<Integer Name="Unit" defaultbri"/>
<Integer Name="Celsiushue"/>
<String <Integer Name="Peripheralsat"/>
<String Name="InterfacePorteffect"/>
<Double <String Name="Interfacexy"/>
<String Name="UniqueId" default="56789 cardinality="2"/>
<Integer <String Name="Baudratect"/>
<String Name="Format" default="ascii"alert"/>
<String Name="Operationcolormode"/>
<String<Boolean Name="Payloadreachable"/>
...
</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.
...
Simply define the Philip Light Bridge API URL using PhilipLightBaseURI Tag
Code Block |
---|
language | xml |
---|
title | PhilipLightBaseURI Tag |
---|
linenumbers | true |
---|
|
<PhilipLightBaseURI>http://10.0.2.16/api/newdeveloper</PhilipLightBaseURI>
|
Lets now create a ThingFacet using the PhilipLightState type and rest of the parameters like - Type, modelId, etc as parameters of the PhilipLightFacet ThingFacet. Now the entire ThingFacet definition maps to the exact Response of the GetLight structure.
Code Block |
---|
language | xml |
---|
title | SerialReadActionPhilipLightBaseURI Tag |
---|
linenumbers | true |
---|
|
<ThingFacet Name="TempFacetSerialPhilipLightFacet">
...
<Action <String Name="SerialReadActionLightNumber"/>
...
</Action>
</ThingFacet> |
Expand |
---|
|
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.
...
...
Go to page
...
...
Go to page
Code Block |
---|
language | xml |
---|
title | Workflow |
---|
linenumbers | true |
---|
|
<Action Name="SerialReadAction">
<Workflow Limit="1" Live="1" Timeout="-1">
<Task name="Main" while="true">
<Event name="Argument" as="ActionArgument"/>
...
</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.
...
<PhilipLightState Name="State"/>
<String Name="Type"/>
<String Name="modelid"/>
<String Name="uniqueid"/>
<String Name="swversion"/>
</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 Philip Light we need simple HTTP request, which is part of the TQLEngine.
1. Write an Action name as PhilipLightAction
Code Block |
---|
language | xml |
---|
title | PhilipLightAction |
---|
linenumbers | true |
---|
|
<ThingFacet Name="TempFacetSerial">
...
<Action Name="PhilipLightAction">
...
</Action>
</ThingFacet> |
2. Create a Workflow within the Action, with one single continuous running Task and waiting for the Event with its ActionArgument.
Expand |
---|
|
Info |
---|
Include Page |
---|
| Structure of a workflow |
---|
| Structure of a workflow |
---|
|
|
Go to page |
Code Block |
---|
language | xml |
---|
title | Workflow |
---|
linenumbers | true |
---|
|
<Action Name="PhilipLightAction">
<Workflow Limit="1" Live="1" Timeout="-1">
<Task name="Main" while="true">
<Event name="Argument" as="ActionArgument"/>
...
</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 |
---|
|
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 |
---|
language | xml |
---|
title | Invoke serial handler |
---|
linenumbers | true |
---|
|
<Invoke name="InvokeSerialRead" waitFor="Argument" get="perif://">
<Message>
<Value>
<InterfacePort>"[%:Event.Argument.interfacePort.Value:%]"
</InterfacePort>
<Baudrate>"[%:Event.Argument.Baudrate.Value:%]"</Baudrate>
<Interface>"[%:Event.Argument.Interface.Value:%]"</Interface>
<UniqueId>"[%:Event.Argument.UniqueId.Value:%]"</UniqueId>
<Operation>"[%:Event.Argument.Operation.Value:%]"</Operation>
<format>"[%:Event.Argument.Format.Value:%]"</format>
<Payload>"[%:Event.Argument.Payload.Value:%]"</Payload>
<Peripheral>"[%: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.
...
3. Invoke HTTP call: Method of HTTP is PUT. We use Invoke modifier Put for this purpose. The parameters required for HTTP PUT are passed as part of <Message> and <Value>.
Code Block |
---|
language | xml |
---|
title | Invoke HTTP Handler |
---|
linenumbers | true |
---|
|
<Invoke Name="SetState" waitFor="ActionArgument" Put="[:PhilipLightBaseURI:]/lights/[%:[:AA:].LightNumber.Value:%]/state">
<Message type="json">
<Value>{"on": [:AA:].state.On.Value}</Value>
</Message>
</Invoke> |
Note that PhilipLightBaseURI is referenced using TP tag: [:PhilipLightBaseURI:] 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 sensorPhilip Light Bridge
Code Block |
---|
language | xml |
---|
title | Message parsing using TP and XPath |
---|
|
<Output Namename="Result" Asas="ActionResult">
<Value>
<TempValue><State>
<On>[%:[:Invoke.InvokeSerialRead.MessageAA:].state.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 |
---|
showSummary | false |
---|
server | JIRA (mqidentity.atlassian.net) |
---|
serverId | 77fb3325-4051-36d9-bcc7-761f62050707 |
---|
key | DOCS-14 |
---|
|
</On>
</State>
</Value>
</Output> |
Anchor |
---|
| Associate Action with a ThingFacet Attribute |
---|
| Associate Action with a ThingFacet Attribute |
---|
|
...
We will now have to associate a ThingFacet Attribute (TempValueState) with the Action using the KnownBy modifier. When TempValue State is "KnownBy" SerialReadActionPhilipLightAction, any TempValue State value changes will activate the SerialReadActionPhilipLightAction.
Code Block |
---|
language | xml |
---|
title | Attribute TempValueState tied to Action |
---|
linenumbers | true |
---|
|
<ThingFacet Name="TempFacetSerialPhilipLightAction">
...
<String
<PhilipLightState Name="TempValueState" update="auto" KnownBy="SerialReadActionPhilipLightActionUsingPut"/>
</ThingFacet> |
Expand |
---|
title | Actionable attributes |
---|
|
Info |
---|
Include Page |
---|
| Actionable attributes |
---|
| Actionable attributes |
---|
|
|
Go to page |
...
Code Block |
---|
language | xml |
---|
title | ThingModel TempSensorPhilipLightModel |
---|
linenumbers | true |
---|
|
<ThingModel <ThingModel Name="TempSensorPhilipLightModel" combinesCombines="TempFacetSerialPhilipLightFacet">
<Sid Name="sensorIdLightId"/>
</ThingModel>
|
...