Porting Weather APP Into Node.js(3)

Get the timstamp of the record

ObjectID could automatically store the insert timestamp, see following command:

> db.usercollection.find().pretty()
........
........
> ObjectId("53be4e7eb5ca215e38c5f651").getTimestamp()
ISODate("2014-07-10T08:27:42Z")
> ObjectId("53be4e7cb5ca215e38c5f650").getTimestamp()
ISODate("2014-07-10T08:27:40Z")

Time Format

Run following commands to get the timestamp since 1970:

> day=new Date()
Sat Jul 12 2014 21:15:10 GMT+0800 (CST)
> day
Sat Jul 12 2014 21:15:10 GMT+0800 (CST)
> day.getTime()
1405170910049

The date which we fetched should be multiply 1000.
And write a for loop for getting out the real date:

      // helper function
      function getDate(d) {
          return new Date(d);
      }
      console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
      // Refers to 1405170910049
      // WhatWeGet 1405170047
      // Should multiply 1000, Print out all of the timestamp
      for ( kk = 1; kk < 24; kk++)
      {
         console.log(getDate(date_data[kk]*1000));
      }

Print the type of the variable:

console.log(typeof (#{weatherlist[3].Temperature}));

Porting Weather APP Into Node.js(2)

Add packages dependencies:

  "dependencies": {
    "express": "^4.5.1",
    "logfmt": "^1.1.2",
    "static-favicon": "~1.0.0",
    "morgan": "~1.0.0",
    "cookie-parser": "~1.0.1",
    "body-parser": "~1.0.0",
    "debug": "~0.7.4",
    "jade": "~1.3.0", 
    "mongodb": "*",
    "monk": "*"
  },

Then npm install to install the dependencies.

Install the package and save the version in package.json:

npm install forecast --save
npm install cron --save
npm install http --save
npm install cheerio --save

Merge the TestNanjing.js and web.js file, let the fetch to be a function, or to be module.

My Translator In ArchLinux(3)

Using redis for cache the dictionary.

    # In C, it's simple to use do...while(), but in python, we need to judge the input, 
    # Fortunately, the input is very simple, because get infos from RedisQue is blocking.
    # Forever Listening...
    while True:
        # Key in RedisQueue is 'dic', and we simply get its content:
        q = RedisQueue('dic')
        # cmdargs = q.get()
        # cmdargs = str(sys.argv) ## args
        to_be_refer_word = q.get()
        try:
            result = my_dict_reader.get_dict_by_word(str(to_be_refer_word))  ## Using args[1] for querying
            print result[0].values()[0]		## output result in terminal
            result_str = "\'<span color=\"green\" size=\"14000\">"+result[0].values()[0]+"</span>\'"	## Build the command line for notify-send
            call(["notify-send", to_be_refer_word, result_str])		## Call notify-send to print on screen, last for 5 seconds
        except Exception, e:
            print "Not Find!"

Then we write the query file named refer.py:

#!/usr/bin/python2
# -*- coding: utf-8 -*-
# For using RedisQueue to fetch the refer words 
import sys
from RedisQueue import RedisQueue

q = RedisQueue('dic')
q.put(str(sys.argv[1]))


Add the following lines as /usr/bin/mydic:

# Using redis
python2 /home/Trusty/code/python/mypython/stardict/refer.py $@


This will greatly improve the refer time, you could get the real-time result via mydic New_Words

Porting Weather APP Into Node.js

Website Design

Use express for generating the whole website.

$ pwd 
/home/Trusty/code/nodejs/weather
[Trusty@~/code/nodejs/weather]$ express weather

The express framework will be generated.

Add following dependencies into the weather/package.json:

    "jade": "~1.3.0", 
    "mongodb": "*",
    "monk": "*"

Install packages:

$ cd weather
$ npm install

mkdir data, this command will create a directory named data which is used for holding our mongodb.
Now visit http://localhost:3000/ you will see the demo html website.

This website should have the inteface for operating the database(MongoDB), so I will add some sub-pages for handling the request for insert and query the database.

Insert Records Into MongoDB

Design database in MongoDB:

$ mongo
$ show dbs
admin       (empty)
local       0.078GB
my-website  0.078GB
mydb        0.078GB
nodetest1   0.078GB
test        (empty)
$ use weathertest

The DataSet should be designed as following:

{
    "_id" : 1234,
    "AQI" : "70",
    "Level" : "良", 
    "FirstPollution" : "臭氧1小时", 
    "PM2_5" : "51", 
    "PM10" : "70", 
    "CO" : "0.148", 
    "NO2" : "31", 
    "O3_1hour" : "168", 
    "O3_8hour" : "68", 
    "S02" : "13" 
}

So the insert sentense should be like following:

db.usercollection.insert({ "AQI" : "70", "Level" : "良", "FirstPollution" : "臭氧1小时", "PM2_5" : "51", "PM10" : "70", "CO" : "0.148", "NO2" : "31", "O3_1hour" : "168", "O3_8hour" : "68", "SO2" :"13"})

Verify the insert result via:

> db.usercollection.find().pretty()
{
	"_id" : ObjectId("53ba7e137346b7523d951084"),
	"AQI" : "70",
	"Level" : "良",
	"FirstPollution" : "臭氧1小时",
	"PM2_5" : "51",
	"PM10" : "70",
	"CO" : "0.148",
	"NO2" : "31",
	"O3_1hour" : "168",
	"O3_8hour" : "68",
	"SO2" : "13"
}

Should add more informations into the database, for example the temperature/humidity, which could also be fetched via npm package.
First delete the inserted item via following command:

> db.usercollection.remove({"_id" : ObjectId("53ba7e137346b7523d951084")});
WriteResult({ "nRemoved" : 1 })
> db.usercollection.find().pretty()

Then insert a new organized records and verify the insertion :

db.usercollection.insert({ "Temperature" : "21.9", "DewPoint" : "19.93", "Humidity" : "0.89", "Pressure" : "1004.85", "Ozeone" : "289.03",  "AQI" : "70", "Level" : "良", "FirstPollution" : "臭氧1小时", "PM2_5" : "51", "PM10" : "70", "CO" : "0.148", "NO2" : "31", "O3_1hour" : "168", "O3_8hour" : "68", "SO2" :"13", "CurrentTime": "ISODate()"})
> db.usercollection.find().pretty()
{
	"_id" : ObjectId("53ba82f97346b7523d951085"),
	"Temperature" : "21.9",
	"DewPoint" : "19.93",
	"Humidity" : "0.89",
	"Pressure" : "1004.85",
	"Ozeone" : "289.03",
	"AQI" : "70",
	"Level" : "良",
	"FirstPollution" : "臭氧1小时",
	"PM2_5" : "51",
	"PM10" : "70",
	"CO" : "0.148",
	"NO2" : "31",
	"O3_1hour" : "168",
	"O3_8hour" : "68",
	"SO2" : "13"
}

We will insert many many records into the database, how to distinguish them? By Timestamp!!!

In MongoDB we have the built-in Function Date():

> Date()
Mon Jul 07 2014 19:29:36 GMT+0800 (CST)

Each inserted Dataset’s timestamp could be fetched out via following command:

> ObjectId("53ba876d7346b7523d951088").getTimestamp()
ISODate("2014-07-07T11:41:33Z")

Next step is using node.js api for processing the dataset.

Display The Inserted Records

We want to display the result like following:

<ul>
    <li>Temperature: 21.9, DewPoint: 19.93, Humidity: 0.89, Pressure: 1004.85, Ozeone: 289.03, AQI: 70, Level: 良, FirstPollution: 臭氧1小时, PM2.5: 51, PM10: 70, CO: 0.148, NO2: 31, O3一小时: 168, O3八小时: 68, So2: 13。 </li>
    <li>Temperature: 21.9, DewPoint: 19.93, Humidity: 0.89, Pressure: 1004.85, Ozeone: 289.03, AQI: 70, Level: 良, FirstPollution: 臭氧1小时, PM2.5: 51, PM10: 70, CO: 0.148, NO2: 31, O3一小时: 168, O3八小时: 68, So2: 13。 </li>
    <li>Temperature: 21.9, DewPoint: 19.93, Humidity: 0.89, Pressure: 1004.85, Ozeone: 289.03, AQI: 70, Level: 良, FirstPollution: 臭氧1小时, PM2.5: 51, PM10: 70, CO: 0.148, NO2: 31, O3一小时: 168, O3八小时: 68, So2: 13。 </li>
</ul>

Change the router/index.js, add following lines:

/* GET weatherlist page. */
router.get('/weatherlist', function(req, res) {
    var db = req.db;
    var collection = db.get('usercollection');
    collection.find({},{},function(e,docs){
        res.render('weatherlist', {
            "weatherlist" : docs
        });
    });
});

Add the new file named weatherlist.jade under views/ folder:

block content
    h1.
        Weather List
    ul
        each weather, i in weatherlist
            li
                首要污染物: #{weather.FirstPollution}, <br />级别: #{weather.Level},<br />AQI: #{weather.AQI},<br />PM2.5: #{weather.PM2_5},<br />PM10: #{weather.PM10}, <br />一氧化碳: #{weather.CO}, <br />二氧化氮: #{weather.NO2}, <br />臭氧一小时浓度: #{weather.O3_1hour}, <br />臭氧八小时浓度: #{weather.O3_8hour}, <br />二氧化硫: #{weather.SO2}, <br />温度: #{weather.Temperature}, <br />露点: #{weather.DewPoint}, <br />湿度: #{weather.Humidity}, <br />气压: #{weather.Pressure}, <br />Ozeone: #{weather.Ozeone}

Now visit http://localhost:3000/weatherlist we could see the record has been listed on the page.

Insert Records In Nodejs

We should use a crontab task for inserting the record once we fetched the data.
The fetching process could be seperated from the web frame, or we could put the script into the directory, and let cron run it, it’s OK.

Following is a sample code for inserting record into mongoDB:

/* 
* This example uses the node MongoDB module to connect to the local
* mongodb database on this virtual machine
*
* More here: http://mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
*/

//require node modules (see package.json)
var MongoClient = require('mongodb').MongoClient
    , format = require('util').format;

//connect away
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
  if (err) throw err;
  console.log("Connected to Database");

  //simple json record
	var document = {name:"David1", title:"About MongoDB1"};
  
	//insert record
	db.collection('test').insert(document, function(err, records) {
		if (err) throw err;
		console.log("Record added as "+records[0]._id);
		//After insertion, close it.
		db.close();
		return;
	});
});

