What Is Project Management?

An official definition of project management, courtesy of the Project Management
Institute, defines the term as: “the application of knowledge, skills, tools and techniques
to project activities to meet project requirements.”1
A more tangible (but less interesting) description is that project management is
everything you need to make a project happen on time and within budget to deliver
the needed scope and quality.

In order to really get our heads around these definitions, we need to discuss some
of the terms. A project is distinguished from regular work in that it’s a one-time effort
to change things in some way. So the creation of a new web site would be a project;
ongoing maintenance and minor updates would not.
Time and budget are familiar terms—perhaps the project is intended to take six
weeks and have a budget of $20,000. Scope refers to the list of deliverables or features
that have been agreed—this is where the scale of the required solution is identified.
For instance, creating a new web site for the company may realistically be possible
in six weeks, but rewriting all the accounting software isn’t. Quality is exactly what
it says on the tin, but in project-speak, quality may include not only the quality of
the finished product, but also the approach. Some industries require that particular
quality management approaches be used—for instance, factories producing automotive
parts have to meet particular international standards.

 

These four aspects (time, budget, scope, and
quality) make up what’s known as the balance
quadrant, which is pictured in Figure 1.1. The
balance quadrant demonstrates the interrelationship
between the four aspects and how a change
to one aspect will unbalance the quadrant. For
instance, an increase in the project’s scope will
have an impact on the time, the cost, and the
quality of the project.2 In practice, any project
decision you or your clients make will have an
impact on these four aspects—will it make the
project more expensive, take longer, be of lower
or higher quality, or affect its scope? Figure 1.1. The balance quadrant
Essentially, project management is a set of skills and tools that will help you get
the project right in every way.

Planning, Executing, and Managing Projects

1. Planning, Executing, and Managing Your Project

Most students have no idea how to begin their project. This is understandable: it is the
first time they will have had to tackle a large amount of work that is probably poorly
defined (the project descriptions provided by lecturers are rarely complete!) To get
started, it helps to know the key activities that result in a successful project. They are:
1. Problem identification
2. Requirements elicitation
3. Problem modelling
4. System analysis and specification
5. System design
6. Module implementation and system integration
7. System test and evaluation
8. Documentation
9. Project management

1.1 Problem Identification

Problem Identification involves a lot of background work in the general area of the
problem. Normally it calls for the use of prior experience, typically experience you may
not yet have. It requires an ability to look at a domain (e.g. telecommunications or
engine control) and to identify the issue that needs to be addressed and the problem to
be solved (e.g. elimination of noise or cross-talk on a communication channel, or
engine control for temperature-dependent fuel efficiency). It also required an
understanding of the theoretical issues by which we can model the problem. So, the
first thing you need to do in your project is become an expert in the problem at hand: a
problem-domain expert.

At the same time, you also need to know how to handle the tools that will enable you to
solve the problem. These might include the operating system, the programming
language, the application programming interface (API) definitions, class libraries,
toolkits, or any application-specific analysis utilities. That is, you also need to become
a solution-domain expert.
The only way to become an expert in both the problem domain and the solution
domain is to learn as much as possible about the area and to learn it as quickly and
efficiently as possible. Many people come unstuck at this first step and they launch
themselves into a frenzy of unstructured research, reading much but learning little.
Here are some tips to avoid this happening.
􀂉 Collect any papers, articles, book chapters you can on the area and make a copy
for your own personal archive.
􀂉 Make sure you keep a full citation index, i.e., you must record exactly where every
article you copy comes from. Typically, you need to record the title of the article,
the authors, the name of the magazine/journal/book, the volume and number of
the journal or magazine, and the page numbers. If it’s a chapter in a book and the
author of the chapter is different from the editor of the book, you need to record
both sets of names.
􀂉 Not all the articles you collect will be equally relevant or important. Consequently,
it’s not efficient to give each of them the same attention. But it’s not easy to know

