Now that we have considered what ball valves to connect to what outputs and sensor inputs we can start programming the Arduino TapHat.

Overview of all steps:
1. Preparing Raspberry Pi
2. Testing the TapHat / Pi connection – Arduino side
3. Testing the TapHat / Pi connection – Pi side
4. Connecting your Hardware
5. Configuring your TapHat and valves
6. Tap Control from the Internet
7. Finishing our Python Tap Control program

There are essentially two options to control your Tap Controller from the internet:
a. Direct: running a webserver on your Pi and exposing it through your Router/Firewall to Internet
b. Indirect by using a typical webserver or database solution.

While I also have a SunScreen solution that works fine, there are also drawbacks, one needs to take care of a lot of technical details etc.
That is why for the Tap Controller we choose option b. After discussing this with a colleague at my University we thought it would be best to use firebase for that.

Firebase is a so-called No SQL database and essentially you don’t need to know anything about databases to be able to use it. It uses JSON: a simple and yet versatile open data format (see: w3schools).

We will keep the database as simple as possible:
– Every Tap Hat controller can control three valves.
– I want to control four ball valves.
– I have two tap controllers and want to determine what tap to control on which module.
– I want to make my database versatile so that you can also use it for e.g. one ball valves but also for maybe even ten.
– I want each valve to have two states: 0 for closed and 1 for open.

{
  "modules" : [{
    "module" : 16,
    "taps" : [{
      "tap" : 1,
      "state" : 0
      },{
      "tap" : 2,
      "state" : 0
      }]}, 
    {
    "module" : 17,
    "taps" : [{
      "tap" : 1,
      "state" : 0
      },{
      "tap" : 2,
      "state" : 0
      }]}
   ]  
}

Apparently JSON only supports base 10 (decimal) numbers so I translated the addresses of the TapHat controllers to decimal (I gave the Arduino of the first module address 0x10 = 16, the second I gave address 0x11 = 17).

Tip! There is a very handy tool to work with JSON and to check your own JSON for correctness: json.parser.online.fr.

Change the script to your wishes and go to firebase.google.com and login using e.g. your Google / Gmail address (or Facebook account or create a new address, totally up to you).

After logging in you need to go to the console panel: console.firebase.google.com. Create a new database by importing your JSON based on the example from above.

This is what my database now looks like:

Setting up Firebase -> Pi with Python

Now that you have your database all setup, we will try to connect your firedatabase to your Pi using Python.

Note: With a recent Raspbian Jessie install this should work out-of-the-box.

The Pi has two python versions installed:
– Python 2 (2.7.9 in my case)
– Python 3 (3.4.2 in my case)

We are going to use Python 3 since it supports a very neat Firebase library: pyrebase.

To install pyrebase:

pi@waterpi:~ $ sudo pip3 install pyrebase

Note: pip3 will install Python 3 libraries instead of ‘normal’ Python 2 libraries.

This takes a while. Time to make sure you setup Firebase.
Note: You could open a second terminal to your Pi and fill in the script from step 5 as you go.

  1. Set authentication mode for your Firebase.
  2. Get the api key for your Firebase.
  3. Get the (Fire)database name (the name that you gave + some tokens by Google)
  4. Get ‘Service Account Credentials’
  5. Bring the data together in a test file
  6. Show database content

Step 1. Setup Email/Password authentication mode.

Go to “Authentication” and add a user under “Users” and enable “Email/Password” under “Sign-in method”.
My example email and password are “myemail@gmail.com” and “MySuperSecurePassword123” (see the script later on).

Step 2. Get the api key for your database.

Note: the key is not my real key of course.
Under the gear wheel at the top left side of Firebase you see: “Project settings”. Under “General” you then see the screen as above. Save the “Web API Key” for later.

Step 3. The Firebase name / Project ID.

Also remember the Project ID to fill in in your script / replace every dbname item. You can see the Project ID in the screen from Step 2.

Step 4. Service Account Credentials

In the screen from Step 3, move to the last tab: “Service Accounts”. Then press: “Generate New Private Key”. A new window will open:

Generate the key. It will download as a JSON file. Save it to your Raspberry Pi as “serviceAccountCredentials.json” (you can give it another name but this is what I use and is used in Step 5. There are more than one ways to get it on your Pi, you could store it somewhere e.g. in your gmail and login to it on your Pi. I opened the file using a plain text editor and copy-pasted the content to a new terminal window on the Pi. First open nano or another nice Linux text editor:

pi@waterpi:~ $ nano serviceAccountCredentials.json

Then copy-paste the JSON content, press CTRL+X, Yes to save and there you are.

Step 5. Bring the data together in a test file

Now we open a test script in nano. Use the source code from below and replace the data with your data from Step 1 – Step 4. Save and close nano.

import pyrebase

#replace dbname with you dbname, watermylawn-c40c6 in my case

config = {
  "apiKey": "AIdiSyDElQzRPSXk1P3j1t5xjgkBNLP2KvziQzw",
  "authDomain": "dbname.firebaseapp.com", 
  "databaseURL": "https://dbname.firebaseio.com",
  "storageBucket": "dbname.appspot.com",
  "serviceAccount": "serviceAccountCredentials.json"
}

firebase = pyrebase.initialize_app(config)

auth = firebase.auth()
user = auth.sign_in_with_email_and_password('myemail@gmail.com', 'MySuperSecurePassword123')

db = firebase.database()

print(user['idToken'])

Step 6. Testing the database connection

After pyrebase install is finished, now you can execute the script you make:

pi@waterpi:~ $ python3 TestPyrebase.py 
eyJhbGciOiJAndSoOnAndSoOnMtcg4gDbxxu56tA

It then should show your ‘idToken’ like in the example above. If it doesn’t work check earlier steps, if you still fail, feel free to drop a note or use Stackoverflow.

Step 7. A more useful example

You can copy the example from above to a new file (e.g. Showdatabase.py) by issuing:

pi@waterpi:~ $ cp TestPyrebase.py Showdatabase.py

Then nano Showdatabase.py and replace “print(user[‘idToken’])” by:

modules = db.child("modules").get()
print(modules.val())

Next issue “python3 Showdatabase.py” and have a look at the results:

pi@waterpi:~ $ python3 Showdatabase.py 
[{'module': 16, 'taps': [{'tap': 1, 'state': 0}, {'tap': 2, 'state': 0}]}, {'module': 17, 'taps': [{'tap': 1, 'state': 0}, {'tap': 2, 'state': 0}]}]

That’s it for now! Proceed to the next step to finish the program.

Next step: 7. Finishing our Python Tap Control program