...
Code Block |
---|
language | xml |
---|
title | Main Create Greenhouse Macro |
---|
linenumbers | true |
---|
|
<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> <!-- Create Query for Greenhouse -->
<QueryString> <SetContextData key="FirstLane">
<Query> <Value>Yes</Value>
<Create> </SetContextData>
<For <Greenhouse>
each="laneRecord" in="Lane" from="$ProcessData.record.Lanes" using="$LocalData">
<GreenhouseName>[:$ProcessData.record.GreenHouseName:]</GreenhouseName>
<!-- Add Lanes -->
<addLanes>
<BoundingBox> <GreenhouseID>[:$ContextData.GreenhouseID:]</GreenhouseID>
<Vertex1>0</Vertex1> <LaneName>[:$LocalData.laneRecord.LaneName:]</LaneName>
<Vertex2>0<<LaneLength>110</Vertex2>LaneLength>
<LaneWidth>40</LaneWidth>
<Vertex3>110</Vertex3> <ZoneInLane>[:$ProcessData.record.ZonesPerLane:]</ZoneInLane>
<Vertex4>40</Vertex4> <BorderLane>No</BorderLane>
</BoundingBox>addLanes>
<if condition="$Response.Message.Value/Create/Status eq 'Success'">
<LaneCount> <then>
[:$ProcessData.record.NumberOfLanes:] <SetLocalData key="LaneID">
</LaneCount> <LaneWidth>110</LaneWidth><Value>[:$Response.Message.Value.Create.Lane.LaneID:]</Value>
<ZoneLength>10<</ZoneLength>SetLocalData>
<loadZoneModels>
<ZoneInLane> <LaneID>[:$ProcessData$LocalData.record.ZonesPerLaneLaneID:]</LaneID>
<ZonesPerLane>[:$ProcessData.record.ZonesPerLane:]</ZoneInLane>ZonesPerLane>
<ZoneCount><CropType>[:$LocalData.NumberOfZoneslaneRecord.CropType:]</ZoneCount>CropType>
<GHLength>110</GHLength><FirstLane>[:$ContextData.FirstLane:]</FirstLane>
<GHWidth>40<</GHWidth>loadZoneModels>
</then>
<ExternalEnv> </if>
<Temperature>1</Temperature> <SetContextData key="FirstLane">
<Humidity>1<<Value>No</Humidity>Value>
<Light>1</Light></SetContextData>
</For>
<SoilMoisture>1<</SoilMoisture>then>
</if>
</for>
<Wind>19.5</Wind></Result>
</Macro> |
Load Zone Models
Data is randomized and generated
Code Block |
---|
language | xml |
---|
title | Load Zone Models |
---|
linenumbers | true |
---|
|
<Macro Name="loadZoneModels">
<Argument>
<ZonesPerLane></ZonesPerLane>
<<LaneID></ExternalEnv>LaneID>
<CropType></CropType>
<InternalEnv>
<FirstLane></FirstLane>
</Argument>
<Result>
<JavaScript>
<Temperature>1</Temperature> var ZonesPerLane = 0;
<Humidity>1</Humidity>if(!isNaN([:$Macro.Argument.ZonesPerLane:])){
ZonesPerLane = <Light>1</Light>[:$Macro.Argument.ZonesPerLane:];
}
<SoilMoisture>1</SoilMoisture>
var loadContent = ListMap.static.newInstance();
for (var row=1; row <= ZonesPerLane; </InternalEnv>row++) {
var svi = loadContent.instanceAdd("addZone");
<GHLanes></GHLanes> svi.put("ZoneName", "Zone"+row);
svi.put("LaneID", "[:$Macro.Argument.LaneID:]");
svi.put("ZoneLength", 10);
<SunnyDay>True</SunnyDay> svi.put("ZoneWidth", 10);
svi.put("Vertex1", 5);
<Location> svi.put("Vertex2", 2);
<latitude> [:$ProcessData.record.Location.latitude:] </latitude> svi.put("Vertex3", 15);
svi.put("Vertex4", 12);
<longitude> [:$ProcessData.record.Location.longitude:] </longitude> svi.put("EndZone", "No");
</Location>svi.put("ZoneAvgSM", 45);
</Greenhouse>
svi.put("CropType", "[:$Macro.Argument.CropType:]");
</Create> </Query>if("[:$Macro.Argument.FirstLane:]" == "Yes" && row==1){
</QueryString> </executeQuery> svi.put("Live", "Yes");
<if condition="$Response.Message.Value/Create/Status eq 'Success'"> <then> }else{
<SetContextData key="GreenhouseID"> svi.put("Live", "No");
<Value>[:$Response.Message.Value.Create.Greenhouse.GreenhouseID:]</Value> </SetContextData> }
svi.put("GridOnLength", 3);
<executeQuery> svi.put("GridOnWidth", 3);
svi.put("GridCount", 9);
<QueryString> svi.put("GridLength", 3.33);
svi.put("GridWidth", 3.33);
<Query> svi.put("ZoneTemperature", "0");
<Save format="version,current"> svi.put("ZoneHumidity", "0");
<ExtTempSensor>
svi.put("ZoneAvgLight", "0");
svi.put("NoOfPlants", Math.floor((Math.random() * 100) <peripheral>+ 1));
}
sffLog.info("load Zone Content ======== "+loadContent);
serial loadContent;
</JavaScript>
</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">
<ExtLightSensor>
<peripheral>
serial
</peripheral>
<baudrate>
115200
</baudrate>
<interfacePort>
/dev/cu.usbserial-AH02V4BU
</interfacePort>
<interface>
serial
</interface>
<format>
ascii
</format>
<operation>
receive
</operation>
<uniqueId>
76522
</uniqueId>
<Intensity>
$Null()
</Intensity>
<HourMeanLight>
</HourMeanLight>
<LightValue>
</LightValue>
</ExtLightSensor>
</Save>
<Save format="version,current">
<GHTempSensor>
<GreenhouseID>
[:$ContextData.GreenhouseID:]
</GreenhouseID>
<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>
</GHTempSensor>
</Save>
<Save format="version,current">
<GHHumiditySensor>
<GreenhouseID>
[:$ContextData.GreenhouseID:]
</GreenhouseID>
<peripheral>
serial
</peripheral>
<baudrate>
115200
</baudrate>
<interfacePort>
/dev/cu.usbserial-AH02V4BU
</interfacePort>
<interface>
serial
</interface>
<format>
ascii
</format>
<operation>
receive
</operation>
<uniqueId>
76522
</uniqueId>
<HumidityValue>
0
</HumidityValue>
</GHHumiditySensor>
</Save>
</Query>
</QueryString>
</executeQuery>
<SetContextData key="FirstLane">
<Value>Yes</Value>
</SetContextData>
<For each="laneRecord" in="Lane" from="$ProcessData.record.Lanes" using="$LocalData">
<addLanes>
<GreenhouseID>[:$ContextData.GreenhouseID:]</GreenhouseID>
<LaneName>[:$LocalData.laneRecord.LaneName:]</LaneName>
<LaneLength>110</LaneLength>
<LaneWidth>40</LaneWidth>
<ZoneInLane>[:$ProcessData.record.ZonesPerLane:]</ZoneInLane>
<BorderLane>No</BorderLane>
</addLanes>
<if condition="$Response.Message.Value/Create/Status eq 'Success'">
<then>
<SetLocalData key="LaneID">
<Value>[:$Response.Message.Value.Create.Lane.LaneID:]</Value>
</SetLocalData>
<loadZoneModels>
<LaneID>[:$LocalData.LaneID:]</LaneID>
<ZonesPerLane>[:$ProcessData.record.ZonesPerLane:]</ZonesPerLane>
<CropType>[:$LocalData.laneRecord.CropType:]</CropType>
<FirstLane>[:$ContextData.FirstLane:]</FirstLane>
</loadZoneModels>
</then>
</if>
<SetContextData key="FirstLane">
<Value>No</Value>
</SetContextData>
</For>
</then>
</if>
</for>
</Result>
</Macro> |
Add Action to Start Simulate
Code Block |
---|
language | xml |
---|
title | Action to Start Simulation |
---|
linenumbers | true |
---|
|
<Action Name="SimulatedReadAction" Documentation="Start reading temperature from simulated env">
<Workflow Limit="1" Live="1" Timeout="-1">
<Task Name="Main1" While="true">
<Event Name="Argument" As="ActionArgument"/>
<Invoke Name="StartSimulation" waitFor="Argument">
<FacetScript>
<If condition="/'[%:Event.Argument.Simulated.Value:%]' eq 'true'">
<then>
<Log Message="Starting simulation.."/>
<SetGHCurrentTemp>
<TempSensorId>
[%:Event.Argument.sensorId:%]
</TempSensorId>
<GreenhouseID>
[%:Event.Argument.GreenhouseID.Value:%]
</GreenhouseID>
</SetGHCurrentTemp>
<ScheduleJob>
<Name>
SetGHCurrentTemperature
</Name>
<ScheduleInterval>
5min
</ScheduleInterval>
<ActionCode>
<SetGHCurrentTemp>
<TempSensorId>
[%:Event.Argument.sensorId:%]
</TempSensorId>
<GreenhouseID>
[%:Event.Argument.GreenhouseID.Value:%]
</GreenhouseID>
</SetGHCurrentTemp>
</ActionCode>
</ScheduleJob>
</then>
<else>
<Log Message="Stopping simulation.."/>
<DeleteScheduleJob>
<JobName>
SetGHCurrentTemperature
</JobName>
</DeleteScheduleJob>
</else>
</If>
</FacetScript>
</Invoke>
<Output Name="Result" As="ActionResult">
<Value>
<Simulated>
[%:Event.Argument.Simulated.Value:%]
</Simulated>
</Value>
</Output>
</Task>
</Workflow>
</Action> |
Changes to TempFacetSerial
Code Block |
---|
language | xml |
---|
title | Changes to Thing Facet |
---|
linenumbers | true |
---|
|
<ThingFacet Name="TempFacetSerial">
<String Name="TempValue"/>
<String Name="Unit" default="Celsius"/>
<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"/>
<Reference Name="GreenhouseID" Type="Greenhouse"/>
<String Name="Simulated" KnownBy="SimulatedReadAction"/>
</ThingFacet> |
Queries
Let's start writing some queries to create and read the data.
Create Greenhouse
Code Block |
---|
language | xml |
---|
title | Create Greenhouse |
---|
linenumbers | true |
---|
|
<Query>
<Create>
<Greenhouse>
<GreenhouseName>Khan Farmhouse</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>
10
</ZoneInLane>
<ZoneCount>3</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>
<SunnyDay>True</SunnyDay>
<Location>
<latitude>-122.1</latitude>
<longitude>32.0</longitude>
</Location>
</Greenhouse>
</Create>
</Query> |
Add Heater
Code Block |
---|
language | xml |
---|
title | Add Heater |
---|
linenumbers | true |
---|
|
<Query>
<Create>
<Heater>
<OnOffState>
on
</OnOffState>
<HeatingLevel>
2
</HeatingLevel>
</Heater>
</Create>
</Query> |
...
Queries
Let's start writing some queries to create and read the data.
Create Greenhouse
Macro can be called directly
Code Block |
---|
language | xml |
---|
title | Start SimulatorCreate Greenhouse |
---|
linenumbers | true |
---|
| <Query>
<DeleteAll>
<TempSensor>
<sensorId ne=""/> |
<CreateGreenhouse>
<Greenhouses>
</TempSensor>
</DeleteAll>
<Find format="Version">
<Greenhouse>
<GreenhouseID ne =""/>
</Greenhouse>
</Find>
<Create> <Greenhouse>
<GreenHouseName>GreenHouse-1</GreenHouseName>
<Location>
<latitude>1.11</latitude>
<longitude>1.12</longitude>
</Location>
<ZonesPerLane>5</ZonesPerLane>
<NumberOfLanes>2</NumberOfLanes>
<Lanes>
<Lane>
<LaneName>Lane-1</LaneName>
<CropType>Tomato</CropType>
</Lane>
<TempSensor> <Lane>
<LaneName>Lane-2</LaneName>
<CropType>Tomato</CropType>
<Simulated>
true
</Lane>
</Lanes>
</Greenhouse>
</Simulated>
Greenhouses>
</CreateGreenhouse> |
Show Query
Code Block |
---|
language | xml |
---|
title | Show Query |
---|
linenumbers | true |
---|
|
<Query>
<Show>
<GreenhouseID> <Entity [:$Response.Message.Value.Find.Result.Greenhouse.GreenhouseID:]
</GreenhouseID>
</TempSensor>
</Create>inherits="DataModel" not.qname="*.TqlSystem.*"/>
</Show>
</Query> |
Find Greenhouse / TempSensor
...