So, now that I have a test platform (and I still have a system in my garage that is watering the grass) its time to think seriously about the design of the software and how it will work.
The OpenSprinkler Pi has at least two open source projects one written in python and one written in C/C++. Both of them model the OpenSprinkler Arduino software, in fact I think both can be run on both platforms. That makes the software usable across more installations BUT at a large cost, loss of flexibility and security. The app has to run on the least powerful hardware the Arduino. The Arduino is an 8-bit Atmel AVR microcontroller, just bare metal is it were. There are no OS services running on such a device. So the current app’s have to do everything on the Arduino, be a web server, serving the programming interface and have a thread that runs all the time to execute the scheduled waterings. Simply because there is no other way for it to work on an Arduino. Now don’t get me wrong, I like Arduino’s, and I use them for simple tasks and data gathering, they are great but they are simple devices and sometimes you need more. Of course being an Arduino it sort of limits the damage that can be caused by crackers, you can’t reflash it remotely (at least I’m not aware of being able to reflash it remotely) so it’s going to limit what you can do with the device if you can crack it.
However the RPi is a different can of worms in this regard. Linux on the RPi is very powerful, it is after all a fully fledged computer, not just an embedded bare metal device. Running a unified single application that has to run as root (to control the RPi GPIO pins) opens potential security holes, because on the RPi if you crack it, you can easily reprogram it to do anything you want. Best practices on the Internet for web servers is you run them at the lowest level of authority so that in the event someone cracks the web site they can’t get control of the entire system. Imagine if you have a single program running as root and a cracker gets control of it they could run up your water bill into thousands of dollars by turning on your sprinklers every night from midnight to 06:00 AM and turn your Internet connection into a spambot or worse. You might not notice the damage until you get your water bill, or my my case a citation for illegal water usage!
Nope, a web server needs to have as little permissions as possible, so what can we do to address this. Well we can break the program apart, the “user interface (UI)”, “the scheduler (TS)” and a “watering program (WP)” to take the watering times and lengths and actually water the grass.
OK so the “UI” is run on a web server, check, low permissions, write data files and tell the “TS” when things need to be run. This is not a complex program but it does require study as interfacing with humans is a skill that not all programmers have. What makes perfect sense to a developer can be gibberish to the average human. You need to present the information needed in a way that makes sense and builds on each step. There could be some configuration sections that only the installer of the system needs to set, and other screens that the average homeowner needs to use to water the grass.
Next you need the “TS”, here on Linux you don’t actually have to write anything, you have cron. Cron is a time-based job scheduler in Linux and Unix-like computer operating systems. It can schedule jobs minute by minute, with the addition of at least one handy dandy script to enhance cron (cron-last-sunday) you can schedule quite intricate requirements. If you need more than that can do, you can add your own special purpose script to assist cron.
Finally the “WP“ here you potentially do need root access (there are ways around even needing root here but that is a topic for another blog entry). The “WP” can only do what is in it’s data files it does not interface to the public so to speak. The first thing the “WP” should do when it is invoked by the “TS” is quickly validate it’s data files to tell if the data files are corrupt, if they are it does nothing harmful, it simply stops. It can however send an email to you saying “I did not water the lawn today because my data files don’t make sense“.
No harm done, all that happened is the lawn did not get watered so no water wasted and all is well. If you carry a smart phone you will see that email within minutes of when the watering was supposed to start. You can go see what the heck happened to the data files potentially fix them and still get the lawn watered in the correct time slot. And finally the “WP” can only read and not write to the data files, so the only thing that can change the data files is the “UI”.
With the single program broken up into three (3) smaller separate bits we get higher security, something that is much easier to debug and we save time as we don’t actually need to write the “TS” program, we have it and its well tested over years of time and 10s of thousands of servers. So 1/3 of the project is already written for you, now that is a score! ;-D
So now what, do I focus on the “UI” or the “WP”. I’m going to focus on the “WP” because I can focus on what it is supposed to do, water the grass the way I want to water it: when (per zone), how much water (per zone), absorption rate (how much water can be applied before it runs off)(per zone). Other things the “WP” can be aware of is a rain gauge (global), local weather reports (did it rain yesterday, is it raining now, does it have a high probability of rain tomorrow and how much is expected)(global), moisture gauges in the soil (is the soil already wet enough, or does it become wet enough while the water is being applied)(per zone or globa depends on how you install them). Oh and lets not forget a temp gauge, because if it’s near freezing you don’t want to water then either. And somebody I know wanted to add a wind gauge as he does not want to water if it’s too windy, as it will simply blow the water away and never get to his lawn.
As you can see the “WP” can be really simple: turn on the water per zone for x time. Or it can be very complex: Turn on the water per zone but if the duration is longer than the absorption rate then only water as long as the ground can absorb it, cycle on to the next zone until it’s reached its absorption limit and keep doing that until all zones are watered then loop back and put the remainder of the water in each zone, oh yea don’t do it if it’s raining now, or rained more than an inch yesterday or it’s expected at more than an 80% chance of an inch of rain tomorrow, and don’t water if its near freezing or the wind is blowing too hard. Whew, that is really really complex and yet easily within reach with an RPi as the controller, not so much with an Arduino.
Really if all you need is the simple instance, an Arduino is perfect for the job, it’s only when you get really complex do you need a bigger computer.
Once again I’ve written a really long blog entry when I meant to write a short entry, oh well, I’m done for now. So a question, Ideas anyone, what features do you want in your sprinkler controller?