ThingModel is one kind of models (the other kinds are DataModels and AppModels). Therefore it has all the properties of Models (Lifecycle of models, Model Attributes, Unique and Constraints).
A ThingModel has
- a Name,
- any number of Model Attributes
- and usually one or more Actions
However, as a recommended practice, the Attributes and Actions related to the interactions with an external thing (sensors, actuators, machines) are often defined in a reusable structure called ThingFacet, and combined into a ThingModel. This relationship was explained in the concept of Models and Model Facets. Application related information are often defined directly as attributes of the ThingModel.
Purpose of ThingModels:
- ThingModels are normally defined by users when interacting with Physical Things. The behavior of Physical Things are modeled via ThingFacet.
- ThingModels are driver for ThingFacets. ThingFacet (s) are reusable models and TQL CRUD operations can not be performed on ThingFacet. ThingFacet(s) are put to use only when combined within a ThingModel.
- ThingModels can contain application related information that are related to things.
Simplest form of defining a ThingModel is to provide a Name and Attributes. Example of a PhidgetServoModel ThingModel with one attribute PhidServoId of type Sid.
<ThingModel Name="PhidgetServoModel"> <Sid Name="PhidServoId"/> </ThingModel> <ThingFacet Name="PhidgetServoFacet"> <String Name="ServoProtocolURL" Default="phid://" /> <String Name="DeviceInterfaceIndex" /> <String Name="PhidgetDeviceType" /> <Integer Name="ServoAngle" KnownBy="PhidgetServoAction" /> <Action Name="PhidgetServoAction" Documentation="Control servo motor"> ... </Action> </ThingFacet>
ThingsFacets are used within ThingModels using Combines modifier. Example of a PhidgetServoModel ThingModel combining a PhidgetServoFacet ThingFacet
<ThingModel Name="PhidgetServoModel" Combines="PhidgetServoFacet"> <Sid Name="PhidServoId"/> </ThingModel>
Note: One can combine multiple ThingFacets within a single ThingModel using comma separated list of ThingFacets.
For Example Esky ThingModel combining EskyPreset and EskyImage Thing Facets
<ThingFacet name="EskyPreset"> <String name="State" KnownBy="SyncPreset"/> <String name="Preset" KnownBy="SyncPreset"/> <Action name="SyncPreset" documentation="Synchronize camera state and preset"> <Workflow Limit="1" Live="1" Timeout="PT20S"> <Task name="Main" while="true"> <Event name="Argument" as="ActionArgument"/> ... </Task> </Workflow> </Action> </ThingFacet> <ThingFacet name="EskyImage" combines="Login"> <String name="State" KnownBy="SyncImage"/> <Clob name="Image" KnownBy="SyncImage"/> <!-- Actions --> <Action name="SyncImage" documentation="Synchronize camera state and snapshot image"> <Workflow Limit="1" Live="1" Timeout="PT10S"> <Task name="Main" while="true"> <Event name="Argument" as="ActionArgument"/> ... </Task> </Workflow> </Action> </ThingFacet> <ThingModel name="Esky" combines="EskyPreset,EskyImage" documentation="actual single instance camera model"> <Sid name="CameraId"/> </ThingModel>
Adding application related information to a ThingModel. For Example, assume that the Phidget Servo Motor is part of a Zone within a Greenhouse environment. Greenhouse contains multiple zones.
<ThingModel Name="PhidgetServoModel" Combines="PhidgetServoFacet"> <Sid Name="PhidServoId"/> <String Name="InstalledAtZone"/> </ThingModel>
Examples of CRUD Operation on a ThingModel:
CREATE:
<Create> <PhidgetServoModel> <ServoProtocolURL> phid:// </ServoProtocolURL> <PhidgetDeviceType> PhidgetAdvancedServo </PhidgetDeviceType> <DeviceInterfaceIndex> 0 </DeviceInterfaceIndex> <ServoAngle> 110 </ServoAngle> </PhidgetServoModel> </Create>
CREATE RESULT:
<Create Status="Success"> <PhidgetServoModel> <PhidServoId>KNJN2YRVAAAAUAABA7LIQ4Y6</PhidServoId> <ServoProtocolURL Status="Success+Created:1:1457384153653;" Value="phid://"/> <DeviceInterfaceIndex Status="Success+Created:1:1457384153653;" Value="0"/> <PhidgetDeviceType Status="Success+Created:1:1457384153653;" Value="PhidgetAdvancedServo"/> <ServoAngle Status="Success+Created:1:1457384153654;" Value="110"/> </PhidgetServoModel> </Create>
Note: If a ThingModel is combined with a ThingFacet, creation of a ThingModel results in instantiating (Trigger) of a ThingFacet action.
UPDATE:
<Query> <Find format="version"> <PhidgetServoModel as="var.PS"> <PhidServoId ne=""/> </PhidgetServoModel> </Find> <SetResponseData> <key> Message.Value.Find.Result.PhidgetServoModel.ServoAngle.Value </key> <value> 120 </value> </SetResponseData> <Update> <from> Result </from> <Include> $Response.Message.Value.Find </Include> </Update> </Query>
UPDATE Result:
<Find Status="Success" Format="version"> <Result> <PhidgetServoModel> <PhidServoId>KNJPIFR6AAAAUAABA67ZRBQO</PhidServoId> <PhidgetDeviceType Value="PhidgetAdvancedServo" Version="1"/> <ServoAngle Version="1" Value="120"/> <DeviceInterfaceIndex Value="0" Version="1"/> <ServoProtocolURL Value="phid://" Version="1"/> </PhidgetServoModel> </Result> </Find> <Update Status="Success" Format="version"> <PhidgetServoModel> <PhidServoId>KNJPIFR6AAAAUAABA67ZRBQO</PhidServoId> <ServoProtocolURL Status="Success_NoAction:1:1457385641534;" Value="phid://" Version="1"/> <DeviceInterfaceIndex Status="Success_NoAction:1:1457385641534;" Value="0" Version="1"/> <PhidgetDeviceType Status="Success_NoAction:1:1457385641535;" Value="PhidgetAdvancedServo" Version="1"/> <ServoAngle Status="Success=Updated:2:1457385767153;" Value="120" Version="2"/> </PhidgetServoModel> </Update>
Note: If a ThingModel is combined with a ThingFacet updating a ThingModel attribute results in Trigger of a Action if that attribute is associated with an action.
DELETE:
<<Query> <DeleteAll> <PhidgetServoModel> <PhidServoId ne=""/> </PhidgetServoModel> </DeleteAll> </Query>
DELETE Result
<DeleteAll Status="Success"> <Result> <PhidgetServoModel> <PhidServoId>KNJOOOBZAAAAUAABA72MMI6E</PhidServoId> <PhidgetDeviceType>PhidgetAdvancedServo</PhidgetDeviceType> <ServoAngle>110</ServoAngle> <DeviceInterfaceIndex>0</DeviceInterfaceIndex> <ServoProtocolURL>phid://</ServoProtocolURL> </PhidgetServoModel> </Result> </DeleteAll>
Note: If a ThingModel is combined with a ThingFacet, creation of a ThingModel results in deleting an instance results in cleanup of connections with actual things as per the protocol Handler used.
FIND
<Query> <Find format="all"> <PhidgetServoModel> <PhidServoId ne="" /> </PhidgetServoModel> </Find> </Query>
Find result: Format="all" - returns all the internal attribute data as well.
<Find Status="Success" Format="all"> <Result> <PhidgetServoModel QName="Atomiton.PhidgetServos.PhidgetServoModel"> <PhidServoId>KNJOOOBZAAAAUAABA72MMI6E</PhidServoId> <PhidgetDeviceType Value="PhidgetAdvancedServo" Known="PhidgetAdvancedServo" Version="1" Timestamp="1457384798266" DateTime="2016-03-07 13:06:38.266" QName="Atomiton.PhidgetServos.PhidgetServoModel.PhidgetDeviceType" FName="PhidgetDeviceType"/> <ServoAngle Value="110" Known="110" Version="1" Timestamp="1457384798266" DateTime="2016-03-07 13:06:38.266" QName="Atomiton.PhidgetServos.PhidgetServoModel.ServoAngle" FName="ServoAngle"/> <DeviceInterfaceIndex Value="0" Known="0" Version="1" Timestamp="1457384798266" DateTime="2016-03-07 13:06:38.266" QName="Atomiton.PhidgetServos.PhidgetServoModel.DeviceInterfaceIndex" FName="DeviceInterfaceIndex"/> <ServoProtocolURL Value="phid://" Known="phid://" Version="1" Timestamp="1457384798265" DateTime="2016-03-07 13:06:38.265" QName="Atomiton.PhidgetServos.PhidgetServoModel.ServoProtocolURL" FName="ServoProtocolURL"/> </PhidgetServoModel> </Result> </Find>
Note:
- When ThingModels are do not combine ThingFacet it is equivalent of a DataModel i.e pure Data only.
- Although not required, it is best practice to always create a ThingModel with one attribute that is of type SystemId or Sid.