Add local weather caching mechanism

This commit is contained in:
Samer Albahra
2015-07-02 19:19:56 -05:00
parent 199399ff5e
commit 66b4d1ccbd
6 changed files with 122 additions and 24 deletions

View File

@@ -0,0 +1,27 @@
files:
"/home/ec2-user/install_mongo.sh" :
mode: "0007555"
owner: root
group: root
content: |
#!/bin/bash
echo "[MongoDB]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
gpgcheck=0
enabled=1" | tee -a /etc/yum.repos.d/mongodb.repo
yum -y update
yum -y install mongodb-org-server mongodb-org-shell mongodb-org-tools
commands:
01install_mongo:
command: ./install_mongo.sh
cwd: /home/ec2-user
test: '[ ! -f /usr/bin/mongo ] && echo "MongoDB not installed"'
services:
sysvinit:
mongod:
enabled: true
ensureRunning: true
commands: ['01install_mongo']

View File

@@ -2,7 +2,6 @@ module.exports = function( grunt ) {
// Load node-modules; // Load node-modules;
grunt.loadNpmTasks( "grunt-contrib-jshint" ); grunt.loadNpmTasks( "grunt-contrib-jshint" );
grunt.loadNpmTasks( "grunt-contrib-compress" );
grunt.loadNpmTasks( "grunt-jscs" ); grunt.loadNpmTasks( "grunt-jscs" );
// Project configuration. // Project configuration.
@@ -10,36 +9,22 @@ module.exports = function( grunt ) {
pkg: grunt.file.readJSON( "package.json" ), pkg: grunt.file.readJSON( "package.json" ),
jshint: { jshint: {
main: [ "server.js", "routes/**" ], main: [ "Gruntfile.js", "server.js", "routes/**", "models/**" ],
options: { options: {
jshintrc: true jshintrc: true
} }
}, },
jscs: { jscs: {
main: [ "server.js", "routes/**" ], main: [ "Gruntfile.js", "server.js", "routes/**", "models/**" ],
options: { options: {
config: true, config: true,
fix: true fix: true
} }
},
compress: {
build: {
options: {
archive: "WeatherService.zip"
},
files: [ {
src: [ ".ebextensions/*", "routes/*", "server.js", "package.json" ],
expand: true
} ]
}
} }
} ); } );
// Default task(s). // Default task(s).
grunt.registerTask( "default", [ "jshint", "jscs" ] ); grunt.registerTask( "default", [ "jshint", "jscs" ] );
grunt.registerTask( "build", [ "jshint", "jscs", "compress:build" ] );
}; };

14
models/Cache.js Normal file
View File

@@ -0,0 +1,14 @@
var mongoose = require( "mongoose" );
var cacheSchema = new mongoose.Schema( {
// Stores the current GPS location as unique for weather data cache
location: { type: String, unique: true },
// This is the end of day value for the humidity yesterday
yesterdayHumidity: Number,
currentHumidityTotal: Number,
currentHumidityCount: Number
} );
module.exports = mongoose.model( "Cache", cacheSchema );

View File

@@ -4,12 +4,13 @@
"version": "0.0.1", "version": "0.0.1",
"repository": "https://github.com/OpenSprinkler/Weather-Adjustments/", "repository": "https://github.com/OpenSprinkler/Weather-Adjustments/",
"dependencies": { "dependencies": {
"cron": "^1.0.9",
"dotenv": "^1.2.0", "dotenv": "^1.2.0",
"express": "^4.13.0", "express": "^4.13.0",
"grunt": "^0.4.5", "grunt": "^0.4.5",
"grunt-contrib-compress": "^0.13.0",
"grunt-contrib-jshint": "^0.11.2", "grunt-contrib-jshint": "^0.11.2",
"grunt-jscs": "^1.8.0", "grunt-jscs": "^1.8.0",
"mongoose": "^4.0.6",
"xml2js": "^0.4.9" "xml2js": "^0.4.9"
} }
} }