how relevant it is until you read it. So how do you proceed? To solve this dilemma,
you should know that there are three levels of reading:
1. Shallow Reading: you just read the article quickly to get an impression of the
general idea. Read it twice. This should take a half-an-hour to an hour.
2. Moderate Reading: Read the article in detail and understand all of the main
concepts; this will probably require you to read it several times and take a
couple of hours to assimilate.
3. Deep Reading: Here you make an in-depth study of the article. This may take
you several hours or even a couple of days. After many careful readings, you
should know as much about the topic as the author.
The way to proceed with your ‘reading in’ is to
♦ Shallow read everything and write a 5-line summary of the article
♦ If you think the article is directly relevant to your project, label it, and put it on
a list of articles to be read at the next level, i.e. Moderate Reading.
♦ Read all the labelled articles and write a 1-page summary.
♦ If the article is going to be used directly in the project, e.g. as a basis for a
hardware design or a software algorithm, then you need to add it to your list of
articles to be read at the next level, i.e. Deep Reading.
♦ Read all the Deep-Read articles and write extensive notes on them.

Note that the ‘reading in’ phase of the project can last quite a long time (there’s a lot of
reading and writing to be done) and it can overlap partially with some of the other early
tasks, such as requirement elicitation, the topic of the next section.
Finally, it is very important that you realize that, in order to fully understand anything
that you read, you must write it up in your own words. If you can’t express or speak
about a given idea, then you haven’t truly understood it in any useful way. This is so
important that it’s worth saying a third time:
Writing is an Essential Part of Understanding
This is why, in all of the above guidelines, you see recommendations to write things
down.

top vegetables for Diet




Vegetables are any flowers, seeds, leaves, buds,
stems, tubers, or roots that can be eaten. A diet
high in vegetables reduces the risk of chronic
diseases including cardiovascular diseases, diabetes,
hypertension, stroke, Alzheimer’s, digestive
disorders, cataracts, and cancer. Vegetables are rich
sources of vitamins, minerals, protein, carbohydrates,
and fiber and contain a relatively new category of
nutrients called phytonutrients or phytochemicals.
These are found in all vegetables and have
antioxidant, antibacterial, antifungal, antiviral, and
anticarcinogenic properties, depending on the plant.
The highest concentrations of phytochemicals are
found in vegetables with rich colors, intense flavors,
and enticing aromas. Brief steaming or rapid boiling
in the least possible amount of water results in the
smallest loss of nutrients. Notable exceptions are
tomatoes and carrots—their nutrient levels are
increased with cooking

1.Avocado(14 g fiber/medium)

A favorite of the Aztecs, the avocado is native
to Central America, with evidence of avocado
cultivation in Mexico for thousands of years.
Avocados were first cultivated in the United States
in the mid-1800s. California produces nearly 90% of
the domestic crop.
Avocados will not ripen on the
tree. This delay in ripening is a
boon to growers, who can
leave avocados on the
tree for up to 7 months
if market conditions
aren’t favorable when
the fruit is first ready
to harvest.

health benefits of avocado

  1. cholesterol-lowering food, second
    only to olives in monounsaturated
    (good) fat
  2. contains lots of heart-healthy
    folate and oleic acid
  3. rich in E, K, and B vitamins, with more
    potassium than bananas
  4. helps guard against high blood
    pressure, heart disease, and stroke

 


2.Broccoli(5g/cup)

Broccoli is native to the shores of the Mediterranean.
The Italians were the first to cultivate broccoli, and it
quickly became a favorite food in ancient Rome.
It was introduced to France in the 1500s, and
then to England in the mid-18th century.
Broccoli arrived in America during
colonial times. George Washington
and Thomas Jefferson both grew
it in their kitchen gardens.
California and Arizona
produce 99% of the U.S.
broccoli crop.

health benefits of broccoli

  1. supplies vitamin C, necessary for
    building healthy blood vessels and
    cartilage
  2. prevents anemia by enhancing the
    absorption of iron from other foods
  3. assists in making thyroxin, which
    regulates the metabolic rate
  4. a gold mine of potent cancer-fighting
    chemicals such as beta carotene



3.Spinach(4g/cup)

Spinach was the favorite vegetable of Catherine
de Medici during the Renaissance. When she left
Florence, Italy, to marry the king of France,
she brought along her own cooks so they
could prepare spinach in the ways she
preferred. Since that time, dishes
prepared on a bed of spinach are
referred to as “à la Florentine.”
The United States and the
Netherlands are the largest
producers of spinach.
Varieties include baby
spoon, flat or smooth leaf,
red, savoy, and semi savoy.

