You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@edgent.apache.org by ho...@apache.org on 2016/04/15 19:02:52 UTC

[2/2] incubator-quarks-website git commit: from 70f00190a01978781701913a2ee705293c1ba2ba

from 70f00190a01978781701913a2ee705293c1ba2ba


Project: http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/commit/11237088
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/tree/11237088
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/diff/11237088

Branch: refs/heads/asf-site
Commit: 11237088aa5d3abd141951ff99d8ce3a19a98732
Parents: e49d0e3
Author: Susan L. Cline <ho...@apache.org>
Authored: Fri Apr 15 10:02:39 2016 -0700
Committer: Susan L. Cline <ho...@apache.org>
Committed: Fri Apr 15 10:02:39 2016 -0700

----------------------------------------------------------------------
 content/404.html                                |   2 +-
 content/algolia_search.json                     |   4 +-
 content/docs/committers.html                    |   2 +-
 content/docs/common-quarks-operations.html      |   2 +-
 content/docs/community.html                     |   2 +-
 content/docs/console.html                       |   2 +-
 content/docs/faq.html                           |   2 +-
 content/docs/home.html                          |   2 +-
 content/docs/overview.html                      |   2 +-
 content/docs/quarks-getting-started.html        |   2 +-
 content/docs/quarks_index.html                  |   2 +-
 content/docs/quickstart.html                    |   2 +-
 content/docs/samples.html                       |   2 +-
 content/docs/search.html                        |   2 +-
 content/docs/tag_collaboration.html             |   2 +-
 content/docs/tag_content_types.html             |   2 +-
 content/docs/tag_formatting.html                |   2 +-
 content/docs/tag_getting_started.html           |   2 +-
 content/docs/tag_mobile.html                    |   2 +-
 content/docs/tag_navigation.html                |   2 +-
 content/docs/tag_publishing.html                |   2 +-
 content/docs/tag_single_sourcing.html           |   2 +-
 content/docs/tag_special_layouts.html           |   2 +-
 .../recipes/recipe_adaptable_filter_range.html  |   2 +-
 ...pe_combining_streams_processing_results.html |   2 +-
 ...ipe_different_processing_against_stream.html | 142 +++++++++----------
 .../recipes/recipe_external_filter_range.html   |   2 +-
 content/recipes/recipe_hello_quarks.html        |   2 +-
 content/recipes/recipe_source_function.html     |   2 +-
 content/recipes/recipe_value_out_of_range.html  |  84 ++++-------
 content/titlepage.html                          |   4 +-
 content/tocpage.html                            |   2 +-
 32 files changed, 127 insertions(+), 163 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/404.html
----------------------------------------------------------------------
diff --git a/content/404.html b/content/404.html
index 050f5f6..c0a9cae 100644
--- a/content/404.html
+++ b/content/404.html
@@ -566,7 +566,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/algolia_search.json
----------------------------------------------------------------------
diff --git a/content/algolia_search.json b/content/algolia_search.json
index f69973e..6cbc069 100644
--- a/content/algolia_search.json
+++ b/content/algolia_search.json
@@ -185,7 +185,7 @@
 "keywords": "",
 "url": "../recipes/recipe_different_processing_against_stream",
 "summary": "",
