Versions Compared

Key

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

...

Code Block
languagexml
titleGreenhouse DataModel and Types
linenumberstrue
<Def Name="GeoLocationEnvInfo">
  <Number Name="latitudeTemperature"/>
  <Number Name="longitudeHumidity"/>
</Def>	

Pipeline Macros

  • Execute Internal Query
  • Schedule and UnSchedule TQL Code

 

Code Block
languagexml
titlePipeline Macros
linenumberstrue
<Def
  <Number Name="GeoLocationLight"/>
  <Number Name="latitudePressure"/>
  <Number Name="longitudeSoilMoisture"/>
</Def>	

 

Macro to Simulate Sensor

Code Block
languagexml
titleGreenhouse DataModel
linenumberstrue
  <Number Name="Wind"/>
  <String Name="LastUpdatedByProvider"/>
</Def>

<Def Name="GeoLocationBoundingBox">
  <Number<GeoLocation Name="latitudeVertex1"/>
  <Number<GeoLocation Name="longitudeVertex2"/>
</Def>	

Queries

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

Create Grids

Code Block
languagexml
titleCreate Grid
linenumberstrue
<Query>
  <Find>
    <Zone>
      <ZoneName eq="Zone1"/>
    </Zone>
  </Find>
  <Create>
    <Grid>
      <GridName>
        Grid1
      </GridName>
      <GridNSPosition>  <GeoLocation Name="Vertex3"/>
  <GeoLocation Name="Vertex4"/>
</Def>

<Def Name="GeoLocation">
  <Number Name="latitude"/>
  <Number Name="longitude"/>
</Def>
<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 -->
</DataModel>
<ThingModel Name="Heater">
  <Sid Name="HeaterID"/>
  <String Name="OnOffState"/>
  <Integer Name="HeatingLevel"/>
</ThingModel>	

Pipeline Macros

  • Execute Internal Query
  • Schedule and UnSchedule TQL Code

 

Code Block
languagexml
titlePipeline Macros
linenumberstrue
<Macro Name="executeQuery">
  <Argument>
    <QueryString>
      <Query/>
    </QueryString>
  </Argument>
  <Result>
    <OnRequest Target="[:RuntimeParams.FacetIDName:]" Disable="CMD_SERVER">
      <Process Return="CMD_NOP">
        <Message>
          <Value>
            [:$Macro.Argument.QueryString:]
          </Value>
        </Message>
      </Process>
    </OnRequest>
  </Result>
</Macro>


<Macro Name="DeleteScheduleJob">
  <Argument>
    <JobName/>
  </Argument>
  <Result>
    <DoRequest target="[:RuntimeParams.SequenceFacetIDName:]">
      <Process>
        <Message type="xml">
          <Value>
            <Remove eid="[:$Macro.Argument.JobName:]"/>
          </Value>
        </Message>
      </Process>
    </DoRequest>
  </Result>
</Macro>

<Macro Name="ScheduleJob">
  <Argument>
    <ScheduleInterval>
    </ScheduleInterval>
    <StartTime>
      0
    </StartTime>
    <EndTime>
    </EndTime>
    <ActionCode>
    </ActionCode>
    <Name>
    </Name>
  </Argument>
  <Result>
    <Log Message="Inside ScheduleJob macro"/>
    <DoRequest target="[:RuntimeParams.SequenceFacetIDName:]">
      <Process>
        <Message>
          <Value>
            <Execute eid="[:$Macro.Argument.Name:]" schedule="[[:$Macro.Argument.StartTime:]..[:$Macro.Argument.EndTime:]/[:$Macro.Argument.ScheduleInterval:]]">
              <Action>
                <ExecuteQuery>
                  <QueryString>
                    [:$Macro.Argument.ActionCode:]
                  </QueryString>
                </ExecuteQuery>
              </Action>
            </Execute>
          </Value>
        </Message>
      </Process>
    </DoRequest>
  </Result>
</Macro>	

 

Macro to Simulate Sensor

