Kevin LaySheen
Published © GPL3+

Smarter Greenhouse

The problem with modern automated greenhouses is that they are reactive instead of proactive.

IntermediateShowcase (no instructions)24 hours748
Smarter Greenhouse

Things used in this project

Story

Read more

Schematics

Schematics

Code

Greenhouse.js

JavaScript
This is our code for opening and closing blinds when temperatures reach a certain degrees. Outside temperatures help us predict if we are going to need to close the blinds beforehand.
/*jslint node:true, vars:true, bitwise:true, unparam:true */
/*jshint unused:true */
/*global */
/*
A simple node.js application intended to read data from Analog pins on the Intel based development boards 
such as the Intel(R) Galileo and Edison with Arduino breakout board, and display it in a browser running on the client.

This demonstrates use of http.createServer, and fs.

MRAA - Low Level Skeleton Library for Communication on GNU/Linux platforms
Library in C/C++ to interface with Galileo & other Intel platforms, in a structured and sane API with port nanmes/numbering that match boards & with bindings to javascript & python.
  
Steps for installing MRAA & UPM Library on Intel IoT Platform with IoTDevKit Linux* image
Using a ssh client: 
1. echo "src maa-upm http://iotdk.intel.com/repos/1.1/intelgalactic" > /etc/opkg/intel-iotdk.conf
2. opkg update
3. opkg upgrade

Article: https://software.intel.com/en-us/xdk-sample-creating-a-web-server
*/
// Set this to the ip address of your board (not 127.0.0.1)
var ipAddress = '10.48.2.77';

var mraa = require('mraa'); //require mraa
console.log('MRAA Version: ' + mraa.getVersion()); //write the mraa version to the console

// Start by loading in some data
var fs = require('fs');

var lightSensorPage = fs.readFileSync('/node_app_slot/lightsensor.html');

// Insert the ip address in the code in the page

lightSensorPage = String(lightSensorPage).replace(/<<ipAddress>>/, ipAddress);

var analogPin0 = new mraa.Aio(0);
var https = require('https');
var http = require('http');
http.createServer(function(req, res) {
    var value;
    // This is a very quick and dirty way of detecting a request for the page
    // versus a request for light values
    if (req.url.indexOf('lightsensor') != -1) {
        res.writeHead(200, {
            'Content-Type': 'text/html'
        });
        res.end(lightSensorPage);
    } else if (req.url.indexOf('motor') != -1) {
        console.log((req.headers));

        res.writeHead(200, {
            'Content-Type': 'text/html'
        });
        res.end(lightSensorPage);
    } else {
        value = analogPin0.read();
        res.writeHead(200, {
            'Content-Type': 'text/json'
        });
        res.end(JSON.stringify({
            Temp: fahrenheit
        }));
    }
}).listen(1337, ipAddress);


//Motor

var Uln200xa_lib = require('jsupm_uln200xa');
// Instantiate a Stepper motor on a ULN200XA Darlington Motor Driver
// This was tested with the Grove Geared Step Motor with Driver

// Instantiate a ULN2003XA stepper object
var myUln200xa_obj = new Uln200xa_lib.ULN200XA(4096, 8, 9, 10, 11);


myUln200xa_obj.goForward = function(changeangle) {


    myUln200xa_obj.setSpeed(5); // 5 RPMs
    if (changeangle > 0) {
        myUln200xa_obj.setDirection(Uln200xa_lib.ULN200XA.DIR_CW);
    } else {
        myUln200xa_obj.setDirection(Uln200xa_lib.ULN200XA.DIR_CCW);
    }
    //console.log("Rotating "+changeangle+" revolution clockwise.");
    myUln200xa_obj.stepperSteps(Math.abs(changeangle) * 1024 / 90);
};

myUln200xa_obj.reverseDirection = function() {
    console.log("Rotating 1/4 revolution counter clockwise.");
    myUln200xa_obj.setDirection(Uln200xa_lib.ULN200XA.DIR_CCW);
    myUln200xa_obj.stepperSteps(1024);
};

myUln200xa_obj.stop = function() {
    myUln200xa_obj.release();
};

myUln200xa_obj.quit = function() {
    myUln200xa_obj = null;
    Uln200xa_lib.cleanUp();
    Uln200xa_lib = null;
    console.log("Exiting");
    process.exit(0);
};


