Versions Compared

Key

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

...

Key Concepts

Tip
iconfalse
 Related docs
DataModel 
Simple Reference 
Create data 

 

Background

In order to model a real-world IoT application or a solution it is imperative to combine things with data. Let's take an example of real-world use case.

Real-world use-case

Image Modified

For the purpose of this tutorial let's model the Greenhouse monitoring system with following configuration.

  • Greenhouse: size: 40 feet by 110 feet
  • crop types, tomatoes and peppers
  • 3 lanes, each lane has 10 zones
  • Total 30 zones (each zone is 10 feet by 10 feet. Lay out is 3 by 10): 20 zones (2 by 10) are tomatoes, 10 zones are peppers

Each zone subdivided into 9 grids. Each grid is 3.33 feet by 3.33 feet. Total 270 grids

 Zone Content: 

  • 1 temperature sensor (total 30)
  • 1 humidity sensor (total 30)
  • 1 camera (total 30)
  • 1 irrigation motor (total 30)

 Zone Grid Content:

  • 1 ambient light sensor (total 270)
  • 1 light (total 270)
  • 1 irrigation nozzle (total 270)

 External Conditions:

  • 1 ambient light sensor
  • 1 temperature sensor
  • 1 humidity sensor

Tutorial Requirement

For the purpose of this tutorial, let's create a Greenhouse, Lane, Zone, Grid and combine Temperature Sensor from tutorial 1 to a particular zone.

DataModel to store non-thing related data

TQLEngine provides DataModel to store "pure" data, DataModels do not combine model facets. They are simply models to store application data that is essential to create a meaningful real-world IoT application.

...

titleDataModel
invalidmacro

...

Custom Types

We create two custom types to store GeoLocation and BoundingBox.

  1. GeoLocation - To Store GeoLocation

    Code Block
    languagexml
    titleGeoLocation Type
    linenumberstrue
    <Def Name="GeoLocation">
      <Number Name="latitude"/>
      <Number Name="longitude"/>
    </Def>	
  2. BoundingBox - To Store Geo Boundary of Zone, etc

    Code Block
    languagexml
    titleBoundingBox Type
    linenumberstrue
    <Def Name="BoundingBox">
      <GeoLocation Name="Vertex1"/>
      <GeoLocation Name="Vertex2"/>
      <GeoLocation Name="Vertex3"/>
      <GeoLocation Name="Vertex4"/>
    </Def>
  3. EnvInfo - Capture all the important environment related information like temperature, humidity, light, pressuue

    Code Block
    languagexml
    titleEnvInfo Type
    linenumberstrue
    <Def Name="EnvInfo">
          <Number Name="Temperature"/>
          <Number Name="Humidity"/>
          <Number Name="Light"/>
          <Number Name="Pressure"/>
          <Number Name="SoilMoisture"/>
          <Number Name="Wind"/>
          <String Name="LastUpdatedByProvider"/>
    </Def>

