Primo commit
This commit is contained in:
11
README.md
Normal file
11
README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
## piGarden
|
||||
|
||||
Bash script to manage an irrigation system built with a Raspberry Pi
|
||||
|
||||
## Official documentation
|
||||
|
||||
Documentation of piGarden and build system irrigation with Raspberry Pi can be found on the [www.lejubila.net/](http://www.lejubila.net/)
|
||||
|
||||
## License
|
||||
|
||||
This script is open-sourced software under GNU GENERAL PUBLIC LICENSE Version 2
|
||||
84
conf/piGarden.conf.example
Normal file
84
conf/piGarden.conf.example
Normal file
@@ -0,0 +1,84 @@
|
||||
# Log file
|
||||
LOG_FILE="/home/pi/piGarden/log/piGarden.log"
|
||||
LOG_FILE_MAX_SIZE=1048576 # 1MB
|
||||
|
||||
# Status directory
|
||||
STATUS_DIR="/home/pi/piGarden/state"
|
||||
|
||||
# Posizione gpio
|
||||
GPIO="/usr/local/bin/gpio"
|
||||
|
||||
# Posizione js
|
||||
JQ="/usr/local/bin/jq"
|
||||
|
||||
# Percorso curl
|
||||
CURL="/usr/bin/curl"
|
||||
|
||||
# Percors wc
|
||||
WC="/usr/bin/wc"
|
||||
|
||||
# Percorso gzip
|
||||
GZIP="/bin/gzip"
|
||||
|
||||
# Percors mv
|
||||
MV="/bin/mv"
|
||||
|
||||
# Id gpio usati per simulare il doppio deviatore con cui eseguire l'alimentazione alle elettrovalvole
|
||||
SUPPLY_GPIO_1=2
|
||||
SUPPLY_GPIO_2=3
|
||||
|
||||
# Stato dei due gpio per impartire l'alimentazione positiva alle elettrovalvole (aperta)
|
||||
SUPPLY_GPIO_POS=0
|
||||
|
||||
# Stato dei due gpio per impartire l'alimentazione negativa alle elettrovalvole (chiusa)
|
||||
SUPPLY_GPIO_NEG=1
|
||||
|
||||
# Stato di ingresso da assegnare al gpio per chiudere il rele
|
||||
RELE_GPIO_CLOSE=0
|
||||
|
||||
# Stato di ingresso da assegnare al gpio per aprire il rele
|
||||
RELE_GPIO_OPEN=1
|
||||
|
||||
# Id del gpio usato per collegare il sensore di rilevamento pioggia
|
||||
RAIN_GPIO=25
|
||||
|
||||
# Valore in ingresso sul gpio definito in RAIN_GPIO che indica lo stato di pioggia
|
||||
RAIN_GPIO_STATE=0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Numero totale di elettrovalvole
|
||||
EV_TOTAL=6
|
||||
|
||||
# Definizione delle elettrovalvole
|
||||
EV1_ALIAS="1" #"posteriore_sinistra"
|
||||
EV1_GPIO=17
|
||||
|
||||
EV2_ALIAS="2" #"posteriore_destra"
|
||||
EV2_GPIO=27
|
||||
|
||||
EV3_ALIAS="3" #
|
||||
EV3_GPIO=22
|
||||
|
||||
EV4_ALIAS="4" #
|
||||
EV4_GPIO=18
|
||||
|
||||
EV5_ALIAS="5" #
|
||||
EV5_GPIO=23
|
||||
|
||||
EV6_ALIAS="6" #
|
||||
EV6_GPIO=24
|
||||
|
||||
# Definisce l'api key e il luogo per recuperare lo stato meteo online
|
||||
WUNDERGROUND_KEY=""
|
||||
WUNDERGROUND_LOCATION="IY/Monsummano" # http://www.wunderground.com/weather/api/d/docs?d=resources/country-to-iso-matching&MR=1
|
||||
|
||||
# Blocca l'irrigazione se l'ultima pioggia rilevata online è avvenuta nell'ultima quantità di tempo inserita.
|
||||
# Il tempo è espresso in secondi. Quindi inserendo 86400, se nelle ultime 24 ore ha pioviuto viene bloccata l'irrigazione. Inserendo il valore zero nonviene eseguito nessun controllo.
|
||||
NOT_IRRIGATE_IF_RAIN_ONLINE=86400
|
||||
|
||||
# Il parametro è simile a quello precedente, il controllo però anziché essere fatto attingendo a wunderground, viene eseguito direttamente sul sensore se installato. Inserendo il valore zero nonviene eseguito nessun controllo.
|
||||
NOT_IRRIGATE_IF_RAIN_SENSOR=86400
|
||||
|
||||
5
debug/debug1.sh
Normal file
5
debug/debug1.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
# Insert in this file debug code callable with
|
||||
# garden.sh debug1
|
||||
#
|
||||
echo "Debug 1"
|
||||
|
||||
5
debug/debug2.sh
Normal file
5
debug/debug2.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
# Insert in this file debug code callable with
|
||||
# garden.sh debug2
|
||||
#
|
||||
echo "Debug 1"
|
||||
|
||||
4
log/.gitignore
vendored
Normal file
4
log/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
||||
482
piGarden.sh
Executable file
482
piGarden.sh
Executable file
@@ -0,0 +1,482 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Bash script to manage an irrigation system built with a Raspberry Pi
|
||||
# Author: david.bigagli@gmail.com
|
||||
# Url: https://github.com/lejubila/piGarden
|
||||
#
|
||||
|
||||
#
|
||||
# Inizializza le elettrovalvole e l'alimentazione
|
||||
#
|
||||
function initialize {
|
||||
|
||||
log_write "Run initialize"
|
||||
|
||||
# Imposta l'alimentazione con voltaggio negativo e setta i gpio in scrittura
|
||||
$GPIO -g write $SUPPLY_GPIO_1 0
|
||||
$GPIO -g write $SUPPLY_GPIO_2 0
|
||||
$GPIO -g mode $SUPPLY_GPIO_1 out
|
||||
$GPIO -g mode $SUPPLY_GPIO_2 out
|
||||
|
||||
# Elimina tutti gli stati delle elettrovalvole preesistenti
|
||||
rm -f "$STATUS_DIR"/*
|
||||
|
||||
# Inizializza i gpio delle elettrovalvole e ne chiude l'alimentazione
|
||||
for i in $(seq $EV_TOTAL)
|
||||
do
|
||||
g=EV"$i"_GPIO
|
||||
$GPIO -g write ${!g} RELE_GPIO_OPEN # chiude l'alimentazione all'elettrovalvole
|
||||
$GPIO -g mode ${!g} out # setta il gpio nella modalita di scrittura
|
||||
ev_set_state $i 0
|
||||
done
|
||||
|
||||
# Chiude tutte le elettrovalvole
|
||||
for i in $(seq $EV_TOTAL)
|
||||
do
|
||||
a=EV"$i"_ALIAS
|
||||
al=${!a}
|
||||
ev_close $al
|
||||
done
|
||||
|
||||
# Inizializza il sensore di rilevamento pioggia
|
||||
if [ -n "$RAIN_GPIO" ]; then
|
||||
$GPIO -g mode $RAIN_GPIO in
|
||||
log_write "Rain sensor initialized"
|
||||
else
|
||||
log_write "Rain sensor not present"
|
||||
fi
|
||||
|
||||
log_write "End initialize"
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Commuta un elettrovalvola nello stato aperto
|
||||
# $1 alias elettrovalvola
|
||||
# $2 se specificata la string "force" apre l'elettrovalvola anche se c'é pioggia
|
||||
#
|
||||
function ev_open {
|
||||
if [ ! "$2" = "force" ]; then
|
||||
if [[ "$NOT_IRRIGATE_IF_RAIN_ONLINE" -gt 0 && -f $STATUS_DIR/last_rain_online ]]; then
|
||||
local last_rain=`cat $STATUS_DIR/last_rain_online`
|
||||
local now=`date +%s`
|
||||
local dif=0
|
||||
let "dif = now - last_rain"
|
||||
if [ $dif -lt $NOT_IRRIGATE_IF_RAIN_ONLINE ]; then
|
||||
log_write "Solenoid '$1' not open for rain (online check)"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
check_rain_sensor
|
||||
if [[ "$NOT_IRRIGATE_IF_RAIN_SENSOR" -gt 0 && -f $STATUS_DIR/last_rain_sensor ]]; then
|
||||
local last_rain=`cat $STATUS_DIR/last_rain_sensor`
|
||||
local now=`date +%s`
|
||||
local dif=0
|
||||
let "dif = now - last_rain"
|
||||
if [ $dif -lt $NOT_IRRIGATE_IF_RAIN_SENSOR ]; then
|
||||
log_write "Solenoid '$1' not open for rain (sensor check)"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
log_write "Solenoid '$1' open"
|
||||
supply_positive
|
||||
#gpio_alias2number $1
|
||||
ev_alias2number $1
|
||||
EVNUM=$?
|
||||
ev_number2gpio $EVNUM
|
||||
g=$?
|
||||
$GPIO -g write $g $RELE_GPIO_CLOSE
|
||||
sleep 1
|
||||
$GPIO -g write $g $RELE_GPIO_OPEN
|
||||
ev_set_state $EVNUM 1
|
||||
}
|
||||
|
||||
#
|
||||
# Commuta un elettrovalvola nello stato chiuso
|
||||
# $1 alias elettrovalvola
|
||||
#
|
||||
function ev_close {
|
||||
log_write "Solenoid '$1' close"
|
||||
supply_negative
|
||||
#$GPIO_alias2number $1
|
||||
ev_alias2number $1
|
||||
EVNUM=$?
|
||||
ev_number2gpio $EVNUM
|
||||
g=$?
|
||||
$GPIO -g write $g $RELE_GPIO_CLOSE
|
||||
sleep 1
|
||||
$GPIO -g write $g $RELE_GPIO_OPEN
|
||||
ev_set_state $EVNUM 0
|
||||
}
|
||||
|
||||
#
|
||||
# Imposta l'alimentazione delle elettrovalvole con voltaggio positivo
|
||||
#
|
||||
function supply_positive {
|
||||
$GPIO -g write $SUPPLY_GPIO_1 $SUPPLY_GPIO_POS
|
||||
$GPIO -g write $SUPPLY_GPIO_2 $SUPPLY_GPIO_POS
|
||||
}
|
||||
|
||||
#
|
||||
# Imposta l'alimentazione delle elettrovalvole con voltaggio negativo
|
||||
#
|
||||
function supply_negative {
|
||||
$GPIO -g write $SUPPLY_GPIO_1 $SUPPLY_GPIO_NEG
|
||||
$GPIO -g write $SUPPLY_GPIO_2 $SUPPLY_GPIO_NEG
|
||||
}
|
||||
|
||||
#
|
||||
# Scrive un messaggio nel file di log
|
||||
# $1 log da scrivere
|
||||
#
|
||||
function log_write {
|
||||
if [ -e "$LOG_FILE" ]; then
|
||||
local actualsize=$($WC -c <"$LOG_FILE")
|
||||
if [ $actualsize -ge $LOG_FILE_MAX_SIZE ]; then
|
||||
$GZIP $LOG_FILE
|
||||
$MV $LOG_FILE.gz $LOG_FILE.`date +%Y%m%d%H%M`.gz
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "`date`\t\t$1" >> $LOG_FILE
|
||||
}
|
||||
|
||||
#
|
||||
# Imposta lo stgato di una elettrovalvola
|
||||
# $1 numero dell'elettrovalvola
|
||||
# $2 stato da scrivere
|
||||
#
|
||||
function ev_set_state {
|
||||
echo "$2" > "$STATUS_DIR/ev$1"
|
||||
}
|
||||
|
||||
#
|
||||
# Legge lo stato di una elettrovalvola
|
||||
#
|
||||
function ev_get_state {
|
||||
return `cat "$STATUS_DIR/ev$1"`
|
||||
}
|
||||
|
||||
#
|
||||
# Passando un alias di un'elettrovalvola recupera il numero gpio associato
|
||||
# $1 alias elettrovalvola
|
||||
#
|
||||
function gpio_alias2number {
|
||||
for i in $(seq $EV_TOTAL)
|
||||
do
|
||||
g=EV"$i"_GPIO
|
||||
a=EV"$i"_ALIAS
|
||||
gv=${!g}
|
||||
av=${!a}
|
||||
if [ "$av" == "$1" ]; then
|
||||
return $gv
|
||||
fi
|
||||
done
|
||||
|
||||
log_write "ERROR solenoid alias not found: $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# Recupera il numero di una elettrovalvola in base all'alias
|
||||
# $1 alias dell'elettrovalvola
|
||||
#
|
||||
function ev_alias2number {
|
||||
for i in $(seq $EV_TOTAL)
|
||||
do
|
||||
a=EV"$i"_ALIAS
|
||||
av=${!a}
|
||||
if [ "$av" == "$1" ]; then
|
||||
return $i
|
||||
fi
|
||||
done
|
||||
|
||||
log_write "ERROR solenoid alias not found: $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# Recupera il numero di gpio associato ad una elettrovalvola
|
||||
# $1 numero elettrovalvola
|
||||
#
|
||||
function ev_number2gpio {
|
||||
# echo "numero ev $1"
|
||||
i=$1
|
||||
g=EV"$i"_GPIO
|
||||
gv=${!g}
|
||||
# echo "gv = $gv"
|
||||
return $gv
|
||||
}
|
||||
|
||||
#
|
||||
# Mostra lo stato di tutte le elettrovalvole
|
||||
#
|
||||
function ev_status_all {
|
||||
for i in $(seq $EV_TOTAL)
|
||||
do
|
||||
a=EV"$i"_ALIAS
|
||||
av=${!a}
|
||||
ev_get_state $i
|
||||
echo -e "$av: $?"
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# Mostra lo stato di una elettrovalvola
|
||||
# $1 alias elettrovalvola
|
||||
#
|
||||
function ev_status {
|
||||
ev_alias2number $1
|
||||
i=$?
|
||||
ev_get_state $i
|
||||
local state=$?
|
||||
echo -e "$state"
|
||||
return $state
|
||||
}
|
||||
|
||||
#
|
||||
# Controlla se se piove tramite http://api.wunderground.com/
|
||||
#
|
||||
function check_rain_online {
|
||||
# http://www.wunderground.com/weather/api/d/docs?d=resources/phrase-glossary&MR=1
|
||||
$CURL http://api.wunderground.com/api/$WUNDERGROUND_KEY/conditions/q/$WUNDERGROUND_LOCATION.json > /tmp/check_rain_online.json
|
||||
local weather=`cat /tmp/check_rain_online.json | $JQ -M ".current_observation.weather"`
|
||||
local local_epoch=`cat /tmp/check_rain_online.json | $JQ -M -r ".current_observation.local_epoch"`
|
||||
#echo $weather
|
||||
if [ "$weather" = "null" ]; then
|
||||
log_write "check_rain_online - failed read online data"
|
||||
else
|
||||
log_write "check_rain_online - weather=$weather, local_epoch=$local_epoch"
|
||||
#if [[ "$weather" == *"Clear"* ]]; then
|
||||
if [[ "$weather" == *"Rain"* ]]; then
|
||||
#echo "ECCOMI!!!!!"
|
||||
echo $local_epoch > "$STATUS_DIR/last_rain_online"
|
||||
return $local_epoch
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Controlla se se piove tramite sensore
|
||||
#
|
||||
function check_rain_sensor {
|
||||
|
||||
if [ -n "$RAIN_GPIO" ]; then
|
||||
local s=`$GPIO -g read $RAIN_GPIO`
|
||||
if [ "$s" = "$RAIN_GPIO_STATE" ]; then
|
||||
local local_epoch=`date +%s`
|
||||
echo $local_epoch > "$STATUS_DIR/last_rain_sensor"
|
||||
log_write "check_rain_sensor - now it's raining ($local_epoch)"
|
||||
return $local_epoch
|
||||
else
|
||||
log_write "check_rain_sensor - now is not raining"
|
||||
fi
|
||||
else
|
||||
log_write "Rain sensor not present"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Chiude tutte le elettrovalvole se sta piovendo
|
||||
# Eseguie il controllo in tempo reale sul sensore hardware e sui dati dell'ultima chiamata eseguita online
|
||||
#
|
||||
function close_all_for_rain {
|
||||
|
||||
local close_all=0
|
||||
local now=`date +%s`
|
||||
|
||||
if [[ "$NOT_IRRIGATE_IF_RAIN_ONLINE" -gt 0 && -f $STATUS_DIR/last_rain_online ]]; then
|
||||
local last_rain=`cat $STATUS_DIR/last_rain_online`
|
||||
local dif=0
|
||||
let "dif = now - last_rain"
|
||||
if [ $dif -lt $NOT_IRRIGATE_IF_RAIN_ONLINE ]; then
|
||||
close_all=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$NOT_IRRIGATE_IF_RAIN_SENSOR" -gt 0 && -f $STATUS_DIR/last_rain_sensor ]]; then
|
||||
local last_rain=`cat $STATUS_DIR/last_rain_sensor`
|
||||
local dif=0
|
||||
let "dif = now - last_rain"
|
||||
if [ $dif -lt $NOT_IRRIGATE_IF_RAIN_SENSOR ]; then
|
||||
close_all=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$close_all" = "1" ]; then
|
||||
for i in $(seq $EV_TOTAL)
|
||||
do
|
||||
local a=EV"$i"_ALIAS
|
||||
local al=${!a}
|
||||
ev_status $al
|
||||
local state=$?
|
||||
#echo "$al = $state"
|
||||
if [ "$state" = "1" ]; then
|
||||
ev_close $al
|
||||
log_write "close_all_for_rain - Close solenod '$al' for rain"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
function close_all {
|
||||
|
||||
for i in $(seq $EV_TOTAL)
|
||||
do
|
||||
local a=EV"$i"_ALIAS
|
||||
local al=${!a}
|
||||
ev_status $al
|
||||
local state=$?
|
||||
#echo "$al = $state"
|
||||
if [[ "$state" = "1" || "$1" = "force" ]]; then
|
||||
ev_close $al
|
||||
log_write "close_all - Close solenod '$al' for rain"
|
||||
fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
function list_alias {
|
||||
|
||||
for i in $(seq $EV_TOTAL)
|
||||
do
|
||||
local a=EV"$i"_ALIAS
|
||||
local al=${!a}
|
||||
echo $al
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
function json_status {
|
||||
local json=""
|
||||
for i in $(seq $EV_TOTAL)
|
||||
do
|
||||
local a=EV"$i"_ALIAS
|
||||
local av=${!a}
|
||||
ev_status $av > /dev/null
|
||||
local sv=$?
|
||||
if [ -n "$json" ]; then
|
||||
json="$json,"
|
||||
fi
|
||||
json="$json\"$i\":{\"name\":\"$av\",\"state\":$sv}"
|
||||
done
|
||||
json="\"zones\":{$json}"
|
||||
|
||||
json="{$json}"
|
||||
|
||||
echo $json
|
||||
|
||||
# {"zones":{"1":{"name":"Zona_1","state":1},"2":{"name":"Zona_2","state":0}}}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function show_usage {
|
||||
echo -e "Usage:"
|
||||
echo -e "\t$NAME_SCRIPT init\t\tinitialize supply and solenoid in closed state"
|
||||
echo -e "\t$NAME_SCRIPT open alias [force]\topen a solenoid"
|
||||
echo -e "\t$NAME_SCRIPT close alias\t\tclose a solenoid"
|
||||
echo -e "\t$NAME_SCRIPT list_alias\t\tview list of aliases solenoid"
|
||||
echo -e "\t$NAME_SCRIPT ev_status alias\tshow status solenoid"
|
||||
echo -e "\t$NAME_SCRIPT ev_status_all \tshow status solenoids"
|
||||
echo -e "\t$NAME_SCRIPT json_status \tshow status in json format"
|
||||
echo -e "\t$NAME_SCRIPT check_rain_online \tcheck rain from http://api.wunderground.com/"
|
||||
echo -e "\t$NAME_SCRIPT check_rain_sensor \tcheck rain from hardware sensor"
|
||||
echo -e "\t$NAME_SCRIPT close_all_for_rain \tclose all solenoid if it's raining"
|
||||
echo -e "\t$NAME_SCRIPT close_all [force]\tclose all solenoid"
|
||||
echo -e "\t$NAME_SCRIPT debug1 [parameter]|[parameter]|..]\tRun debug code 1"
|
||||
echo -e "\t$NAME_SCRIPT debug2 [parameter]|[parameter]|..]\tRun debug code 2"
|
||||
}
|
||||
|
||||
function debug1 {
|
||||
. "$DIR_SCRIPT/debug/debug1.sh"
|
||||
}
|
||||
|
||||
function debug2 {
|
||||
. "$DIR_SCRIPT/debug/debug1.sh"
|
||||
}
|
||||
|
||||
DIR_SCRIPT=`dirname $0`
|
||||
NAME_SCRIPT=${0##*/}
|
||||
CONFIG_ETC="/etc/piGarden.conf"
|
||||
|
||||
if [ -f $CONFIG_ETC ]; then
|
||||
. $CONFIG_ETC
|
||||
else
|
||||
echo -e "Config file not found in $CONFIG_ETC"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
init)
|
||||
initialize
|
||||
;;
|
||||
|
||||
open)
|
||||
if [ "empty$2" == "empty" ]; then
|
||||
echo -e "Alias solenoid not specified"
|
||||
fi
|
||||
ev_open $2 $3
|
||||
;;
|
||||
|
||||
close)
|
||||
if [ "empty$2" == "empty" ]; then
|
||||
echo -e "Alias solenoid not specified"
|
||||
fi
|
||||
ev_close $2
|
||||
;;
|
||||
|
||||
list_alias)
|
||||
list_alias
|
||||
;;
|
||||
|
||||
ev_status)
|
||||
ev_status $2force
|
||||
;;
|
||||
|
||||
ev_status_all)
|
||||
ev_status_all
|
||||
;;
|
||||
|
||||
json_status)
|
||||
json_status
|
||||
;;
|
||||
|
||||
check_rain_online)
|
||||
check_rain_online
|
||||
;;
|
||||
|
||||
check_rain_sensor)
|
||||
check_rain_sensor
|
||||
;;
|
||||
|
||||
close_all_for_rain)
|
||||
close_all_for_rain
|
||||
;;
|
||||
|
||||
close_all)
|
||||
close_all $2
|
||||
;;
|
||||
|
||||
debug1)
|
||||
debug1 $2 $3 $4 $5
|
||||
;;
|
||||
|
||||
debug2)
|
||||
debug2 $2 $3 $4 $5
|
||||
;;
|
||||
|
||||
|
||||
*)
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
|
||||
4
state/.gitignore
vendored
Normal file
4
state/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
||||
Reference in New Issue
Block a user