Versions Compared

Key

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

...

  • Create a new Project in TQLStudio by importing content from Baseline models.

Pipeline Macros

  • Execute Internal Query

 

Code Block
languagexml
titleGreenhouse DataModel and TypesPipeline Macros
linenumberstrue
<Def<Macro Name="EnvInfoexecuteQuery">
  <Argument>
   <Number Name="Temperature"/> <QueryString>
      <Number Name="Humidity"<Query/>
    </QueryString>
 <Number Name="Light"/>
</Argument>
  <Result>
     <Number Name="Pressure"/<OnRequest Target="[:RuntimeParams.FacetIDName:]" Disable="CMD_SERVER">
      <Number<Process NameReturn="SoilMoistureCMD_NOP"/>
      <Number Name="Wind"/> <Message>
     <String Name="LastUpdatedByProvider"/>
    </Def>

    <Def Name="BoundingBox     <Value>
            [:$Macro.Argument.QueryString:]
          </Value>
        </Message>
      </Process>
    </OnRequest>
  </Result>
</Macro>

 

Main CreateGreenhouse Macro

Code Block
languagexml
titleMain Create Greenhouse Macro
linenumberstrue
<Macro Name="CreateGreenhouse">

  <Argument>

    <Greenhouses></Greenhouses>

  </Argument>

  <Result>

    <SetLocalData key="Greenhouses">

      <Value>

        <Include>$Macro.Argument.Greenhouses</Include>

      </Value>

    </SetLocalData>

    <for each="record" in="Greenhouse" from="$LocalData.Greenhouses" using="$ProcessData">

       <JavaScript>

        var NumberOfLanes = [:$ProcessData.record.NumberOfLanes:];

        var ZonesPerLane = [:$ProcessData.record.ZonesPerLane:];

        var NumberOfZones = NumberOfLanes * ZonesPerLane;

        sffContext.execute("SetLocalData","key","NumberOfZones","value",NumberOfZones);

       </JavaScript>

      <executeQuery>

        <QueryString>

          <Query>

            <Create>

              <Greenhouse>

              	<GreenhouseName>[:$ProcessData.record.GreenHouseName:]</GreenhouseName>

                <BoundingBox>

                  <Vertex1>0</Vertex1>

                  <Vertex2>0</Vertex2>

                  <Vertex3>110</Vertex3>

                  <Vertex4>40</Vertex4>

                </BoundingBox>

                <LaneCount>

                  [:$ProcessData.record.NumberOfLanes:]

                </LaneCount>

                <LaneWidth>110</LaneWidth>

                <ZoneLength>10</ZoneLength>

                <ZoneInLane>

                  [:$ProcessData.record.ZonesPerLane:]

                </ZoneInLane>

                <ZoneCount>[:$LocalData.NumberOfZones:]</ZoneCount>

                <GHLength>110</GHLength>

                <GHWidth>40</GHWidth>

                <ExternalEnv>

                  <Temperature>1</Temperature>

                  <Humidity>1</Humidity>

                  <Light>1</Light>

                  <SoilMoisture>1</SoilMoisture>

                  <Wind>19.5</Wind>

                </ExternalEnv>

                <InternalEnv>

                  <Temperature>1</Temperature>

                  <Humidity>1</Humidity>

                  <Light>1</Light>

                  <SoilMoisture>1</SoilMoisture>

                </InternalEnv>

                <GHLanes></GHLanes>

                <SunnyDay>True</SunnyDay>

                <Location>

              	  <latitude> [:$ProcessData.record.Location.latitude:] </latitude>

              	  <longitude> [:$ProcessData.record.Location.longitude:] </longitude>

                </Location>

              </Greenhouse>

            </Create>

          </Query>

        </QueryString>

      </executeQuery>

      <if condition="$Response.Message.Value/Create/Status eq 'Success'">

        <then>

          <SetContextData key="GreenhouseID">

            <Value>[:$Response.Message.Value.Create.Greenhouse.GreenhouseID:]</Value>

          </SetContextData>

          <executeQuery>

            <QueryString>

              <Query>

                <Save format="version,current">

                  <ExtTempSensor>

                    <peripheral>

                      serial

                    </peripheral>

                    <baudrate>

                      115200

                    </baudrate>

                    <interfacePort>

                      /dev/cu.usbserial-AH02V4BU

                    </interfacePort>

                    <interface>

                      serial

                    </interface>

                    <format>

                      ascii

                    </format>

                    <operation>

                      receive

                    </operation>

                    <uniqueId>

                      76522

                    </uniqueId>

                    <avgMonthHighTemp>

                    </avgMonthHighTemp>

                    <avgMonthLowTemp>

                    </avgMonthLowTemp>

                    <TempValue>

                    </TempValue>

                    <SensingInterval>

                      3600

                    </SensingInterval>

                  </ExtTempSensor>

                </Save>

                <Save format="version,current">

                  <ExtHumiditySensor>

                    <peripheral>

                      serial

                    </peripheral>

                    <baudrate>

                      115200

                    </baudrate>

                    <interfacePort>

                      /dev/cu.usbserial-AH02V4BU

                    </interfacePort>

                    <interface>

                      serial

                    </interface>

                    <format>

                      ascii

                    </format>

                    <operation>

                      receive

                    </operation>

                    <uniqueId>

                      76522

                    </uniqueId>

                    <avgMonthHighTemp>

                    </avgMonthHighTemp>

                    <avgMonthLowTemp>

                    </avgMonthLowTemp>

                    <HumidityValue>

                    </HumidityValue>

                  </ExtHumiditySensor>

                </Save>

                <Save format="version,current">

     <GeoLocation Name="Vertex1"/>       <GeoLocation Name="Vertex2"/>    <ExtLightSensor>

 <GeoLocation Name="Vertex3"/>       <GeoLocation Name="Vertex4"/>     </Def>     <peripheral>
