Published © CC BY-NC-SA

Pick-A-Plant

Choose the right plant for you, using Pick-A-Plant. This IoT device will help you find the best match for every location!

BeginnerFull instructions provided20 hours602

Things used in this project

Hardware components

AVR-IoT WG Development Board
Microchip AVR-IoT WG Development Board
×1
2xAAA Battery Holder w/ Cover & Switch
×1

Software apps and online services

Cloud IoT Core
Google Cloud IoT Core

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

Thingiverse

https://www.thingiverse.com/thing:2222088

Flower Casing

Code

JS Code

JavaScript
var myChart = null;
var lastUpdate = null;
var plants = null;


function initialLoadData() {

  var settings = {
    "async": true,
    "crossDomain": true,
    "url": 'https://<YOUR_PROJECT_NAME>.firebaseio.com/avr-iot/data/<YOUR_UID>.json?orderBy="time"&limitToLast=10',
    "method": "GET"
  }

  $.ajax(settings)

    .done(function (data) {
      var cleanData = formatData(data);
      drawChart(cleanData);
    })

  $.getJSON("./data/plants.json", function (json) {
    plants = json;
  });
}

function formatData(data) {

  var dataSets = [
    {
      data: [],
      label: "Temperature",
      borderColor: "#3e95cd",
      fill: false
    },
    {
      data: [],
      label: "Light",
      borderColor: "#8e5ea2",
      fill: false
    }
  ];

  Object.keys(data).forEach(function (key) {

    dataSets[0].data.push(parseInt(data[key]["Temp"]));
    dataSets[1].data.push(data[key]["Light"]);

  });

  return dataSets;
}

function drawChart(dataSets) {

  myChart = new Chart(document.getElementById("line-chart"), {
    type: 'line',
    data: {
      labels: ['-18s', '-16s', '-14s', '-12s', '-10s', '-8s', '-6s', '-4s', '-2s', 'now'],
      datasets: dataSets
    },
    options: {
      title: {
        display: true,
        text: 'Measurements'
      }
    }
  });
}

function updateChart() {

  // Get the latest record
  var settings = {
    "async": true,
    "crossDomain": true,
    "url": 'https://<YOUR_PROJECT_NAME>.firebaseio.com/avr-iot/data/<YOUR_UID>.json?orderBy="time"&limitToLast=1',
    "method": "GET"
  }

  $.ajax(settings)
    .done(function (data) {

      var update = false;

      Object.keys(data).forEach(function (key) {

        if (lastUpdate !== data[key]["time"]) {
          myChart.data.datasets[0].data.push(parseInt(data[key]["Temp"]));
          myChart.data.datasets[1].data.push(data[key]["Light"]);
          lastUpdate = data[key]["time"];
          update = true;
        }
      });

      if (update) {

        delete myChart.data.datasets[0].data[0];
        myChart.data.datasets[0].data.shift();

        delete myChart.data.datasets[1].data[0];
        myChart.data.datasets[1].data.shift();


        var date = new Date(lastUpdate);
        var updatedSection = document.getElementById("lastUpdated");
        var content = document.createTextNode(date.toString());

        while (updatedSection.hasChildNodes()) {
          updatedSection.removeChild(updatedSection.lastChild);
        }

        updatedSection.appendChild(content);


        myChart.update();
      }

    })
}