Once fetched, insert into the weathertest Database.

Display How Many Items

It should fetch the latest 24 items from the database, thus we should modify the code for fetching out 24 items.

Edit routes/index.js:

/* GET weatherlist page. */
router.get('/weatherlist', function(req, res) {
    var db = req.db;
    var collection = db.get('usercollection');

    collection.find({},{limit:24},function(e,docs){
        res.render('weatherlist', {
            "weatherlist" : docs
        });
    });

});

Deploy it on heroku

Via following commands we could setup a brand new APP on heroku:

$ heroku login
$ cat web.js
// web.js
var express = require("express");
var logfmt = require("logfmt");
var app = express();

app.use(logfmt.requestLogger());

app.get('/', function(req, res) {
  res.send('Hello World!');
});

var port = Number(process.env.PORT || 5000);
app.listen(port, function() {
  console.log("Listening on " + port);
});
$ npm init
$ npm install express logfmt --save
$ cat package.json
  "engines": {
    "node": "0.10.x"
  }
$ cat Procfile 
web: node web.js
$ foreman start
$ chromium http://localhost:5000
$ git init
$ git add .
$ git commit -m "init"
$ git remote add heroku git@heroku.com:node-weather-app.git
$ git push heroku master

Now visit http://node-weather-app.herokuapp.com you can see “Hello World!".

When adding MongoDB add-ons, it says failed with following information:

$ heroku addons:add mongolab
Adding mongolab on node-weather-app... failed
 !    Please verify your account to install this add-on plan
 !    For more information, see https://devcenter.heroku.com/categories/billing
 !    Verify now at https://heroku.com/verify

Apply the free account athttps://www.mongosoup.de/, then login and create a new database plan, Next time if you want to view your database, simply open your browser and go to https://controlpanel.mongosoup.de/.
Click the Databases, and select the database, then show password, it will shows you with the Database info, something like:

Connection string:	mongodb://############:###########@dbs004.mongosoup.de/cc_KNoBTXxNbHhS

It seems the account failed, so I create a new account using another email, xxxxxxxxxx.
This time the app’s name is named nodeweatherapp git@heroku.com:nodeweatherapp.git
And this time we will use root account for uploading.

    Git URL: git@heroku.com:nodeweather.gi

Proto Thread In Arduino

Recently I want to use RTOS on Arduino, but after reading the material I find it’s not so easy to run another “OS” on Arduino. But I found this library which named “Proto Thread” which could afford me thread-like operation. Following is the steps for using this library for controlling 2 different threads.

Installation of Proto Thread