Water Level Notifier awesome arduino projects with php web mailer

If you live in the midwestern part of the United States like I do, you know all
about heavy rains and the effects they can have on a basement. Stories of
sump pumps failing during torrential downpours are often punctuated with
“Had I only known how quickly the water level in my sump pit was rising, I
would have had more time to move my stored items out of the way.”



other scenario, where someone needs to use a dehumidifier to
remove dampness in a cellar. Inexpensive dehumidifiers often stop working
when water reaches a certain height in the condensation bucket. Some
models may include an audible alarm or flashing light when this shutdown
occurs, but such alerts are ineffective because the dehumidifier is typically
installed in an infrequently visited area.
Wouldn’t it be more convenient to receive an email from your house when the
water levels in these containment areas exceed a certain threshold, alerting
you to take action? (See Figure 1, Have your house email you, on page 24.)
Let’s get our feet wet, so to speak, and build a system that will provide this
helpful notification service.

1.What You Need…

  •  flex sensor.
  •  The buoyancy of rising water levels will bend the sensor.
  •  As the sensor bends one way or the other, current values will increase or decrease
    accordingly.
  •  The sensor’s position can be read with a simple Arduino program.
  •  powered via either the Arduino’s 3.3 or 5.0 volt pins.

1. An Arduino Uno
2. An Ethernet shield1
3. A flex sensor2
4. A 10k ohm resistor3

 




5. A 1-inch fishing bobber
6. Three wires (power, ground, and analog pin 0) trimmed to desired length
7. A 9-volt power supply to power the Arduino and Ethernet shield once
untethered from the USB cable
8. A pole or wood plank to attach and hang the flex resistor from
9. A web server running PHP 4.3 or higher (not pictured)
You will also need a standard A-B USB cable (not pictured) to connect the
Arduino to the computer and an Ethernet cable (also not pictured) to connect
the Ethernet shield to your network.
We will be reusing the Arduino and Ethernet shield again in several other
projects, so—not including the cost of these two items—the remaining hardware
expenses should be under twenty dollars. Considering the peace of mind
and the ease with which you can build further ideas upon this concept, this
is money well spent.

Building the Solution

Before the Water Level Notifier can start broadcasting alerts, we need to
complete the following tasks:
1. Attach wires and a resistor to the exposed sensor leads on one end of the
flex resistor and the fishing bobber on its other end.
2. Connect the leads of the flex sensor to an analog pin of an Arduino.
3. Write a program (i.e., sketch) for the Arduino that will monitor changes
in the flex sensor readings. It should trigger an event when a large-enough
deviation from the initial value is detected.
4. Attach an Ethernet shield to the Arduino so that the sketch can communicate
with a web server running PHP.
5. Write a PHP script that will capture incoming values from the Arduino.
When the water level has changed, it should format a message and send
an email alert to the intended recipient, who will need to react quickly to
the alert!
We will begin by assembling the hardware and testing out the flex sensor
measurements.

Hooking It Up

Let’s start by making sure our flex sensor works the way we intend it to.
Connect the positive lead of the sensor to the Arduino’s 5.0-volt pin using a
wire. When looking at the flex sensor standing on its end, the positive lead
is the trace that runs vertically. The negative lead is the one that looks like


the rungs of a ladder. Connect the negative lead to the analog 0 pin with
another wire. Lastly, bridge the analog 0 pin to the ground pin using the 10k
ohm resistor to dampen the flow of current through the circuit. Refer to Figure
3, Water Level Notifier wiring diagram, on page 28, to make sure you attach
the wires and resistor to the correct pins.
Attach the bobber to the end of the flex sensor. Most bobbers come with a
retractable hook that can be fastened to the plastic tip of the sensor. If the
bobber doesn’t stay affixed to the sensor, you can also use hot glue or heat
shrink tubing to help keep the bobber attached. Just be careful not to damage
the sensor when heating it with these affixing solutions. You can also try duct
tape as a safe alternative, though the tape may lose its grip over time.
Use plenty of wire so you have enough length to safely mount the Arduino
and power source far away from the water source. The Arduino that I have
monitoring my sump pit is sitting in a hobby box mounted on the wall several
feel above the sump pit, and the two wires attached to the flex resistor are
about two meters (roughly six feet) in length.
Now that the Arduino has been wired up, we can work on the logic of what
the hardware is supposed to do for us. We will begin with a quick test program
that will verify that the flex sensor is connected correctly and working properly.

Sketching Things Out

Before we start writing code, we first need to make sure we can communicate
with the Arduino. Then we will learn how to collect and act upon data sent
by the flex sensor with a program (what the Arduino community prefers to
call a sketch).
The first sketch we write will detect when the flex resistor values have changed.
If the change is large enough (in other words, if water is making the resistor
bend), we will transmit a request to a PHP server that will process the request.
That server will then send out an email notifying us of the change.
We will build the sketch incrementally, first by connecting the flex sensor to
the Arduino and collecting values when the sensor is straight and then when
it bends in both directions. Once these values have been identified, we will
write conditional statements that will call functions to send HTTP GET
statements containing data we will include in the email alert.

Configuring an Arduino
We will use the Arduino IDE to write, compile, and download our code into
the Arduino. For those who would like a more comprehensive introduction
to Arduino programming, read Maik Schmidt’s excellent Arduino: A Quick
Start Guide [Sch11].
If you are already familiar with the Arduino or are willing to hang on for the
ride, let’s get started by launching the Arduino IDE. Check to ensure that
your Arduino is connected via USB cable and recognized and selected accordingly
on one of the serial ports identified by the Arduino IDE’s Tools→Serial
Port menu. You can perform a quick test of your configuration with the LED
Blink example program located in the Arduino IDE’s File→Examples→1.Basics
→Blink menu. Upload it to the attached Arduino and check to see that it
executes correctly.
If it fails to do so, first verify that the Arduino is correctly plugged into the
computer and powered by the USB. If it is, check next to be sure you’ve
selected the correct serial port in the Arduino IDE and highlighted the right
type of Arduino board in the Tools→Board. A few correctly placed mouse
clicks on either of these settings usually fixes the problem.
The Flex Sensor Sketch
Now that the Arduino is connected and tested, we can write a sketch that will
validate and interpret the bending of the flex sensor. We will begin by defining
a few constants that we will refer to in the program.


Since we have to account for the sensor bending in either direction, we will
define two named constants that will be used to set the upper and lower
threshold limits.
We place these constants at the beginning of the sketch so they’re easier to
locate in case we need to edit these values later on. By convention, defined
constants are also all uppercase so that they are easier to identify in the code.
Let’s call them FLEX_TOO_HI and FLEX_TOO_LOW. The range between these upper
and lower limits will depend on the degree of flex that is optimal for your own
scenario. I prefer a variance of plus or minus five units to allow a minor
amount of bend before the notification event is triggered. Having such a range
will allow us to account for minor environmental effects like a light breeze or
a low-grade vibration.
We also need to account for the Arduino’s onboard LED and the analog pin
that the flex sensor is attached to.
• FLEX_TOO_HIGH is the value of the assigned analog pin when the flex sensor
is bent forward past this threshold.
• FLEX_TOO_LOW is the value of the assigned analog pin when the flex sensor
is bent backward past this threshold.
• ONBOARD_LED is assigned to the Arduino’s onboard LED located at pin 13.
We will use it provide us with a visual indicator when the flex resistor has
deviated far enough to send an alert. This allows us to use the Arduino’s