function pickPlant() {

  var temp = myChart.data.datasets[0].data;
  var tempAvg = 0;
  var tempMax = null;
  var tempMin = null;


  for (var i = 0; i < temp.length; i++) {

    var currentValue = parseInt(temp[i]);

    if (tempMin == null && tempMax == null) {

      tempMin = currentValue;
      tempMax = currentValue;
    }

    if (tempMax < currentValue) {
      tempMax = currentValue;
    } if (tempMin > currentValue) {
      tempMin = currentValue;
    }

    tempAvg += currentValue;
  }

  tempAvg = tempAvg / temp.length - 1;

  var light = myChart.data.datasets[1].data;
  var lightAvg = 0;
  var lightMax = null;
  var lightMin = null;

  for (var i = 0; i < light.length; i++) {

    var currentValue = parseInt(light[i]);

    if (lightMin == null && lightMax == null) {

      lightMin = currentValue;
      lightMax = currentValue;
    }

    if (lightMax < currentValue) {
      lightMax = currentValue;
    } if (lightMin > currentValue) {
      lightMin = currentValue;
    }

    lightAvg += currentValue;

  }

  lightAvg = lightAvg / light.length - 1;

  document.getElementById("lightAvg").innerHTML = (lightAvg.toString()).bold();
  document.getElementById("lightMin").innerHTML = (lightMin.toString()).bold();
  document.getElementById("lightMax").innerHTML = (lightMax.toString()).bold();

  document.getElementById("tempAvg").innerHTML = (tempAvg.toString()).bold();
  document.getElementById("tempMin").innerHTML = (tempMin.toString()).bold();
  document.getElementById("tempMax").innerHTML = (tempMax.toString()).bold();


  var plantPicked = selectPlantFromJSON(tempAvg, lightAvg);
  document.getElementById("plantName").innerHTML = "Your best match is: " + plantPicked.name.bold();
  document.getElementById("description").innerHTML = plantPicked.description;
  document.getElementById("plantLink").href = plantPicked.url;
  document.getElementById("plantLink").hidden = false;


}

function selectPlantFromJSON(tempAvg, lightAvg) {

  var possiblePlants = plants.plants;
  var pickedPlant = null;

  possiblePlants.forEach(plant => {

    if (tempAvg > plant["min-temp"] && tempAvg < plant["max-temp"]) {

      if (lightAvg > plant["min-light"] && lightAvg < plant["max-light"]) {
        pickedPlant = plant;
      }
    }
  });
  return pickedPlant;

}

Plant JSON