<Def
Name="GeoLocation">       <Number Name="latitude"/>       <Number Name="longitude"/>     </Def> serial

   <DataModel Name="Greenhouse">       <Sid Name="GreenhouseID"/>       <String Name="GreenhouseName"/></peripheral>

        <GeoLocation Name="Location"/>       <String Name="LocationName"/>   <baudrate>

  <BoundingBox Name="Boundary"/>       <Integer Name="LaneCount"/>       <Double Name="LaneWidth"/>   115200

  <Double Name="ZoneLength"/>       <Integer Name="ZoneInLane"/>       <Integer Name="ZoneCount"/>  </baudrate>

       <Double Name="GHLength"/>       <Double Name="GHWidth"/>    <interfacePort>

 <EnvInfo Name="ExternalEnv"/>       <EnvInfo Name="InternalEnv"/>       <String Name="VentOnOffState"/>    /dev/cu.usbserial-AH02V4BU

 <String Name="FansOnOffState"/>       <Boolean Name="SunnyDay"/>       <Boolean Name="Running" default="false"/> <!-- true / false -->/interfacePort>

      </DataModel>      <ThingModel Name="Heater">       <Sid Name="HeaterID"/><interface>

      <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"> serial

<Argument>     <QueryString>       <Query/>     </QueryString>   </Argument>interface>

 <Result>     <OnRequest Target="[:RuntimeParams.FacetIDName:]" Disable="CMD_SERVER">       <Process Return="CMD_NOP">    <format>

   <Message>           <Value>        ascii

   [:$Macro.Argument.QueryString:]           </Value>
        </Message>format>

     </Process>     </OnRequest>   </Result> </Macro>   <Macro Name="DeleteScheduleJob">  <operation>
<Argument>
    <JobName/>   </Argument>   <Result>     <DoRequest target="[:RuntimeParams.SequenceFacetIDName:]">        receive

<Process>         <Message type="xml">          </operation>
<Value>
            <Remove eid="[:$Macro.Argument.JobName:]"/>       <uniqueId>

  </Value>         </Message>       </Process>    76522
</DoRequest>
   </Result> </Macro>  <Macro Name="ScheduleJob">   <Argument>     <ScheduleInterval>     </ScheduleInterval>uniqueId>

      <StartTime>       0     </StartTime>  <Intensity>

 <EndTime>     </EndTime>     <ActionCode>     </ActionCode>     <Name> $Null()

  </Name>   </Argument>   <Result>     <Log Message="Inside ScheduleJob macro"/>    </Intensity>
