EZFLORA IRRIGATION SYSTEM
2013-03-06
I recently bought an Insteon irrigation controller called the EZFlora. In this article, I will describe how the controller
works and how to use it from scratch with a PLM. I am not using any well-known software to control my Insteon devices. This
information is usefull for people building their own software and communicate directly with the PLM .
Before going any further, basic knowledge of how to send standard and extended commands to a PLM is required. This is part of my Home Automation system. You can find an example source code in that Home Automation system article.
The EZFlora is a 8 zone irrigation controller. It allows me to control up to 8 solenoid valves for my garden.
The EZFlora lets you open/close a valve or run a program. A program is a sequence of timers. It is possible
to make 4 different sequences. A sequence is represented internally by an array of 8 bytes that represents the runtime
in minutes of each valve. Byte 0 is for valve 0, byte 1 is for valve 1 etc. Programs are very usefull because your
application sends a command to start a program (sequence) and just waits for the results. If your application
would open a valve and for some reason the application crashed, hung or communication with EZFlora would go down (or any other reasons),
then you could not send a "valve off" message. With a program, you leave it to the EZFlora to do everything.
An application "uploads" such programs by sending the "set sprinkler timers" extended command.
CMD1 is 0x40, CMD2 is the program number (0-4) and the first 8 extended bytes represent the sequence.
Note that this will store the program into eeprom. The program numbers are from 1 to 4. Program number 0 is the default
timers. Default timers are used when a valve is opened with the "valve open" command. After the timeout expires, the
valve will close. This is usefull in case you would forget to close the valve.
My server initially sends a "sprinkler control" command to enable valve status messages. These messages
are broadcast messages. The annoying thing is that the PLM will not forward those events to your application.
So my server needed to put the PLM in "monitor mode" using command 0x6B (see the 2412 Dev guide). It
is really important that you do this, otherwise you will not receive any of the broadcast events. The EZFlora
also needs to be in the PLM's All-Link database.
One nice thing is that any "sprinkler control" command sent, will return a status byte in the ACK message. So by
sending such a command, I am also requesting the system status indirectly. Now every time a valve
status changes, I will also receive a message that contains the status byte. The status byte tells me
what valve is currently opened and what program is running (if any). As the command set document
indicates, the status event broadcast message also contains the water meter counter hidden in the
"To Address". So bascially, when I send a command to start a program, I get the valve/program status in the ACK
message. Then everytime the program activates another valve, I get a broadcasted message with the valve/program status
and the meter counter value. And the end of the program, I can see in the event that the program is not running anymore
and using the meter counter I know how much water was used during the whole program. Note that when a program turns off
a valve and opens the next one, it broadcasts only one event with the newly opened valve number. This is fine since
the EZFlora always activates one zone at a time. So when you see that valve X is opened, it is safe to assume
that all other valves are closed.
Water meter counter
It is possible to attach a water meter counter to the EZFlora and get events every time the meter makes a pulse.
The meter I was looking at generates 450 pulses per liters. That would generate way too much traffic.
So I decided to leave the "Meter count change" event off. Instead, I reset the counter everytime I send a
start valve or start program command. And I look at the meter count every time I get a status message.
When I get a status message that says that no program is running, I can deduce that it was because
a program has terminated so I check the meter count and I know how much water I used while the program
was running.
SUMP PUMP MONITORING
2013-02-20
Goal
When I built my Home Automation System, I wanted a way to monitor my sump pump. There are many ways of doing this. I chose to use a current sensor to detect when the pump is on or off. Since the pump will not draw any current when it does nothing and draw about 3.5A when it is pumping, it is very easy to know when the pump is on or off whith a current sensor. I used the CR9321-npn sensor.
By running the hot wire of my sump pump inside the sensor's hole, the sensor will detect if current is running through. I won't go into the details of this but it works with induction current. The nice thing about this sensor is that it has a transistor inside. So instead of giving you an analog output, it gives you a dry contact that is on or off depending if more than 350mA runs in the wire. So it is easy for me to attach this to my home automation system. The home automation system looks at the device just as if it were a door contact or any other dry contact.
Device
Since I didn't wanna pull apart my sump pump, I made an outlet in which I can plug the sump pump in. The outlet has a power cord and plugs into any other outlet. My special outlet has a terminal block on it that breaks out the sensor's red and black wire. I didn't take any pictures of the inside of the box but it basically looks something like this:
And here is what I do with the data. I know it is a bit overkill to make those statistics but it's always fun to observe a trend with any data sets. This is a snapshot of my status page on my intranet site.
BUILDING A HOSTED MAILSERVER SERVICE
2012-09-22
I guess that with the new buzzwords today we would call this "cloud service" or mailbox in the cloud.
What it is really: a service similar to any big providers like GoDaddy or DomainPeople that hosts a mail
server for you and let you create email addresses and mailboxes hosted on their servers. Except I wanted
to do it myself and offer this type of service to other people. Well not really... I just wanted to
create the service but I don't want any customers. It's just a proof of concept. So my server will
host mailboxes and email forwarding services for people who already own a domain name and want
to have their MX record point to my server. My server also offers a web page to let users manage their
email addresses. Oh, and this is all done on an Amazon EC2 virtual machine. So guaranteed uptime.
So in another post (I am now hosting my own DNS and Mail servers on Amazon EC2)
, I talked about installing postfix on an EC2 VM. Now I wanna offer my users a way to create
mailboxes and forward addresses by themselves instead of having to call me every time to manage
their domain. As I said in the other post, a mysql server integration with postfix is probably
a good idea for this type of setup. First thing to do is to install the mysql server.
I won't go into details here as this
is widely covered on the internet. I did a search for "ec2 mysql" to see if there was
any special considerations to take since it was my first installation on a
non-slackware distribution and I found this:
http://www.samstarling.co.uk/2010/10/installing-mysql-on-an-ec2-micro-instance/
After you have a functional mysql server that will automatically run after a reboot, you should create
a database for the mail config and create a mysql user that has access to it.
in main.cf:
virtual_mailbox_domains = mysql:/etc/postfix/vdomains-mysql
virtual_mailbox_maps = mysql:/etc/postfix/vmbox-mysql
virtual_alias_maps = mysql:/etc/postfix/valias-mysql
in mysql:
create database dbmail;
create user 'mysqlmailuser'@'localhost' IDENTIFIED BY 'pass123';
grant all privileges on dbmail.* to 'mysqlmailuser'@'localhost' with grant option;
create table owners
(
id INT NOT NULL AUTO_INCREMENT,
owner VARCHAR(255),
pass VARCHAR(255),
PRIMARY KEY(id)
);
create table domains
(
domainkey VARCHAR(255),
domain VARCHAR(255),
owner INT not null,
FOREIGN KEY(owner) REFERENCES owners(id) ON DELETE CASCADE
);
create table aliases
(
alias VARCHAR(255),
fwd VARCHAR(255)
);
create table mailbox
(
username VARCHAR(255),
mbox VARCHAR(255)
);
/etc/postfix/vdomains-mysql
user = mysqlmailuser
password = pass123
dbname = dbmail
query = SELECT domain FROM domains WHERE domainkey='%s'
/etc/postfix/valias-mysql
user = mysqlmailuser
password = pass123
dbname = dbmail
query = SELECT fwd FROM aliases WHERE alias='%s'
/etc/postfix/vmbox-mysql
user = mysqlmailuser
password = pass123
dbname = dbmail
query = SELECT mbox FROM mailbox WHERE username='%s'
I'm not sure why, but when adding/removing an entry in the "domain" table, changes don't
get picked up instantly by postfix. You don't need to "postfix reload" but it could take a minute or two.
Changes to the alias and mailbox tables are reflected right away though.
Letting users do it themselves
I wanted to provide a way of having different user accounts on the server. Each user owns
a different subset of domains that are registered somewhere on some registrar. The users would have
set the MX record of their domain to point towards my server. Or they could use my name server and I could
setup their MX record but that is a different story. I just need an automated way for the users to add their
domain in the list of domains for which postfix accepts email from. I also want users to create their
aliases/forwards and mailboxes. This will be done through a web page on which each users will have to login.
After they are logged on, a list of their domains will appear and they have the choice of adding/remove domains.
When they will click on a domain, they will be able to manage their mailboxes and forwards.
So all this web application does is to add/remove domains, aliases and mailboxes
from the mysql tables that postfix uses. Since the changes are in a mysql server, the changes
will be immediately available to postfix, giving instant control to the users on their virtual mail server.
Note that this code does not produce a very nice web page layout, it just does the work.
A bit more a validation could also be done to improve robustness. It is more of a proof
of concept than a real design. Here is the code: ww.zip
I AM NOW HOSTING MY OWN DNS AND MAIL SERVERS ON AMAZON EC2
2012-09-22
Using an Amazon EC2 virtual machine, I wanted to host my own domain by doing as much as I could myself. By that,
I mean that I wanted to host my own DNS server, mail server and web server. So after registering a new domain name,
the first thing I did was to change the nameserver of that domain to use my own server instead of the registrar's.
After that, all the work is done on my EC2 machine. Note that for this to work, I needed to unblock TCP port 25 and 53
and also UDP port 53 on my virtual server. This can be done in the EC2 management console under the "security groups"
section.
Configuring the DNS server
First thing to do is to add the new zone definition in /etc/named.conf. Let's assume that I registered
"exampledomain.ca".
zone "exampledomain.ca" IN {
type master;
file "exampledomain.ca";
};
Then I need to define the zone in /var/named/exampledomain.ca. I wanted to create a subdomain called "www"
so that my web server could be accessible from www.exampledomain.ca. I needed an MX record that points
to the mail server that is also hosted on the same server as the DNS server. For this example, let's
assume that the public IP address of my server is 1.2.3.4.
$TTL 300
@ IN SOA exampledomain.ca. www.exampledomain.ca. (
2012220104 ;
1H ; refresh
15M ; retry
1W ; expiry
1D ) ; minimum
IN NS ns.
IN A 1.2.3.4
IN MX 10 mail
ns IN A 1.2.3.4
www IN A 1.2.3.4
mail IN A 1.2.3.4
Mail server
after looking for a solution to host multiple domains with virtual mailboxes that are not associated
with a unix account, I discovered that that postix might be better for the job than sendmail.
after installing postfix and setting it to run automatically at boot time, we need to configure
the /etc/postfix/main.cf file. I am only telling it to listen to all network interface
and where to look for the list of domains we are hosting and the mailbox definition.
The other nice thing about postfix VS sendmail is that you can easily add more mailboxes/forwards and domains
without having to restart postfix. This is very usefull if you wanna make a webpage on which users can
create their own mailboxes and add their own domains. But the nicest thing of all is that you
can use a mysql server (or several other kinds of DB) so that your web site can configure the server
more easily. But for now, I will stick with scripts. Here is an example of my main.cf script:
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
# listen to all interfaces so we can accept incomming connection from LAN and WAN.
inet_interfaces = all
inet_protocols = all
mydestination = $myhostname, localhost.$mydomain, localhost
unknown_local_recipient_reject_code = 550
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
debug_peer_level = 2
debugger_command =
PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix-2.6.6/samples
readme_directory = /usr/share/doc/postfix-2.6.6/README_FILES
# mailboxes will be saved in /var/vhosts
virtual_mailbox_base = /var/vhosts
#/etc/postfix/vmbox will contain the list of mailboxes
virtual_mailbox_maps = hash:/etc/postfix/vmbox
#/etc/postfix/vdomains will contain the list of domains we are accepting mail for.
virtual_mailbox_domains = hash:/etc/postfix/vdomains
virtual_alias_maps = hash:/etc/postfix/valias
# The /var/vhosts folder must be writeable by user 4000 and group 4000
virtual_uid_maps = static:4000
virtual_gid_maps = static:4000
A note on postifx lookup tables. Postifx is great because it lets use use different type of lookup tables.
In the example posted above, I use hash:/etc/postfix/valias. This is a reference to a Berkely DB file.
You need to create a text file with key/pair values separated by a space and generate a DB with the
"postmap" command in order to use this. But if you want to use another table type such as a mysql table,
then you could specify mysql:/etc/postfix/valias. But in that case, the "valias" file's content would be different.
It would contain information on how to access the database table.
More information on different types of tables can be found here: http://www.postfix.org/DATABASE_README.html
The virtual_uid_maps and virtual_gid_maps lines indicate that the mailboxes inside /var/vhosts will be owned
by 4000:4000 on the system. This means that you have to create a user with ID 4000 and change ownership
of the base folder to that user:group
useradd virtualmailbox -u 4000
chown virtualmailbox:virtualmailbox /var/vhosts
The virtual_mailbox_domains line indicates that postfix needs to look into that file to
find the list of domains it is accepting mail for. Everytime that you modify the vdomains of vmbox file,
you need to rebuild the hash database by issuing the "postmap /etc/postfix/vdomains" command. Of course,
you would replace "vdomains" with "vmbox" if you need to rebuild the vmbox database. virtual mailboxes
are files that will be stored on the server. But if you need to forward to another address, then you
will need aliases. I'm not sure why, but I discovered that you should not use "virtual_alias_domains"
if you want to use mailboxes and aliases for the same domains. Only list the domains in "virtual_mailbox_maps".
# This file will be compiled by the "postmap" tool. It needs
# to contain 2 columns on each line. Since this is just a list
# of domains, we only need one column but the tool will expect 2.
# So you can put anything you want in the second column. I decided
# to put the domain name a second time.
#
exampledomain.ca exampledomain.ca
vmbox file
#because there is a slash at the end of the path, mail will be saved in maildir format
admin@exampledomain.ca exampledomain.ca/admin/
#because there is no slash at the end of the path, mail will be saved in linux mbox format
test@exampledomain.ca exampledomain.ca/test
valias file
user1@exampledomain.ca user1@gmail.com
user2@exampledomain.ca user2@yahoo.com
Automation
It could become very handy to automate the process of adding domains and user mailbox though a perl of php script.
The best way to do it would be by using a database, but let's see how to do it with files first.
Files
- Add the domain name in /etc/postfix/vdomains
- Add mailbox in /etc/postfix/vmbox
- Add forwarding addresses in /etc/postfix/valias
- Run "postmap /etc/postfix/vdomains"
- Run "postmap /etc/postfix/vmbox"
- Run "postmap /etc/postfix/valias"
Of course, this requires that the script locks the files to prevent two process from accessing
the same files at the same time. And also, it would be better to schedule the "postmap" instead or running
it everytime because if you have a large system where users create several mailboxes in 1 minute, you would
want to wait a little bit before running postmap oherwise you would add a great load on your CPU.
Database
With this method, your scripts don't need to lock any files and you don't need to schedule a "postmap".
All you need to do is to insert a mailbox/domain in the database and the change is instantaneous. In my
opinion, this is the ideal way of doing thing if you have a server that hosts several domains and you allow
users to create their own mailboxes. For an example on how to do this, you can refer to this post I did: Building a hosted mailserver service