onboard LED as a kind of visual debugger so that we can visually confirm
that the flex events are being detected.
• FLEX_SENSOR is connected to the analog pin on the Arduino that the flex
resistor is connected to. In this case, that value is 0 because the resistor
is connected to pin 0.
These constants will be defined at the beginning of the sketch.
Download WaterLevelNotifier/WaterLevelSensor.pde
#define FLEX_TOO_HI 475
#define FLEX_TOO_LOW 465
#define ONBOARD_LED 13
#define FLEX_SENSOR 0
Now we will create two variables to capture the changing value and state of
the flex resistor and set their initial values to zero.
• bend_value will store the changing analog values of the flex resistor as it
bends.

• bend_state is the binary condition of the flex sensor. If it’s straight, its value
is equal to zero. If the flex resistor deviates either direction, we will set its
state to one.
These variables will follow after the define statements we wrote earlier.
Download WaterLevelNotifier/WaterLevelSensor.pde
int bend_value = 0;
byte bend_state = 0;
With the constants defined and the variables initialized, we need to set up
the serial port to monitor the continuous stream of values being polled in the
main program’s loop. The onboard LED also has to be configured so we can
see it turn on and off based on the bend_state of the flex resistor.

void setup()
{
// for serial window debugging
Serial.begin(9600);
// set pin for onboard led
pinMode(ONBOARD_LED, OUTPUT);
}

With the upper and lower flex bending limits defined, we need a routine that
will check to see if these limits have been exceeded. If they have, we will turn
on the Arduino’s onboard LED. When the flex resistor returns to its resting
straight position, we will turn the LED off.

void SendWaterAlert(int bend_value, int bend_state)
{
digitalWrite(ONBOARD_LED, bend_state ? HIGH : LOW);
if (bend_state)
Serial.print(“Water Level Threshold Exceeded, bend_value=”);
else
Serial.print(“Water Level Returned To Normal bend_value=”);
Serial.println(bend_value);
}
Note the first line of this code block: digitalWrite(ONBOARD_LED, bend_state ? HIGH :
LOW);. This ternary operation polls the current state of the flex resistor based
on the value (0 or 1) that we passed to the function. The conditional statement
that follows prints out an appropriate message to the Arduino IDE’s serial
window. If the bend_state is true (HIGH), the flex resistor has been bent past
the limits we defined. In other words, water has exceeded the threshold. If
it’s false (LOW), the flex resistor is straight (i.e., the water level is not rising).

All that is left to write is the program’s main loop. Poll the FLEX_SENSOR
pin (currently defined as analog pin 0) every second for any increase or
decrease in value. When a flex event is detected, print the bend_value to the
serial port so we can see it displayed in the Arduino IDE’s serial window.
Download WaterLevelNotifier/WaterLevelSensor.pde
void loop()
{
// wait a second each loop iteration
delay(1000);
// poll FLEX_SENSOR voltage
bend_value = analogRead(FLEX_SENSOR);
// print bend_value to the serial port for baseline measurement
// comment this out once baseline, upper and lower threshold
// limits have been defined
Serial.print(“bend_value=”);
Serial.println(bend_value);
switch (bend_state)
{
case 0: // bend_value does not exceed high or low values
if (bend_value >= FLEX_TOO_HI || bend_value <= FLEX_TOO_LOW)
{
bend_state = 1;
SendWaterAlert(bend_value, bend_state);
}
break;
case 1: // bend_value exceeds high or low values
if (bend_value < FLEX_TOO_HI && bend_value > FLEX_TOO_LOW)
{

bend_state = 0;
SendWaterAlert(bend_value, bend_state);
}
break;
}
}
The main loop of the sketch will poll the value of the flex resistor every second.
A switch statement tests the condition of the flex resistor. If its last status was
straight (case 0:), check to see if it has since bent beyond the upper and lower
threshold limits. If so, set the bend_state accordingly and call the SendWaterAlert
function. Conversely, if the resistor’s last status was bent (case 1:), check to
see if it’s now straight. If it is, set the bend_state variable to zero and pass that
new state to the SendWaterAlert function.


Depending on the type of flex sensor and Ethernet shield used along with the
voltage pin selected, your baseline value may be different from the baseline
one I recorded. My flex sensor reported a value of 470.
Note the use of semicolons to mark the end of a line of instruction and
brackets to identify conditional blocks. Save the file. It’s also a good idea to
place this and all other code you write under your preferred choice of version
control before proceeding. I recommend Git,6 but others like Mercurial and
Subversion are certainly better than any non–version controlled alternative.
Later on, we will ask the SendWaterAlert function to call another function that
will connect to a designated PHP server. This in turn will send an email alert
that will contain the appropriate alert and the bend_value being monitored. But
before we do, we will verify that our threshold test is working by monitoring
the messages sent to the Arduino IDE’s serial window.
Run the Sketch
Save and click the Verify button in the Arduino IDE’s toolbar. This will compile
the sketch to check for any syntax errors. After confirming that there are
none, send the sketch to the Arduino by clicking the Upload button on the
toolbar. You should see the Arduino’s onboard LED flash a few times, indicating
that it is receiving the sketch. When the rapid flashing stops, the sketch
should be running.

 

Open up the Arduino IDE’s Serial Monitor window. Assuming you haven’t yet
commented out the Serial.print(“bend_value=”); statement in the main loop of the
sketch, observe the numbers that are continuously scrolling upward at a rate
of roughly once a second on the serial monitor’s display. If the characters
being displayed in the window look like gibberish, make sure to select the
correct baud rate (in this case, 9600) in the serial monitor’s drop-down list
located in the lower right corner of the serial monitor window. Take note of
the values of the flex resistor when it is straight, bent forward, and backward.
Depending on the amount of electrical resistance and the type of hardware
being used, update the FLEX_TOO_HIGH and FLEX_TOO_LOW constants to better
calibrate them to the changing values you are seeing in the serial window.
Once these defined amounts have been entered, save the program and upload
again to the Arduino, performing the same procedure as before. It may take
two or three tries to narrow in on the high and low values that help determine
the bend state of the flex resistor.


With the modified upper and lower limits set to best suit your particular
configuration, observe the Arduino’s onboard LED to ensure that it lights up
when the flex resistor bends far enough forward or backward and turns off
when the resistor is straightened back to its original position.

Testing the Sketch

When you are confident that the hardware setup and the uploaded Arduino
sketch are behaving correctly, it’s time to try a simple water test by filling up
a bowl with water and dipping the bobber into the water while holding the
base of the flex resistor between your thumb and forefinger. As an extra precaution,
wrap any exposed solder connecting the two wires to the flex resistor
in waterproof electrical tape. I suggest wrapping the tape several layers thick,
both to have a solid base to hold the resistor as well as to protect it from any
errant drops of water that may accidentally splash or spill.
After properly and safely setting up the test, verify that as the buoyancy of
the water deflects the bobber attached to the flex resistor, the resistor bends
far enough in either direction to turn the LED light on.
Be careful not to submerge the exposed flex resistor. While the amount of
current flowing through the Arduino is relatively low, water and electricity
can make for a deadly combination. Place any electronics, including the flex
resistor and attached bobber, in a sealed plastic bag with enough room to
allow the flex resistor to bend. Use a high degree of caution to make absolutely
sure to not get any of the exposed wiring or electrical connections wet. Doing

 