-"body": "In the previous [recipe](recipe_value_out_of_range), we learned how to filter a stream to obtain the interesting sensor readings and ignore the mundane data. Typically, a user scenario is more involved, where data is processed using different stream operations. Consider the following scenario, for example.Suppose a package delivery company would like to monitor the gas mileage of their delivery trucks using embedded sensors. They would like to apply different analytics to the sensor data that can be used to make more informed business decisions. For instance, if a truck is reporting consistently poor mileage readings, the company might want to consider replacing that truck to save on gas costs. Perhaps the company also wants to convert the sensor readings to JSON format in order to easily display the data on a web page. It may also be interested in determining the expected gallons of gas used based on the current mileage.In this instance, we can take the stream of mileage s
 ensor readings and apply multiple types of processing against it so that we end up with streams that serve different purposes.## Setting up the applicationWe assume that the environment has been set up following the steps outlined in the [Getting started guide](../docs/quarks-getting-started). Let's begin by creating a `DirectProvider` and `Topology`. We choose a `DevelopmentProvider` so that we can view the topology graph using the console URL (refer to the [Application console](../docs/console) page for a more detailed explanation of this provider). The initial mileage value and the number of miles in a typical delivery route have also been defined.```java    import java.text.DecimalFormat;    import java.util.Random;    import java.util.concurrent.TimeUnit;    import com.google.gson.JsonObject;    import quarks.console.server.HttpServer;    import quarks.providers.development.DevelopmentProvider;    import quarks.providers.direct.DirectProvider;    import quarks.topology.TStream;
     import quarks.topology.Topology;    public class ApplyDifferentProcessingAgainstStream {        /**         * Hypothetical values for the initial gas mileage and the         * number of miles in a typical delivery route         */        static double currentMileage = 10.5;        static double ROUTE_MILES = 80;        public static void main(String[] args) throws Exception {            DirectProvider dp = new DevelopmentProvider();            System.out.println(dp.getServices().getService(HttpServer.class).getConsoleUrl());            Topology top = dp.newTopology(\"TruckSensor\");            // The rest of the code pieces belong here        }    }```## Generating mileage sensor readingsThe next step is to simulate a stream of gas mileage readings. In our `main()`, we use the `poll()` method to generate a flow of tuples (readings), where each tuple arrives every second. We ensure that the generated reading is between 7.0 mpg and 14.0 mpg.```java    // Generate a stream of milea
 ge sensor readings    DecimalFormat df = new DecimalFormat(\"#.#\");    Random r = new Random();    TStream mileage = top.poll(() -> {        // Change current mileage by some random amount between -0.4 and 0.4        while (true) {            double newMileage = -0.4 + (0.4 + 0.4) * r.nextDouble() + currentMileage;            // Ensure that new temperature is within [7.0, 14.0]            if (newMileage >= 7.0 && newMileage  poorMileage = mileage            .filter(mpg -> mpg  json = mileage            .map(mpg -> {                JsonObject jObj = new JsonObject();                jObj.addProperty(\"mileage\", mpg);                return jObj;            }).tag(\"mapped\");```In addition, we can calculate the estimated gallons of gas used based on the current mileage using `modify`.```java    // Modify mileage stream to obtain a stream containing the estimated gallons of gas used    TStream gallonsUsed = mileage            .modify(mpg -> Double.valueOf(df.format(ROUTE_MILES / mpg))
 ).tag(\"modified\");```The three examples demonstrated here are a small subset of the many other possibilities of stream processing.With each of these resulting streams, the company can perform further analytics, but at this point, we terminate the streams by printing out the tuples on each stream.```java    // Terminate the streams    poorMileage.sink(mpg -> System.out.println(\"Poor mileage! \" + mpg + \" mpg\"));    json.sink(mpg -> System.out.println(\"JSON: \" + mpg));    gallonsUsed.sink(gas -> System.out.println(\"Gallons of gas: \" + gas + \"\\n\"));```We end our application by submitting the `Topology`.## Observing the outputWhen the final application is run, the output looks something like the following:```    JSON: {\"mileage\":9.5}    Gallons of gas: 8.4    JSON: {\"mileage\":9.2}    Gallons of gas: 8.7    Poor mileage! 9.0 mpg    JSON: {\"mileage\":9.0}    Gallons of gas: 8.9    Poor mileage! 8.8 mpg    JSON: {\"mileage\":8.8}    Gallons of gas: 9.1```## A look at the t
 opology graphLet's see what the topology graph looks like. We can view it using the console URL that was printed to standard output at the start of the application. We see that original stream is fanned out to three separate streams, and the `filter`, `map`, and `modify` operations are applied.## The final application```java    import java.text.DecimalFormat;    import java.util.Random;    import java.util.concurrent.TimeUnit;    import com.google.gson.JsonObject;    import quarks.console.server.HttpServer;    import quarks.providers.development.DevelopmentProvider;    import quarks.providers.direct.DirectProvider;    import quarks.topology.TStream;    import quarks.topology.Topology;    /**     * Fan out stream and perform different analytics on the resulting streams.     */    public class ApplyDifferentProcessingAgainstStream {        /**         * Hypothetical values for the initial gas mileage and the         * number of miles in a typical delivery route         */        stati
 c double currentMileage = 10.5;        static double ROUTE_MILES = 80;        /**         * Polls a simulated delivery truck sensor to periodically obtain         * mileage readings (in miles/gallon). Feed the stream of sensor         * readings to different functions (filter, map, and modify).         */        public static void main(String[] args) throws Exception {            DirectProvider dp = new DevelopmentProvider();            System.out.println(dp.getServices().getService(HttpServer.class).getConsoleUrl());            Topology top = dp.newTopology(\"TruckSensor\");            // Generate a stream of mileage sensor readings            DecimalFormat df = new DecimalFormat(\"#.#\");            Random r = new Random();            TStream mileage = top.poll(() -> {                // Change current mileage by some random amount between -0.4 and 0.4                while (true) {                    double newMileage = -0.4 + (0.4 + 0.4) * r.nextDouble() + currentMileage;         
            // Ensure that new temperature is within [7.0, 14.0]                    if (newMileage >= 7.0 && newMileage  poorMileage = mileage                    .filter(mpg -> mpg  json = mileage                    .map(mpg -> {                        JsonObject jObj = new JsonObject();                        jObj.addProperty(\"mileage\", mpg);                        return jObj;                    }).tag(\"mapped\");            // Modify mileage stream to obtain a stream containing the estimated gallons of gas used            TStream gallonsUsed = mileage                    .modify(mpg -> Double.valueOf(df.format(ROUTE_MILES / mpg))).tag(\"modified\");            // Terminate the streams            poorMileage.sink(mpg -> System.out.println(\"Poor mileage! \" + mpg + \" mpg\"));            json.sink(mpg -> System.out.println(\"JSON: \" + mpg));            gallonsUsed.sink(gas -> System.out.println(\"Gallons of gas: \" + gas + \"\\n\"));            dp.submit(top);        }    }```"
+"body": "In the previous [recipe](recipe_value_out_of_range), we learned how to filter a stream to obtain the interesting sensor readings and ignore the mundane data. Typically, a user scenario is more involved, where data is processed using different stream operations. Consider the following scenario, for example.Suppose a package delivery company would like to monitor the gas mileage of their delivery trucks using embedded sensors. They would like to apply different analytics to the sensor data that can be used to make more informed business decisions. For instance, if a truck is reporting consistently poor gas mileage readings, the company might want to consider replacing that truck to save on gas costs. Perhaps the company also wants to convert the sensor readings to JSON format in order to easily display the data on a web page. It may also be interested in determining the expected gallons of gas used based on the current gas mileage.In this instance, we can take the stream of g
 as mileage sensor readings and apply multiple types of processing against it so that we end up with streams that serve different purposes.## Setting up the applicationWe assume that the environment has been set up following the steps outlined in the [Getting started guide](../docs/quarks-getting-started). Let's begin by creating a `DirectProvider` and `Topology`. We choose a `DevelopmentProvider` so that we can view the topology graph using the console URL (refer to the [Application console](../docs/console) page for a more detailed explanation of this provider). The gas mileage bounds, initial gas mileage value, and the number of miles in a typical delivery route have also been defined.```java    import java.text.DecimalFormat;    import java.util.concurrent.TimeUnit;    import com.google.gson.JsonObject;    import quarks.analytics.sensors.Ranges;    import quarks.console.server.HttpServer;    import quarks.providers.development.DevelopmentProvider;    import quarks.providers.direc
 t.DirectProvider;    import quarks.samples.utils.sensor.SimpleSimulatedSensor;    import quarks.topology.TStream;    import quarks.topology.Topology;    public class ApplyDifferentProcessingAgainstStream {        /**         * Gas mileage (in miles per gallon, or mpg) value bounds         */        static double MPG_LOW = 7.0;        static double MPG_HIGH = 14.0;        /**         * Initial gas mileage sensor value         */        static double INITIAL_MPG = 10.5;        /**         * Hypothetical value for the number of miles in a typical delivery route         */        static double ROUTE_MILES = 80;        public static void main(String[] args) throws Exception {            DirectProvider dp = new DevelopmentProvider();            System.out.println(dp.getServices().getService(HttpServer.class).getConsoleUrl());            Topology top = dp.newTopology(\"GasMileageSensor\");            // The rest of the code pieces belong here        }    }```## Generating gas mileage senso
 r readingsThe next step is to simulate a stream of gas mileage readings using [`SimpleSimulatedSensor`](https://github.com/apache/incubator-quarks/blob/master/samples/utils/src/main/java/quarks/samples/utils/sensor/SimpleSimulatedSensor.java). We set the initial gas mileage and delta factor in the first two arguments. The last argument ensures that the sensor reading falls in an acceptable range (between 7.0 mpg and 14.0 mpg). In our `main()`, we use the `poll()` method to generate a flow of tuples (readings), where each tuple arrives every second.```java    // Generate a stream of gas mileage sensor readings    SimpleSimulatedSensor mpgSensor = new SimpleSimulatedSensor(INITIAL_MPG,            0.4, Ranges.closed(MPG_LOW, MPG_HIGH));    TStream mpgReadings = top.poll(mpgSensor, 1, TimeUnit.SECONDS);```## Applying different processing to the streamThe company can now perform analytics on the `mpgReadings` stream and feed it to different functions.First, we can filter out gas mileage 
 values that are considered poor and tag the resulting stream for easier viewing in the console.```java    // Filter out the poor gas mileage readings    TStream poorMpg = mpgReadings            .filter(mpg -> mpg  json = mpgReadings            .map(mpg -> {                JsonObject jObj = new JsonObject();                jObj.addProperty(\"gasMileage\", mpg);                return jObj;            }).tag(\"mapped\");```In addition, we can calculate the estimated gallons of gas used based on the current gas mileage using `modify`.```java    // Modify gas mileage stream to obtain a stream containing the estimated gallons of gas used    DecimalFormat df = new DecimalFormat(\"#.#\");    TStream gallonsUsed = mpgReadings            .modify(mpg -> Double.valueOf(df.format(ROUTE_MILES / mpg))).tag(\"modified\");```The three examples demonstrated here are a small subset of the many other possibilities of stream processing.With each of these resulting streams, the company can perform furthe
 r analytics, but at this point, we terminate the streams by printing out the tuples on each stream.```java    // Terminate the streams    poorMpg.sink(mpg -> System.out.println(\"Poor gas mileage! \" + mpg + \" mpg\"));    json.sink(mpg -> System.out.println(\"JSON: \" + mpg));    gallonsUsed.sink(gas -> System.out.println(\"Gallons of gas: \" + gas + \"\\n\"));```We end our application by submitting the `Topology`.## Observing the outputWhen the final application is run, the output looks something like the following:```    JSON: {\"gasMileage\":9.5}    Gallons of gas: 8.4    JSON: {\"gasMileage\":9.2}    Gallons of gas: 8.7    Poor gas mileage! 9.0 mpg    JSON: {\"gasMileage\":9.0}    Gallons of gas: 8.9    Poor gas mileage! 8.8 mpg    JSON: {\"gasMileage\":8.8}    Gallons of gas: 9.1```## A look at the topology graphLet's see what the topology graph looks like. We can view it using the console URL that was printed to standard output at the start of the application. We see that ori
 ginal stream is fanned out to three separate streams, and the `filter`, `map`, and `modify` operations are applied.## The final application```java    import java.text.DecimalFormat;    import java.util.concurrent.TimeUnit;    import com.google.gson.JsonObject;    import quarks.analytics.sensors.Ranges;    import quarks.console.server.HttpServer;    import quarks.providers.development.DevelopmentProvider;    import quarks.providers.direct.DirectProvider;    import quarks.samples.utils.sensor.SimpleSimulatedSensor;    import quarks.topology.TStream;    import quarks.topology.Topology;     /**     * Fan out stream and perform different analytics on the resulting streams.     */    public class ApplyDifferentProcessingAgainstStream {        /**         * Gas mileage (in miles per gallon, or mpg) value bounds         */        static double MPG_LOW = 7.0;        static double MPG_HIGH = 14.0;        /**         * Initial gas mileage sensor value         */        static double INITIAL_MP
 G = 10.5;        /**         * Hypothetical value for the number of miles in a typical delivery route         */        static double ROUTE_MILES = 80;        /**         * Polls a simulated delivery truck sensor to periodically obtain         * gas mileage readings (in miles/gallon). Feed the stream of sensor         * readings to different functions (filter, map, and modify).         */        public static void main(String[] args) throws Exception {            DirectProvider dp = new DevelopmentProvider();            System.out.println(dp.getServices().getService(HttpServer.class).getConsoleUrl());            Topology top = dp.newTopology(\"GasMileageSensor\");            // Generate a stream of gas mileage sensor readings            SimpleSimulatedSensor mpgSensor = new SimpleSimulatedSensor(INITIAL_MPG,                    0.4, Ranges.closed(MPG_LOW, MPG_HIGH));            TStream mpgReadings = top.poll(mpgSensor, 1, TimeUnit.SECONDS);            // Filter out the poor gas milea
 ge readings            TStream poorMpg = mpgReadings                    .filter(mpg -> mpg  json = mpgReadings                    .map(mpg -> {                        JsonObject jObj = new JsonObject();                        jObj.addProperty(\"gasMileage\", mpg);                        return jObj;                    }).tag(\"mapped\");            // Modify gas mileage stream to obtain a stream containing the estimated gallons of gas used            DecimalFormat df = new DecimalFormat(\"#.#\");            TStream gallonsUsed = mpgReadings                    .modify(mpg -> Double.valueOf(df.format(ROUTE_MILES / mpg))).tag(\"modified\");            // Terminate the streams            poorMpg.sink(mpg -> System.out.println(\"Poor gas mileage! \" + mpg + \" mpg\"));            json.sink(mpg -> System.out.println(\"JSON: \" + mpg));            gallonsUsed.sink(gas -> System.out.println(\"Gallons of gas: \" + gas + \"\\n\"));            dp.submit(top);        }    }```"
 
 },
 
@@ -237,7 +237,7 @@
 "keywords": "",
 "url": "../recipes/recipe_value_out_of_range",
 "summary": "",
-"body": "Oftentimes, a user expects a sensor value to fall within a particular range. If a reading is outside the accepted limits, the user may want to determine what caused the anomaly and/or take action to reduce the impact. For instance, consider the following scenario.Suppose a corn grower in the Midwestern United States would like to monitor the average temperature in his corn field using a sensor to improve his crop yield. The optimal temperatures for corn growth during daylight hours range between 77°F and 91°F. When the grower is alerted of a temperature value that is not in the optimal range, he may want to assess what can be done to mitigate the effect.In this instance, we can use a filter to detect out-of-range temperature values.## Setting up the applicationWe assume that the environment has been set up following the steps outlined in the [Getting started guide](../docs/quarks-getting-started). Let's begin by creating a `DirectProvider` and `Topology`. We also define t
 he optimal temperature range and the initial temperature.```java    import static quarks.function.Functions.identity;    import java.text.DecimalFormat;    import java.util.Random;    import java.util.concurrent.TimeUnit;    import quarks.analytics.sensors.Filters;    import quarks.providers.direct.DirectProvider;    import quarks.topology.TStream;    import quarks.topology.Topology;    public class DetectValueOutOfRange {        /**         * Optimal temperatures (in Fahrenheit)         */        static double TEMP_LOW = 77.0;        static double TEMP_HIGH = 91.0;        static double currentTemp = 80.0;        public static void main(String[] args) throws Exception {            DirectProvider dp = new DirectProvider();            Topology top = dp.newTopology(\"TemperatureSensor\");            // The rest of the code pieces belong here        }    }```## Generating temperature sensor readingsThe next step is to simulate a stream of temperature readings. In our `main()`, we use th
 e `poll()` method to generate a flow of tuples, where a new tuple (temperature reading) arrives every second. We ensure that the generated reading is between 28°F and 112°F.```java    // Generate a stream of temperature sensor readings    DecimalFormat df = new DecimalFormat(\"#.#\");    Random r = new Random();    TStream temp = top.poll(() -> {        // Change current temp by some random amount between -1 and 1        while (true) {            double newTemp = -1 + (1 + 1) * r.nextDouble() + currentTemp;            // Ensure that new temperature is within [28, 112]            if (newTemp >= 28 && newTemp  simpleFiltered = temp.filter(tuple ->            tuple  TEMP_HIGH);    simpleFiltered.sink(tuple -> System.out.println(\"Temperature is out of range! \"            + \"It is \" + tuple + \"\\u00b0F!\"));```## Deadband filterAlternatively, a deadband filter can be used to glean more information about temperature changes, such as extracting the in-range temperature immediately a
 fter a reported out-of-range temperature. For example, large temperature fluctuations could be investigated more thoroughly. The `deadband` filter is a part of the `quarks.analytics` package focused on handling sensor data. Let's look more closely at the method declaration below.```java    deadband(TStream stream, Function value, Predicate inBand)```The first parameter is the stream to the filtered, which is `temp` in our scenario. The second parameter is the value to examine. Here, we use the `identity()` method to return a tuple on the stream. The last parameter is the predicate that defines the optimal range, that is, between 77°F and 91°F. it is important to note that this differs from the `TStream` version of `filter` in which one must explicitly specify the values that are out of range. The code snippet below demonstrates how the method call is pieced together. The `deadbandFiltered` stream contains temperature readings that follow the rules as described in the [Javadoc](htt
 p://quarks-edge.github.io/quarks/docs/javadoc/quarks/analytics/sensors/Filters.html#deadband-quarks.topology.TStream-quarks.function.Function-quarks.function.Predicate-):- the value is outside of the optimal range (deadband)- the first value inside the optimal range after a period being outside it- the first tupleAs with the simple filter, the stream is terminated by printing out the warnings.```java    TStream deadbandFiltered = Filters.deadband(temp,            identity(), tuple -> tuple >= TEMP_LOW && tuple  System.out.println(\"Temperature may not be \"            + \"optimal! It is \" + tuple + \"\\u00b0F!\"));```We end our application by submitting the `Topology`.## Observing the outputTo see what the temperatures look like, we can print the stream to standard out.```java    temp.print();```When the final application is run, the output looks something like the following:```    Temperature may not be optimal! It is 79.1°F!    79.1    79.4    79.0    78.8    78.0    78.3    77.
 4    Temperature is out of range! It is 76.5°F!    Temperature may not be optimal! It is 76.5°F!    76.5    Temperature may not be optimal! It is 77.5°F!    77.5    77.1    ...```Note that the deadband filter outputs a warning message for the very first temperature reading of 79.1°F. When the temperature falls to 76.5°F (which is outside the optimal range), both the simple filter and deadband filter print out a warning message. However, when the temperature returns to normal at 77.5°F, only the deadband filter prints out a message as it is the first value inside the optimal range after a period of being outside it.## Range valuesFiltering against a range of values is such a common analytic activity that the ``quarks.analytics.sensors.Range`` class is provided to assist with that.Using a Range can simplify and clarify your application code and lessen mistakes that may occur when writing expressions to deal with ranges.Though not covered in this recipe, Ranges offer additional c
 onveniences for creating applications with external range specifications and adaptable filters.In the above examples, a single Range can be used in place of the two different expressions for the same logical range:```java    static double TEMP_LOW = 77.0;    static double TEMP_HIGH = 91.0;    static Range optimalTempRange = Ranges.closed(TEMP_LOW, TEMP_HIGH);```Using ``optimalTempRange`` in the Simple filter example code:```java    TStream simpleFiltered = temp.filter(tuple ->             !optimalTempRange.contains(tuple));```Using ``optimalTempRange`` in the Deadband filter example code:```java    TStream deadbandFiltered = Filters.deadband(temp,            identity(), optimalTempRange);```## The final application```java    import static quarks.function.Functions.identity;    import java.text.DecimalFormat;    import java.util.Random;    import java.util.concurrent.TimeUnit;    import quarks.analytics.sensors.Filters;    import quarks.analytics.sensors.Range;    import quarks.analy
 tics.sensors.Ranges;    import quarks.providers.direct.DirectProvider;    import quarks.topology.TStream;    import quarks.topology.Topology;    /**     * Detect a sensor value out of expected range.     */    public class DetectValueOutOfRange {        /**         * Optimal temperatures inclusive (in Fahrenheit)         */        static double TEMP_LOW = 77.0;        static double TEMP_HIGH = 91.0;        static Range optimalTempRange = Ranges.closed(TEMP_LOW, TEMP_HIGH);        static double currentTemp = 80.0;        /**         * Polls a simulated temperature sensor to periodically obtain         * temperature readings (in Fahrenheit). Use a simple filter         * and a deadband filter to determine when the temperature         * is out of the optimal range.         */        public static void main(String[] args) throws Exception {            DirectProvider dp = new DirectProvider();            Topology top = dp.newTopology(\"TemperatureSensor\");            // Generate a strea
 m of temperature sensor readings            DecimalFormat df = new DecimalFormat(\"#.#\");            Random r = new Random();            TStream temp = top.poll(() -> {                // Change current temp by some random amount between -1 and 1                while (true) {                    double newTemp = -1 + (1 + 1) * r.nextDouble() + currentTemp;                    // Ensure that new temperature is within [28, 112]                    if (newTemp >= 28 && newTemp  simpleFiltered = temp.filter(tuple ->                    !optimalTempRange.contains(tuple));            simpleFiltered.sink(tuple -> System.out.println(\"Temperature is out of range! \"                    + \"It is \" + tuple + \"\\u00b0F!\"));            // Deadband filter: Perform analytics on sensor readings to            // output the first temperature, and to generate warnings            // when the temperature is out of the optimal range and            // when it returns to normal            TStream deadbandF
 iltered = Filters.deadband(temp,                    identity(), optimalTempRange);            deadbandFiltered.sink(tuple -> System.out.println(\"Temperature may not be \"                    + \"optimal! It is \" + tuple + \"\\u00b0F!\"));            // See what the temperatures look like            temp.print();            dp.submit(top);        }    }```"
+"body": "Oftentimes, a user expects a sensor value to fall within a particular range. If a reading is outside the accepted limits, the user may want to determine what caused the anomaly and/or take action to reduce the impact. For instance, consider the following scenario.Suppose a corn grower in the Midwestern United States would like to monitor the average temperature in his corn field using a sensor to improve his crop yield. The optimal temperatures for corn growth during daylight hours range between 77°F and 91°F. When the grower is alerted of a temperature value that is not in the optimal range, he may want to assess what can be done to mitigate the effect.In this instance, we can use a filter to detect out-of-range temperature values.## Setting up the applicationWe assume that the environment has been set up following the steps outlined in the [Getting started guide](../docs/quarks-getting-started). Let's begin by creating a `DirectProvider` and `Topology`. We also define t
 he optimal temperature range.```java    import static quarks.function.Functions.identity;    import java.util.concurrent.TimeUnit;    import quarks.analytics.sensors.Filters;    import quarks.analytics.sensors.Range;    import quarks.analytics.sensors.Ranges;    import quarks.providers.direct.DirectProvider;    import quarks.samples.utils.sensor.SimulatedTemperatureSensor;    import quarks.topology.TStream;    import quarks.topology.Topology;    public class DetectValueOutOfRange {        /**         * Optimal temperature range (in Fahrenheit)         */        static double OPTIMAL_TEMP_LOW = 77.0;        static double OPTIMAL_TEMP_HIGH = 91.0;        static Range optimalTempRange = Ranges.closed(OPTIMAL_TEMP_LOW, OPTIMAL_TEMP_HIGH);        public static void main(String[] args) throws Exception {            DirectProvider dp = new DirectProvider();            Topology top = dp.newTopology(\"TemperatureSensor\");            // The rest of the code pieces belong here        }    }``
 `## Generating temperature sensor readingsThe next step is to simulate a stream of temperature readings using [`SimulatedTemperatureSensor`](https://github.com/apache/incubator-quarks/blob/master/samples/utils/src/main/java/quarks/samples/utils/sensor/SimulatedTemperatureSensor.java). By default, the sensor sets the initial temperature to 80°F and ensures that new readings are between 28°F and 112°F. In our `main()`, we use the `poll()` method to generate a flow of tuples, where a new tuple (temperature reading) arrives every second.```java    // Generate a stream of temperature sensor readings    SimulatedTemperatureSensor tempSensor = new SimulatedTemperatureSensor();    TStream temp = top.poll(tempSensor, 1, TimeUnit.SECONDS);```## Simple filteringIf the corn grower is interested in determining when the temperature is strictly out of the optimal range of 77°F and 91°F, a simple filter can be used. The `filter` method can be applied to `TStream` objects, where a filter predic
 ate determines which tuples to keep for further processing. For its method declaration, refer to the [Javadoc](http://quarks-edge.github.io/quarks/docs/javadoc/quarks/topology/TStream.html#filter-quarks.function.Predicate-).In this case, we want to keep temperatures below the lower range value *or* above the upper range value. This is expressed in the filter predicate, which follows Java's syntax for [lambda expressions](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#syntax). Then, we terminate the stream (using `sink`) by printing out the warning to standard out. Note that `\\u00b0` is the Unicode encoding for the degree (°) symbol.```java    TStream simpleFiltered = temp.filter(tuple ->            tuple  OPTIMAL_TEMP_HIGH);    simpleFiltered.sink(tuple -> System.out.println(\"Temperature is out of range! \"            + \"It is \" + tuple + \"\\u00b0F!\"));```## Deadband filterAlternatively, a deadband filter can be used to glean more information about
  temperature changes, such as extracting the in-range temperature immediately after a reported out-of-range temperature. For example, large temperature fluctuations could be investigated more thoroughly. The `deadband` filter is a part of the `quarks.analytics` package focused on handling sensor data. Let's look more closely at the method declaration below.```java    deadband(TStream stream, Function value, Predicate inBand)```The first parameter is the stream to the filtered, which is `temp` in our scenario. The second parameter is the value to examine. Here, we use the `identity()` method to return a tuple on the stream. The last parameter is the predicate that defines the optimal range, that is, between 77°F and 91°F. it is important to note that this differs from the `TStream` version of `filter` in which one must explicitly specify the values that are out of range. The code snippet below demonstrates how the method call is pieced together. The `deadbandFiltered` stream contai
 ns temperature readings that follow the rules as described in the [Javadoc](http://quarks-edge.github.io/quarks/docs/javadoc/quarks/analytics/sensors/Filters.html#deadband-quarks.topology.TStream-quarks.function.Function-quarks.function.Predicate-):- the value is outside of the optimal range (deadband)- the first value inside the optimal range after a period being outside it- the first tupleAs with the simple filter, the stream is terminated by printing out the warnings.```java    TStream deadbandFiltered = Filters.deadband(temp,            identity(), tuple -> tuple >= OPTIMAL_TEMP_LOW && tuple  System.out.println(\"Temperature may not be \"            + \"optimal! It is \" + tuple + \"\\u00b0F!\"));```We end our application by submitting the `Topology`.## Observing the outputTo see what the temperatures look like, we can print the stream to standard out.```java    temp.print();```When the final application is run, the output looks something like the following:```    Temperature ma
 y not be optimal! It is 79.1°F!    79.1    79.4    79.0    78.8    78.0    78.3    77.4    Temperature is out of range! It is 76.5°F!    Temperature may not be optimal! It is 76.5°F!    76.5    Temperature may not be optimal! It is 77.5°F!    77.5    77.1    ...```Note that the deadband filter outputs a warning message for the very first temperature reading of 79.1°F. When the temperature falls to 76.5°F (which is outside the optimal range), both the simple filter and deadband filter print out a warning message. However, when the temperature returns to normal at 77.5°F, only the deadband filter prints out a message as it is the first value inside the optimal range after a period of being outside it.## Range valuesFiltering against a range of values is such a common analytic activity that the ``quarks.analytics.sensors.Range`` class is provided to assist with that.Using a Range can simplify and clarify your application code and lessen mistakes that may occur when writing expre
 ssions to deal with ranges.Though not covered in this recipe, Ranges offer additional conveniences for creating applications with external range specifications and adaptable filters.In the above examples, a single Range can be used in place of the two different expressions for the same logical range:```java    static double OPTIMAL_TEMP_LOW = 77.0;    static double OPTIMAL_TEMP_HIGH = 91.0;    static Range optimalTempRange = Ranges.closed(OPTIMAL_TEMP_LOW, OPTIMAL_TEMP_HIGH);```Using ``optimalTempRange`` in the Simple filter example code:```java    TStream simpleFiltered = temp.filter(tuple ->             !optimalTempRange.contains(tuple));```Using ``optimalTempRange`` in the Deadband filter example code:```java    TStream deadbandFiltered = Filters.deadband(temp,            identity(), optimalTempRange);```## The final application```java    import static quarks.function.Functions.identity;    import java.util.concurrent.TimeUnit;    import quarks.analytics.sensors.Filters;    impor
 t quarks.analytics.sensors.Range;    import quarks.analytics.sensors.Ranges;    import quarks.providers.direct.DirectProvider;    import quarks.samples.utils.sensor.SimulatedTemperatureSensor;    import quarks.topology.TStream;    import quarks.topology.Topology;    /**     * Detect a sensor value out of expected range.     */    public class DetectValueOutOfRange {        /**         * Optimal temperature range (in Fahrenheit)         */        static double OPTIMAL_TEMP_LOW = 77.0;        static double OPTIMAL_TEMP_HIGH = 91.0;        static Range optimalTempRange = Ranges.closed(OPTIMAL_TEMP_LOW, OPTIMAL_TEMP_HIGH);        /**         * Polls a simulated temperature sensor to periodically obtain         * temperature readings (in Fahrenheit). Use a simple filter         * and a deadband filter to determine when the temperature         * is out of the optimal range.         */        public static void main(String[] args) throws Exception {            DirectProvider dp = new Direc
 tProvider();            Topology top = dp.newTopology(\"TemperatureSensor\");            // Generate a stream of temperature sensor readings            SimulatedTemperatureSensor tempSensor = new SimulatedTemperatureSensor();            TStream temp = top.poll(tempSensor, 1, TimeUnit.SECONDS);            // Simple filter: Perform analytics on sensor readings to            // detect when the temperature is completely out of the            // optimal range and generate warnings            TStream simpleFiltered = temp.filter(tuple ->                    !optimalTempRange.contains(tuple));            simpleFiltered.sink(tuple -> System.out.println(\"Temperature is out of range! \"                    + \"It is \" + tuple + \"\\u00b0F!\"));            // Deadband filter: Perform analytics on sensor readings to            // output the first temperature, and to generate warnings            // when the temperature is out of the optimal range and            // when it returns to normal      
       TStream deadbandFiltered = Filters.deadband(temp,                    identity(), optimalTempRange);            deadbandFiltered.sink(tuple -> System.out.println(\"Temperature may not be \"                    + \"optimal! It is \" + tuple + \"\\u00b0F!\"));            // See what the temperatures look like            temp.print();            dp.submit(top);        }    }```"
 
 },
 

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/committers.html
----------------------------------------------------------------------
diff --git a/content/docs/committers.html b/content/docs/committers.html
index 977d832..debda3f 100644
--- a/content/docs/committers.html
+++ b/content/docs/committers.html
@@ -578,7 +578,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/common-quarks-operations.html
----------------------------------------------------------------------
diff --git a/content/docs/common-quarks-operations.html b/content/docs/common-quarks-operations.html
index 451831b..6a901c2 100644
--- a/content/docs/common-quarks-operations.html
+++ b/content/docs/common-quarks-operations.html
@@ -611,7 +611,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/community.html
----------------------------------------------------------------------
diff --git a/content/docs/community.html b/content/docs/community.html
index b0a7c40..27297ed 100644
--- a/content/docs/community.html
+++ b/content/docs/community.html
@@ -634,7 +634,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/console.html
----------------------------------------------------------------------
diff --git a/content/docs/console.html b/content/docs/console.html
index 7a9b6c6..75a67ab 100644
--- a/content/docs/console.html
+++ b/content/docs/console.html
@@ -1041,7 +1041,7 @@ The bars that are the tallest and therefore have the highest tuple count are OP_
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/faq.html
----------------------------------------------------------------------
diff --git a/content/docs/faq.html b/content/docs/faq.html
index bef6933..282e22e 100644
--- a/content/docs/faq.html
+++ b/content/docs/faq.html
@@ -649,7 +649,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/home.html
----------------------------------------------------------------------
diff --git a/content/docs/home.html b/content/docs/home.html
index 4414965..b65591d 100644
--- a/content/docs/home.html
+++ b/content/docs/home.html
@@ -654,7 +654,7 @@ medical device.</li>
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/overview.html
----------------------------------------------------------------------
diff --git a/content/docs/overview.html b/content/docs/overview.html
index 4458fd0..c3e4901 100644
--- a/content/docs/overview.html
+++ b/content/docs/overview.html
@@ -638,7 +638,7 @@ medical device.</li>
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/quarks-getting-started.html
----------------------------------------------------------------------
diff --git a/content/docs/quarks-getting-started.html b/content/docs/quarks-getting-started.html
index 8fd66b1..6fe184a 100644
--- a/content/docs/quarks-getting-started.html
+++ b/content/docs/quarks-getting-started.html
@@ -740,7 +740,7 @@ Your environment is set up! You can start writing your first Quarks application.
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/quarks_index.html
----------------------------------------------------------------------
diff --git a/content/docs/quarks_index.html b/content/docs/quarks_index.html
index 2451048..7a82cb3 100644
--- a/content/docs/quarks_index.html
+++ b/content/docs/quarks_index.html
@@ -596,7 +596,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/quickstart.html
----------------------------------------------------------------------
diff --git a/content/docs/quickstart.html b/content/docs/quickstart.html
index e6a2779..5910b51 100644
--- a/content/docs/quickstart.html
+++ b/content/docs/quickstart.html
@@ -615,7 +615,7 @@ Here we map a stream of random numbers into JSON as the payload for a device eve
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/samples.html
----------------------------------------------------------------------
diff --git a/content/docs/samples.html b/content/docs/samples.html
index e1fd2e0..0eeedce 100644
--- a/content/docs/samples.html
+++ b/content/docs/samples.html
@@ -629,7 +629,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/search.html
----------------------------------------------------------------------
diff --git a/content/docs/search.html b/content/docs/search.html
index 08d5383..ce2754d 100644
--- a/content/docs/search.html
+++ b/content/docs/search.html
@@ -556,7 +556,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/tag_collaboration.html
----------------------------------------------------------------------
diff --git a/content/docs/tag_collaboration.html b/content/docs/tag_collaboration.html
index 8bdad07..f684e8f 100644
--- a/content/docs/tag_collaboration.html
+++ b/content/docs/tag_collaboration.html
@@ -647,7 +647,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/tag_content_types.html
----------------------------------------------------------------------
diff --git a/content/docs/tag_content_types.html b/content/docs/tag_content_types.html
index 3b9077b..7692e6f 100644
--- a/content/docs/tag_content_types.html
+++ b/content/docs/tag_content_types.html
@@ -647,7 +647,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/tag_formatting.html
----------------------------------------------------------------------
diff --git a/content/docs/tag_formatting.html b/content/docs/tag_formatting.html
index 514ea55..913959c 100644
--- a/content/docs/tag_formatting.html
+++ b/content/docs/tag_formatting.html
@@ -647,7 +647,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/tag_getting_started.html
----------------------------------------------------------------------
diff --git a/content/docs/tag_getting_started.html b/content/docs/tag_getting_started.html
index 3f96ba7..4a2fc67 100644
--- a/content/docs/tag_getting_started.html
+++ b/content/docs/tag_getting_started.html
@@ -652,7 +652,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/tag_mobile.html
----------------------------------------------------------------------
diff --git a/content/docs/tag_mobile.html b/content/docs/tag_mobile.html
index b581f80..7628eee 100644
--- a/content/docs/tag_mobile.html
+++ b/content/docs/tag_mobile.html
@@ -647,7 +647,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/tag_navigation.html
----------------------------------------------------------------------
diff --git a/content/docs/tag_navigation.html b/content/docs/tag_navigation.html
index 4b11023..91f4e9a 100644
--- a/content/docs/tag_navigation.html
+++ b/content/docs/tag_navigation.html
@@ -647,7 +647,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/tag_publishing.html
----------------------------------------------------------------------
diff --git a/content/docs/tag_publishing.html b/content/docs/tag_publishing.html
index 98a5c0e..4dd2dd9 100644
--- a/content/docs/tag_publishing.html
+++ b/content/docs/tag_publishing.html
@@ -647,7 +647,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/tag_single_sourcing.html
----------------------------------------------------------------------
diff --git a/content/docs/tag_single_sourcing.html b/content/docs/tag_single_sourcing.html
index 72caaaa..a655c53 100644
--- a/content/docs/tag_single_sourcing.html
+++ b/content/docs/tag_single_sourcing.html
@@ -647,7 +647,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/docs/tag_special_layouts.html
----------------------------------------------------------------------
diff --git a/content/docs/tag_special_layouts.html b/content/docs/tag_special_layouts.html
index fa625f9..14cad76 100644
--- a/content/docs/tag_special_layouts.html
+++ b/content/docs/tag_special_layouts.html
@@ -647,7 +647,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/recipes/recipe_adaptable_filter_range.html
----------------------------------------------------------------------
diff --git a/content/recipes/recipe_adaptable_filter_range.html b/content/recipes/recipe_adaptable_filter_range.html
index bba9470..edeec4c 100644
--- a/content/recipes/recipe_adaptable_filter_range.html
+++ b/content/recipes/recipe_adaptable_filter_range.html
@@ -674,7 +674,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-quarks-website/blob/11237088/content/recipes/recipe_combining_streams_processing_results.html
----------------------------------------------------------------------
diff --git a/content/recipes/recipe_combining_streams_processing_results.html b/content/recipes/recipe_combining_streams_processing_results.html
index 19542f6..5f9c9ae 100644
--- a/content/recipes/recipe_combining_streams_processing_results.html
+++ b/content/recipes/recipe_combining_streams_processing_results.html
@@ -805,7 +805,7 @@ $('#toc').on('click', 'a', function() {
         <div class="col-lg-12 footer">
 
              Site last
-            generated: Apr 14, 2016 <br/>
+            generated: Apr 15, 2016 <br/>
 
         </div>
     </div>