List of DataModels

  1. Greenhouse : Overall DataModel holder for Greenhouse. GHLanes is defined as Reference to include all the Lanes from Lane model.

    Code Block
    languagexml
    titleGreenhouse DataModel
    linenumberstrue
    <DataModel Name="Greenhouse">
          <Sid Name="GreenhouseID"/>
          <String Name="GreenhouseName"/>
          <GeoLocation Name="Location"/>
          <String Name="LocationName"/>
          <BoundingBox Name="Boundary"/>
          <Integer Name="LaneCount"/>
          <Double Name="LaneWidth"/>
          <Double Name="ZoneLength"/>
          <Integer Name="ZoneInLane"/>
          <Integer Name="ZoneCount"/>
          <Double Name="GHLength"/>
          <Double Name="GHWidth"/>
          <EnvInfo Name="ExternalEnv"/>
          <EnvInfo Name="InternalEnv"/>
          <String Name="VentOnOffState"/>
          <String Name="FansOnOffState"/>
          <Boolean Name="SunnyDay"/>
          <Boolean Name="Running" default="false"/> <!-- true / false -->
          <Reference Name="GHLanes"/>
          <Reference Name="GHExternalEnv"/>
          <Reference Name="GHInternalEnv"/>
    </DataModel>
  2. GHExternalEnv & GHInternalEnv

    Code Block
    languagexml
    titleGHExternalEnv and GHInternalEnv Data Model
    linenumberstrue
    <DataModel Name="ExternalEnv">
          <Sid Name="ExternalEnvID"/>
          <Number Name="ExtTemperature"/>
          <Number Name="ExtHumidity"/>
          <Number Name="ExtLight"/>
          <Reference Name="GreenhouseID" Type="Greenhouse" Cardinality="1"/>
        </DataModel>
    <DataModel Name="InternalEnv">
          <Sid Name="InternalEnvID"/>
          <Number Name="IntTemperature"/>
          <Number Name="IntHumidity"/>
          <Number Name="IntLight"/>
          <Reference Name="GreenhouseID" Type="Greenhouse" Cardinality="1"/>
    </DataModel>


  3. Grid - DataModel for storing Grid information.

    Code Block
    languagexml
    titleGrid DataModel
    linenumberstrue
    <DataModel Name="Grid">
          <Sid Name="GridID"/>
          <String Name="GridName"/>
          <BoundingBox Name="GridLocation"/>
          <Integer Name="GridNSPosition"/>
          <Integer Name="GridWEPosition"/>
          <Double Name="GridLength"/>
          <Double Name="GridWidth"/>
          <Double Name="SoilMoisture"/>
          <Double Name="AmbientLight"/>
          <Reference Name="ZoneID" Type="Zone" Cardinality="1"/>
     </DataModel>
  4. Zone - DataModel for storing Zone information. Does a Smart Reference  to Grid at instantiation time by simply defining ZoneGrids as Reference type. The Find query can be add at the instantiation time.

    Code Block
    languagexml
    titleZone DataModel
    linenumberstrue
    <DataModel Name="Zone">
          <Sid Name="ZoneID"/>
          <String Name="ZoneName"/>
          <BoundingBox Name="ZoneLocation"/>
          <GeoLocation Name="Location"/>
          <Double Name="ZoneWidth"/>
          <Double Name="ZoneLength"/>
          <Integer Name="GridOnLength"/>
          <Integer Name="GridOnWidth"/>
          <Integer Name="GridCount"/>
          <Double Name="GridLength"/>
          <Double Name="GridWidth"/>
          <String Name="EndZone"/>
          <Double Name="ZoneTemperature"/>
          <Double Name="ZoneHumidity"/>
          <Double Name="ZoneAvgSM"/>
          <Double Name="ZoneAvgLight"/>
          <String Name="CropType"/>
          <Date Name="SeedingDate" format="$SimpleDateFormat(dd-MM-yyyy)"/>
          <Date Name="LastFertilisationDate" format="$SimpleDateFormat(dd-MM-yyyy)"/>
          <String Name="HarvestingSeason"/>
          <Integer Name="NoOfPlants"/>
          <Double Name="VPD"/>
          <String Name="Live"/> <!-- Yes/No -->
          <Reference Name="LaneID" Type="Lane" Cardinality="1"/>
          <Reference Name="ZoneGrids"/>
    </DataModel>
  5. Lane - DataModel to hold Lane information. Defines Smart Reference to Zones.

    Code Block
    languagexml
    titleLane DataModel
    linenumberstrue
    <DataModel Name="Lane">
          <Sid Name="LaneID"/>
          <String Name="LaneName"/>
          <Double Name="LaneLength"/>
          <Double Name="LaneWidth"/>
          <Integer Name="ZoneInLane"/>
          <String Name="BorderLane"/>
          <BoundingBox Name="LaneLocation"/>
          <Reference Name="GreenhouseID" Type="Greenhouse" Cardinality="1"/>
          <Reference Name="LaneZones"/
    </DataModel>

Data + Things

We have to assign 1 temperature sensor per zone. We do this by:

  1. Use the content of MultipleSensors tutorial project and bring in all the model content into this tutorial.
  2. Use Simple Reference in TempSensorModel to a particular Zone using ZoneID
    Other sensors and actuators can be referenced in a similar fashion.
Code Block
languagexml
titleTempSensorModel with reference to Zone
linenumberstrue

...

<Def Name="

...