so could damage your equipment or, even worse, you.
The base functionality of the water level notifier is complete. However, its
method of communicating a rise in water height is limited to a tiny LED on
the Arduino board. While that may be fine for science projects and people
who work right next to the Arduino monitoring the water source in question,
it needs to broadcast its alert beyond simple light illumination.
Receiving an email notification makes more sense, especially when the location
of water measurement is somewhere in the home that is not frequently visited.
Perhaps the detector will even operate at a remote location, such as when
monitoring the status of a sump pit at a vacation home after a heavy rain.
To do so, we will need to clip on an Ethernet shield to the Arduino and write
some code to send an email when the bend threshold is crossed. But before
we add more hardware to this project, we first need to set up a web-based
email notification application that our Arduino sketch can call upon when it
needs to send out an alert.

Writing the Web Mailer



Libraries for sending email directly from the Arduino abound. But these all
rely on a stand-alone, dedicated email server providing the mail gateway. So
even though the mailer code can be compiled into the Arduino sketch, the
solution still relies on an intermediary to send messages from the Arduino to
the email inbox of the intended recipient(s).
If you have access to an SMTP mail server that you can connect to for outbound
message transmission, check out Maik Schmidt’s Arduino: A Quick
Start Guide [Sch11]. His book supplies the necessary code and walkthrough
on how to make this work. If you don’t have access to a dedicated SMTP
gateway, we can use an Internet web hosting service that supports sending
email from a PHP script.
For this project, I have chosen a popular, preconfigured PHP-enabled web
server with an SMTP outbound gateway, a configuration that popular website
hosting companies like Dreamhost.net, Godaddy.com, and others offer to
their customers.
The PHP script for sending email consists of only a few short lines of code.
First, we will pass two parameters to the server: the type of alert to send and
the recorded value of the flex resistor. Then we will compose a mail message
containing the recipient’s email address, the subject, and the message contents.
Then we will send the email.



<?php
// Grab the type of alert to email and
// the current value of the flex resistor.
$alertvalue = $_GET[“alert”];
$flexvalue = $_GET[“flex”];
$contact = ‘your@emailaddress.com’;
if ($alertvalue == “1”) {
$subject = “Water Level Alert”;
$message = “The water level has deflected the flex
resistor to a value of ” . $flexvalue . “.”;
mail($contact, $subject, $message);
echo(“<p>Water Level Alert email sent.</p>”);
} elseif ($alertvalue == “0”) {
$subject = “Water Level OK”;
$message = “The water level is within acceptable levels.
Flex resistor value is ” . $flexvalue . “.”;
mail($contact, $subject, $message);
echo(“<p>Water Level OK email sent.</p>”);

}
?>

The script calls the built-in PHP mail function that passes three required
parameters: recipient(s), subject, and the body of the email. Yes, it’s that
simple.
Save the code to a file called wateralert.php in the root web directory of your
PHP server. You can test the script by opening your web browser and visiting
http://MYPHPSERVERNAME/wateralert.php?alert=1&flex=486. The page
should return a Wat er Level Alert email sent. message in the browser window, and
a corresponding email message should appear in the defined recipient’s inbox.
If it doesn’t, check your PHP server settings and make sure that your web
server is properly configured to use a working email gateway. If you’re still
not having luck with the message test, contact your website hosting provider
to make sure your hosted solution is correctly configured for PHP email
messaging.
By abstracting the delivery mechanism from the logic running in the Arduino,
we can easily modify the message recipients and contents.
Now that we have a working message gateway, we can hook up the Arduino
to an Ethernet shield so the deflected flex resistor can talk to the rest of the
world.

Adding an Ethernet Shield

Attach the Ethernet shield to the Arduino by lining up the base pins so that
the Ethernet jack is on top and facing the same direction as the Arduino USB
jack. Reconnect the wires to the 5V and analog-in 0 (A0) pins found on the
Ethernet shield just like you did when these wires were connected to the
Arduino.
Do the same for the 10k ohm resistor bridging across the ground (Gnd) and
A0 pins. Run your test again and check the values. In my tests, the base
value being read was different compared to the Arduino without the Ethernet
shield, and yours will likely reflect similar results. Since we’re more interested
in the deviation from this base value than the calibration of the actual value
itself, it’s important to use the unbent resistor value in the code and then
determine how far of a plus or minus deflection from this base value is acceptable
before transmitting the alert.
Now that our hardware is network-enabled, we can add the necessary code
to our sketch that transmits the flex sensor status to our PHP server.

Coding the Shield

We will programmatically send data via the Ethernet shield. But we first must
include a reference in the sketch to both the Arduino Ethernet library and
its dependency, the Serial Peripheral Interface (SPI) library.7 These two libraries
contain the code needed to initialize the Ethernet shield and allow us to initialize
it with network configuration details. Both libraries are included in the
Arduino IDE installation, so the only thing we need to do is import the SPI.h

and Ethernet.h libraries via the #include statement. Add these statements at the
beginning of the sketch:
Download WaterLevelNotifier/WaterLevelNotifier.pde
#include <SPI.h>
#include <Ethernet.h>
With the Ethernet library dependency satisfied, we can assign a unique Media
Access Control (MAC) and IP address to the shield. While DHCP libraries are
available from the Arduino community, it’s easier just to set the shield with
a static IP address.
For example, if your home network uses a 192.168.1.1 gateway address, set
the address of the shield to a high IP address like 192.168.1.230. If you plan
on using this address as a persistent static IP, refer to your home router’s
documentation on how to set a static IP range within a DHCP-served network.
Download WaterLevelNotifier/WaterLevelNotifier.pde
// configure the Ethernet Shield parameters
byte MAC[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEF };
// replace this shield IP address with one that resides within
// your own network range
byte IPADDR[] = { 192, 168, 1, 230 };
// replace with your gateway/router address
byte GATEWAY[] = { 192, 168, 1, 1 };
// replace with your subnet address
byte SUBNET[] = { 255, 255, 255, 0 };

// replace this server IP address with that of your PHP server
byte PHPSVR[] = {???, ???, ???, ???};
// initialize a Client object and assign it to your PHP server’s
// IP address connecting over the standard HTTP port 80
Client client(PHPSVR, 80);
Assign constants for the static MAC and IP addresses that will be used by
the Ethernet shield. Add the address of your Internet router to the GATEWAY
value, and add your SUBNET value as well (most home network subnets are
255.255.255.0). The IP address of your PHP server also has to be declared
prior to the sketch’s setup routine.
With the constants declared, we can now properly initialize the Ethernet
shield in the setup section of the sketch.

void setup()

{
// for serial window debugging
Serial.begin(9600);
// set up on board led on digital pin 13 for output
pinMode(ONBOARD_LED, OUTPUT);
// Initialize Ethernet Shield with defined MAC and IP address
Ethernet.begin(MAC, IPADDR, GATEWAY, SUBNET);
// Wait for Ethernet shield to initialize
delay(1000);
}
Note the use of the Ethernet object in Ethernet.begin(MAC, IPADDR, GATEWAY, SUBNET);.
This is where the Ethernet shield gets initialized with the assigned Media
Access Control (MAC) address and IP Address.
38 • Chapter 3. Water Level Notifier
report