var groveSensor = require('jsupm_grove');

// Create the temperature sensor object using AIO pin 0
var temp = new groveSensor.GroveTemp(1);
console.log(temp.name());

// Read the temperature ten times, printing both the Celsius and
// equivalent Fahrenheit temperature, waiting one second between readings
var i = 0;

var fahrenheit;
var motorState = 0;
var c1 = .15; //sunlight coefficient
var c2 = .4; //convection coefficient
var angle = 0;

var getAngle = function(Ti, To, Td) {
    var nextangle = (Td + c2 * (Ti - To) - Ti) / (c1 * To);
    return nextangle * 90;
}

var setAngle = function(currentangle, nextangle) {
    myUln200xa_obj.goForward(nextangle - currentangle);
}

var waiting = setInterval(function() {
    var celsius = temp.value();
    fahrenheit = celsius * 9.0 / 5.0 + 32.0;
    console.log(Math.round(fahrenheit) + " degrees Fahrenheit");
    console.log(angle);
    if (finishedLoading) {
        var Ti = fahrenheit;
        var valuestring = JSON.stringify(x[1])
            //console.log(valuestring.substring(28,30));
        var To = valuestring.substring(28, 30);
        var Td = 80;
        var nextangle = getAngle(Ti, To, Td);
        if (nextangle > 90) {
            nextangle = 90
        }
        if (nextangle < 0) {
            nextangle = 0
        }
        console.log("setting angle to: " + nextangle);

        if (Math.abs(nextangle - angle) > 5) {
            setAngle(angle, nextangle);
            angle = nextangle;
        }
    }
}, 5000);
var rawdata;
var x;
var finishedLoading;
var username = 'e6dc3f40-b7c8-45fc-92ae-e0451db0b9c1';
var password = '6eL0ZfkXIN';
var auth = 'Basic' + new Buffer(username + ':' + password).toString('base64');
var options = {
    host: 'twcservice.mybluemix.net',
    path: '/api/weather/v1/geocode/37.77/-122.41/forecast/hourly/48hour.json',


    headers: {
        'Authorization': 'Basic ' + new Buffer(username + ':' + password).toString('base64')
    }
};


var y;
var c;
https.get(options, function(res) {
    res.setEncoding('utf8')
    var str = '';
    res.on('data', function(chunk) {
        str += chunk;
    });
    res.on('end', function() {
        var rawdata = JSON.parse(str);
        var forecasts = rawdata.forecasts;
        temparray = [];

        for (var i = 0; i < 47; i++) {
            //console.log(forecasts[i].fcst_valid_local);

            if (forecasts[i].fcst_valid_local != null) {
                //                    var currentdate = extractdate(forecasts[i].fcst_valid_local);
                var key = forecasts[i].fcst_valid_local.toString();
                var obj = {};
                obj[key] = forecasts[i].temp;
                temparray.push(obj);

                // console.log(y)
                // temparray.push({y: forecasts[i].temp});

            }
        }
        //        extractDate(temparray[0].time);

        x = temparray;
        finishedLoading = true;

    });


}).end();

var getDateTime = function() {

    var date = new Date();

    var hour = date.getHours();
    hour = (hour < 10 ? "0" : "") + hour;

    var min = date.getMinutes();
    min = (min < 10 ? "0" : "") + min;

    var sec = date.getSeconds();
    sec = (sec < 10 ? "0" : "") + sec;

    var year = date.getFullYear();

    var month = date.getMonth() + 1;
    month = (month < 10 ? "0" : "") + month;

    var day = date.getDate();
    day = (day < 10 ? "0" : "") + day;

    return (year + "-" + month + "-" + day + "T" + (hour - 7) + ":00:00-0700");
}

var extractDate = function(inputdate) {
    var year = inputdate.substring(0, 4);
    var month = inputdate.substring(5, 7);
    var day = inputdate.substring(8, 10);
    var hour = inputdate.substring(11, 13);
    //console.log("year" + year + "month" + month + "day"+day+"hour"+hour);
    return ([year, month, day, hour])
}


var readX = function() {
    console.log("X = ")
    console.log(x);
    var days = getDateTime();
    console.log(days);

}

Credits

Kevin Lay

Kevin Lay

1 project • 1 follower
Sheen

Sheen

1 project • 1 follower

Comments