Who has not dreamed of calling your garden irrigation system to turn it on? Well probably hardly anyone 🙂
The thing is, that idea entered my head. I do not know if it is really practical, but here is an article that relates in some detail the experiment I did.
It is important to explain, before continuing, that there are some things that I am going to assume from now on, and that is that the reader is familiar with Elastix, Asterisk, AGI, PHP and Arduino. Also I will assume that you also have basic knowledge of electronics.
To better clarify how the system will work, I drew the following figure where the components that comprise it are illustrated.
As the previous figure illustrates, there are two main components that we will need, and they are:
- the server Elastix, Y
- the interface with the irrigation valve (or irrigation interface)
VoIP PBX Server
For the Elastix server I installed version 2.2 RC1. This server is the one that will serve as a PBX as I will connect it to the outside world through a telephone line. In this way I can telephone the Elastix server and activate the irrigation.
As can be seen in the figure above, two little programs that I developed will reside on this server: An AGI script and a high-level driver (to communicate with the irrigation interface via USB). I will write both in PHP because it is a very popular language and there is a lot of documentation that can be consulted via the Web; in this way the explanation is more understandable.
Some may wonder why I don't control the Arduino directly from the AGI script. The answer is that I preferred to have the driver separately because it will also help me to control the Arduino from the Web interface that I will develop in the near future. That's what the rectangle that says \ "Web Interface \" in the figure above means.
Irrigation interface
The irrigation interface is a circuit that on the one hand connects to the Elastix server through a USB port and on the other it connects to the irrigation valve. There are many ways to make this circuitry. In my case I decided to use an Arduino board connected to a relay. Basically because I had an idle Arduino board and decided to give it some interesting use. This board is connected to a relay through simple circuitry.
The following figure shows the irrigation interface when I first planned it on breadboard.
In practice I ended up replacing the relay circuit with a pre-built one that I bought for Arduino (with opto-isolated input and double relay) and that there are a lot on the Internet at reasonable prices.
The only thing I did not like very much about the circuit I bought is that it has logic negated. In other words, when the input is HIGH the relay is off, while when it is LOW it is on. That is why you will see later that the code for the Arduino takes this logic into consideration.
Irrigation valve
In my case it is a Rainbird brand valve controlled with 24 volts AC. Nothing special; It has two cables and if we energize them with 24 VAC the valve turns on and the water passes to the sprinklers.
The communication protocol between Elastix and the irrigation interface
The protocol that I will use will be as simple as possible. This way it will be easier for the reader to understand the code. The protocol consists of a single command made up of one byte. This byte will be interpreted as an integer by the Arduino and will represent the number of minutes that you want to activate the irrigation. If I want to interrupt irrigation, I send the number 128.
Asterisk dial plan modification
In my particular case I have configured the following context in the /etc/asterisk/extensions_custom.conf file
[sprinkler] exten => * 2222,1, Answer exten => * 2222, n, AGI (sprinkler.agi) exten => * 2222, n, Hangup ()
This means that when someone dials the number * 2222 they will be answered by my AGI script, which by the way is called sprinkler.agi.
The AGI script
Here too I leave you with the code of my AGI script. Don't forget to give it the correct permissions.
#! / Usr / bin / php -q get_data ('custom / activeminutes', 20000, 3); $rink_minutes = $arr_water_minutes ['result']; $comm = "sudo / opt / sprinkler / driver". $rink_minutes; exec ($comm, $sal); $agi-> stream_file ('custom / configured irrigation'); ?>
The previous script can be divided into two parts:
- It first asks the caller for the number of minutes they want the irrigation system to stay on. It does this using the get_data function
- Then it invokes the driver and passes it as a parameter the number of minutes previously obtained. This is accomplished by / opt / sprinkler / driver
It should be noted that the previous script uses two audio files that the reader can record as desired. These files I have called active minutes.wav and configured irrigation.wav. In the first file I recorded a message similar to the following:
"Please enter the number of minutes you want to water"
And in the second I recorded a simple thank you message:
"Thank you for using the Elastix irrigation system"
It should be mentioned that I have preferred to keep the AGI script as simple as possible for didactic purposes, but the reader can add complexity and for example, validate the user's input, or ask him to confirm the number of minutes, among other things.
Driver for communication with the irrigation interface
Well, now let's see what the high-level driver that controls the Arduino via USB is made of.
#! / Usr / bin / php -q
Again, I have preferred to keep the above code to a minimum. I leave the task of adding validations to the reader. For example, I'm assuming the device has been associated with / dev / ttyUSB0, but that can vary from system to system.
Code for the Arduino
Now yes, the code for the Arduino. This code must be uploaded to the Arduino for it to do what we need.
#includeint relPin = 2; int usbnumber = 0; int active = 0; time_t timeend = 0; void setup () {pinMode (relPin, OUTPUT); digitalWrite (relPin, HIGH); Serial.begin (9600); } void loop () {// Read from USB port here if (Serial.available ()> 0) {usbnumber = Serial.read (); } // 128 is the command to turn off (interrupt) the relay output if (usbnumber == 128) {active = 0; digitalWrite (relPin, HIGH); } if (active == 0) {// If irrigation was inactive and a number greater than zero was received if (usbnumber> 0) {active = 1; digitalWrite (relPin, LOW); timeend = now () + usbnumber * 60; } usbnumber = -128; } else {// If the scheduled time is reached I turn off the relay if (now ()> = timeend) {active = 0; digitalWrite (relPin, HIGH); }}}
Conclution
Quite apart from the utility for watering a garden, I hope this project will find many other applications. Ultimately it is a relay that is activated for a certain time. If someone builds it or finds some other practical application for it, it will be gratifying to see your comment around here.