I created a system to automate the operations and monitor the water level of a fountain at my office.
The system is controlled by a Raspberry Pi.
I’m using Insteon technology for the automaton. The main interface is a 2413U dual-band USB PowerLinc Modem which is better known as a PLM. The PLM connects to the Pi via a standard USB cable. It allows the Pi to communicate with a wide variety of Insteon modules. Dual band indicates that transmissions are both over the home power lines and via RF wireless. This is preferable for increased reliability.
To control the 120 VAC power to the fountain pump, I’m using an Insteon 2634 dual-band outdoor module. It is basically a weather-resistant appliance module that can be turned off and on via Insteon commands.
To monitor the fountain water level, I’m using an Insteon IO Linc 2450 input/output module which has 1 input high/low sensor and 1 relay output. The outlet on the front is not controlled. It is just a pass through so you save an outlet.
The IO Linc module was originally connected to a stainless steel water level float sensor which was suspended above the reservoir of my fountain on a copper bar. However, this sensor didn’t work out. The problem was when low water activated the float, the fountain would turn off and all the water would drain down into the reservoir. This would cause the float to rise which would turn the fountain back on, which resulted in an infinite on/off loop. To remedy this I swapped out the single float sensor for a dual float sensor. The residual water is not enough to affect the top sensor. Now I can use the bottom float to signal low water and check the top sensor for a refill.
The IO Linc module only has 1 input which was sufficient for the single float sensor, but the double float requires two. There are multi-input modules but they are very expensive. To address the problem I utilized the SPDT relay output on the IO Linc module to switch between floats. Under normal operations the lower float sensor monitors the water level. Then when a low water state is detected the relay switches the IO Linc to monitor the upper float. When the fountain is refilled enough to disengage the upper float, the relay is switched back to monitor the lower float and the fountain is turned back on. The following diagrams illustrate the wiring differences between the single and double floats.
I’m using a modified version of a Python module called pyLights to control the PLM. It only takes 3 lines of code to instantiate a PLM class.
import pylights3 # Specify devices configuration file pylights3.device_cfg_filename='devices.xml' # Initialize PowerLinc Modem p = pylights3.plm()
The devices.xml file allows you specify all your Insteon modules and refer to them in code by a short name rather than by hex codes. Instead of having to remember B4.21.69, I can just use ioLinc in my python code. PyLights will also synchronize the level properties with the actual modules.
<?xml version="1.0" ?> <Devices> <Device> <name>Outdoor 2634 Appliance Module-</name> <shortName>outdoorModule</shortName> <devType>Switch</devType> <address>86.B0.C3</address> <level>255</level> </Device> <Device> <name>I/O Linc 2450 Input/Output Module</name> <shortName>ioLinc</shortName> <devType>Sensor</devType> <address>B4.21.69</address> <level>255</level> </Device> </Devices>
Using the PLM class is very simple. Here are the 3 most important commands for this project:
- getLevel: to get the current state of a module.
- setLevel: to turn on and off modules and relays.
- getSensorState: to return the sensor state of a module.
# Retrieve state of fountain (on or off) result = p.getLevel('outdoorModule') # Retrieve state of IO Linc relay (upper or lower float) result = p.getLevel('ioLinc') # Set IO Linc relay to upper float result = p.setLevel('ioLinc', 100) # Set IO Linc relay to lower float result = p.setLevel('ioLinc', 0) # Turn fountain on result = p.setLevel('outdoorModule', 100) # Turn fountain off result = p.setLevel('outdoorModule', 0) # Retrieve state of water level float sensor (open or closed) result = p.getSensorState('ioLinc')
XML and Python code v.1.00 – 10/03/2014
Please note that in order to subsidize my site, I’m an Amazon affiliate. If you click the Amazon links below and buy the item, I will get a commission. I have personally bought all the linked items below for this project from Amazon. I also recommend you check out Adafruit for high quality Raspberry Pi products. I have no affiliation with Adafruit. Another way to support my site is to subscribe to my YouTube channel.