Code Block
languagexml
titleSimulate Sensor Logic
linenumberstrue
<Macro Name="SetGHCurrentTemp">
  <Argument>
    <TempSensorId></TempSensorId>
    <GreenhouseID></GreenhouseID>
  </Argument>
  <Result>
    <executeQuery>
      <QueryString>
        <Query>
          <Find>
            <Greenhouse>
              <GreenhouseID>[:$Macro.Argument.GreenhouseID:]</GreenhouseID>
            </Greenhouse>
          </Find>
        </Query>
      </QueryString>
    </executeQuery>

    <if condition="$Response.Message.Value/Find/Status eq 'Success'">
      <then>
        <SetLocalData key="CurrentTemp">
          <Value>[:$Response.Message.Value.Find.Result.Greenhouse.ExternalEnv.Temperature:]</Value>
        </SetLocalData>

        <SetLocalData key="GHCurrentTemp">
          <Value>[:$Response.Message.Value.Find.Result.Greenhouse.InternalEnv.Temperature:]</Value>
        </SetLocalData>

        <SetLocalData key="Vent">
          <Value>[:$Response.Message.Value.Find.Result.Greenhouse.VentOnOffState:]</Value>
        </SetLocalData>

        <SetLocalData key="Fans">
          <Value>[:$Response.Message.Value.Find.Result.Greenhouse.FansOnOffState:]</Value>
        </SetLocalData>

        <SetLocalData key="SunnyDay">
          <Value>[:$Response.Message.Value.Find.Result.Greenhouse.SunnyDay:]</Value>
        </SetLocalData>

        <executeQuery>
          <QueryString>
            <Query>
              <Find>
                <Heater>
                  <ZoneID ne=''/>
                  <OnOffState eq='On'/>
                </Heater>
              </Find>
            </Query>
          </QueryString>
        </executeQuery>

        <Javascript>
          <resp>
            <Include>$Response.Message.Value</Include>
          </resp>
          var resultList = resp.Find;
          var heaterLevels = [];
          var heaterLevelsSum = 0;
          for each (var result in resultList.iterEntries("Result")){
          var heaters = result.getValue();
          heaterLevels.push(heaters.Heater.HeatingLevel);
          heaterLevelsSum = heaterLevelsSum + heaters.Heater.HeatingLevel;
          }
          var GHTempAdj =0;
          if([:$LocalData.SunnyDay:]){
          GHTempAdj = Math.pow((100/([:$LocalData.CurrentTemp:]+237.1)), 3) * 100;
          }else{
          GHTempAdj =
          Math.pow((100/([:$LocalData.CurrentTemp:]+237.1)), 3) * 60;
          }
          var GHBaseTemp = [:$LocalData.CurrentTemp:] + GHTempAdj;
          var TempVentImp =
          ([:$LocalData.CurrentTemp:] - [:$LocalData.GHCurrentTemp:]) * 0.03;
          var HeaterEffectRatio = heaterLevelsSum / 90;
          var TempHeaterImp =
          HeaterEffectRatio * (Math.sqrt(Math.max(0,(45-[:$LocalData.GHCurrentTemp:]))));
          var GHCurrentTemp = GHBaseTemp + TempVentImp + TempHeaterImp;
          sffContext.execute("SetContextData","key","GHCurrentTemp","value",GHCurrentTemp);
        </Javascript>
        <executeQuery>
          <QueryString>
            <Query>
              <Find format="Version">
                <TempSensor>
                  <sensorId>[:$Macro.Argument.TempSensorId:]</sensorId>
                </TempSensor>
              </Find>
              <SetResponseData>
         1       </GridNSPosition><Key>Message.Value.Find.Result.TempSensor.TempValue.Value</Key>
          <GridWEPosition>      <Value>[:$ContextData.GHCurrentTemp:]</Value>
  1       </GridWEPosition>     </SetResponseData>
 <GridLength>         3.33    <Save>
  </GridLength>       <GridWidth>       <from>Result</from>
 3.33       </GridWidth>       <SoilMoisture>
 <Include>$Response.Message.Value.Find</Include>
       0       </SoilMoisture>Save>
       <AmbientLight>     </Query>
   0       </AmbientLight>QueryString>
        <ZoneGrid>[:$Response.Message.Value.Find.Result.Zone.ZoneID:]</ZoneGrid></executeQuery>

        <executeQuery>
        </Grid>  <QueryString>
</Create>   </Query>

Create Zone

Code Block
languagexml
titleCreate Zone
linenumberstrue
<Query>   <DeleteAll>     <Zone> <Query>
     <ZoneID ne=""/>     </Zone>   </DeleteAll>
<Find format="Version">
 <Create>     <Zone>       <ZoneWidth>   <Greenhouse>
     10       </ZoneWidth>       <ZoneLength><GreenhouseID>[:$Macro.Argument.GreenhouseID:]</GreenhouseID>
         10       </ZoneLength>Greenhouse>
      <GridOnLength>        </Find>
3        </GridOnLength>      <SetResponseData>
<GridOnWidth>         3       </GridOnWidth><Key>Message.Value.Find.Result.Greenhouse.InternalEnv.Temperature.Value</Key>
      <GridCount>         9
      </GridCount> <Value>[:$ContextData.GHCurrentTemp:]</Value>
      <GridLength>         3.33</SetResponseData>
        </GridLength>      <Save>