health benefits of spinch

  1. calorie for calorie, provides more
    nutrients than any other food
  2. high in lutein, a carotenoid that
    protects against macular degeneration
    and cataracts
  3. an excellent source of iron, especially
    important for women
  4. reduces symptoms of asthma,
    osteoarthritis, osteoporosis, and
    rheumatoid arthritis



4.sweat patato(4g/cop)

Sweet potatoes aren’t related to white potatoes at
all, but are in the morning glory family. One of the
oldest known vegetables, the sweet potato is native
to the New World and has been found in pre-Incan
ruins in Peru. Columbus brought sweet potatoes
to Europe after his first voyage in 1492. They
were a popular aphrodisiac
in Shakespeare’s day.
North Carolina is
the leading sweet
potato producer in
the U.S., followed
by California,
Louisiana, and
Mississippi.

health benefits of sweat patatoes

  1. ranked by food scientists as the most
    nutritious of all vegetables
  2. excellent source of minerals such
    as potassium, iron, manganese, and
    copper
  3. a perfect blend of everything needed
    for long-lasting energy
  4. abundant in the “cancer-fighting
    ninjas”—quercetin and chlorogenic acid

5.carrots(5g/cup)

Carrots were esteemed for their medicinal value
prior to the time of Christ. Settlers arriving in
Virginia were the first to bring carrot seeds to
America. Originally, purple carrots came from the
region now known as Afghanistan 5000 years ago.
Beta III carrots have 5 times the beta carotene of
regular carrots. Maroon carrots are sweeter than
regular carrots and have a porous texture like
celery or apples. Look for leafy tops that
are crisp and green, an indication of
freshness.

health benefits of carrots

  1. supplies calcium pectate, a soluble
    fiber that helps remove LDL (bad)
    cholesterol from the body
  2. high in beta carotene, from which the
    body makes vitamin A
  3. very low in calories, with virtually no
    fat—a superlative diet food
  4. antioxidant and anti-cancer
    properties in beta carotene



What is EAV within magento?

In order to understand what EAV is and what its role within Magento is, we need to
break down it into the parts of the EAV model.



• Entity: The entity represents the data items (objects) inside Magento
products, customers, categories, and orders. Each entity is stored in the
database with a unique ID.
• Attribute: These are our object properties. Instead of having one column per
attribute on the product table, attributes are stored on separates sets of tables.
• Value: As the name implies, it is simply the value link to a particular attribute.
This design pattern is the secret behind Magento’s flexibility and power, allowing
entities to add and remove new properties without having to do any changes to the
code or templates.
Whereas model can be seen as a vertical way of growing our database (new
attributes add more rows), the traditional model would involve a horizontal grow
pattern (new attributes add more columns) that would result in a schema redesign
every time new attributes are added.
The EAV model not only allows the fast evolution of our database, but also, it is
more efficient, because it only works with non-empty attributes, avoiding the need
to reserve additional space in the database for null values.
Adding a new product attribute is as simple as going to the Magento backend
and specifying the new attribute type, be it color, size, brand, and so on. The
opposite is also true, because we can get rid of unused attributes on our products
or customer models.
Magento Community Edition currently has eight different types of EAV objects:
• Customer
• Customer address
• Products
• Product categories
• Orders
• Invoices
• Credit memos
• Shipments



All this flexibility and power is not free, and there is a price to pay; implementing the
EAV model results in having our entity data distributed on a large number of tables,
for example, just the Product Model is distributed on around 40 different tables.
The following diagram only shows a few of the tables involved in saving the
information of Magento products:

Another major downside of EAV is the loss of performance when retrieving large
collections of EAV objects and an increase on the database query complexity.
Since the data is more fragmented (stored in more tables), selecting a single record
involves several joins.
Let’s continue using Magento products as our example and manually build the query
for retrieving a single product.

 

The first table that we will need to use is the catalog_product_entity. We can
consider this as our main product EAV table since it contains the main entity recordsfor our products:

Let’s query the table by running the following SQL query:
SELECT * FROM `catalog_product_entity`;
The table contains the following fields:
• entity_id: This is our product unique identifier and is used internally
by Magento.
• entity_type_id: Magento has several different types of EAV models,
products, customers, and orders, and these are just some of them. Identifying
each by type allows Magento to retrieve the attributes and values from the
appropriate tables.
• attribute_set_id: Products attributes can be grouped locally into attribute
sets. Attribute sets allow even further flexibility on the product structure
since products are not forced to use all available attributes.
• type_id: There are several different types of products in Magento: simple,
configurable, bundled, downloadable, and grouped products, each with
unique settings and functionality.
• sku: Stock Keeping Unit (SKU) is a number or code used to identify each
unique product or item for sale in a store. This is a user-defined value.



