Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
Scott Shumate
Published

Hunter Sprinkler WiFi Remote Control

Control your Hunter sprinkler system from anywhere in the world with this WiFi-connected remote control based on the Esquilo Air.

IntermediateShowcase (no instructions)29,162
Hunter Sprinkler WiFi Remote Control

Things used in this project

Hardware components

Esquilo Air
Esquilo Air
×1
Esquilo Sprinkler Shield
×1

Software apps and online services

Esquilo.io Cloud

Hand tools and fabrication machines

Hunter Sprinkler System

Story

Read more

Custom parts and enclosures

SmartPort enclosure top

Top side STL file for the 3D-printed enclosure that mounts on the Hunter SmartPort connector.

SmartPort enclosure bottom

Bottom side STL file for the 3D-printed enclosure that mounts on the Hunter SmartPort connector.

Schematics

Wiring Diagram

Wiring diagram of the Sprinkler Shield.

Wiring Diagram

This diagram shows the connection between the Esquilo Air, Sprinkler Shield, and the Hunter sprinkler controller.

Hunter Shield Schematics

The electrical schematics for the Hunter Shield.

Code

Esquilo Air Squirrel Nut

C/C++
This file is the Squirrel language nut that runs on the Esquilo Air to control the Hunter sprinkler controller via the Sprinkler Shield.
// Sprinkler Remote
//
// See readme.txt for more information.
//
// This work is released under the Creative Commons Zero (CC0) license.
// See http://creativecommons.org/publicdomain/zero/1.0/dofile("sd:/lib/buses/hunter/hunter.nut");

require("GPIO");
        
// Include the Hunter bus class
dofile("sd:/lib/buses/hunter/hunter.nut");

//
// Define your programs here.  Hunter supports 3 or 4 programs depending
// on the model.
//
programs <- [
    // Program A
    "Yards",
    // Program B
    "Flower Beds"
];

//
// Define your zones here in numerical order starting with zone 1.
//
zones <- [
    // Zone 1
    "Front Yard"
    // Zone 2
    "Front Flower Beds"
    // Zone 3
    "Back Yard"
    // Zone 4
    "Back Flower Beds"
    // Zone 5
    "Left Side Yard"
    // Zone 6
    "Right Side Yard"
];

function init()
{
    //
    // Enable the bus output
    //
    oe <- GPIO(2);
    oe.low();
    oe.output();
    
    //
    // Create the hunter instance
    //
    hunter <- Hunter(0);
}

//
// ERPC functions
//
function getZones()
{
    return zones;
}

function getPrograms()
{
    return programs;
}

function startZone(params)
{
  	hunter.start(params[0] + 1, params[1]);
}

function startProgram(params)
{
   	hunter.program(params[0] + 1);
}

function stop()
{
    hunter.stop();
}

//
// Initialize the nut
//
init();

JavaScript for the HTML user interface

JavaScript
This file is the JavaScript that implements the HTML user interface for the remote. jQuery is used for accessing the DOM and Esquilo RPC is used for communicating to the Esquilo Air.
// Sprinkler Controller
//
// This work is released under the Creative Commons Zero (CC0) license.
// See http://creativecommons.org/publicdomain/zero/1.0/
var duration = 5;
var startClick;
var zoneSelect;

function error(text)
{
    $('#errorText').text(text);
    $('#errorModal').modal();
}

function startProgram(program)
{
    erpc("startProgram", [program], null, function() {
        error("Program start failed");
    });
}

function startZone(zone)
{
    erpc("startZone", [zone, duration], null, function() {
        error("Zone start failed");
    });
}

function initControls()
{
    // Stop button
    $('#stopButton').click(function() {
        erpc("stop", null, null, function() {
            error("Zone stop failed");
        });
    });

    // Start button
    $('#startButton').click(function() {
        if (startClick) {
            startClick();
        }
        else {
            error("Select a zone or program");
        }
    });

    // Duration time picker
    $('#durationPicker').timepicker({
        minuteStep: 1,
        showMeridian: false,
        defaultTime: minsToHourMin(duration)
    });

    $('#durationPicker').timepicker().on('changeTime.timepicker', function(e) {
        duration = e.time.hours * 60 + e.time.minutes;
    });
}

