Quickly create a dropdown of world currencies on your HTML form

The Code

You can use the following utility JavaScript function that will list all currencies in a dropdown that can be placed on your HTML page.

Note: This requires JQuery libraries to be imported on your page.

/* 
 HTML element is the id of the <SELECT> tag on the HTML page.
*/
function listCurrencies(HTMLelement) {
 $.ajax({
   type : "GET",
   url : "http://restcountries.eu/rest/",
   success: function(curr) {
     var options = "";
     for(var i=0; i<curr.length; i++) {
       options += "<option value='"+curr[i].currency+"'>"+curr[i].currency+" ["+curr[i].name+"]</option>";
     }
     $('#'+HTMLelement).append(options);
   }
 }); // ajax - get currencies
} // listCurrencies()

 

The HTML code would look something like this.

< script src='https://code.jquery.com/jquery-1.12.1.min.js'></script>
<select id="currencies"></select>
< script>
    listCurrencies("currencies");
</script>

 

 

 


 

References:

  • Programmable web for the API
  • Open Exchange Rates contains alternative API’s (need signup). However, use of their API will need changing the code in the listCurrencies() function
Advertisements

Creating Smart Initiatives with Internet of Things

Preface

Unlike the other articles of this blog, which are mainly geared towards coding and code snippets, this article is intended to discuss some of the key angles in terms of creating Smart Initialtives with the use of IoT technologies.


There has been a lot of development already around Smart Homes via gadgets like switches, lights, thermostats, leak sensors, even lately – refrigerators. IoT is also a widely discussed topic in Industrial Automation. There is also a lot of buzz out there about Internet of Things (IoT) and some exciting concepts around Smart Cities. And why shouldn’t opportunities be looked for in improving citizens’ lives? Luckily many governments are interested today already that are taking vested interest in delivering that to the residents.

“Smart”

Typically, the availability of Internet, Devices (including sensors within devices) and Communication Tools are by far the key ingredients of any Smart Initiative.

Always available internet ensures constant data flow between devices, sensors and consumers. Devices that can seamlessly connect and stay connected to internet ensure that the required data points are accurately captured and timely delivered. By the way, it is also getting critically important that these devices use low power. Communication tools and methods provide frameworks to develop various models of data transmission such as – on-demand connections, message queuing, etc.

Finally, what makes all of this “Smart” are the use-cases and the execution of these use cases. For example, just because it is possible, what improvement to the quality of life would a Smart Toaster or Smart Coffee machine provide? I want to argue there is none! However, Smart Lights that turn themselves ON and OFF, or Smart Thermostats that set themselves based on time of day and weather conditions is a smart value add to the quality of life. How many times have we forgotten to turn lights off before leaving our homes or how many times have we not set the right temperatures in winter that have led to bursting the water pipes? Not having to deal with that on a day-to-day basis is an improvement in quality of life, not to mention the financial benefits coming from the use of smart devices.

So, is anything that is Automated, Smart?

Few years ago, as the “Smart” concepts were being coined, I always used to wonder how is Smart different from Automation? Or was it one and the same thing?

Well, let’s take a factory. Factories have machines. Some machines are fully automated (a.k.a. CNC) and require attention only on an exception basis. So if they are already automated, are they Smart? or if not, what keeps them away from being Smart?

In my opinion what differentiates Automation from being Smart is simply the ways the amount of and method in which metric data is collected, analyzed and used in making a decision or taking an action (by both, humans as well as machines themselves).

A digital (non-internet-connected) thermostat at our homes is capable of providing automation to start and stop the heater or air conditioner based on the sensors in-built within that unit. We can tell that is automation right away. But that is definitely not Smart as it is not able to store and analyze the historical data easily. We cannot know whether it is ON or OFF from far away, i.e. without physical inspection. We cannot control it from far away unless pre-programmed already. Bottom line, the digital thermostat in this example, improved our quality of life minimally by providing ability to read out digital numbers from the LCD panel. An internet-connected thermostat on the other hand, because of its ability to fill the gaps mentioned above, drastically improves the quality of our life.

