As part of my training program at scriptr.io, 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 scriptr.io 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.
Components
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 scriptr.io and in keen.io and don’t forget to import the keen.io module to use the connector (In sciptr.io’s workspace, click on the arrow next to “New Script”, then click on “Import Modules” and choose “Keenio”).
On the hardware side

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 scriptr.io’s scripts and our Keen.io connector.
- The User Interface module, a simple HTML + JavaScript page.

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 else: actualLevel = 0
- Opens a WebSocket connection to a scriptr.io account and sends a message containing the following JSON structure conveying the value of the water level:
jsonMsg = json.dumps({"method" : scriptName_in_scriptr.io, "params" : {"value": actualLevel}}) ws.send(jsonMsg)
The Data Analyzer module – The role of scriptr.io
Receiving the data
Scriptr.io receives the data sent by the Banana Pi from the native request object
var waterLevel = request.parameters.value;
Recording an event in keen.io using the keen.io connector
It executes a script that forwards the data with the day and month to a keen.io project – A set of powerful APIs that collect, analyze and visualize events from anything connected to the internet – using scriptr.io’s connector to keen.io’s API (you can use the connector by importing the keen.io 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 keen.io try { var anEvent = { collection : "Water_Level", data : { "value" : parseInt(waterLevel), "day" : day, "month" : month } }; keenio.recordEvent(anEvent); } 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" : "write_your_project_email@domain.com", "fromName" : "Name", "subject" : "Water Level Alert", "body" : mailBody }; sendMail(emailConfig.to, emailConfig.fromName, emailConfig.subject, emailConfig.body); }
Querying keen.io for data
On demand, scriptr.io executes another script that will query keen.io to extract available data from keen.io, 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]; dataToChart.push(chartValue); } return dataToChart;
The User Interface module
The user interface module is a simple HTML page in the scriptr.io account where I link my chart generated by scriptr.io and check the current level of the water in the tank. This is done by creating a Google chart in scriptr.io, 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).