PeripheralParams">
      <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"/>
    </Def>

    <ThingFacet 

...

Name="

...

TempFacetSerial"

...

>

...


      

...

<String Name="SensorData" update="

...

auto" 

...

KnownBy="

...

SensorDataReadAction"/>
      <PeripheralParams Name="PerifParams"/>
      

...

<Action Name="

...

SensorDataReadAction"

...

>
        <Workflow 

...

Limit="1" Live="

...

1" 

...

Timeout="

...

-1"

...

>
          <Task 

...

name="Main" while="

...

true"

...

>
           

...

 <Event name="Argument" as="

...

ActionArgument"/>
            

...

<Invoke name="InvokeSerialRead" waitFor="Argument" get="perif://">
              <Message>
 

...

  

...

 

...

            <Value>
           

...

 

...

 

...

     <InterfacePort>
                   

...

 

...

"

...

[%:Event.Argument.PerifParams.InterfacePort.Value:%]"
                  

...

</InterfacePort>
                  <Baudrate>
         

...

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

...

                <Interface>
                    

...

"[%:Event.Argument.PerifParams.

...

Interface.Value:%]"

...


                  

...

</Interface>
          

...

        

...

<UniqueId>
                    

...

"[%:Event.Argument.PerifParams.

...

UniqueId.Value:%]"

...


                  </UniqueId>
                  

...

<Operation>
                    "[%:Event.Argument.PerifParams.Operation.Value:%]"
                  

...

</Operation>
                  <Peripheral>
                    

...

"[%:Event.Argument.

...

PerifParams.Peripheral.Value:%]"

...


                  </Peripheral>
                  <Payload>

...


                    "[%:Event.Argument.

...

PerifParams.Payload.Value:%]"
                  </Payload>
                  <Format>
                   

...

 "[%:Event.Argument.PerifParams.

...

Format.Value:%]"

...


                  </Format>
                </Value>
              

...

</Message>
            </

...

Invoke>
            <Output Name="Result" As="ActionResult">
         

...

     <Value>
                <SensorData>
  

...

 

...

 

...

              [%:Invoke.InvokeSerialRead.Message.Value/normalize-space(received):%]
              

...

  </SensorData>
              </Value>
            </Output>
  

...

        </Task>
        </Workflow>
      </Action>
    </ThingFacet>    
<ThingModel 

...

Name="TempSensor" combines="TempFacetSerial">
    <Sid Name="sensorId"/>
    <Reference Name="ZoneID" Type="Zone" 

...

Cardinality="1"/>
</ThingModel>

Queries

Let's start writing some queries to create and read the data. 

Create Grids

Code Block
languagexml
titleCreate Grid
linenumberstrue
<Query>
  <DeleteAll format="version,current">
    <Grid>
   

...

   <GridID ne=""/>
    </Grid>
  </DeleteAll>
  <Create>
    <Grid>
      <GridName>
 

...

       Intel-Grid
      </GridName>
      

...

<GridID>
  

...

      livegrid
      </GridID>
      <ZoneID>
        livezone
      </

...

ZoneID>
      <GridLength>
        1
      </

...

GridLength>
      <GridWidth>
     

...

 

...

 

...

 

...

1
     

...

 

...

</GridWidth>
     

...

 

...

Queries

Let's start writing some queries to create and read the data. 

Create Grids

...

languagexml
titleCreate Grid
linenumberstrue

...

<GridNSPosition>
        1
      </GridNSPosition>
      <GridWEPosition>
       2
      </GridWEPosition>
      <GridLocation>
        <Vertex1>
          1
        </Vertex1>
        <Vertex2>
          1
        </Vertex2>
        <Vertex3>
          1
        </Vertex3>
        <Vertex4>
          1
        </Vertex4>
      </GridLocation>
      <SoilMoisture>
        53
      </SoilMoisture>
      <AmbientLight>
        0
      </AmbientLight>
    </Grid>
  </Create>
</Query>

Create Zone