Thus, Automation and Smart are not the same!

Conclusion

Internet provides a very big boost to our abilities to develop Smart Initiatives. Internet already has a reputation of breaking the barriers related to knowledge & information and this benefit gets extended to Smart Initiatives as well. Concepts like Smart Cities, Smart Homes, Smart Offices and (although not an official term) Smart Industries are possible today and are just going to grow in the future. Possibilities are endless and it’s all in the ideas. Speaking of idea, imagine the power your Smart Thermostat will deliver if it can not only read data from its sensors and save for your analytics but also call external weather API’s to adjust its settings based on external weather conditions. Now, that would certainly improve our quality of life and is worth calling a Smart Initiative.

Control humidity with Node.js on Raspberry Pi

The End Game

I won’t claim this to be an IoT (Internet of Things) article just because you are going to read about Raspberry Pi. But what I will certainly call it is an Internet Automation project that solves one small problem without me needing to take any action.

Throughout this article I am going to provide a lot of references to external resources that I found useful which will enable us to quickly get to the node.js and JavaScript part of the project.

The Problem Statement

With negative winter temperatures, we want to use heaters to maintain a cozy warm temperature in our homes / offices. However, closed and artificially heated spaces impact humidity levels. We use Humidifiers to the resolve! In the context of this article, I am referring to the portable humidifiers that are connected to an electric outlet.

My goal was to automatically turn the humidifier ON or OFF based on the humidity or temperature levels of the room.

How to even achieve this?

Hardware:

This can be simply achieved if we could automatically control the electric outlet (or the switch) the humidifier would be connected to. So, we need an outlet that can controlled preferably via the internet. For that purpose I used one such internet enabled switch called Wemo Switch from Belkin.

(Please Note: Most portable humidifiers also come with an automated switch or a timer, but the idea is to DIY. So please keep that context as you read this article further)

IFTTT provides a platform called Maker that allows (obviously you will need to signup to their service):

  1. Connecting Wemo Switch to them
  2. Controlling the Wemo Switch state using the Maker API (created specifically for your account and devices)

We obviously need sensors that will be connected to Raspberry Pi. Instead of getting individual sensors and connecting them to the Raspberry Pi, I strongly recommend using Raspberry Pi SenseHAT which is a “hat” on top of Raspberry Pi and contains a lots of sensors already installed. They also provide a rich Python library to get the sensor readings.

Finally, we need Raspberry Pi to be connected to internet also. This is simply achieved by any WiFi dongle that plugs into a Raspberry Pi’s USB port. Of course, WiFi needs to be configured on the Raspberry Pi. (Hint: Use Linux commands or IDE).

Software:

Since Raspberry Pi can run an operating system, such as Linux and Windows, we can easily  install Node.js on it. Thus, node.js provides us with the core backbone for getting readings from the sensors and calling API’s to control the state (ON or OFF) of the Wemo Switch via IFTTT Maker.

As mentioned earlier,  we will also be relying on a lot of python scripts provided by SenseHAT. We will not be covering the python scripts in this article because they are already available on the SenseHAT API reference. We will however be covering how to invoke these python scripts from the node.js application.

Node.js App

The app performs three-stage functions:

  1. Invoke the python scripts that read the sensor data (in this case temperature, but it could also be based on humidity) at frequent intervals
  2. Assess the reading against condition that would lead to whether Wemo Switch needs to be turned ON or OFF
  3. Actually call the IFTTT Maker API discussed earlier to actually turn the connected Wemo Switch ON or OFF

Let’s look at the code for each of these stages below:

Stage 1: Get sensor readings

Node.js provides a module called child_process that provides a method called exec to execute commands from the operating system. This stage relies on this module to invoke the python script. Remember, because we want to invoke the python script at a regular frequency, we wrap this around the setInterval function of JavaScript.