<DoRequest
target="[:RuntimeParams.SequenceFacetIDName:]">       <Process>         <Message>    <HourMeanLight>

     <Value>             <Execute eid="[:$Macro.Argument.Name:]" schedule="[[:$Macro.Argument.StartTime:]..[:$Macro.Argument.EndTime:]/[:$Macro.Argument.ScheduleInterval:]]"> </HourMeanLight>

             <Action>       <LightValue>

        <ExecuteQuery>            </LightValue>

     <QueryString>             </ExtLightSensor>

      [:$Macro.Argument.ActionCode:]          </Save>

       </QueryString>         <Save format="version,current">

     </ExecuteQuery>             <GHTempSensor>

</Action>             </Execute>       <GreenhouseID>

  </Value>         </Message>       </Process>     </DoRequest>
  </Result>
</Macro>	

 

Macro to Simulate Sensor

Code Block
languagexml
titleSimulate Sensor Logic
linenumberstrue
<Macro Name="SetGHCurrentTemp">[:$ContextData.GreenhouseID:]

           <Argument>         <TempSensorId><</TempSensorId>GreenhouseID>

       <GreenhouseID></GreenhouseID>       </Argument>      <peripheral>
<Result>
        <Log Message="*********Calculating Temperature..."/>         <executeQuery>   serial

      <QueryString>             <Query> </peripheral>

            <Find>        <baudrate>

       <Greenhouse>               115200
   <GreenhouseID>[:$Macro.Argument.GreenhouseID:]</GreenhouseID>                 </Greenhouse>baudrate>
                    <interfacePort>
 </Find>             </Query>         /dev/cu.usbserial-AH02V4BU
 </QueryString>         </executeQuery>         <if condition="$Response.Message.Value/Find/Status eq 'Success'"> </interfacePort>
            <then>        <interface>
    <SetLocalData key="CurrentTemp">               <Value>[:$Response.Message.Value.Find.Result.Greenhouse.ExternalEnv.Temperature:]</Value>  serial
          </SetLocalData>          </interface>
  <SetLocalData key="GHCurrentTemp">               <Value>[:$Response.Message.Value.Find.Result.Greenhouse.InternalEnv.Temperature:]</Value>     <format>
              </SetLocalData>        ascii
    <SetLocalData key="Vent">               <Value>[:$Response.Message.Value.Find.Result.Greenhouse.VentOnOffState:]</Value>format>
             </SetLocalData>       <operation>
     <SetLocalData key="Fans">               <Value>[:$Response.Message.Value.Find.Result.Greenhouse.FansOnOffState:]</Value>
 receive
           </SetLocalData>         </operation>
   <SetLocalData key="SunnyDay">                  <Value>[:$Response.Message.Value.Find.Result.Greenhouse.SunnyDay:]</Value><uniqueId>
             </SetLocalData>         76522
   <executeQuery>               <QueryString>  </uniqueId>
              <Query>      <avgMonthHighTemp>
            <Find>        </avgMonthHighTemp>
            <Heater>        <avgMonthLowTemp>
              <OnOffState eq='On'/>     </avgMonthLowTemp>
               </Heater>     <TempValue>
             </Find>       </TempValue>
         </Query>           <SensingInterval>
   </QueryString>             </executeQuery>      3600
       <Javascript>             </SensingInterval>
 <resp>                 <Include>$Response.Message.Value</Include></GHTempSensor>
                </resp>Save>

               var resultList<Save format= resp.Find;"version,current">
                  <GHHumiditySensor>
  var heaterLevels = [];               var<GreenhouseID>