Code Block
languagexml
titleCreate Zone
linenumberstrue
<Query>
  <DeleteAll format="version,current">
    <Zone>
      <ZoneID ne = ""/>
    </Zone>
  </DeleteAll>
  <Create>
    <Zone>
      <ZoneID>
        livezone
      </ZoneID>
      <ZoneName>
        Intel-Zone
      </ZoneName>
      <LaneID>
        livelane
      </LaneID>
      <ZoneLength>
        1
      </ZoneLength>
      <ZoneWidth>
        1
      </ZoneWidth>
      <ZoneLocation>
        <Vertex1>
          1
        </Vertex1>
        <Vertex2>
          1
        </Vertex2>
        <Vertex3>
          1
        </Vertex3>
        <Vertex4>
          1
        </Vertex4>
      </ZoneLocation>
      <EndZone>
        endzone
      </EndZone>
      <GridOnLength>
        1
      </GridOnLength>
      <GridOnWidth>
        1
      </GridOnWidth>
      <GridCount>
        1
      </GridCount>
      <GridLength>
        1
      </GridLength>
      <GridWidth>
        1
      </GridWidth>
      <ZoneTemperature>
        26
      </ZoneTemperature>
      <ZoneHumidity>
        53
      </ZoneHumidity>
      <ZoneAvgSM>
        20
      </ZoneAvgSM>
      <ZoneAvgLight>
        2
      </ZoneAvgLight>
      <CropType>
        Apple
      </CropType>
      <SeedingDate>
        11-04-2016
      </SeedingDate>
      <LastFertilisationDate>
        14-04-2016
      </LastFertilisationDate>
      <HarvestingSeason>
        April
      </HarvestingSeason>
      <NoOfPlants>
        5
      </NoOfPlants>
      <VPD>
        0
      </VPD>
      <Location>
        <latitude>
          1.11
        </latitude>
        <longitude>
          1.12
        

...

</longitude>
      </

...

Location>
      

...

<Live>
        

...

yes
      </

...

Live>
    </Zone>
 

...

 

...

</Create>
</Query>

Create Lane

Code Block
languagexml
titleCreate Lane
linenumberstrue
<Query>
  <DeleteAll 

...

format="version,current">
    <Lane>
  

...

    <LaneID ne = 

...

""/>
    </Lane>
  </DeleteAll>

...

  <Create>
    

...

<Lane>
      

...

<LaneID>
        

...

livelane
      </

...

LaneID>
      

...

<GreenhouseID>
        

...

livegreenhouse
      </

...

GreenhouseID>
      

...

<LaneName>
        

...

lane-1
      </

...

LaneName>
      <LaneLength>
  

...

      5

...

   

...

   </

...

Create Zone

...

languagexml
titleCreate Zone
linenumberstrue

...

LaneLength>
    

...

  <LaneWidth>
  

...

      1

...

 

...

     </

...

LaneWidth>
      <ZoneInLane>
        4

...

   

...

   </ZoneInLane>
 

...

     <BorderLane>
 

...

       1
 

...

     </BorderLane>
 

...

     <BoundingBox>
 

...

       <Vertex1>
 

...

       

...

  5
    

...

    </Vertex1>
    

...

    <Vertex2>
  

...

       

...

 28
       

...

 </Vertex2>
     

...

   <Vertex3>
   

...

       105
 

...

       </

...

Vertex3>
      

...

  <Vertex4>
     

...

     38
 

...

       

...

</Vertex4>
      </BoundingBox>
 

...

   </Lane>
  </Create>
</

...

Query>

Create Greenhouse

Code Block
languagexml
titleCreate Greenhouse
linenumberstrue
<<Query>
  <DeleteAll format="version,current">
  

...

  <Greenhouse>
      

...

<GreenhouseID ne=""/>
    

...

</

...

Greenhouse>
  </DeleteAll>
  <Create>

...

    <Greenhouse>
    

...

  <GreenhouseID>
    

...

    livegreenhouse
  

...

    </GreenhouseID>
    

...

  <GreenhouseName>
   

...

     Intel-GreenHouse
 

...

     </

...

GreenhouseName>
  

...

Create Lane

...

languagexml
titleCreate Lane
linenumberstrue

...

    <BoundingBox>
     

...

   <Vertex1>
   

...

       0
 

...

       </

...

Vertex1>
        <Vertex2>
   

...

       0
 

...

       </

...

Vertex2>
        <Vertex3>
   

...

       110
 