OK, we have a working network connection. Now we can move on to the next
step of requesting the appropriate emailer page on your PHP server when the
bend thresholds have been exceeded.

Sending a Message

 



Up to this point, we have told the Arduino to report the analog values being
generated by the flex resistor, initialized the Ethernet shield to connect the
Arduino to our network, and added stubs for routines to call out to our PHP
server script. Now it’s time to add that routine. We’ll call it ContactWebServer.
The ContactWebServer routine will take the same two parameters we captured
for the SendWaterAlert function, namely band_value and bend_state. Add the ContactWeb-
Server(bend_value, bend_state); line at the end of the SendWaterAlert function, since
we will talk to the designated PHP web server address each time the flex
resistor state changes.
We’re almost done. We just have to write the body of the ContactWebServer
function. This will consist of connecting to the PHP web server and printing
the well-formed HTTP GET string to the server. The string will contain and
pass the values of the bend_state and bend_value variables. These will then be
parsed on the server side and the PHP function will respond in kind.

void ContactWebServer(int bend_value, int bend_state)
{
Serial.println(“Connecting to the web server to send alert…”);
if (client.connect())
{
Serial.println(“Connected to PHP server”);
// Make an HTTP request:
client.print(“GET /wateralert.php?alert=”);
client.print(bend_state);
client.print(“&flex=”);
client.print(bend_value);
client.println(” HTTP/1.0″);
client.println();
client.stop();
}
else
{
Serial.println(“Failed to connect to the web server”);
}
}
It’s time to test the completed sketch. Download it to the Arduino, open up
a serial monitor window, bend the flex resistor, and watch the messages.
Check your recipient’s inbox for the corresponding email messages. Did you
receive the “Water Level Alert” and “Water Level OK” email messages that
correspond to the notifications you saw in the serial monitor window? If not,
make sure that your Arduino is connected to your home network by pinging
the IP address you assigned.
Test the PHP email URL and verify that you receive an email when you enter
http://MYPHPSERVER/wateralert.php?alert=1&flex=486 into your web
browser. When everything works as expected, we will be ready to put the
finishing touches on this project and make it fully operational.

All Together Now

We’re nearing the home stretch. Your hardware should look like the setup
pictured , An assembled water level notifier, on page 41. All that
remains is mounting the flex resistor securely and safely in place so that its
flexion is accurately detected and not impeded by any obstacles.
The base where the two wires attach to the exposed flex resistor leads needs
to be firmly stabilized so that when the water level rises and pushes the
bobber upward, the base does not pivot at its fulcrum. If it does pivot, the
flex resistor will remain straight and the running Arduino sketch will fail to
send the appropriate alert notification. Keep the base stabilized and prevent
it from pivoting.
Try using hot glue, heat shrink tubing, or duct tape. If the base still moves,
try attaching a small wood chip splint on each side of the base of the flex
resistor. Extend the splint length-wise approximately two centimeters above
and below the base. Then snugly wrap the splint several times with electrical
tape. Tack the top of the splinted base to a small wood post (such as that cut
from a typical two-by-four piece of lumber) that spans the diameter of the
hole containing the water source.
In the case of a sump pit, you will need to remove the cover of the pit, measure
the interior diameter and visit a lumberyard or hardware store that can cut
the wood for you. Add an extra centimeter to the cut so that the beam can
be wedged tightly as it spans the pit.
Similar principles apply in the case of a dehumidifier. Instead of using a large
piece of wood to act as the mounting base support, use the bottom, pantshanging
portion of an old wooden hanger that can be cut to slightly longer

than the diameter of the dehumidifier’s water collection bucket. Mount the
base of the splinted flex resistor in the center of the wood support. Depending

 



on the depth of the dehumidifier’s bucket, you may need to raise the base of
the flex resistor higher so that the alert doesn’t trigger prematurely when the
bucket is only half-full.
Once you’re satisfied with the stability of the mounted resistor, place the
bobber and flex resistor inside a small plastic bug, such as a locking seal
sandwich bag. This will keep the resistor dry and protected if the water level
rises excessively. Run the wires attached to the resistor a meter or more from
the measured water source and attach them to the Arduino/Ethernet shield
assembly. Power the Arduino using the 9-volt power supply and attach the
network cable to the Ethernet shield. Several seconds after you power up the
Arduino, perform a quick bend test. If you received the water alert and all-clear
messages in your email inbox, then you have succeeded!
Replace the cover of the water containment vessel you are monitoring and
wait for your device to alert you to rising water levels.

 



Congratulations

 

To use the Agents view in composer



1 Click the Agents view.
Configurable agents:
• 4Store—Set up and manage 4Store logins, apps, themes, and storage.
• Access—Show or hide icons on your Navigators using a pass code.
• Advanced Lighting Scenes—Control lighting throughout your residence or business from any device—on-screen Navigators, touch screens, and tablets.
• Announcements—Create an announcement to display on the touch screens, Control4 apps, or on-screen Navigators.
• Communication—Sets up the Intercom system and configures Intercom groups. Required in place of Intercom agent if using any TS3 Touch Screens. Supports other Intercom-enabled devices as well.
• Custom Buttons—Shown on the Navigators. You can create up to four screens with six buttons each to show on the Navigators in specific rooms or in all rooms in the system. Use programming to link the Custom Button events to the actions you’d like to perform.
• E-mail Notification—Send email to any Internet mail address. Use programming (requires a 4Sight subscription and remote access enabled on the controller) to send out the notification.
Notes:

Remote Access is required to use the E-mail Notification agent. Check with your dealer for details about using Remote Access.
Avoid setting up email notifications for events that occur frequently (for example, when a motion sensor detects motion). If the email notification trigger event occurs too often, it will cause the system to become sluggish.
• Intercom—Sets up the Intercom system for 5″ or 7″ In-Wall Touch Screens, the 7” In-Wall Touch Screen with Camera, 7” Portable Touch Screen with Camera, or the Door Stations.
Note: If using any T3 Touch Screens, the Communication agent must be used in place of the Intercom agent.



• Wakeup—Incorporate your music selection, light level and ramp rate, and temperature control to wake you up.
See “Agent Types” in the Composer HE User Guide for a definition of each agent with examples.
• Options available on some agents:
• Add—Lets you add agents to your system.
• Remove—Lets you remove agents from your system.
• New—Lets you create a new instance to customize the highlighted agent in the Agents pane (left pane). For each specific instance of an agent, you provide a unique name and customize it for the specific need.
• Copy—(Lighting Scene only.) Lets you copy an existing instance of the highlighted Lighting Scene agent.
• Delete—Lets you remove an existing instance of the highlighted agent.
• Agent Navigation pane—Provides each agent a unique interface to set up agent information in a majority of cases for future programming in the Programming view.

Program the Control4 system (Programming view)

For the Control4 system to control its devices, you need to configure the behavior of those devices to occur automatically in the Control4 system. The Programming view lets you write a programming script using Composer’s drag-and-drop or double-click functions.

Programming view:

\