function initPrograms()
{
    // Call ERPC getPrograms() to retrieve all of the programs
    erpc("getPrograms", null, function(result) {
        if (result) {
            // For each program, insert it in the zone drop down list
            for (var i = 0; i < result.length; i++) {
                if (result[i] != "") {
                    var letter = ['A', 'B', 'C', 'D'];
                    var name = result[i] + ' (Program ' + letter[i] + ')';
                    $('#programList').append('<li><a href="#" id="program' + i + '">' +
                                             name + '</a></li>');
                    $('#program' + i).click(function(i, name) {
                        return function(e) {
						  $('#programSelect').text(name);
						    $('#zoneSelect').text("");
                            startClick = function() { startProgram(i); };
                            console.log("prog " + i);
                        }
                    }(i, name));
                }
            }
        }
    }, function() {
        error("Unable to retrieve programs");
    });
}

function initZones()
{
    // Call ERPC getZones() to retrieve all of the zones
    erpc("getZones", null, function(result) {
        if (result) {
            // For each zone, insert it in the zone drop down list
            for (var i = 0; i < result.length; i++) {
                if (result[i] != "") {
                    var name = result[i] + ' (Zone ' + (i + 1) + ')';
                    $('#zoneList').append('<li><a href="#" id="zone' + i + '">' +
                                          name + '</a></li>');
                    $('#zone' + i).click(function(i, name) {
                        return function(e) {
						    $('#programSelect').text("");
						    $('#zoneSelect').text(name);
                            startClick = function() { startZone(i); };
                            console.log("zone " + i);
                        }
                    }(i, name));
                }
            }
        }
    }, function() {
        error("Unable to retrieve zones");
    });
}

// Convert minutes to an HOUR:MIN format string
function minsToHourMin(mins)
{
	return mins / 60 + ':' + mins;
}

// Initialize the controls
initControls();

// Initialize the programs
initPrograms();

// Initialize the zones
initZones();

HTML user interface

HTML
This file is the HTML that implements the user interface. The bootstrap framework provides mobile friendly formatting.
<!DOCTYPE html>
<!--
Sprinkler Remote 

See readme.txt for more information.

This work is released under the Creative Commons Zero (CC0) license.
See http://creativecommons.org/publicdomain/zero/1.0/
-->
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Sprinkler Remote</title>

    <link rel="stylesheet" href="../libs/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="../libs/bootstrap/css/bootstrap-timepicker.min.css">
    <link rel="stylesheet" href="remote.css">

</head>

<body>

<div class="container">
    <div class="header">
        <h3 class="text-muted">Sprinkler Remote</h3>
    </div>
    
    <div class="row dropdown form-group">
        <div class="col-md-12">
            Program: 
            <button type="button" class="btn btn-default dropdown-toggle form-control" data-toggle="dropdown" aria-expanded="false"> 
                <span id="programSelect"></span>
                <span class="caret"></span>
            </button>
            <ul id="programList" class="dropdown-menu" role="menu">
            </ul>
	    </div>
    </div>
    
    <div class="row dropdown form-group">
        <div class="col-md-12">
            Zone: 
            <button type="button" class="btn btn-default dropdown-toggle form-control" data-toggle="dropdown" aria-expanded="false"> 
                <span id="zoneSelect"></span>
                <span class="caret"></span>
            </button>
            <ul id="zoneList" class="dropdown-menu" role="menu">
            </ul>
	    </div>
    </div>
    
    <div class="row form-group">
        <div class="col-md-12">
            <div class="input-group bootstrap-timepicker">
                <span class="input-group-addon">Duration:</span>
                <input id="durationPicker" type="text" class="form-control">
                <span class="input-group-addon"><i class="glyphicon glyphicon-time"></i></span>
            </div>
        </div>
    </div>
    
    
    <div class="row form-group">
        <div class="col-md-12">
            <button id="startButton" class="btn btn-success form-control" type="button">
                <span class="glyphicon glyphicon-play"></span> Start
            </button>
        </div>
    </div>
    
    <div class="row form-group">
        <div class="col-md-12">
            <button id="stopButton" class="btn btn-danger form-control" type="button">
                <span class="glyphicon glyphicon-stop"></span> Stop
            </button>
        </div>
    </div>

  <!-- Modal -->
  <div class="modal fade" id="errorModal" role="dialog">
    <div class="modal-dialog modal-sm">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">&times;</button>
          <h4 class="modal-title">Error</h4>
        </div>
        <div class="modal-body">
          <p id="errorText"></p>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">OK</button>
        </div>
      </div>
    </div>
  </div>
    
</div>

<script type="text/javascript" src="/js/libs/jquery.min.js"></script>
<script type="text/javascript" src="../libs/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../libs/bootstrap/js/bootstrap-timepicker.min.js"></script>
<script type="text/javascript" src="/js/erpc.js"></script>
<script type="text/javascript" src="remote.js"></script></body>

</html>

Credits

Scott Shumate
1 project • 11 followers
Long time hardware and software hacker.

Comments