heaterLevelsSum = 0;               for each (var result in resultList.iterEntries("Result")){[:$ContextData.GreenhouseID:]
              var heaters =    </GreenhouseID>
          result.getValue();           <peripheral>
   heaterLevels.push(heaters.Heater.HeatingLevel);               heaterLevelsSum = heaterLevelsSum + heaters.Heater.HeatingLevel; serial
               }     </peripheral>
         var GHTempAdj =         <baudrate>
     0;                if([:$LocalData.SunnyDay:]){
 115200
             GHTempAdj = Math.pow((100/([:$LocalData.CurrentTemp:]+237.1)), 3) * 100;  </baudrate>
            }else{        <interfacePort>
      GHTempAdj =               Math.pow((100/([:$LocalData.CurrentTemp:]+237.1)), 3) * 60;/dev/cu.usbserial-AH02V4BU
                     }</interfacePort>
                  var GHBaseTemp = [:$LocalData.CurrentTemp:] + GHTempAdj;<interface>
                 var TempVentImp =   serial
           ([:$LocalData.CurrentTemp:] - [:$LocalData.GHCurrentTemp:]) * 0.03;     </interface>
         var HeaterEffectRatio = heaterLevelsSum / 90;      <format>
        var TempHeaterImp =            ascii
  HeaterEffectRatio * (Math.sqrt(Math.max(0,(45-[:$LocalData.GHCurrentTemp:]))));                 </format>
     var GHCurrentTemp = GHBaseTemp + TempVentImp + TempHeaterImp;        <operation>
      sffContext.execute("SetContextData","key","GHCurrentTemp","value",GHCurrentTemp);             </Javascript>   receive
          <executeQuery>          </operation>
    <QueryString>                <uniqueId>
<Query>                   <Find format="Version">  76522
                  <TempSensor>  </uniqueId>
                    <sensorId>[:$Macro.Argument.TempSensorId:]</sensorId><HumidityValue>
                    </TempSensor>  0
                </Find>    </HumidityValue>
              <SetResponseData>    </GHHumiditySensor>
                <Key>Message.Value.Find.Result.TempSensor.TempValue.Value</Key></Save>
              </Query>
     <Value>[:$ContextData.GHCurrentTemp:]</Value>       </QueryString>
           </SetResponseData>executeQuery>
          <SetContextData key="FirstLane">
      <Save>      <Value>Yes</Value>
          </SetContextData>
   <from>Result</from>       <For each="laneRecord" in="Lane"   from="$ProcessData.record.Lanes" using="$LocalData">
        <Include>$Response.Message.Value.Find</Include>    <addLanes>
              <GreenhouseID>[:$ContextData.GreenhouseID:]</Save>GreenhouseID>
                <LaneName>[:$LocalData.laneRecord.LaneName:]</Query>LaneName>
              <<LaneLength>110</QueryString>LaneLength>
            </executeQuery>  <LaneWidth>40</LaneWidth>
           <executeQuery>   <ZoneInLane>[:$ProcessData.record.ZonesPerLane:]</ZoneInLane>
           <QueryString>   <BorderLane>No</BorderLane>
            </addLanes>
<Query>                   <Find format="Version">
      <if condition="$Response.Message.Value/Create/Status eq 'Success'">
             <Greenhouse> <then>
                <SetLocalData key="LaneID">
   <GreenhouseID>[:$Macro.Argument.GreenhouseID:]</GreenhouseID>                     </Greenhouse>
<Value>[:$Response.Message.Value.Create.Lane.LaneID:]</Value>
                 </Find>SetLocalData>
                <loadZoneModels>
 <SetResponseData>                     <Key>Message.Value.Find.Result.Greenhouse.InternalEnv.Temperature.Value</Key>
 <LaneID>[:$LocalData.LaneID:]</LaneID>
                  <Value><ZonesPerLane>[:$ContextData$ProcessData.record.GHCurrentTempZonesPerLane:]</Value>ZonesPerLane>
                  <CropType>[:$LocalData.laneRecord.CropType:]</SetResponseData>CropType>
                  <Save><FirstLane>[:$ContextData.FirstLane:]</FirstLane>
                    <from>Result</from></loadZoneModels>
              </then>
     <Include>$Response.Message.Value.Find</Include>       </if>
           </Save> <SetContextData key="FirstLane">
              <<Value>No</Query>
 Value>
            </QueryString>SetContextData>
            </executeQuery>
 For>
        </then>
 
      </if>
    </for>
  </Result>
   
</Macro>	

Add Action to Start Simulate

...