JSON
{"plants":[{
  "name":"Lucky Bamboo",
  "description": "The Lucky bamboo is an easy to grow plant which can thrive in soil or water. While this plant has the common name of bamboo it is not an actual bamboo plant species and belongs to the dracaena genus, although the stalks have a similar appearance." ,
  "url": "https://www.houseplantsexpert.com/lucky-bamboo-plant.html",
  "min-temp":18 ,
  "max-temp":32 ,
  "min-light":150 ,
  "max-light":400
}, {
  "name":"Moth Orchid",
  "description": "Moth orchid is the common name for the phalaenopsis orchid that's quickly become one of the most popular species from the orchidaceae family of flowering plants. Glorious colored blooms all year round and the 'ease of growing' is what makes these a popular house plant choice." ,
  "url": "https://www.houseplantsexpert.com/moth-orchid.html" ,
  "min-temp": 16,
  "max-temp": 24,
  "min-light": 400 ,
  "max-light": 1000
},{
  "name":"Weeping Fig",
  "description": "The weeping fig is part of the Ficus plant genus (scientific name: F. benjamina) and tree like, in looks. With large arching branches and long pointed leaves, it looks attractive indoors (apart from leaves dropping).",
  "url": "https://www.houseplantsexpert.com/weeping-fig.html",
  "min-temp":16 ,
  "max-temp": 24,
  "min-light": 150,
  "max-light": 400
},{
  "name":"Aloe Vera",
  "description": "The Aloe Vera plant (succulent type) is well known for offering possible health and beauty benefits. This succulent is a tough species that is very easy to care for and rarely presents problems for most growers.",
  "url": "https://www.houseplantsexpert.com/aloe-vera-house-plant.html",
  "min-temp": 21 ,
  "max-temp": 26,
  "min-light": 200,
  "max-light": 1000
},{
  "name":"Bunny Ear Cactus",
  "description": "Enthusiasts of this traditional cacti enjoy its easy to please nature. Despite the cute name, the Bunny Ear Cactus is in no way cuddly. The polka dot cactus (other common name) is fairly easy to grow if a grower can provide enough bright light, no over-watering, provide it's winter resting period and average room temperatures. Simple!",
  "url": "https://www.houseplantsexpert.com/bunny-ear-cactus.html",
  "min-temp": 10,
  "max-temp": 37,
  "min-light": 200,
  "max-light": 1000
},{
  "name":"Areca Palm",
  "description": "The areca palm, also known as the butterfly and golden cane palm is the most popular grown indoors from the dypsis genus, and easy to grow. Multiple cane like stems grow from the root system and produce attractive arching fronds, with quite narrow leaflets." ,
  "url": "https://www.houseplantsexpert.com/areca-palm.html",
  "min-temp": 16,
  "max-temp": 24,
  "min-light": 150,
  "max-light": 400
},{
  "name":"Boston Fern",
  "description": "The Boston fern is the most popular of all ferns grown indoors and has been found to be one of the easiest to care for and maintain. Compared to most other ferns your going to find this plant a lot easier to care for in regards to light, humidity levels and propagating.",
  "url": "https://www.houseplantsexpert.com/boston-fern-care-indoors.html",
  "min-temp": 16,
  "max-temp": 24,
  "min-light": 50,
  "max-light": 300
},{
  "name":"African Violet",
  "description": "The African violet is one of the most popular flowering house plants from the saintpaulia genus. The genus has about 20 species and thousands of varieties. These have become easier for the average home grower to produce perfect blooms, although they need to be provided with some special care and attention." ,
  "url": "https://www.houseplantsexpert.com/african-violet-care-information.html",
  "min-temp": 16,
  "max-temp": 24,
  "min-light": 150,
  "max-light": 600
},{
  "name":"Calla Lilly",
  "description": "Although an outdoor plant by nature, the Calla Lily will perform wonderfully as an indoor plant. Keeping this rhizome happy indoors is a matter of paying attention to some very basic growing conditions. The Zantedeschia aethiopica is native to southern Africa. As such, this plant is used to very different growing conditions than are found naturally in other parts of the world.",
  "url": "https://www.houseplantsexpert.com/growing-calla-lilly-plants-indoors-and-care.html",
  "min-temp": 12,
  "max-temp": 24,
  "min-light": 150,
  "max-light": 600
},{
  "name":"Rubber Plant",
  "description": "The rubber plant (Ficus elastica) is a popular ornamental plant from the Ficus genus. In it's natural habitat it grows over 30 metres tall, however, the varieties grown indoors are a much more manageable height." ,
  "url": "https://www.houseplantsexpert.com/rubber-plant.html" ,
  "min-temp": 15,
  "max-temp": 24,
  "min-light": 150,
  "max-light": 400
}],
"light":[
  {"very bright": 1000},
  {"direct sunlight": [400, 1000]},
  {"normal":[150, 400]},
  {"dim": [50, 150]},
  {"shade": 50}
  ]}

Bootstrap fronted

HTML
<!DOCTYPE html>
<html lang="en">

<head>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">

  <title>Pick-a-Plant</title>

  <!-- Custom fonts for this template-->
  <link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">

  <!-- Page level plugin CSS-->
  <link href="vendor/datatables/dataTables.bootstrap4.css" rel="stylesheet">

  <!-- Custom styles for this template-->
  <link href="css/sb-admin.css" rel="stylesheet">

  <script src="index.js"></script>

</head>