...

       </

...

Vertex3>
        <Vertex4>
       

...

   40
   

...

     </

...

Vertex4>
     

...

Create Greenhouse

...

languagexml
titleCreate Greenhouse
linenumberstrue

...

 </BoundingBox>
   

...

 

...

  <LaneCount>
  

...

      3

...

 

...

     </

...

LaneCount>
      <LaneWidth>
       

...

 110
 

...

     

...

</LaneWidth>
      

...

<ZoneLength>
        

...

10
      </

...

ZoneLength>
      

...

<ZoneInLane>
        

...

5
      </

...

ZoneInLane>
      <ZoneCount>
  

...

      15
   

...

   </ZoneCount>
      <GHLength>

...

        110

...

      </GHLength>
  

...

    <GHWidth>
      

...

  40
      </

...

GHWidth>
      <ExternalEnv>
 

...

       <Temperature>
   

...

       26
 

...

       </Temperature>
 

...

       <Humidity>
   

...

       53
 

...

       </

...

Humidity>
     

...

   <Light>
     

...

     1
 

...

       

...

</Light>
        

...

<SoilMoisture>
      

...

    20
  

...

      </SoilMoisture>
  

...

      <Wind>

...

       

...

   

...

19.5
 

...

       </

...

Wind>
      

...

</ExternalEnv>
      <InternalEnv>
 

...

       

...

<Temperature>
   

...

       20
 

...

       </

...

Temperature>
      

...

  <Humidity>
      

...

    

...

53
 

...

       

...

</Humidity>
        

...

<Light>
          

...

1
        </

...

Light>
        

...

<SoilMoisture>
          

...

1
        </

...

SoilMoisture>
      </InternalEnv>
 

...

     

...

<GHLanes>
      

...

</

...

GHLanes>
      <SunnyDay>
  

...

      True
    

...

  </SunnyDay>
      

...

<Location>
        

...

<latitude>
          

...

37.

...

3718999
        </

...

latitude>
        

...

<longitude>
      

...

    -122.0022377
    

...

    </longitude>
      

...

</Location>
    </Greenhouse>
  </Create>
</

...

Query>

Initialize Temperature Sensor

TempSensorInZone value is the ZoneID value of the Zone.

Code Block
languagexml
titleCreate Temperature Sensor
linenumberstrue
<Query>
  <DeleteAll format="version,current">
    

...

<TempSensor>
      <sensorId ne=""/>
  

...

  </TempSensor>
  </DeleteAll>
  

...

<Save format="version,current">
    <!-- This will read 

...

-->
    <TempSensor>
     

...

 <PerifParams>
       

...

 <Peripheral>
       

...

   serial
       

...

 </Peripheral>
       

...

 <Baudrate>
     

...

     9600
 

...

       </

...

Baudrate>
      

...

  

...

<InterfacePort>
     

...

     /dev/cu.usbserial-A1025R0Y
 

...

       

...

</InterfacePort>
        

...

<Interface>
          

...

serial
        </

...

Interface>
        

...

<Format>
          

...

ascii
 

...

       </

...

Format>
        

...

<Operation>
  

...

 

...

Create Temperature Sensor

TempSensorInZone value is the ZoneID value of the Zone. This is dynamically assigned by querying the Zone Model.

...

languagexml
titleCreate Temperature Sensor
linenumberstrue

...

   

...

    receive

...

       

...

 

...

</Operation>
    

...

   

...

 <UniqueId>
 

...

     

...

    76522
  

...

 

...

     </

...

UniqueId>
    

...

   

...

 <Payload>
   

...

       

...

$Null()
        

...

</Payload>
      </

...

PerifParams>
      

...

<SensorData>
        

...

$Null()
      </

...

SensorData>
      <TempSensorInZone>
        

...

livezone
      </TempSensorInZone>
    </

...

TempSensor>
  </

...

Save>
</Query>

Find

...

Greenhouse

Code Block
languagexml
titleFind

...

Greenhouse
linenumberstrue
<Query>
  <Find nested="*

...

"

...

>
    

...

<Greenhouse>
      

...

<GreenhouseID ne=""

...

/>
    </

...

Greenhouse>
  </Find>
</Query>