setInterval(function(){
   require('child_process').exec(command, function(error, stdout, stderr) {
      if (error == null) {
          var data = stdout.replace("\n","");
          // ... Call Stage 2
      }
      else {
        console.log("Error occured. " + error);
        }
    }); child_process.exec
}, 60000); // frequency = 60 seconds

Stage 2: Assess Condition

This would be a simple comparison of the reading obtained from Stage 1. However, this is also where you can get all fancy with advanced features like storing the data in database, store last few readings, determine if reading is consistently increasing or decreasing over last few readings, etc. For the sake of this article, we are going to assume the condition is going to be evaluated based on the latest sensor reading.

// assumption: We are looking for Temperature in Stage 1
var YOUR_API_KEY = "?????"; // obtain this from IFTTT
var wemoState = "off"; // or as defined in IFTTT Maker
if(data > 35) { // deg. Celsius is what SenseHat APIs returns
    wemoState = "on";
}
// ... Call Stage 3

Stage 3: Call IFTTT Maker API

As mentioned earlier, we have not covered how to create an IFTTT Maker API that would control the state of an existing device that is registered with IFTTT or yet call another API. You can refer to the maker reference or this blog.

Having said that, now to actually call the API from Node.js, we will use the https module from node.js which provides a request method.

var makerAPI_host = "maker.ifttt.com";
var makerAPI_path = "/trigger/"+wemoState+"/with/key/"+YOUR_API_KEY;
var https = require('https');
 var optionsget = {
 method : "GET",
 host : makerAPI_host, 
 port : 80,
 path : makerAPI_path
 };
var reqGet = https.request(optionsget, function(resp) {
 var str = "";
 resp.setEncoding('utf8');
 resp.on('data', function(d) { // data chunk
 str += d;
 });
 resp.on('end', function() { // all data sent
 console.log(str); // We are Done!
 }); 
});
reqGet.on('error', function(e) {
 error = {
 message : "Error occured",
 error : e
 };
 console.log(error);
});
reqGet.end();

alternatively, can also use the same child_process.exec() method from Stage 2 as below

var callAPI = "curl -X GET https://maker.ifttt.com/trigger/"+wemoState+"/with/key/"+YOUR_API_KEY;    
require('child_process').exec(callAPI, function(error, stdout, stderr) {
   if (error == null) {
      console.log(stdout); // We are Done!
   }
  else {
     console.log("Error occured. " + error);
   }
}); child_process.exec

 

Further Scope

To summarize, while the scope of this article was to demonstrate use of Node.js on Raspberry Pi using various node.js modules, the DIY project also leaves scope for further expansion. One re-use I envision is utilizing the same apparatus to control any other internet-connected  device, such as Nest Thermostat, etc. to create many custom and fancy Internet Automation DIY projects.

Please feel free to comment, share your experience, provide feedback or call out if anything obvious was missed or if any additional perspective needs to be covered.

 

Recursion to the Rescue in Asynchronous JavaScript

Callbacks within Loops

While callbacks provide capability to serialize execution of code, which is sometimes required in an asynchronous framework that javascript offers (e.g. nodeJS), they can also get daunting very easily. Throw in a loop (such as for-loop or a while-loop) within the callback hell and now it’s a completely elevated level of complexity.

There are already a lot of alternatives to simplify the callback hell. One popular solution is use of Promises. There are also some good discussions on this topic on Quora.

This article is one of such attempt to simplify callbacks that are called within loops (such as for-loop or while-loop). The problem specifically in this case is that if an asynchronous function is called within the loop, each iteration is executed asynchronously. Now, if further processing is required after the entire loop is executed, it becomes difficult to track the last iteration. Why? Because, what if although the last iteration is complete and the one before the last takes longer to return? So, just tracking the last iteration is not good enough!