All programming is based on events and actions in a Control4 system. For example, if a door with a sensor opens, it is logged as an event. When an event occurs in the system, it can trigger programmed actions to take place. For example, when the bathroom door opens (event), you can program the bathroom light to turn on (action).
The Programming view consists of several panes:
• Device Events and Project Tree (top left pane)—Displays all devices that have associated events.
• Events (bottom left pane below the Events project tree)—Displays the available Events for the currently selected device in the Events project tree. If there are no events for that device, none are displayed.
• Script (center pane)—Displays the script that is associated with the currently selected event from the Events pane. Drag and drop items to rearrange the order and nest items in the Script pane.
• Device Actions (top right pane)—Displays all available device options (in tree form) that have associated actions you can use to write your script.
• Actions (bottom right pane)—Displays the selection of the Command, Conditionals, and Loops tabs you can select to move to the Script pane. To add an action to the script, select the action, and then double-click or drag-and-drop the green arrow or blue question mark to the Script pane.

See the Composer HE User Guide for more details about how to create a script.

 


To manage your multimedia sources with composer

1 Click the Media view. The media source devices display.
Media view:

This list provides the media types for the Stored and Broadcast Media categories:
• Stored Media
• CDs—Store CD cover art, albums, artist ratings, and genres (for example, Rock or Country).
• DVD player or disc changer—Store DVD and CD (when DVD player supports CD) selections by viewing cover art, titles, info, results, media, and disc list.
• USB Driver or USB drive—Store a variety of media and access it from one of these USB-connected devices.
• MP3, WMA, AAC, or FLAC on digital audio player—Store MP3/HDD music cover art, albums, artist ratings, and genres.
• Broadcast Media
• DIRECTV—View DIRECTV channel options, including station IDs, genres, ratings, and music channels.
• Dish Network—View Dish Network channel options, including station IDs, genres, ratings, and music channels.
• Cable TV—View cable TV channel options, including station IDs, genres, ratings, and music channels.
• UHF/VHF—View UHF channel options, including station IDs, genres, ratings, and HDTV.
• AM/FM/XM and Internet radio—Scan AM, FM, Internet radio, and XM stations.
2 Select any source device to modify the media list for that device.
• Scan for new music on your network devices (configured USB-attached storage device or configured network file storage).
• Scan for a new DVD in a configured Sony disc changer.
• Search for media information using the media lookup service

• Manually customize your MP3, WMA, MP4, FLAC, or AAC-formatted albums and songs.
• Manually add, edit, or delete DVD information.
• Search for the channel lineup on cable, satellite, or off-air programming service. Manually edit channel lineup.
• Create playlists.
• Export media lists for backup purposes or import media lists.
• Export playlists for backup purposes or import playlists.
• Set up Internet radio (your dealer can do this for you).
3 To add new MP3/WMA/MP4 files to your collection, copy the files to a configured storage location on your USB-attached storage device or a configured network storage device.
4 To add a new storage device, have your Control4 Dealer add it to the Composer project and configure it for your use.
• The network address of the controller used for your MP3/WMA/MP4 files is \\<ipaddress>\media\audio where <ipaddress> is your controller’s TCP/IP address (for example, 192.168.0.100). To copy MP3/WMA/MP4 files from your PC to the controller, open that folder in Windows Explorer and copy the files to a folder in that location.
• After you copy the files, use the Media view to select the storage device, and then click Scan to add them to your media list.
• Customize, if necessary, the metadata for the newly added media.

Use intelligent agents (Agents view)

Agents are modules that let you program complex tasks by using simple, pre-built functions. For example, the Scheduler agent lets you program an action using dates and times.

Agents view:

 

Using basic sessions and cookies in laravel

There will be times when we want to pass data from one page of our app to another page
without needing to store the information in a database. To accomplish this, we can use the
various Session and Cookie methods that Laravel provides us.

Getting ready




For this recipe, we need a standard Laravel installation.

How to do it…

For this recipe, follow the given steps:
1. In the views folder, create a file named session-one.php with the following code:
<!DOCTYPE html>
<html>
<head>
<title>Laravel Sessions and Cookies</title>
<meta charset=”utf-8″>
</head>
<body>
<h2>Laravel Sessions and Cookies</h2>
<?= Form::open() ?>
<?= Form::label(’email’, ‘Email address: ‘) ?>
<?= Form::text(’email’) ?>
<br>
<?= Form::label(‘name’, ‘Name: ‘) ?>
<?= Form::text(‘name’) ?>
<br>
<?= Form::label(‘city’, ‘City: ‘) ?>
<?= Form::text(‘city’) ?>
<br>
<?= Form::submit(‘Go!’) ?>
<?= Form::close() ?>
</body>
</html>
2. In the routes.php file, create our routes as given in the following code:
Route::get(‘session-one’, function()
{
return View::make(‘session-one’);

});
Route::post(‘session-one’, function()
{
Session::put(’email’, Input::get(’email’));
Session::flash(‘name’, Input::get(‘name’));
$cookie = Cookie::make(‘city’, Input::get(‘city’), 30);
return Redirect::to(‘session-two’)->withCookie($cookie);
});
Route::get(‘session-two’, function()
{
$return = ‘Your email, from a Session, is ‘
Session::get(’email’) . ‘. <br>’;

$return .= ‘You name, from flash Session, is ‘
Session::get(‘name’) . ‘. <br>’;
$return .= ‘You city, from a cookie, is ‘ .
Cookie::get(‘city’) . ‘.<br>’;
$return .= ‘<a href=”session-three”>Next page</a>’;
echo $return;
});
Route::get(‘session-three’, function()
{
$return = ”;
if (Session::has(’email’)) {
$return .= ‘Your email, from a Session, is ‘ .
Session::get(’email’) . ‘. <br>’;
} else {
$return .= ‘Email session is not set.<br>’;
}
if (Session::has(‘name’)) {
$return .= ‘Your name, from a flash Session, is ‘ .
Session::get(‘name’) . ‘. <br>’;
} else {
$return .= ‘Name session is not set.<br>’;
}
if (Cookie::has(‘city’)) {
$return .= ‘Your city, from a cookie, is ‘ .
Cookie::get(‘city’) . ‘. <br>’;
} else {
$return .= ‘City cookie is not set.<br>’;
}
Session::forget(’email’);
$return .= ‘<a href=”session-three”>Reload</a>’;
echo $return;
});




How it works…

To begin, we create a simple form that we will use to submit information to the sessions and
cookies. After posting the values, we take the email field and add it to a regular session. The
name field will be added to a flash session and the city will be added to a cookie. Also, we’ll
set the cookie to expire after 30 minutes. Once they’re all set, we redirect to our second page,
and make sure we pass the cookie to the return value.

Building a shopping cart in laravel

E-commerce is a huge business on the web. An integral part of most e-commerce sites is the
use of a shopping cart system. This recipe will walk through how to use Laravel sessions to
store items for sales and build a shopping cart.

Getting ready

For this recipe, we need a standard installation of Laravel, as well as a properly set up and
configured MySQL database.

How to do it…