<GridWidth>         3.33       <<from>Result</GridWidth>from>
      <EndZone>         No
 <Include>$Response.Message.Value.Find</Include>
     </EndZone>       <ZoneTemperature>   </Save>
     0       </ZoneTemperature>
Query>
     <ZoneHumidity>       </QueryString>
 0       </ZoneHumidity>executeQuery>
      <CropType>Tomato<</CropType>then>
    </Zone>if>
  </Create>Result>
</Query>Macro>	

Queries

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

Create

...

Greenhouse

<Query> <Create> <Lane>
Code Block
languagexml
titleCreate Lane
linenumberstrue
Greenhouse
linenumberstrue
<Query>
  <Create>
   <LaneWidth> <Greenhouse>
       110
      </LaneWidth><GreenhouseName>Khan Farmhouse</GreenhouseName>
      <ZoneInLane><BoundingBox>
        10
      </ZoneInLane>
      <BorderLane>
        Yes
      </BorderLane><Vertex1>0</Vertex1>
        <Vertex2>0</Vertex2>
 <LaneZones>       <<Vertex3>110</LaneZones>Vertex3>
    </Lane>   </Create> </Query>

Create Greenhouse

Code Block
languagexml
titleCreate Greenhouse
linenumberstrue
<Query><Vertex4>40</Vertex4>
  <Create>    </BoundingBox>
<Greenhouse>       <LaneCount>
        3
      </LaneCount>
      <LaneWidth>110</LaneWidth>
  <LaneWidth>    <ZoneLength>10</ZoneLength>
    110  <ZoneInLane>
      </LaneWidth>  10
    <ZoneLength>  </ZoneInLane>
      10<ZoneCount>3</ZoneCount>
      <<GHLength>110</ZoneLength>GHLength>
      <ZoneInLane><GHWidth>40</GHWidth>
      <ExternalEnv>
 10       <<Temperature>1</ZoneInLane>Temperature>
      <ZoneCount>  <Humidity>1</Humidity>
      90  <Light>1</Light>
    </ZoneCount>    <SoilMoisture>1</SoilMoisture>
  <ExtEnvInfo>      <Wind>19.5</Wind>
  <Temperature>    </ExternalEnv>
      0<InternalEnv>
        <<Temperature>1</Temperature>
        <Humidity><Humidity>1</Humidity>
          0<Light>1</Light>
        <<SoilMoisture>1</Humidity>SoilMoisture>
      </InternalEnv>
  <Light>    <SunnyDay>True</SunnyDay>
      0<Location>
        </Light><latitude>-122.1</latitude>
        <<longitude>32.0</ExtEnvInfo>longitude>
      <GHLanes><</GHLanes>Location>
    </Greenhouse>
  </Create>
</Query>

Create Temperature Sensor

...

Start / Stop Simulation

Code Block
languagexml
titleCreate Temperature SensorZone
linenumberstrue
<Query>
  <Find format="Version">
  <DeleteAll>  <GHTempSensor>
      <TempSensorModel><GreenhouseID>[:$Macro.Argument.GreenhouseID:]</GreenhouseID>
    </GHTempSensor>
  <TempSensorId ne=""/</Find>
  <SetResponseData key="Message.Value.Find.Result.GHTempSensor.simulated.value">
    <<Value>True</TempSensorModel>Value>
  </DeleteAll>SetResponseData>
  <Find><Save>
    <Zone><from>Result</from>
    <Include>$Response.Message.Value.Find</Include>
 <ZoneName eq="Zone1"/>
    </Zone>
  </Find></Save>
</Query>

Find Greenhouse / TempSensor

Code Block
languagexml
titleCreate Lane
linenumberstrue
<Query>
  <Create>
    <TempSensorModel><Lane>
      <TempValueInC><LaneWidth>
        0110
      </TempValueInC>LaneWidth>
      <TempValueInF><ZoneInLane>
        010
      </TempValueInF>ZoneInLane>
      <TempSensorInZone>
 <BorderLane>
      [:$Response.Message.Value.Find.Result.Zone.ZoneID:]
      </TempSensorInZone>
    </TempSensorModel>  Yes
</Create> </Query>

Find Temperature above x degree C

Code Block
languagexml
titleFind Temperature
linenumberstrue
<Query>   <Find nested="*" format="Version"> </BorderLane>
    <TempSensorModel>  <LaneZones>
    <TempSensorId ne="" </>LaneZones>
    </TempSensorModel>Lane>
  </Find>Create>
</Query>