<body id="page-top">

  <div id="wrapper">

    <div id="content-wrapper">

      <div class="container-fluid">

        <!-- Icon Cards-->
        <div class="row">

          <div class="col-xl-8 col-sm-8 mb-8">
            <div class="card text-white bg-success o-hidden h-100">
              <div class="card-body">
                <div class="card-body-icon">
                  <i class="fas fa-fw fa-leaf"></i>
                </div>
                <div id="advice" class="mr-5">
                  <h4 class="">Advice</h4>
                  <p></p>
                  <p id="plantName"> </p>
                  <p id='description'> </p>
                </div>
              </div>
              <div class="card-footer text-white clearfix small z-1">
                <button type="button" class="btn btn-lg btn-outline-light" onclick="pickPlant()"><i
                    class="fas fa-lg fa-search"></i></button>
                <span>
                  <a id="plantLink" hidden="true" class="float-right btn btn-lg btn-outline-light" href="#"
                    target="_blank"><i class="fas fa-lg fa-info-circle"></i></a>
                </span>
              </div>
            </div>
          </div>

          <div class="col-xl-2 col-sm-2 mb-2">
            <div id='lightSection' class="card text-white bg-warning o-hidden h-100">
              <div class="card-body">
                <div class="card-body-icon">
                  <i class="fas fa-fw fa-sun"></i>
                </div>
                <div class="mr-5" id="lightText">
                  <h4 class="">Light</h4>
                  <p></p>
                  <p>
                    <span><i class="fas fa-sun fa-2x mr-3"></i></span>
                    <span id='lightMax'></span>
                  </p>
                  <p>
                    <span><i class="far fa-sun fa-2x mr-3"></i></span>
                    <span id='lightMin'></span>
                  </p>
                  <p>
                    <span><i class="fas fa-chart-line fa-2x mr-3"></i></span>
                    <span id='lightAvg'></span>
                  </p>
                </div>
              </div>
              <div class="card-footer text-white clearfix small z-1">
                <h5>Lux</h5>
              </div>
            </div>
          </div>

          <div class="col-xl-2 col-sm-2 mb-2">
            <div id='tempSection' class="card text-white bg-danger o-hidden h-100">
              <div class="card-body">
                <div class="card-body-icon">
                  <i class="fas fa-fw fa-thermometer-empty"></i>
                </div>
                <div class="mr-5" id="tempText">
                  <h4 class="">Temperature</h4>
                  <p></p>
                  <p>
                    <span><i class="fas fa-thermometer-full fa-2x mr-3"></i></span>
                    <span id='tempMax'></span>
                  </p>
                  <p>
                    <span><i class="fas fa-thermometer-empty fa-2x mr-3"></i></span>
                    <span id='tempMin' class=""></span>
                  </p>
                  <p>
                    <span><i class="fas fa-chart-line fa-2x mr-3"></i></span>
                    <span id='tempAvg'></span>
                  </p>
                </div>
              </div>
              <div class="card-footer text-white clearfix small z-1">
                <h5>Celcius</h5>
              </div>
            </div>
          </div>
        </div>

        <!-- Area Chart Example-->
        <div class="card mb-3 mt-3">
          <div class="card-header">
            <i class="fas fa-chart-area"></i>
            Data</div>
          <div class="card-body">
            <canvas id="line-chart" width="100%" height="30"></canvas>
          </div>
          <div id="lastUpdated" class="card-footer small text-muted">Last updated: <div id="lastUpdated"></div>
          </div>
        </div>

      </div>

    </div>

  </div>
  </div>

  <!-- Bootstrap core JavaScript-->
  <script src="vendor/jquery/jquery.min.js"></script>
  <script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

  <!-- Core plugin JavaScript-->
  <script src="vendor/jquery-easing/jquery.easing.min.js"></script>

  <!-- Page level plugin JavaScript-->
  <script src="vendor/chart.js/Chart.min.js"></script>
  <script src="vendor/datatables/jquery.dataTables.js"></script>
  <script src="vendor/datatables/dataTables.bootstrap4.js"></script>

  <!-- Custom scripts for all pages-->
  <script src="js/sb-admin.min.js"></script>

  <script>
    initialLoadData();
    setInterval(updateChart, 2000);
  </script>
</body>

</html>

Github

https://github.com/Leverege/microchip-avr-iot

Credits

Comments