As part of my training program at, I had the pleasure of working on a fun DIY project that the team had assigned to me. They provided me with a general problem that any household might face, which was monitoring their water consumption, and asked me to use to create a solution for it, which brought me to the Water Level Calculator.

The idea of the Water Level Calculator was created to monitor the water consumption and to make sure not to run out of water (in some countries where water is not always provided) . This device checks the water level inside the water tank every five hours, sends an email to a specific person if it’s lower than 25% indicating the current water level and generates a chart of the variation of the water level in a specific period of time.

mme complaning2


My application has a hardware and a software side. The hardware side is the electronic device attached to the tube that goes inside the water tank and controlled by a Banana Pi, and the software side is composed of three modules interacting with each others that we will develop in the second paragraph of the article related to the software modules.
In this tutorial, I focused on the implementation of the hardware and software inside of this project.
Prerequisites: Make sure you have an account in and in and don’t forget to import the module to use the connector (In’s workspace, click on the arrow next to “New Script”, then click on “Import Modules” and choose “Keenio”).

On the hardware side

electrical circuit

The electrical circuit

The tube contains five shielded copper wires having different lengths, the wires are connected to a small circuit made of five LEDs to indicate the water level, resistors and an IC (Inverter). The circuit is powered by a 9V battery and the electrical circuit is opened and closed by a relay controlled by a Banana Pi GPIO pin in output mode. Four GPIO pins set to input are linked to the LED circuit to read the current water value.


On the software side

I implemented three modules:

  • The Device controller module, implemented using Python on the Banana Pi.
  • The Data Analyzer module, implemented using’s scripts and our connector.
  • The User Interface module, a simple HTML + JavaScript page.
The interaction between different modules

The interaction between different modules

The Device controller module (The role of the Banana Pi)

The Banana Pi executes a Python program periodically (each 5 hours) to do the following:

  • Imports necessary modules to control the Banana Pi pins, sending WebSockets and sending a message as a JSON.
from __future__ import print_function
from time import sleep
import RPi.GPIO as GPIO
import websocket
import json
  • Indicates which pins are set be output and input pins
GPIO.setup (relayOpener, GPIO.OUT)
GPIO.setup (level1, GPIO.IN)
GPIO.setup (level2, GPIO.IN)
GPIO.setup (level3, GPIO.IN)
GPIO.setup (level4, GPIO.IN)

The relayOpener, level1, level2, level3 and level4 are variables containing the pin number that are connected (don’t forget to add the pin numbering mode you’re using – the two options are GPIO.BOARD and GPIO.BCM, In this case I used GPIO.BOARD and the variable are affected as the following: relayOpener = 11; level1 = 13; level2 = 15; level3 = 12; level4 = 16)

  • Close the Relay and by doing so activating the electrical circuit.
GPIO.output (relayOpener, GPIO.HIGH)
  • Read the water level (four Raspberry Pi GPIOs are set to Input and connected to the 4 LEDs above 0% (25%, 50%, 75% and 100%), The Banana Pi is programmed to consider the current level as the highest lighting LED on the electrical circuit.)
if GPIO.input (level4):
	actualLevel = 100
elif GPIO.input (level3):
	actualLevel = 75
elif GPIO.input (level2):
	actualLevel = 50
elif GPIO.input (level1):
	actualLevel = 25
	actualLevel = 0
  • Opens a WebSocket connection to a account and sends a message containing the following JSON structure conveying the value of the water level:
jsonMsg = json.dumps({"method" :, "params" : {"value": actualLevel}})

The Data Analyzer module – The role of

Receiving the data receives the data sent by the Banana Pi from the native request object

var waterLevel = request.parameters.value;

Recording an event in using the connector

It executes a script that forwards the data with the day and month to a project –  A set of powerful APIs that collect, analyze and visualize events from anything connected to the internet – using’s connector to’s API (you can use the connector by importing the module).

var keenioclient = require("/modules/keenio/keenioclient.js");
var keenio = new keenio = new keenioclient.Keenio( _Project_ID );

// get the current day and month
var date = new Date();
var day = date.getDate();
var month  = date.getMonth();

// create an event in Json format to record in
try {
	var anEvent = {
		collection : "Water_Level",
		data : {
			"value" : parseInt(waterLevel),
			"day" : day,
			"month" : month

} catch (exception) {return exception ;}

Alerting user by e-mail

If the water level is lower than 25%, our script sends an e-mail to a chosen person containing the current water level.

if (waterLevel <= level1) { //level1 is a variable initialized to 25
	var mailBody = "Hello, Please note that the water level is now below" + waterLevel + "%";
	var emailConfig = {
		"to" : "",
		"fromName" : "Name",
		"subject" : "Water Level Alert",
		"body" : mailBody
	sendMail(, emailConfig.fromName, emailConfig.subject, emailConfig.body);

Querying for data

On demand, executes another script that will query to extract available data from, this script is used to generate the necessary data to draw the water level variation chart in the user interface.

var params = {
	event_collection : "Water_Level",
	timeframe : "this_366_days"
var extractions = keenio.createExtractions(params);
var extractionData = extractions.execute();

Drawing the Dashboard

Then I created the array dataToChart in which we push the data we want to represent in the chart

var dataToChart = [[ "Day" , "Water Level" ]];
for (var i = 0; i < resultFiltered.length ; i++) {
	var day = resultFiltered[i].day.toString();
	var waterLevel = resultFiltered[i].value;
	var chartValue = [day, waterLevel];
return dataToChart;

The User Interface module

The user interface module is a simple HTML page in the account where I link my chart generated by and check the current level of the water in the tank. This is done by creating a Google chart in, then embedding the chart (on the right on the workspace there is an “Embed URL” button that will generate the iframe code that should be written in the html body).

UI ScreenShot