To complete this recipe, follow these given steps:
1. In our database, create a table and add some data with this SQL code:
CREATE TABLE items (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(255) DEFAULT NULL,
description text,
price int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;
INSERT INTO items VALUES (‘1’, ‘Lamp’, ‘This is a Lamp.’,’14’);
INSERT INTO items VALUES (‘2’, ‘Desk’, ‘This is a Desk.’,’75’);
INSERT INTO items VALUES (‘3’, ‘Chair’, ‘This is a
Chair.’, ’22’);
INSERT INTO items VALUES (‘4’, ‘Sofa’, ‘This is a
Sofa/Couch.’, ‘144’);
INSERT INTO items VALUES (‘5’, ‘TV’, ‘This is a
Television.’, ’89’);

2. In the routes.php file, create the routes for our cart with the following code:
Route::get(‘items’, function()
{
$items = DB::table(‘items’)->get();
return View::make(‘items’)->with(‘items’, $items)
>nest(‘cart’, ‘cart’, array(‘cart_items’ =>
Session::get(‘cart’)));
});
Route::get(‘item-detail/{id}’, function($id)
{
$item = DB::table(‘items’)->find($id);
return View::make(‘item-detail’)->with(‘item’, $item)
>nest(‘cart’, ‘cart’, array(‘cart_items’ =>
Session::get(‘cart’)));
});
Route::get(‘add-item/{id}’, function($id)
{
$item = DB::table(‘items’)->find($id);
$cart = Session::get(‘cart’);
$cart[uniqid()] = array (‘id’ => $item->id, ‘name’ =>
$item >name, ‘price’ => $item->price);
Session::put(‘cart’, $cart);
return Redirect::to(‘items’);
});
Route::get(‘remove-item/{key}’, function($key)
{
$cart = Session::get(‘cart’);
unset($cart[$key]);
Session::put(‘cart’, $cart);
return Redirect::to(‘items’);
});
Route::get(’empty-cart’, function()
{
Session::forget(‘cart’);
return Redirect::to(‘items’);
});
3. In the views directory, create a file named items.php with the following code:
<!doctype html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<title>Item List</title>

</head>
<body>
<div>
<?php foreach ($items as $item): ?>
<p>
<a href=”item-detail/<?= $item->id ?>”>
<?= $item->name ?>
</a> —
<a href=”add-item/<?= $item->id ?>”>Add to Cart</a>
</p>
<?php endforeach; ?>
</div>
<?php $cart_session = Session::get(‘cart’) ?>
<?php if ($cart_session): ?>
<?= $cart ?>
<?php endif; ?>
</body>
</html>
4. In the views directory, create a file named item-detail.php by the given code:
<!doctype html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<title>Item: <?= $item->name ?></title>
</head>
<body>
<div>
<h2><?= $item->name ?></h2>
<p>Price: <?= $item->price ?></p>
<p>Description: <?= $item->description ?></p>
<p>
<a href=”../add-item/<?= $item->id ?>”>Add to Cart</a>

</p>
<p><a href=”../items”>Item list</a></p>
</div>
<? if (Session::has(‘cart’)): ?>
<?= $cart ?>
<? endif; ?>
</body>
</html>
5. In the views directory, create a file named cart.php with the following code:
<div class=”cart” style=”border: 1px solid #555″>
<?php if ($cart_items): ?>
<?php $price = 0 ?>
<ul>

<?php foreach ($cart_items as $cart_item_key =>
$cart_item_value): ?>
<?php $price += $cart_item_value[‘price’]?>
<li>
<?= $cart_item_value[‘name’] ?>:
<?= $cart_item_value[‘price’] ?> (<a href=”remove-item/<?=
$cart_item_key ?>”>remove</a>)
</li>
<?php endforeach; ?>
</ul>
<p><strong>Total: </strong> <?= $price ?></p>
<?php endif; ?>
</div>
6. Now, we can go in our browser to http://{your-server}/items to view the list
of items from our database, links to their detail pages, and an option to add them to
a cart. When added to the cart, they will show at the bottom of the page.

How it works…

To begin this recipe, we need to set up a database table that will hold items that we want to
add to the cart. We’ll also add in a few test items, so we have some data to work with.
In our first route, we get all of the existing items in our table and display them. We’re also
nesting in a cart view that will show the items we already added. In that nested view, we also
send in our cart session, so the list can populate.
Our next route does something similar but it accepts only one item and displays the full
information.
The next route actually adds the items. First, we get the item from the database based on its
ID. Then we save the existing cart session to a variable, so we can manipulate it. We add the
item to the array, using php’s uniqid() function as our key. Then we put the cart array back
into the Session and redirect it.
If we want to remove an item, we first make a way to get the item’s ID and remove it from the
cart array. The other way is to just delete all the session and start over.
In our view, we’ll also notice that we are only allowing the cart list to show if there actually is
anything in the cart.

Using advanced validation laravel in forms

There might be times when we need to validate our forms for something that’s not part of the
framework. This recipe will show you how to build a custom validation rule and apply it.

Getting ready

For this recipe, we need a standard installation of Laravel.

How to do it…

The following are the steps to complete this recipe:
1. In the views directory, create a file named valid.php to hold our form using the
following code:
<!doctype html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<title>Custom Validation</title>
</head>
<body>
<p>
<?php if ($errors): ?>
<?php echo $errors->first(’email’) ?>
<?php echo $errors->first(‘captain’) ?>
<?php endif; ?>
</p>
<p>
<h3>Custom Validation</h3>
<?= Form::open(array(‘url’ => ‘valid’, ‘method’ => ‘post’))
?>
<?= Form::label(’email’, ‘Email’) ?>
<?= Form::text(’email’) ?><br><br>
<?= Form::label(‘captain’, ‘Your favorite captains (choose
three)’) ?><br>
<?= ‘Pike: ‘ . Form::checkbox(‘captain[]’, ‘Pike’) ?><br>
<?= ‘Kirk: ‘ . Form::checkbox(‘captain[]’, ‘Kirk’) ?><br>

<?= ‘Picard: ‘ . Form::checkbox(‘captain[]’, ‘Picard’)
?><br>
<?= ‘Sisko: ‘ . Form::checkbox(‘captain[]’, ‘Sisko’) ?><br>
<?= ‘Janeway: ‘ . Form::checkbox(‘captain[]’, ‘Janeway’)
?><br>
<?= ‘Archer: ‘ . Form::checkbox(‘captain[]’, ‘Archer’)
?><br>
<?= ‘Crunch: ‘ . Form::checkbox(‘captain[]’, ‘Crunch’)
?><br>
<?= Form::submit(‘Submit’) ?>
<?= Form::close() ?>
</p>
</body>
</html>

2. In the routes.php file, create our routes with the following code:
Route::get(‘valid’, function()
{
return View::make(‘valid’);
});
Route::post(‘valid’, function()
{
$rules = array(’email’ => ‘required|email’,
‘captain’ => ‘required|check_three’);
$messages = array(
‘check_three’ => ‘Thou shalt choose three captains. No
more. No less. Three shalt be the number thou shalt
choose, and the number of the choosing shall be
three.’,);
$validation = Validator::make(Input::all(), $rules,
$messages);
if ($validation->fails())
{
return Redirect::to(‘valid’)->withErrors($validation);
}
echo “Form is valid!”;
});
3. Also in the routes.php file, create our custom validation as given in the
following code:
Validator::extend(‘check_three’, function($attribute,
$value, $parameters)
{
return count($value) == 3;
});

How it works…

To begin, we create the form in our view. We ask for a valid e-mail and exactly three of the
checkboxes to be checked. Since there’s no Laravel validation method for exactly three
checkboxes, we need to create a custom validation.
Our custom validation takes the input array and does a simple count. If it comes up to three, it
returns TRUE. If not, it returns FALSE and fails the validation.
Back in our form processing route, all we then need to do is add the name of the custom
validator we created to our validation rules. If we want to set a custom message, we can add
that as well.

Creating a sortable table using jQuery and Laravel

When handling large amounts of data, it can be helpful to display it in a table view. To manipulate
the data, such as for sorting or searching, we can use the data tables JavaScript library. This way,
we don’t need to keep making database calls every time we want to change the view.

Getting ready

For this recipe, we need a standard installation of Laravel and a properly configured
MySQL database.

How to do it…

Follow the given steps to complete this recipe:
1. In our database, create a new table and add some example data using the
following commands:
DROP TABLE IF EXISTS bookprices;
CREATE TABLE bookprices (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
price float(10,2) DEFAULT NULL,
book varchar(100) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO bookprices VALUES (‘1’, ‘14.99’, ‘Alice in
Wonderland’);
INSERT INTO bookprices VALUES (‘2’, ‘24.50’,
‘Frankenstein’);
INSERT INTO bookprices VALUES (‘3’, ‘29.80’, ‘War and
Peace’);
INSERT INTO bookprices VALUES (‘4’, ‘11.08’, ‘Moby
Dick’);
INSERT INTO bookprices VALUES (‘5’, ‘19.72’, ‘The Wizard
of Oz’);
INSERT INTO bookprices VALUES (‘6’, ‘45.00’, ‘The
Odyssey’);
2. In the app/models directory, create a file named Bookprices.php with the
following code snippet:
<?php
class Bookprices extends Eloquent {
}
3. In the routes.php file, add our route as given in the following code:
Route::get(‘table’, function()
{
$bookprices = Bookprices::all();
return View::make(‘table’)->with(‘bookprices’,
$bookprices);
});
4. In the views directory, create a file named table.php with the following code:
<!doctype html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<title></title>
<script src=”//ajax.googleapis.com/ajax/libs/jquery
/1.10.2/jquery.min.js”></script>
<script src=”//ajax.aspnetcdn.com/ajax/jquery.dataTables
/1.9.4/jquery.dataTables.min.js”></script>
<link rel=”stylesheet” type=”text/css” href=”
//ajax.aspnetcdn.com/ajax/jquery.dataTables/
1.9.4/css/jquery.dataTables.css”>
</head>

<body>
<h1>Book List</h1>
<table>
<thead>
<tr>

<th>Price</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<?php foreach ($bookprices as $book): ?>
<tr>
<td><?php echo $book[‘price’] ?></td>
<td><?php echo $book[‘book’] ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<script>
$(function(){
$(“table”).dataTable();
});
</script>
</body>
</html>

How it works…

To start this recipe, we create a table to hold our book price data. We then insert the data into
the table. Next, we create an Eloquent model so we can interact with the data. We then pass
that data into our view.
In our view, we load in jQuery and the dataTables plugin. Then, we create a table to hold
our data and then loop through the data, putting each record into a new row. When we add
the dataTable plugin to our table, it will automatically add sorting to our table for each of
our columns.

Sending an e-mail using Laravel and jQuery in laravel

When creating a contact form, we may choose to let the user send the form asynchronously.
Using Laravel and jQuery, we can have the form submitted without needing the user to go to a
different page.

Getting ready

For this recipe, we need a standard Laravel installation and our mail client properly
configured. We can update our mail configuration in the app/config/mail.php file.

How to do it…

To complete this recipe, follow the given steps:
1. In the views directory, create a file named emailform.php as shown in the
following code:
<!doctype html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<title></title>
<script src=”//ajax.googleapis.com/ajax/libs
/jquery/1.10.2/jquery.min.js”></script>
</head>
<body>
<div id=”container”>
<div id=”error”></div>
<form id=”email-form”>
<label>To: </label>
<input name=”to” type=”email”><br>
<label>From: </label>
<input name=”from” type=”email”><br>
<label>Subject: </label>
<input name=”subject”><br>
<label>Message:</label><br>
<textarea name=”message”></textarea><br>
<input type=”submit” value=”Send”>
</form>
</div>
<script>
$(function(){
$(“#email-form”).on(‘submit’, function(e){
e.preventDefault();
$.post(’email-send’, $(this).serialize(), function(data){
if (data == 0) {
$(“#error”).html(‘<h3>There was an error</h3>’);

} else {
if (isNaN(data)) {
$(“#error”).html(‘<h3>’ + data + ‘</h3>’);
} else {
$(“#container”).html(‘Your email has been sent!’);
}
}
});
});
});
</script>
</body>
</html>

2. In the views folder, create our e-mail template view file named ajaxemail.php
with the following code:
<!DOCTYPE html>
<html lang=”en-US”>
<head>
<meta charset=”utf-8″>
</head>
<body>
<h2>Your Message:</h2>
<div><?= $message ?></div>
</body>
</html>
3. In the routes.php file, create the routes as given in the following code snippet:
Route::get(’email-form’, function()
{
return View::make(’emailform’);
});
Route::post(’email-send’, function()
{
$input = Input::all();
$rules = array(
‘to’ => ‘required|email’,
‘from’ => ‘required|email’,
‘subject’ => ‘required’,
‘message’ => ‘required’
);
$validation = Validator::make($input, $rules);
if ($validation->fails())

{
$return = ”;
foreach ($validation->errors()->all() as $err) {
$return .= $err . ‘<br>’;
}
return $return;
}
$send = Mail::send(‘ajaxemail’, array(‘message’ =>
Input::get(‘message’)), function($message)
{
$message->to(Input::get(‘to’))
->replyTo(Input::get(‘from’))
->subject(Input::get(‘subject’));
});
return $send;
});

How it works…

For this recipe, we need to have our e-mail client properly configured. We have many options
to choose from, including PHP’s mail() method, sendmail, and SMTP. We could even use a
third-party e-mail service such as mailgun or postmark.
Our e-mail form is a regular HTML form with four fields: the to and from e-mail addresses,
the subject line, and the actual e-mail message. When the form is submitted, the fields are
serialized and posted to our email-send route.
The email-send route first validates all of the posted input. If there are any validation
errors, they are returned back as a string. If everything checks out, we send our values to the
Mail::send method and then send it.
Back in our e-mail-form route JavaScript, we check if email-send returned FALSE, and
if so, we display an error. If not, we need to check if the response was a number or not. If
it wasn’t a number, that means there were validation errors and we display them. If it is a
number, that means the e-mail was sent successfully, so we display a success message.

Making an Ajax newsletter sign-up box in laravel

One way to have users added to our e-mail list is to have them sign-up through our website.
In this recipe, we’ll be using MailChimp’s API and a modal window to show a sign-up form and
have it sent through an Ajax call.

Getting ready

For this recipe, we’ll need a standard Laravel installation. We’ll also be using the MailChimp API
for the newsletter; a free account and API key can be created at www.mailchimp.com.

How to do it…

To complete this recipe, follow the given steps:
1. Open the composer.json file and update the require section to resemble the
following code:
“require”: {
“laravel/framework”: “4.0.*”,
“rezzza/mailchimp”: “dev-master”
}
2. In the command-line window, where the artisan file is located, update Composer with
the following command:
php composer.phar update

3. In the app/config directory, create a file named mailchimp.php:
<?php
return array(
‘key’ => ‘12345abcde-us1’,
‘list’ => ‘123456789’
);
4. In the views directory, create a file named signup.php:
<!doctype html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<title>Newsletter Signup</title>
<link href=”//netdna.bootstrapcdn.com/twitterbootstrap/
2.2.2/css/bootstrap-combined.min.css”
rel=”stylesheet”>
<script src=”//ajax.googleapis.com/ajax/libs/jquery/
1.9.0/jquery.min.js”></script>
<script src=”//netdna.bootstrapcdn.com/twitterbootstrap/
2.2.2/js/bootstrap.min.js”></script>
</head>
<body>
<p>
<a href=”#signupModal” role=”button” class=”btn btn-info”
data-toggle=”modal”>Newsletter Signup</a>
</p>
<div id=”results”></div>
<div id=”signupModal” class=”modal hide fade”>
<div class=”modal-header”>
<button type=”button” class=”close” data-dismiss=”modal”
aria-hidden=”true”>&times;</button>
<h3>Sign-up for our awesome newsletter!</h3>

</div>
<div class=”modal-body”>
<p>
<form id=”newsletter_form”>
<label>Your First Name</label>
<input name=”fname”><br>
<label>Last Name</label>
<input name=”lname”><br>
<label>Email</label>
<input name=”email”>
</form>
</p>
</div>
<div class=”modal-footer”>

<a href=”#” class=”btn close” datadismiss=”
modal”>Close</a>
<a href=”#” class=”btn btn-primary”
id=”newsletter_submit”>Signup</a>
</div>
</div>
<script>
$(function(){
$(“#newsletter_submit”).on(‘click’, function(e){
e.preventDefault();
$(“#results”).html(“loading…”);
$.post(‘signup-submit’,
$(“#newsletter_form”).serialize(),
function(data){
$(‘#signupModal’).modal(‘hide’);
$(“#results”).html(data);
});
});
});
</script>
</body>
</html>

5. In the routes.php file, add the routes we need with the following code:
Route::get(‘signup’, function()
{
return View::make(‘signup’);
});
Route::post(‘signup-submit’, function()
{
$mc = new MCAPI(Config::get(‘mailchimp.key’));
$response = $mc->listSubscribe(
‘{list_id}’,
Input::get(’email’),
array(
‘FNAME’ => Input::get(‘fname’),
‘LNAME’ => Input::get(‘lname’)
)
);
if ($mc->errorCode){
return ‘There was an error: ‘ . $mc->errorMessage;
} else {
return ‘You have been subscribed!’;
}
});

How it works…

We start by installing the MailChimp package into our application using a composer version of
the MailChimp SDK. We then need to create a configuration file to hold our API key and the list
ID we want to use.
Our sign-up page will utilize jQuery and Bootstrap for our processing and display. Since we
only want to display the form when the user wants to sign-up, we have a single button that,
when clicked on, will display a modal window with our form. The form will take out first name,
last name, and e-mail address.
When the sign-up form is submitted, we serialize the data and send it to our signup-submit
route. Once we get a response, we hide the modal and display the results on our page.
In our signup-submit route, we attempt to subscribe the user with the information entered.
If we get a response, we check if the response includes an error. If there is an error, we display
that to the user, and if not, we show our success message.

 

Filtering data based on checkbox selection in laravel

When displaying data to a user, it could be convenient to allow them to filter the data. So we
don’t have to make the user click on submit and reload the page every time, we can do all the
filtering using Ajax. For this recipe, we’ll make a book list and allow the user to filter it based
on the genre.

Getting ready

For this recipe, we need a standard Laravel installation that’s configured to work with a
database. We’ll need to set up a table to use by running this SQL statement:
DROP TABLE IF EXISTS books;
CREATE TABLE books (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(255) DEFAULT NULL,
author varchar(255) DEFAULT NULL,
genre varchar(255) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO books VALUES (‘1’, ‘Alice in Wonderland’,
‘Lewis Carroll’, ‘fantasy’);
INSERT INTO books VALUES (‘2’, ‘Tom Sawyer’, ‘Mark
Twain’, ‘comedy’);
INSERT INTO books VALUES (‘3’, ‘Gulliver\’s Travels’,
‘Jonathan Swift’, ‘fantasy’);

INSERT INTO books VALUES (‘4’, ‘The Art of War’, ‘Sunzi’,
‘philosophy’);
INSERT INTO books VALUES (‘5’, ‘Dracula’, ‘Bram Stoker’,
‘horror’);
INSERT INTO books VALUES (‘6’, ‘War and Peace’, ‘Leo
Tolstoy’, ‘drama’);
INSERT INTO books VALUES (‘7’, ‘Frankenstein’, ‘Mary
Shelley’, ‘horror’);
INSERT INTO books VALUES (‘8’, ‘The Importance of Being
Earnest’, ‘Oscar Wilde’, ‘comedy’);
INSERT INTO books VALUES (‘9’, ‘Peter Pan’, ‘J. M.
Barrie’, ‘fantasy’);

How to do it…

To complete this recipe, follow these steps:
1. In the controllers directory, create a new file named BooksController.php:
<?php
class BooksController extends BaseController {
public function getIndex()
{
return View::make(‘books.index’);
}

public function postBooks()
{
if (!$genre = Input::get(‘genre’)) {
$books = Book::all();
} else {
$books = Book::whereIn(‘genre’, $genre)->get();
}
return $books;
}
}
2. Register the books controller in the routes.php file:
Route::controller(‘books’, ‘BooksController’);
3. In the views directory, create a new folder named books, and in that folder, create a
file named index.php:
<!doctype html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>

<title>Books filter</title>
<scriptsrc=”//ajax.googleapis.com/ajax/libs/jquery
/1.10.2/jquery.min.js”></script>
</head>
<body>
<form id=”filter”>
Comedy: <input type=”checkbox” name=”genre[]”
value=”comedy”><br>
Drama: <input type=”checkbox” name=”genre[]”
value=”drama”><br>
Fantasy: <input type=”checkbox” name=”genre[]”
value=”fantasy”><br>
Horror: <input type=”checkbox” name=”genre[]”
value=”horror”><br>
Philosophy: <input type=”checkbox” name=”genre[]”
value=”philosophy”><br>
</form>
<hr>
<h3>Results</h3>
<div id=”books”></div>
<script>
$(function(){
$(“input[type=checkbox]”).on(‘click’, function() {
var books = ”;
$(“#books”).html(‘loading…’);
$.post(‘books/books’, $(“#filter”).serialize(),
function(data){
$.each(data, function(){
books += this.name + ‘ by ‘ + this.author + ‘ (‘ +
this.genre + ‘)<br>’;
});
$(“#books”).html(books);
});
});
});
</script>
</body>
</html>
4. In the models directory, create a file named Book.php:
<?php
class Book extends Eloquent {
}
5. In the browser, go to http://{my-server}/books and click on a few checkboxes
to see the result.

How it works…

With our database set up, we begin with our main list page. This page has a number of
checkboxes, with the value of each corresponding to a genre in our books table. When a box
is checked, the form is submitted asynchronously to our postBooks() method. We use those
results, loop through them, and display them in our books div.
Our postBooks() method begins by making sure a genre was actually submitted. If not, that
means everything is unchecked and it will return all the books. If something is checked, we
get everything from the database that matches the checked values. Since Laravel provides us
with the raw returned data in JSON format, we then return the results, and in our index, the
results are displayed correctly.