• has_options: This is used to identify if a product has custom options.
• required_options: This is used to identify if any of the custom options
are required.
• created_at: This is a row creation date.
• updated_at: This shows the last time the row was modified.
Now we have a basic understanding of the product entity table, and we also know
that each record represents a single product in our Magento store, but we don’t have
much information about that product beyond the SKU and the product type.
So, where are the attributes stored? And how does Magento know the difference
between a product attribute and a customer attribute?
For that, we need to take a look at the eav_attribute table by running the following
SQL query:
SELECT * FROM `eav_attribute`;
As a result, we will not only see the product attributes but also attributes
corresponding to the customer model, order model, and so on. Fortunately,
we already have a key for filtering the attributes from this table. Let’s run the
following query:
SELECT * FROM `eav_attribute`
WHERE entity_type_id = 4;
This query is telling the database to only retrieve the attributes where the
entity_type_id columns are equal to the product entity_type_id(4). Before
moving on, let’s analyze the most important fields inside the eav_attribute table:
• attribute_id: This is the unique identifier for each attribute and primary
key of the table.
• entity_type_id: This field relates each attribute to a specific EAV
model type.
• attribute_code: This field is the name or key of our attribute and is used to
generate the getters and setters for our magic methods.
• backend_model: The backend model manages loading and storing data into
the database.
• backend_type: This field specifies the type of value stored into the
backend (database).
• backend_table: This field is used to specify if the attribute should be stored
on a special table instead of the default EAV tables.

• frontend_model: The frontend model handles the rendering of the attribute
element into a web browser.
• frontend_input: Similar to the frontend model, the frontend input specifies
the type of input field the web browser should render.
• frontend_label: This field is the label/name of the attribute as it should be
rendered by the browser.
• source_model: The source models are used to populate an attribute with
possible values. Magento comes with several predefined


Understanding and Setting Up Magento Development Environment

Getting VirtualBox

VirtualBox is open source, and it is supported across all platforms. It can be
downloaded directly from www.virtualbox.org/wiki/Downloads.
Now, we will proceed to setting up a Linux virtual machine. We have selected
Ubuntu Server 12.04.2 LTS for its ease of use and widely available support. First,
download the ISO file from www.ubuntu.com/download/server; both 64-bit and
32-bit versions will work.

To create a new Linux virtual machine, perform the following steps:
1. Start VirtualBox Manager and click on the New button in the upper-left corner, as shown in the following screenshot:


2. A wizard dialog will pop up and will guide us through the steps for creating
a bare virtual machine. The wizard will ask us for the basic information for
setting up the virtual machine:
*  VM Name: How shall we name our virtual machine? Let’s name it
Magento_dev 01.
*  Memory: This is the value of system memory that will be assigned
to the guest operating system when our VM starts; for running a full
LAMP server, 1 GB or more is recommended.

°° Operating System Type: This is the type of OS that we will be
installing later; in our case, we want to select Linux/Ubuntu, and
depending on our selection, VirtualBox will enable or disable certain
VM options.
3. Next, we need to specify a virtual hard disk. Select Create a virtual hard
drive now, as shown in the following screenshot:

 

4. There are many hard disk options available, but for most purposes, selecting
VirtualBox Disk Image (VDI) will suffice. This will create a single file on our
host operating system.
5. We now need to select the type of storage on the physical drive. We are
provided with the following two options:
°° Dynamically Allocated: The disk image will grow automatically as
the number of files and usage on our guest operating system grows
°° Fixed Size: This option will limit the size of the virtual disk from
the start
6. Next, we will need to specify the size of our virtual hard disk. We want
to adjust the size depending on how many Magento installations we
plan to use.

The newly created box will appear on the left-hand side navigation menu,
but before starting our recently created VM, we need to make some changes,
as follows:
i. Select our newly created VM and click on the Settings button at
the top.
ii. Open the Network menu and select Adapter 2. We will set
Attached to to Bridged Adapter as we want to set this up as a
bridged adapter to our main network

