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

...

Go to page

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>
      

...

<GridNSPosition>
        

...

1
      </

...

GridNSPosition>
      

...

<GridWEPosition>
       2

...

      

...

</

...

GridWEPosition>
      <GridLocation>
        

...

<Vertex1>
    

...

   

...

   

...

Create Zone

...

languagexml
titleCreate Zone
linenumberstrue

...

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>
    

...

   

...

Create Lane

...

languagexml
titleCreate Lane
linenumberstrue

...

 1
  

...

    </ZoneLength>

...

      <ZoneWidth>

...

        

...

1
      </

...

ZoneWidth>
      

...

<ZoneLocation>
        

...

<Vertex1>
      

...

    1
  

...

      </Vertex1>
  

...

      <Vertex2>

...

        

...

  1
        </

...

Vertex2>
      

...

  <Vertex3>

...

 

...

Create Greenhouse

...

languagexml
titleCreate Greenhouse
linenumberstrue

...

   

...

     

...

 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>
    

...

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

...

  <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
      </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>
      <BoundingBox>
        <Vertex1>
          0
        </Vertex1>
        <Vertex2>
          0
        </Vertex2>
        <Vertex3>
          110
        </Vertex3>
        <Vertex4>
          40
        </Vertex4>
      </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>
          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>