-
Notifications
You must be signed in to change notification settings - Fork 0
Code
This system is mainly written in R. That's the language I'm most comfortable with, so deal with it.
Log on to the Raspberry Pi with ssh. You'll find the current address by looking at Dashboard::Status::I am (Maybe this link works). This number may change depending on the whim of the router/dhcp. Here is a screen shot with the current address circled:
Get onto the local network, then open a terminal window. A typical log-in looks like this:
mnr@Marks-MacBook-Pro ~ % ssh [email protected]
[email protected]'s password:
The password (last I checked) is "rnm"
You'll need to install R on the Raspberry Pi for any of this to work. Use instructions found at R4pi.org
You'll also need to install the sprinklR package:
# log into the RPi with ssh: ssh [email protected]
# start R: R
devtools::install_github("mnr/sprinklR")
cron
is a linux system command that runs specified programs at specified times. This irrigation system all starts with cron.
mnr@raspberrypi:~ $ crontab -l
0 18 * * * Rscript /home/mnr/sprinklR/inst/startup.R
* * * * * Rscript /home/mnr/sprinklR/inst/manualIrrigation.R
cron runs this script every day at 18:00. The code for all subroutines can be found in the R folder in this repository.
# startup script. Runs at boot
# install.packages("httr2")
# install.packages("devtools")
# library(devtools)
library(httr2)
library(sprinklR)
library(rpigpior)
sinkFile <- file("/home/mnr/sprinklR/sprinklR_log.txt", open = "at")
sink(file = sinkFile,
append = TRUE,
type = "message"
)
sink(file = sinkFile,
append = TRUE,
type = "output"
)
logStatus <- function(theMessage) {
print(paste(date(), theMessage))
}
logStatus("start of run")
yearDay <- as.POSIXlt(Sys.Date())$yday + 1
# create_waterByZone() #create a fresh copy of this matrix
waterByZone <- readRDS("/home/mnr/sprinklR/waterByZone.RDS") # retrieve zone watering matrix
waterByZone <- update_waterbyzone(waterByZone, yearDay) # update with current forecasts
# Calculate needed irrigation ---------------------------------------------
waterByZone <- howMuchToWater(waterByZone,yearDay)
# Trigger irrigation ------------------------------------------------------
# water in front
logStatus("Start of front zone water")
waterFrontSeconds <- conv_mm_to_duration(waterByZone["wateredInFront",yearDay])
irrigate(1, waterFrontSeconds) # turn on front yard
waterByZone["secondsWateredInFront", yearDay] <- waterFrontSeconds
# water in rear
logStatus("Start of rear zone water")
waterRearSeconds <- conv_mm_to_duration(waterByZone["wateredInRear",yearDay])
irrigate(2, waterRearSeconds) # turn on back yard
waterByZone["secondsWateredInRear", yearDay] <- waterRearSeconds
# save all of these calculations
saveRDS(waterByZone, "/home/mnr/sprinklR/waterByZone.RDS")
# Send a heartbeat --------------------------------------------------------
send_heartbeat(waterByZone)
logStatus("end of run")
sink()
cron runs this script every minute. It handles the request to manually turn on/off zone 1 or zone 2
# Handle a request for manual irrigation
# cron runs every minute
# This program watches for a two way switch
# position one turns on zone 1
# position two turns on zone 2
# position central returns to automatic
library(sprinklR)
library(rpigpior)
zoneToPin <- c(15, 19)
while (rpi_get(zoneToPin[1])) {
irrigate(1,30)
}
while (rpi_get(zoneToPin[2])) {
irrigate(2,30)
}
This is located at http://niemannross.com/sprinklR/heartbeat.php and is called by send_heartbeat(waterByZone)
. heartbeat.php accepts a copy of the current waterByZone
data object in json format. It then adds a "modified" day/time to the data, then stores it to heartbeat_data.json
, which is used by the dashboard.
<?php
// Takes raw data from the request
$json = file_get_contents('php://input');
// check for valid json input
if (isset($json['wbz_rainfall'])) {
// add dateTime to json
$json_tmp = json_decode($json, true) ;
$json_tmp['modified'] = date("Y-m-d H:i:s") ;
$json = json_encode($json_tmp) ;
// save to a local file
$fp = fopen("heartbeat_data.json", "w") ;
fwrite($fp, $json) ;
fclose($fp);
}
exit();
?>