...
Code Block |
---|
language | xml |
---|
title | Greenhouse DataModel and Types |
---|
linenumbers | true |
---|
|
<Def Name="GeoLocationEnvInfo">
<Number Name="latitudeTemperature"/>
<Number Name="longitudeHumidity"/>
</Def> |
Pipeline Macros
- Execute Internal Query
- Schedule and UnSchedule TQL Code
Code Block |
---|
language | xml |
---|
title | Pipeline Macros |
---|
linenumbers | true |
---|
|
<Def
<Number Name="GeoLocationLight"/>
<Number Name="latitudePressure"/>
<Number Name="longitudeSoilMoisture"/>
</Def> |
Macro to Simulate Sensor
Code Block |
---|
language | xml |
---|
title | Greenhouse DataModel |
---|
linenumbers | true |
---|
|
<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 |
---|
language | xml |
---|
title | Create Grid |
---|
linenumbers | true |
---|
|
<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 |
---|
language | xml |
---|
title | Pipeline Macros |
---|
linenumbers | true |
---|
|
<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 |
---|
language | xml |
---|
title | Simulate Sensor Logic |
---|
linenumbers | true |
---|
|
<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 |
---|
language | xml |
---|
title | Create Zone |
---|
linenumbers | true |
---|
|
<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
Code Block |
---|
language | xml |
---|
title | Create Lane |
---|
linenumbers | true |
---|
| <Query>
<Create>
<Lane>Greenhouse | linenumbers | true |
---|
|
<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 |
---|
language | xml |
---|
title | Create Greenhouse |
---|
linenumbers | true |
---|
|
<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 |
---|
language | xml |
---|
title | Create Temperature SensorZone |
---|
linenumbers | true |
---|
|
<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 |
---|
language | xml |
---|
title | Create Lane |
---|
linenumbers | true |
---|
|
<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 |
---|
language | xml |
---|
title | Find Temperature |
---|
linenumbers | true |
---|
|
<Query> <Find nested="*" format="Version"> </BorderLane>
<TempSensorModel> <LaneZones>
<TempSensorId ne="" </>LaneZones>
</TempSensorModel>Lane>
</Find>Create>
</Query> |