View File

@@ -2,6 +2,7 @@
var http = require( "http" ), var http = require( "http" ),
parseXML = require( "xml2js" ).parseString, parseXML = require( "xml2js" ).parseString,
Cache = require( "../models/Cache" ),
// Define regex filters to match against location // Define regex filters to match against location
filters = { filters = {
@@ -126,9 +127,20 @@
httpRequest( url, function( data ) { httpRequest( url, function( data ) {
try { try {
var weather = JSON.parse( data );
// Return the data to the callback function if successful location = location.join( "," );
callback( JSON.parse( data ) );
Cache.findOne( { location: location }, function( err, record ) {
if ( record && record.hasOwnProperty( "yesterdayHumidity" ) ) {
weather.yesterdayHumidity = record.yesterdayHumidity;
}
// Return the data to the callback function if successful
callback( weather );
} );
updateCache( location, weather );
} catch (err) { } catch (err) {
// Otherwise indicate the request failed // Otherwise indicate the request failed
@@ -163,6 +175,28 @@
} ); } );
} }
// Update weather cache record in the local database
function updateCache( location, weather ) {
// Search for a cache record for the provided location
Cache.findOne( { location: location }, function( err, record ) {
// If a record is found update the data and save it
if ( record ) {
record.currentHumidityTotal += weather.observation.imperial.rh;
record.currentHumidityCount++;
record.save();
} else {
// If no cache record is found, generate a new one and save it
new Cache( {
currentHumidityTotal: weather.observation.imperial.rh,
currentHumidityCount: 1
} ).save();
}
} );
}
// Calculates the resulting water scale using the provided weather data, adjustment method and options // Calculates the resulting water scale using the provided weather data, adjustment method and options
function calculateWeatherScale( adjustmentMethod, adjustmentOptions, weather ) { function calculateWeatherScale( adjustmentMethod, adjustmentOptions, weather ) {

View File

@@ -1,12 +1,23 @@
var express = require( "express" ), var express = require( "express" ),
weather = require( "./routes/weather.js" ), weather = require( "./routes/weather.js" ),
port = process.env.PORT || 3000; mongoose = require( "mongoose" ),
app = express(); Cache = require( "./models/Cache" ),
CronJob = require( "cron" ).CronJob,
port = process.env.PORT || 3000;
app = express();
if ( !process.env.PORT ) { if ( !process.env.PORT ) {
require( "dotenv" ).load(); require( "dotenv" ).load();
} }
// Connect to local MongoDB instance
mongoose.connect( "localhost" );
// If the database connection cannot be established, throw an error
mongoose.connection.on( "error", function() {
console.error( "MongoDB Connection Error. Please make sure that MongoDB is running." );
} );
// Handle requests matching /weatherID.py where ID corresponds to the // Handle requests matching /weatherID.py where ID corresponds to the
// weather adjustment method selector. // weather adjustment method selector.
// This endpoint is considered deprecated and supported for prior firmware // This endpoint is considered deprecated and supported for prior firmware
@@ -23,3 +34,29 @@ var server = app.listen( port, "127.0.0.1", function() {
console.log( "OpenSprinkler Weather Service now listening on port %s", port ); console.log( "OpenSprinkler Weather Service now listening on port %s", port );
} ); } );
// Schedule a cronjob daily to consildate the weather cache data, runs daily
new CronJob( "0 * * * * *", function() {
// Find all records in the weather cache
Cache.find( {}, function( err, records ) {
// Cycle through each record
records.forEach( function( record ){
// If the record contains any unaveraged data, then process the record
if ( record.currentHumidityCount > 0 ) {
// Average the humidity by dividing the total over the total data points collected
record.yesterdayHumidity = record.currentHumidityTotal / record.currentHumidityCount;
// Reset the current humidity data for the new day
record.currentHumidityTotal = 0;
record.currentHumidityCount = 0;
// Save the record in the database
record.save();
}
} );
} );
}, null, true, "UTC" );