iii. Go to the System menu and change the boot order so that the
CD/DVD-ROM boots first.
iv. On the Storage menu, select one of the empty IDE controllers and
mount our previously downloaded Ubuntu ISO image.



Booting our virtual machine

At this point, we have successfully installed and configured our VirtualBox instance,
and we are now ready to boot our new virtual machine for the first time. To do this,
just select the VM in the left sidebar and click on the Start button at the top.
A new window will pop up with an interface to the VM. Ubuntu will take a few
minutes to boot up.

Once Ubuntu has finished booting up, we will see two menus. The first menu
will allow us to select the language, and the second one is the main menu, which
provides several options. In our case, we just want to proceed with the Install Ubuntu Server option.

We should now see the Ubuntu installation wizard, which will ask for our language
and keyboard settings; after selecting the appropriate settings for our country and
language, the installer will proceed to load all the necessary packages in memory.
This can take up a few minutes.
Ubuntu will proceed to configure our main network adapter, and once the automatic
configuration is done, we will be asked to set up the hostname for the virtual
machine. We can leave the hostname to default settings.

The next screen will request us to enter the full name of our user; for this example,
let’s use Magento Developer:

Next, we will be asked to create a username and password. Let’s use magedev as
our username:

And let’s use magento2013 as our password:

On the next screens, we will be asked to confirm our password and set up the
correct time zone; after entering the right values, the installation wizard will
show the following screen asking about our partition settings:

 

In our case, we select Guided – use entire disk and set up LVM; let’s now confirm
that we are partitioning our virtual disk:

We will be asked to confirm our changes a final time; select Finish partitioning and
write changes to disk,

The installation wizard will ask us to select predefined packages to install; one of the
options available is LAMP server.
Although this is highly convenient, we don’t want to install the LAMP server that
comes pre-packaged with our Ubuntu CD; we will be installing all the LAMP
components manually to guarantee that they are set up according to specific needs
and are up to date with the latest patches.
Next, for this, we will need an SSH server; select OpenSSH server from the list and
click on Continue:



Now, installation of Ubuntu is complete and it will reboot into our newly installed
virtual box.
We are almost ready to proceed with the installation of the rest of our environment,
but first we need to update our package manager repository definitions, log in to the
console and run the following command:
$ sudo apt-get update
APT stands for Advanced Packaging Tool and is one of the core libraries included
with most Debian GNU/Linux distributions; apt greatly simplifies the process of
installing and maintaining software on our systems.
Once apt-get has finished updating all the repository sources, we can proceed with
the installation of the other components of our LAMP server.

Installing Apache2

Apache is an HTTP server. Currently, it is used to host over 60 percent of the
websites on the Web and is the accepted standard for running Magento stores.
There are many guides and tutorials available online for fine-tuning and tweaking
Apache2 for increasing Magento performance.
Installing Apache is as simple as running the following command:
$ sudo apt-get install apache2 -y
This will take care of installing Apache2 and all the required dependencies for us. If
everything has been installed correctly, we can now test by opening our browser and
entering http://192.168.36.1/.
Apache by default runs as a service and can be controlled with the following commands:
$ sudo apache2ctl stop
$ sudo apache2ctl start
$ sudo apache2ctl restart
You should now see Apache’s default web page with the message It Works!.

Installing PHP

PHP is a server-side scripting language and stands for PHP Hypertext Processor.
Magento is implemented on PHP5 and Zend Framework, and we would need to
install PHP and some additional libraries in order to run it.
Let’s use apt-get again and run the following commands to get php5 and all the
necessary libraries installed:
$ sudo apt-get install php5 php5-curl php5-gd php5-imagick php5-imap
php5-mcrypt php5-mysql -y
$ sudo apt-get install php-pear php5-memcache -y
$ sudo apt-get install libapache2-mod-php5 -y
The first command installed, not only php5, but also additional packages required by
Magento to connect with our database and manipulate images.

Installing MySQL

MySQL is a popular choice of database for many web applications, and Magento is
no exception. We will need to install and set up MySQL as part of development stack
using the following command:
$ sudo apt-get install mysql-server mysql-client -y
During installation, we will be asked to enter a root password; use magento2013.
Once the installer has finished, we should have a mysql service instance running
in the background. We can test it by trying to connect to the mysql server using the
following command:
$ sudo mysql -uroot -pmagento2013
If everything has been installed correctly, we should see the following mysql
server prompt:
mysql>
At this point, we have a fully functional LAMP environment that can be used not
only for developing and working on Magento websites but also for any other kind
of PHP development.