Before we look at how we can use recursion in this situation as one possible alternative, let’s take a quick dive into Recursion.

A little-bit about Recursion

Divide and conquer is perhaps the most common algorithm used to solve some complex programming problems with optimal efficiency. Recursion is one method under divide and conquer algorithms. Recursion really reduces down a large problem into smaller simpler problems and the idea is that solving each small unit will eventually lead to have solved the larger original problem. Recursion is achieved by writing recursive functions, which we will take a look at in a minute.

Recursive Functions (quick refresher)

To put it simply, a recursive function is one that calls itself and looks for whether a base condition has been reached or not. If not, the problem is chopped down further by calling itself again. Let’s look at an example. In this example, we are going to add numbers between 1 and 10.
Hint: Recursion involves a base case which is the last case in recursive function after which the recursion is complete and the problem has been solved.


var add = function(n, sum) {
if(n<1) {
return sum;
}// base case
else {
sum = sum + n;
n--;
return add(n, sum); // recursive call
} // chop down problem further
}

// calling recursive function
var result = 0; // this is where the final result will be stored
result = add(10,result); // call recursive function

Just take a few minutes to look at where we applied the “Divide” from the Divide & Conquer.

What we did here is that we divided the larger problem of adding all numbers between 1 and 10 into smaller problem of performing only one ‘addition’ operation per function call, meanwhile decrementing the number to be added by 1 before it was passed as a parameter to the subsequent function call.

similarly, at the start of each function call, we determined whether the exit condition was reached, i.e. whether the number in question to be added was less than 1 or not. When the exit condition was reached, we simply returned the result, i.e. sum, back to the main program.

Now, let’s get back to the Solution of the Asynchronous Loop Problem

The Solution via Recursion

Assume a requirement similar to pricing a shopping cart. When a product is added to the shopping cart, we need to do the following for each product in the cart:

  1. Check if the product and quantity is eligible for a promotion. If eligible, price it accordingly, else price as usual.
  2. When all products are priced, calculate the total.
  3. Calculate the tax based on the total.
  4. Finally, calculate the total cost of the shopping cart.

Below is the high level code for achieving the above steps using recursion and callbacks. As mentioned earlier, the challenge is that steps 1 and 2 are performed for each product in the pricing cart, however steps 3 and 4 are computed on the results from steps 1 and 2.


var calculatePrice = function(productid, quantity, callback){
// ... check promotion eligibility
callback(calculated_price);
}

var calculateTotal = function(total, productid, quantity, finalcallback, callback){
// ...
calculatePrice (productid, quantity, function(price){
total = total + price;
callback(total, finalcallback);
});
}

var calculateTax = function(total, tax_rate){
return (total + (total * tax_rate));
}

// And here is the recursive function
function forEachProductInCart(cartIndex, shoppingCart, total, callback){
if(cartIndex < 0) {
callback(total);
} // base case
else {
calculateTotal(total, shoppingCart[cartIndex].productid, shoppingCart[cartIndex].quantity, callback, function(total, callback){
cartIndex--;
forEachProductInCart(cartIndex, shoppingCart, total, callback);
})
}
} // forEachProductInCart: recursive function

/* .....................................................
And we call it here
..................................................... */
// var shoppingCart = [];
// shoppingCart contains all products added to the shopping cart

var subtotal = 0; // initial total cost
var finalTotal = 0; // initial final cost
var cartIndex = shoppingCart.length - 1;

// We call the recursive function here
forEachProductInCart(cartIndex, shoppingCart, subtotal, function(total){
var final_with_tax = calculateTax(total, 0.75); // final with tax
});

Conclusion

JavaScript provides solid asynchronous framework to build highly complex web applications already. It also provides ability to create synchronous execution logic via “callbacks”. Add them up with algorithms like recursions and what you now have is ability to solve any complex computing requirement.

Please feel free to comment, provide feedback or add if anything obvious was missed or if any additional perspective needs to be covered.