Putting everything together

At this point, we have a basic LAMP set up and running. However, for working with
Magento, we would need to do some configuration changes and additional setup.
The first thing that we will need to do is to create a location to store our development
site’s files, so we will run the following commands:
$ sudo mkdir -p /srv/www/magento_dev/public_html/
$ sudo mkdir /srv/www/magento_dev/logs/
$ sudo mkdir /srv/www/magento_dev/ssl/
This will create the necessary folder structure for our first Magento site. Now
we need to check out the latest version of Magento. We can quickly get the files
by using SVN.
We would first need to install SVN on our server with the following command:
$ sudo apt-get install subversion -y
Once the installer has finished, open the magento_dev directory and run the svn
command to get the latest version files:
$ cd /srv/www/magento_dev
$ sudo svn export –force http://svn.magentocommerce.com/source/
branches/1.7 public_html/
We will also need to fix some of the permissions on our new Magento copy:
$ sudo chown -R www-data:www-data public_html/
$ sudo chmod -R 755 public_html/var/
$ sudo chmod -R 755 public_html/media/
$ sudo chmod -R 755 public_html/app/etc/
Next, we need to create a new database for our Magento installation. Let’s open our
mysql shell:
$ sudo mysql -uroot -pmagento2013
Once in the mysql shell, we can use the create command, which should be followed
by the type of entity (database, table) we want to create and the database name to
create a new database:
mysql> create database magento_dev;

Although we could use the root credentials for accessing our development database,
this is not a recommended practice to follow because it could compromise not only a
single site but also the full database server. MySQL accounts are restricted based on
privileges. We want to create a new set of credentials that has limited privileges to
only our working database:
mysql> GRANT ALL PRIVILEGES ON magento_dev.* TO ‘mage’@’localhost’
IDENTIFIED BY ‘dev2013$#’;
Now, we need to properly set up Apache2 and enable some additional modules;
fortunately, this version of Apache comes with a set of useful commands:
• a2ensite: This creates symlinks between the vhost files in the
sites-available and the sites-enabled folders to allow the
Apache Server to read those files.
• a2dissite: This removes the symlinks created by the a2ensite command.
This effectively disables the site.
• a2enmod: This is used to create symlinks between the mods-enabled
directory and the module configuration files.
• a2dismod: This will remove the symlinks from mods-enabled directory. This
command will prevent the module from being loaded by Apache.
Magento uses the mod_rewrite module for generating the URLs. mod_rewrite uses
a rule-based rewriting engine to rewrite request URLs on the fly.
We can enable mod_rewrite with the a2enmod command:
$ sudo a2enmod rewrite
The next step will require that we create a new virtual host file under the
sites-available directory:
$ sudo nano /etc/apache2/sites-available/magento.localhost.com
The nano command will open a shell text editor where we can set up the
configuration for our virtual domain:
<VirtualHost *:80>
ServerAdmin magento@locahost.com
ServerName magento.localhost.com
DocumentRoot /srv/www/magento_dev/public_html
<Directory /srv/www/magento_dev/public_html/>
Options Indexes FollowSymlinks MultiViews
AllowOverride All
Order allow,deny



allow from all
</Directory>
ErrorLog /srv/www/magento_dev/logs/error.log
LogLevel warn
</VirtualHost>
To save the new virtual host file, press Ctrl + O and then Ctrl + X. The virtual host
file will tell Apache where it can find the site files and what permissions to give
them. In order for the new configuration changes to take effect, we need to enable
the new site and restart Apache. We can use the following commands to do so:
$ sudo a2ensite magento.localhost.com
$ sudo apache2ctl restart
We are nearly ready to install Magento. We just need to set up a local mapping into
our host system host file by using any of the following:
• Windows
i. Open C:\system32\drivers\etc\hosts in notepad
ii. Add the following line at the end of the file:
192.168.36.1 magento.localhost.com
• Unix/Linux/OSX
i. Open /etc/hosts using nano:
$ sudo nano /etc/hosts
ii. Add the following line at the end of the file:
192.168.36.1 magento.localhost.com



 

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.