Eseguito merge del brench drv nel brench develop

This commit is contained in:
lejubila
2017-10-12 23:54:18 +02:00
42 changed files with 2939 additions and 873 deletions

View File

@@ -1,24 +1,32 @@
## 0.x.x - xx/xx/2017
Add kicad electric schemas
# 0.5.0 - 12/10/2017
- Implemented driver subsystem for interfacing with other board
- Added driver spb16ch for interfacing with "Smart Power Board 16 channel with RTC"
- Added socket server api for close all zones and disable all scheduling
- Implement command and socket server api to perform system shutdown and reboot
- Fix problem with cron management on similar type cron
- Fix bug: in case of rain the weather data were not updated
- Fix bug: delete the temporary files for managing the socket server messages that were kept on the system
- Change manage of the lock/unlock function for encrase performance (do you need manualy remove the file /var/shm/piGarden.lock or /tmp/piGarden.lock)
- Add kicad electric schemas
## 0.4.4 - 17/06/2017
Remove lock/unlock from init function for resove bug
- Remove lock/unlock from init function for resove bug
## 0.4.3 - 17/06/2017
Fix path of sed in lock function
- Fix path of sed in lock function
## 0.4.2 - 16/06/2017
Fix another problem on generate installation identifier to sendo for statistic
- Fix another problem on generate installation identifier to sendo for statistic
## 0.4.1 - 14/06/2017
Fix problem on send identifier installation for statistic
- Fix problem on send identifier installation for statistic
## 0.4.0 - 14/06/2017
Add credentials support to socket server (define TCPSERVER_USER and TCPSERVER_PWD in your config file)
Add management lock/unlock for prevent concurrente call to open/close solenoid
Added the ability to enter an open / close schedule in disabled mode
Add send statistic information to remote server
During the initialization function, information on the last rain is no longer removed
- Add credentials support to socket server (define TCPSERVER_USER and TCPSERVER_PWD in your config file)
- Add management lock/unlock for prevent concurrente call to open/close solenoid
- Added the ability to enter an open / close schedule in disabled mode
- Add send statistic information to remote server
- During the initialization function, information on the last rain is no longer removed
## 0.3.1 - 13/05/2017
Add experimental support for monostable solenoid valve:
@@ -26,27 +34,27 @@ Add experimental support for monostable solenoid valve:
- if the solenoid valves close instead of opening and vice versa, reverse the values of the RELE_GPIO_CLOSE and RELE_GPIO_OPEN variables in your configuration file
## 0.3.0 - 07/05/2017
Add command "open_in" for scheduling on the fly the opens/close a solenoid
Add command "del_cron_open_in" for delete scheduling the fly the opens/close a solenoid
Add api in socket server for command open_in and delete_cron_open_in
Fix minor bug on command "open"
Changed the path of some temporary files to prevent sd card faults
- Add command "open_in" for scheduling on the fly the opens/close a solenoid
- Add command "del_cron_open_in" for delete scheduling the fly the opens/close a solenoid
- Add api in socket server for command open_in and delete_cron_open_in
- Fix minor bug on command "open"
- Changed the path of some temporary files to prevent sd card faults
## 0.2.2 - 25/04/2017
Fix bug: if it's reining, the solenoid valves were also closed even if they were pushed open in "force" mode
- Fix bug: if it's reining, the solenoid valves were also closed even if they were pushed open in "force" mode
## 0.2.1 - 22/04/2017
Add installation instructions in README.md file
- Add installation instructions in README.md file
## 0.2 (Easter egg) - 17/04/2017
Implementation of socket server for communicate with piGardenWeb
Implementation of messages (error, warning, success) passed to piGardenWeb
Added many information in json status to be passed to piGardenWeb
Added management cron for scheduling open and closed solenoid, for initialize control unit, for rain control
- Implementation of socket server for communicate with piGardenWeb
- Implementation of messages (error, warning, success) passed to piGardenWeb
- Added many information in json status to be passed to piGardenWeb
- Added management cron for scheduling open and closed solenoid, for initialize control unit, for rain control
## 0.1.1 - 24/12/2015 - BugFix
Fix the problem for 'av_status' parameter
- Fix the problem for 'av_status' parameter
## 0.1 - 18/12/2015 - First release
First release to piGarden
- First release to piGarden

View File

@@ -10,7 +10,7 @@ Documentation of piGarden and build system irrigation with Raspberry Pi can be f
This script is open-sourced software under GNU GENERAL PUBLIC LICENSE Version 2
## Installation
## Installation to Raspbian Jessie
1) Installs the necessary packages on your terminal:
@@ -26,7 +26,7 @@ sudo apt-get install flex -y
sudo apt-get install bison -y
sudo apt-get install gcc -y
sudo apt-get install make -y
sudo apt-get install autotools -y
sudo apt-get install libtool autoconf automake gettext autotools-dev -y
sudo apt-get install dh-autoreconf -y
wget https://github.com/stedolan/jq/releases/download/jq-1.5/jq-1.5.tar.gz
tar xfvz jq-1.5.tar.gz

View File

@@ -2,6 +2,9 @@
LOG_FILE="/home/pi/piGarden/log/piGarden.log"
LOG_FILE_MAX_SIZE=1048576 # 1MB
# Log file for driver output
LOG_OUTPUT_DRV_FILE="/tmp/piGarden.drv.log"
# Status directory
STATUS_DIR="/home/pi/piGarden/state"
@@ -52,8 +55,8 @@ STAT="/usr/bin/stat"
EV_MONOSTABLE=0
# Id gpio usati per simulare il doppio deviatore con cui eseguire l'alimentazione alle elettrovalvole
SUPPLY_GPIO_1=2
SUPPLY_GPIO_2=3
SUPPLY_GPIO_1=2 # Physical 3 - wPi 8
SUPPLY_GPIO_2=3 # Physical 5 - wPi 9
# Stato dei due gpio per impartire l'alimentazione positiva alle elettrovalvole (aperta)
SUPPLY_GPIO_POS=0
@@ -68,7 +71,7 @@ RELE_GPIO_CLOSE=0
RELE_GPIO_OPEN=1
# Id del gpio usato per collegare il sensore di rilevamento pioggia
RAIN_GPIO=25
RAIN_GPIO=25 # Physical 22 - wPi 6
# Valore in ingresso sul gpio definito in RAIN_GPIO che indica lo stato di pioggia
RAIN_GPIO_STATE=0
@@ -82,22 +85,22 @@ EV_TOTAL=6
# Definizione delle elettrovalvole
EV1_ALIAS="1" #
EV1_GPIO=17
EV1_GPIO=17 # Physical 11 - wPi 0
EV2_ALIAS="2" #
EV2_GPIO=27
EV2_GPIO=27 # Physical 13 - wPi 2
EV3_ALIAS="3" #
EV3_GPIO=22
EV3_GPIO=22 # Physical 15 - wPi 3
EV4_ALIAS="4" #
EV4_GPIO=18
EV4_GPIO=18 # Physical 12 - wPi 1
EV5_ALIAS="5" #
EV5_GPIO=23
EV5_GPIO=23 # Physical 16 - wPi 4
EV6_ALIAS="6" #
EV6_GPIO=24
EV6_GPIO=24 # Physical 18 - wPi 5
# Definisce l'api key e il luogo per recuperare lo stato meteo online
WUNDERGROUND_KEY=""

View File

@@ -0,0 +1,510 @@
# Log file
LOG_FILE="/home/pi/piGarden/log/piGarden.log"
LOG_FILE_MAX_SIZE=1048576 # 1MB
# Log file for driver output
#LOG_OUTPUT_DRV_FILE="/tmp/piGarden.drv.log"
# 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"
# Percorso wc
WC="/usr/bin/wc"
# Percorso gzip
GZIP="/bin/gzip"
# Percorso mv
MV="/bin/mv"
# Percorso di tr
TR="/usr/bin/tr"
# Percorso di cut
CUT="/usr/bin/cut"
# Percorso tcpserver
TCPSERVER="/usr/bin/tcpserver"
# Percorso cron
CRONTAB="/usr/bin/crontab"
# Percorso grep
GREP="/bin/grep"
# Percorsp sed
SED="/bin/sed"
# Percorso readlink
READLINK="/bin/readlink"
# Percorso stat
STAT="/usr/bin/stat"
# Se impostato con il valore 1, indica che il sistema gestisce elettrovalvole monostabili,
# se impostato a 0 il sistema gestirà elettrovalvole bisstabili
EV_MONOSTABLE=1
# Id gpio usati per simulare il doppio deviatore con cui eseguire l'alimentazione alle elettrovalvole
SUPPLY_GPIO_1="drv:spb16ch:15"
SUPPLY_GPIO_2="drv:spb16ch:16"
# 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=
# 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=128
# Definizione delle elettrovalvole
EV1_ALIAS="Zona_1" #
EV1_GPIO="drv:spb16ch:1"
EV2_ALIAS="Zona_2" #
EV2_GPIO="drv:spb16ch:2"
EV3_ALIAS="Zona_3" #
EV3_GPIO="drv:spb16ch:3"
EV4_ALIAS="Zona_4" #
EV4_GPIO="drv:spb16ch:4"
EV5_ALIAS="Zona_5" #
EV5_GPIO="drv:spb16ch:5"
EV6_ALIAS="Zona_6" #
EV6_GPIO="drv:spb16ch:6"
EV7_ALIAS="Zona_7" #
EV7_GPIO="drv:spb16ch:7"
EV8_ALIAS="Zona_8" #
EV8_GPIO="drv:spb16ch:8"
EV9_ALIAS="Zona_9" #
EV9_GPIO="drv:spb16ch:9"
EV10_ALIAS="Zona_10" #
EV10_GPIO="drv:spb16ch:10"
EV11_ALIAS="Zona_11" #
EV11_GPIO="drv:spb16ch:11"
EV12_ALIAS="Zona_12" #
EV12_GPIO="drv:spb16ch:12"
EV13_ALIAS="Zona_13" #
EV13_GPIO="drv:spb16ch:13"
EV14_ALIAS="Zona_14" #
EV14_GPIO="drv:spb16ch:14"
EV15_ALIAS="Zona_15" #
EV15_GPIO="drv:spb16ch:15"
EV16_ALIAS="Zona_16" #
EV16_GPIO="drv:spb16ch:16"
EV17_ALIAS="Zona_17" #
EV17_GPIO="drv:spb16ch:17"
EV18_ALIAS="Zona_18" #
EV18_GPIO="drv:spb16ch:18"
EV19_ALIAS="Zona_19" #
EV19_GPIO="drv:spb16ch:19"
EV20_ALIAS="Zona_20" #
EV20_GPIO="drv:spb16ch:20"
EV21_ALIAS="Zona_21" #
EV21_GPIO="drv:spb16ch:21"
EV22_ALIAS="Zona_22" #
EV22_GPIO="drv:spb16ch:22"
EV23_ALIAS="Zona_23" #
EV23_GPIO="drv:spb16ch:23"
EV24_ALIAS="Zona_24" #
EV24_GPIO="drv:spb16ch:24"
EV25_ALIAS="Zona_25" #
EV25_GPIO="drv:spb16ch:25"
EV26_ALIAS="Zona_26" #
EV26_GPIO="drv:spb16ch:26"
EV27_ALIAS="Zona_27" #
EV27_GPIO="drv:spb16ch:27"
EV28_ALIAS="Zona_28" #
EV28_GPIO="drv:spb16ch:28"
EV29_ALIAS="Zona_29" #
EV29_GPIO="drv:spb16ch:29"
EV30_ALIAS="Zona_30" #
EV30_GPIO="drv:spb16ch:30"
EV31_ALIAS="Zona_31" #
EV31_GPIO="drv:spb16ch:31"
EV32_ALIAS="Zona_32" #
EV32_GPIO="drv:spb16ch:32"
EV33_ALIAS="Zona_33" #
EV33_GPIO="drv:spb16ch:33"
EV34_ALIAS="Zona_34" #
EV34_GPIO="drv:spb16ch:34"
EV35_ALIAS="Zona_35" #
EV35_GPIO="drv:spb16ch:35"
EV36_ALIAS="Zona_36" #
EV36_GPIO="drv:spb16ch:36"
EV37_ALIAS="Zona_37" #
EV37_GPIO="drv:spb16ch:37"
EV38_ALIAS="Zona_38" #
EV38_GPIO="drv:spb16ch:38"
EV39_ALIAS="Zona_39" #
EV39_GPIO="drv:spb16ch:39"
EV40_ALIAS="Zona_40" #
EV40_GPIO="drv:spb16ch:40"
EV41_ALIAS="Zona_41" #
EV41_GPIO="drv:spb16ch:41"
EV42_ALIAS="Zona_42" #
EV42_GPIO="drv:spb16ch:42"
EV43_ALIAS="Zona_43" #
EV43_GPIO="drv:spb16ch:43"
EV44_ALIAS="Zona_44" #
EV44_GPIO="drv:spb16ch:44"
EV45_ALIAS="Zona_45" #
EV45_GPIO="drv:spb16ch:45"
EV46_ALIAS="Zona_46" #
EV46_GPIO="drv:spb16ch:46"
EV47_ALIAS="Zona_47" #
EV47_GPIO="drv:spb16ch:47"
EV48_ALIAS="Zona_48" #
EV48_GPIO="drv:spb16ch:48"
EV49_ALIAS="Zona_49" #
EV49_GPIO="drv:spb16ch:49"
EV50_ALIAS="Zona_50" #
EV50_GPIO="drv:spb16ch:50"
EV51_ALIAS="Zona_51" #
EV51_GPIO="drv:spb16ch:51"
EV52_ALIAS="Zona_52" #
EV52_GPIO="drv:spb16ch:52"
EV53_ALIAS="Zona_53" #
EV53_GPIO="drv:spb16ch:53"
EV54_ALIAS="Zona_54" #
EV54_GPIO="drv:spb16ch:54"
EV55_ALIAS="Zona_55" #
EV55_GPIO="drv:spb16ch:55"
EV56_ALIAS="Zona_56" #
EV56_GPIO="drv:spb16ch:56"
EV57_ALIAS="Zona_57" #
EV57_GPIO="drv:spb16ch:57"
EV58_ALIAS="Zona_58" #
EV58_GPIO="drv:spb16ch:58"
EV59_ALIAS="Zona_59" #
EV59_GPIO="drv:spb16ch:59"
EV60_ALIAS="Zona_60" #
EV60_GPIO="drv:spb16ch:60"
EV61_ALIAS="Zona_61" #
EV61_GPIO="drv:spb16ch:61"
EV62_ALIAS="Zona_62" #
EV62_GPIO="drv:spb16ch:62"
EV63_ALIAS="Zona_63" #
EV63_GPIO="drv:spb16ch:63"
EV64_ALIAS="Zona_64" #
EV64_GPIO="drv:spb16ch:64"
EV65_ALIAS="Zona_65" #
EV65_GPIO="drv:spb16ch:65"
EV66_ALIAS="Zona_66" #
EV66_GPIO="drv:spb16ch:66"
EV67_ALIAS="Zona_67" #
EV67_GPIO="drv:spb16ch:67"
EV68_ALIAS="Zona_68" #
EV68_GPIO="drv:spb16ch:68"
EV69_ALIAS="Zona_69" #
EV69_GPIO="drv:spb16ch:69"
EV70_ALIAS="Zona_70" #
EV70_GPIO="drv:spb16ch:70"
EV71_ALIAS="Zona_71" #
EV71_GPIO="drv:spb16ch:71"
EV72_ALIAS="Zona_72" #
EV72_GPIO="drv:spb16ch:72"
EV73_ALIAS="Zona_73" #
EV73_GPIO="drv:spb16ch:73"
EV74_ALIAS="Zona_74" #
EV74_GPIO="drv:spb16ch:74"
EV75_ALIAS="Zona_75" #
EV75_GPIO="drv:spb16ch:75"
EV76_ALIAS="Zona_76" #
EV76_GPIO="drv:spb16ch:76"
EV77_ALIAS="Zona_77" #
EV77_GPIO="drv:spb16ch:77"
EV78_ALIAS="Zona_78" #
EV78_GPIO="drv:spb16ch:78"
EV79_ALIAS="Zona_79" #
EV79_GPIO="drv:spb16ch:79"
EV80_ALIAS="Zona_80" #
EV80_GPIO="drv:spb16ch:80"
EV81_ALIAS="Zona_81" #
EV81_GPIO="drv:spb16ch:81"
EV82_ALIAS="Zona_82" #
EV82_GPIO="drv:spb16ch:82"
EV83_ALIAS="Zona_83" #
EV83_GPIO="drv:spb16ch:83"
EV84_ALIAS="Zona_84" #
EV84_GPIO="drv:spb16ch:84"
EV85_ALIAS="Zona_85" #
EV85_GPIO="drv:spb16ch:85"
EV86_ALIAS="Zona_86" #
EV86_GPIO="drv:spb16ch:86"
EV87_ALIAS="Zona_87" #
EV87_GPIO="drv:spb16ch:87"
EV88_ALIAS="Zona_88" #
EV88_GPIO="drv:spb16ch:88"
EV89_ALIAS="Zona_89" #
EV89_GPIO="drv:spb16ch:89"
EV90_ALIAS="Zona_90" #
EV90_GPIO="drv:spb16ch:90"
EV91_ALIAS="Zona_91" #
EV91_GPIO="drv:spb16ch:91"
EV92_ALIAS="Zona_92" #
EV92_GPIO="drv:spb16ch:92"
EV93_ALIAS="Zona_93" #
EV93_GPIO="drv:spb16ch:93"
EV94_ALIAS="Zona_94" #
EV94_GPIO="drv:spb16ch:94"
EV95_ALIAS="Zona_95" #
EV95_GPIO="drv:spb16ch:95"
EV96_ALIAS="Zona_96" #
EV96_GPIO="drv:spb16ch:96"
EV97_ALIAS="Zona_97" #
EV97_GPIO="drv:spb16ch:97"
EV98_ALIAS="Zona_98" #
EV98_GPIO="drv:spb16ch:98"
EV99_ALIAS="Zona_99" #
EV99_GPIO="drv:spb16ch:99"
EV100_ALIAS="Zona_100" #
EV100_GPIO="drv:spb16ch:100"
EV101_ALIAS="Zona_101" #
EV101_GPIO="drv:spb16ch:101"
EV102_ALIAS="Zona_102" #
EV102_GPIO="drv:spb16ch:102"
EV103_ALIAS="Zona_103" #
EV103_GPIO="drv:spb16ch:103"
EV104_ALIAS="Zona_104" #
EV104_GPIO="drv:spb16ch:104"
EV105_ALIAS="Zona_105" #
EV105_GPIO="drv:spb16ch:105"
EV106_ALIAS="Zona_106" #
EV106_GPIO="drv:spb16ch:106"
EV107_ALIAS="Zona_107" #
EV107_GPIO="drv:spb16ch:107"
EV108_ALIAS="Zona_108" #
EV108_GPIO="drv:spb16ch:108"
EV109_ALIAS="Zona_109" #
EV109_GPIO="drv:spb16ch:109"
EV110_ALIAS="Zona_110" #
EV110_GPIO="drv:spb16ch:110"
EV111_ALIAS="Zona_111" #
EV111_GPIO="drv:spb16ch:111"
EV112_ALIAS="Zona_112" #
EV112_GPIO="drv:spb16ch:112"
EV113_ALIAS="Zona_113" #
EV113_GPIO="drv:spb16ch:113"
EV114_ALIAS="Zona_114" #
EV114_GPIO="drv:spb16ch:114"
EV115_ALIAS="Zona_115" #
EV115_GPIO="drv:spb16ch:115"
EV116_ALIAS="Zona_116" #
EV116_GPIO="drv:spb16ch:116"
EV117_ALIAS="Zona_117" #
EV117_GPIO="drv:spb16ch:117"
EV118_ALIAS="Zona_118" #
EV118_GPIO="drv:spb16ch:118"
EV119_ALIAS="Zona_119" #
EV119_GPIO="drv:spb16ch:119"
EV120_ALIAS="Zona_120" #
EV120_GPIO="drv:spb16ch:120"
EV121_ALIAS="Zona_121" #
EV121_GPIO="drv:spb16ch:121"
EV122_ALIAS="Zona_122" #
EV122_GPIO="drv:spb16ch:122"
EV123_ALIAS="Zona_123" #
EV123_GPIO="drv:spb16ch:123"
EV124_ALIAS="Zona_124" #
EV124_GPIO="drv:spb16ch:124"
EV125_ALIAS="Zona_125" #
EV125_GPIO="drv:spb16ch:125"
EV126_ALIAS="Zona_126" #
EV126_GPIO="drv:spb16ch:126"
EV127_ALIAS="Zona_127" #
EV127_GPIO="drv:spb16ch:127"
EV128_ALIAS="Zona_128" #
EV128_GPIO="drv:spb16ch:128"
# 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 piovuto viene bloccata l'irrigazione. Inserendo il valore zero non viene 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 non viene eseguito nessun controllo.
NOT_IRRIGATE_IF_RAIN_SENSOR=86400
# Indirizzo ip e porta di ascolto del socket server
TCPSERVER_IP="127.0.0.1"
TCPSERVER_PORT="8084"
# Utente e password che i clients devono utilizzare per stabilire una connessione tramite socket server
TCPSERVER_USER=""
TCPSERVER_PWD=""
# Con impostato il valore 1 non invia l'identificativi per statistiche di utilizzo
NO_SEND_IDENTIFIER=0
#
# Configurazione schede spb16ch
#
# Stato da assegnare ai gpio per abilitare/disabilitare le schede spb16ch
SPB16CH_GPIO_ON=1
SPB16CH_GPIO_OFF=0
# Gpio di per gestire l'abilitazione/disabilitazione delle chede spb16ch
SPB16CH1_GPIO=17 # Physical 11 - wPi 0
SPB16CH2_GPIO=27 # Physical 13 - wPi 2
SPB16CH3_GPIO=22 # Physical 15 - wPi 3
SPB16CH4_GPIO=18 # Physical 12 - wPi 1
SPB16CH5_GPIO=23 # Physical 16 - wPi 4
SPB16CH6_GPIO=24 # Physical 18 - wPi 5
SPB16CH7_GPIO=4 # Physical 7 - wPi 7
SPB16CH8_GPIO=14 # Physical 8 - wPi 15

2
drv/sample/README.md Normal file
View File

@@ -0,0 +1,2 @@
# Fake driver for sample and testing

View File

@@ -0,0 +1,12 @@
#
# Funzioni comuni utilizzate dal driver
#
#
# Funzione di esempio
#
function sample_foo {
echo "bar"
}

View File

@@ -0,0 +1,7 @@
#
# File di configurazione del driver
#
# Dichiarazione variabile di esempio
declare -g SAMPLE_FOO
SAMPLE_FOO="bar"

View File

@@ -0,0 +1,9 @@
#
# Questa funzione viene invocata dalla funzione "init" di piGarden se sono presenti elettrovalvole o sensori che utilizzano questo driver
#
function drv_sample_init {
local FOO="bar"
}

View File

@@ -0,0 +1,23 @@
#
# Inizializza il sensore di rilevamento pioggia
#
# $i identificativo gpio del sensore di pioggia
#
function drv_sample_rain_sensor_init {
local FOO="bar"
}
#
# Ritorna lo stato del sensore di rilevamento pioggia
#
# $i identificativo gpio del sensore di pioggia
#
function drv_sample_rain_sensor_get {
local FOO="bar"
}

View File

@@ -0,0 +1,33 @@
#
# Inizializzazione rele
#
# $1 identificativo relè da inizializzare
#
function drv_sample_rele_init {
local FOO="bar"
}
#
# Apertura rele
#
# $1 identificativo relè da aprire
#
function drv_sample_rele_open {
local FOO="bar"
}
#
# Chiusura rele
#
# $1 identificativo relè da chiudere
#
function drv_sample_rele_close {
local FOO="bar"
}

View File

@@ -0,0 +1,10 @@
#
# Questa funzione viene invocata dalla funzione "setup_drv" di piGarden ad ogni avvio dello script
# e serve per eseguire l'evenutale setup del driver se necessario
#
function drv_sample_setup {
local FOO="bar"
}

View File

@@ -0,0 +1,34 @@
#
# Inizializza i rele che gestiscono l'alimentazione per le valvole bistabili
#
# $1 identificativo relè
#
function drv_sample_supply_bistable_init {
local FOO="bar"
}
#
# Imposta l'alimentazione delle elettrovalvole con voltaggio positivo
#
# $1 identificativo relè
#
function drv_sample_supply_positive {
local FOO="bar"
}
#
# Imposta l'alimentazione delle elettrovalvole con voltaggio negativo
#
# $1 identificativo relè
#
function drv_sample_supply_negative {
local FOO="bar"
}

12
drv/spb16ch/README.md Normal file
View File

@@ -0,0 +1,12 @@
# Driver per controllare la scheda "Smart Power Board 16 channel with RTC" (spb16ch)
Questo driver richiede l'interprete python e la libreria python-smbus. Inoltre l'utente pi deve fare parte del gruppo i2c
sudo apt-get install python python-smbus
sudo usermod -a -G i2c pi
Oltre a quanto sopra indicato, il raspberry deve avere caricato i moduli di gestione del bus i2c:
sudo raspi-config
Interfacing Options / I2C / Yes
Per maggiori informazioni consulta https://www.lejubila.net/2017/10/pigarden-spb16ch-gestiamo-fino-a-128-zone-nel-nostro-impianto-di-irrigazione/

View File

@@ -0,0 +1,80 @@
#
# Funzioni comuni per il driver spb16ch
#
#
# Abilita una scheda spb16ch in modo che possa esseregli impartito un comando successivamente
# $1 identificativo scheda da abilitare
#
function drv_spb16ch_board_enable {
local board_id=$1
local a=SPB16CH"$board_id"_GPIO
local gpio_n=${!a}
echo "** drv_spb16ch_board_enable() - Enable board: $board_id - gpio $gpio_n"
$GPIO -g write $gpio_n $SPB16CH_GPIO_ON
}
#
# Disabilita una scheda spb16ch
# $1 identificativo scheda da disabilitare
#
function drv_spb16ch_board_disable {
local board_id=$1
local a=SPB16CH"$board_id"_GPIO
local gpio_n=${!a}
echo "** drv_spb16ch_board_disable() - Disable board: $board_id - gpio $gpio_n"
$GPIO -g write $gpio_n $SPB16CH_GPIO_OFF
}
#
# Disabilita tutte le schede
#
function drv_spb16ch_board_disable_all {
echo "** drv_spb16ch_board_disable_all() - Boads id: ${SPB16CH_USED_ID[@]}"
local board_id
for board_id in ${SPB16CH_USED_ID[@]}
do
local a=SPB16CH"$board_id"_GPIO
local gpio_n=${!a}
echo "** drv_spb16ch_board_disable_all() - Disable board: $board_id - gpio $gpio_n"
$GPIO -g write $gpio_n $SPB16CH_GPIO_OFF
done
}
#
# Memorizza in un file di appoggio gli id delle schede spb16ch utilizzate
#
function drv_spb16ch_boards_id_store {
echo "${SPB16CH_USED_ID[@]}" > "$SPB16CH_BOARD_ID_STORE_FILE"
}
#
# Recupera gli di delle schede spb16ch utilizzate leggendoli dal file di appoggio
# $1 identificativi schede da salvare
#
function drv_spb16ch_boards_id_load {
if [ -f "$SPB16CH_BOARD_ID_STORE_FILE" ]; then
for board_id in $(cat "$SPB16CH_BOARD_ID_STORE_FILE")
do
SPB16CH_USED_ID+=("$board_id")
done
else
log_write "spb16ch: file $SPB16CH_BOARD_ID_STORE_FILE not found: remember to run 'piGarden init' to generate the file"
fi
}

View File

@@ -0,0 +1,160 @@
#
# Mapping rele spb16ch: l'indice indica il relè, ogni elemento deve essere lungo 8 caratteri,
# 1-2: i primi due indicano l'indirizzo della scheda
# 3-3: separatore
# 4-4: il quarto carattere indica il mux channel
# 5-5: separatore
# 6-8: dal 6 all'ottavo carattere indicano il numero del rele sul canale
# 10-10: l'ultimo carattere indica il numero identificativo della scheda spb16ch
# Scheda 1 - address 70h - GS1:chiuso, GS2:chiuso, GS3:chiuso
SPB16CH_RELE_MAP[1]="70|0| 1|1"
SPB16CH_RELE_MAP[2]="70|0| 2|1"
SPB16CH_RELE_MAP[3]="70|0| 4|1"
SPB16CH_RELE_MAP[4]="70|0| 8|1"
SPB16CH_RELE_MAP[5]="70|0| 16|1"
SPB16CH_RELE_MAP[6]="70|0| 32|1"
SPB16CH_RELE_MAP[7]="70|0| 64|1"
SPB16CH_RELE_MAP[8]="70|0|128|1"
SPB16CH_RELE_MAP[9]="70|1| 1|1"
SPB16CH_RELE_MAP[10]="70|1| 2|1"
SPB16CH_RELE_MAP[11]="70|1| 4|1"
SPB16CH_RELE_MAP[12]="70|1| 8|1"
SPB16CH_RELE_MAP[13]="70|1| 16|1"
SPB16CH_RELE_MAP[14]="70|1| 32|1"
SPB16CH_RELE_MAP[15]="70|1| 64|1"
SPB16CH_RELE_MAP[16]="70|1|128|1"
# Scheda 2 - address 71h - GS1:aperto, GS2:chiuso, GS3:chiuso
SPB16CH_RELE_MAP[17]="71|0| 1|2"
SPB16CH_RELE_MAP[18]="71|0| 2|2"
SPB16CH_RELE_MAP[19]="71|0| 4|2"
SPB16CH_RELE_MAP[20]="71|0| 8|2"
SPB16CH_RELE_MAP[21]="71|0| 16|2"
SPB16CH_RELE_MAP[22]="71|0| 32|2"
SPB16CH_RELE_MAP[23]="71|0| 64|2"
SPB16CH_RELE_MAP[24]="71|0|128|2"
SPB16CH_RELE_MAP[25]="71|1| 1|2"
SPB16CH_RELE_MAP[26]="71|1| 2|2"
SPB16CH_RELE_MAP[27]="71|1| 4|2"
SPB16CH_RELE_MAP[28]="71|1| 8|2"
SPB16CH_RELE_MAP[29]="71|1| 16|2"
SPB16CH_RELE_MAP[30]="71|1| 32|2"
SPB16CH_RELE_MAP[31]="71|1| 64|2"
SPB16CH_RELE_MAP[32]="71|1|128|2"
# Scheda 3 - address 72h - GS1:chiuso, GS2:aperto, GS3:chiuso
SPB16CH_RELE_MAP[33]="72|0| 1|3"
SPB16CH_RELE_MAP[34]="72|0| 2|3"
SPB16CH_RELE_MAP[35]="72|0| 4|3"
SPB16CH_RELE_MAP[36]="72|0| 8|3"
SPB16CH_RELE_MAP[37]="72|0| 16|3"
SPB16CH_RELE_MAP[38]="72|0| 32|3"
SPB16CH_RELE_MAP[39]="72|0| 64|3"
SPB16CH_RELE_MAP[40]="72|0|128|3"
SPB16CH_RELE_MAP[41]="72|1| 1|3"
SPB16CH_RELE_MAP[42]="72|1| 2|3"
SPB16CH_RELE_MAP[43]="72|1| 4|3"
SPB16CH_RELE_MAP[44]="72|1| 8|3"
SPB16CH_RELE_MAP[45]="72|1| 16|3"
SPB16CH_RELE_MAP[46]="72|1| 32|3"
SPB16CH_RELE_MAP[47]="72|1| 64|3"
SPB16CH_RELE_MAP[48]="72|1|128|3"
# Scheda 4 - address 73h - GS1:aperto, GS2:aperto, GS3:chiuso
SPB16CH_RELE_MAP[49]="73|0| 1|4"
SPB16CH_RELE_MAP[50]="73|0| 2|4"
SPB16CH_RELE_MAP[51]="73|0| 4|4"
SPB16CH_RELE_MAP[52]="73|0| 8|4"
SPB16CH_RELE_MAP[53]="73|0| 16|4"
SPB16CH_RELE_MAP[54]="73|0| 32|4"
SPB16CH_RELE_MAP[55]="73|0| 64|4"
SPB16CH_RELE_MAP[56]="73|0|128|4"
SPB16CH_RELE_MAP[57]="73|1| 1|4"
SPB16CH_RELE_MAP[58]="73|1| 2|4"
SPB16CH_RELE_MAP[59]="73|1| 4|4"
SPB16CH_RELE_MAP[60]="73|1| 8|4"
SPB16CH_RELE_MAP[61]="73|1| 16|4"
SPB16CH_RELE_MAP[62]="73|1| 32|4"
SPB16CH_RELE_MAP[63]="73|1| 64|4"
SPB16CH_RELE_MAP[64]="73|1|128|4"
# Scheda 5 - address 74h - GS1:chiuso, GS2:chiuso, GS3:aperto
SPB16CH_RELE_MAP[65]="74|0| 1|5"
SPB16CH_RELE_MAP[66]="74|0| 2|5"
SPB16CH_RELE_MAP[67]="74|0| 4|5"
SPB16CH_RELE_MAP[68]="74|0| 8|5"
SPB16CH_RELE_MAP[69]="74|0| 16|5"
SPB16CH_RELE_MAP[70]="74|0| 32|5"
SPB16CH_RELE_MAP[71]="74|0| 64|5"
SPB16CH_RELE_MAP[72]="74|0|128|5"
SPB16CH_RELE_MAP[73]="74|1| 1|5"
SPB16CH_RELE_MAP[74]="74|1| 2|5"
SPB16CH_RELE_MAP[75]="74|1| 4|5"
SPB16CH_RELE_MAP[76]="74|1| 8|5"
SPB16CH_RELE_MAP[77]="74|1| 16|5"
SPB16CH_RELE_MAP[78]="74|1| 32|5"
SPB16CH_RELE_MAP[79]="74|1| 64|5"
SPB16CH_RELE_MAP[80]="74|1|128|5"
# Scheda 6 - address 75h - GS1:aperto, GS2:chiuso, GS3:aperto
SPB16CH_RELE_MAP[81]="75|0| 1|6"
SPB16CH_RELE_MAP[82]="75|0| 2|6"
SPB16CH_RELE_MAP[83]="75|0| 4|6"
SPB16CH_RELE_MAP[84]="75|0| 8|6"
SPB16CH_RELE_MAP[85]="75|0| 16|6"
SPB16CH_RELE_MAP[86]="75|0| 32|6"
SPB16CH_RELE_MAP[87]="75|0| 64|6"
SPB16CH_RELE_MAP[88]="75|0|128|6"
SPB16CH_RELE_MAP[89]="75|1| 1|6"
SPB16CH_RELE_MAP[90]="75|1| 2|6"
SPB16CH_RELE_MAP[91]="75|1| 4|6"
SPB16CH_RELE_MAP[92]="75|1| 8|6"
SPB16CH_RELE_MAP[93]="75|1| 16|6"
SPB16CH_RELE_MAP[94]="75|1| 32|6"
SPB16CH_RELE_MAP[95]="75|1| 64|6"
SPB16CH_RELE_MAP[96]="75|1|128|6"
# Scheda 7 - address 76h - GS1:chiuso, GS2:aperto, GS3:aperto
SPB16CH_RELE_MAP[97]="76|0| 1|7"
SPB16CH_RELE_MAP[98]="76|0| 2|7"
SPB16CH_RELE_MAP[99]="76|0| 4|7"
SPB16CH_RELE_MAP[100]="76|0| 8|7"
SPB16CH_RELE_MAP[101]="76|0| 16|7"
SPB16CH_RELE_MAP[102]="76|0| 32|7"
SPB16CH_RELE_MAP[103]="76|0| 64|7"
SPB16CH_RELE_MAP[104]="76|0|128|7"
SPB16CH_RELE_MAP[105]="76|1| 1|7"
SPB16CH_RELE_MAP[106]="76|1| 2|7"
SPB16CH_RELE_MAP[107]="76|1| 4|7"
SPB16CH_RELE_MAP[108]="76|1| 8|7"
SPB16CH_RELE_MAP[109]="76|1| 16|7"
SPB16CH_RELE_MAP[110]="76|1| 32|7"
SPB16CH_RELE_MAP[111]="76|1| 64|7"
SPB16CH_RELE_MAP[112]="76|1|128|7"
# Scheda 8 - address 77h - GS1:aperto, GS2:aperto, GS3:aperto
SPB16CH_RELE_MAP[113]="77|0| 1|8"
SPB16CH_RELE_MAP[114]="77|0| 2|8"
SPB16CH_RELE_MAP[115]="77|0| 4|8"
SPB16CH_RELE_MAP[116]="77|0| 8|8"
SPB16CH_RELE_MAP[117]="77|0| 16|8"
SPB16CH_RELE_MAP[118]="77|0| 32|8"
SPB16CH_RELE_MAP[119]="77|0| 64|8"
SPB16CH_RELE_MAP[120]="77|0|128|8"
SPB16CH_RELE_MAP[121]="77|1| 1|8"
SPB16CH_RELE_MAP[122]="77|1| 2|8"
SPB16CH_RELE_MAP[123]="77|1| 4|8"
SPB16CH_RELE_MAP[124]="77|1| 8|8"
SPB16CH_RELE_MAP[125]="77|1| 16|8"
SPB16CH_RELE_MAP[126]="77|1| 32|8"
SPB16CH_RELE_MAP[127]="77|1| 64|8"
SPB16CH_RELE_MAP[128]="77|1|128|8"
# Array contenente i gli identificativi delle schede usate
declare -g -a SPB16CH_USED_ID
SPB16CH_USED_ID=()
# Nome del file dove memorizzare gli id delle schede utilizzate
declare -g SPB16CH_BOARD_ID_STORE_FILE
SPB16CH_BOARD_ID_STORE_FILE="$STATUS_DIR/spb16ch_board_id_store"

View File

@@ -0,0 +1,84 @@
#
# Questa funzione viene inviocata dalla funzione "init" di piGarden se sono presenti elettrovalvole o sensori che utilizzano questo driver
#
function drv_spb16ch_init {
declare -a address_used
address_used=()
SPB16CH_USED_ID=()
local address=""
local board_id=""
# Cerca gli indirizzi delle schede spb16ch utilizzate per i rele utilizzati per le zone
for i in $(seq $EV_TOTAL)
do
local a=EV"$i"_GPIO
local gpio="${!a}"
if [[ "$gpio" == drv:spb16ch:* ]]; then
local rele_id=`echo $gpio | $CUT -d':' -f3,3`
local rele_data=${SPB16CH_RELE_MAP[$rele_id]}
if [[ ! -z $rele_data ]]; then
local address_num=${rele_data:0:2}
local board_id=${rele_data:9:1}
if [[ ! " ${address_used[@]} " =~ " ${address_num} " ]]; then
address_used+=("$address_num")
SPB16CH_USED_ID+=("$board_id")
fi
fi
fi
done
# Cerca gli indirizzi delle schede spb16ch utilizzate per i rele che gestiscono l'alimentazione delle elettrovalvole bistabili
for gpio in "$SUPPLY_GPIO_1" "$SUPPLY_GPIO_2"
do
if [[ "$gpio" == drv:spb16ch:* ]]; then
local rele_id=`echo $gpio | $CUT -d':' -f3,3`
local rele_data=${SPB16CH_RELE_MAP[$rele_id]}
if [[ ! -z $rele_data ]]; then
local address_num=${rele_data:0:2}
local board_id=${rele_data:9:1}
if [[ ! " ${address_used[@]} " =~ " ${address_num} " ]]; then
address_used+=("$address_num")
SPB16CH_USED_ID+=("$board_id")
fi
fi
fi
done
# Memorizza gli id delle schede usate
drv_spb16ch_boards_id_store
# Esegue l'inizializzazione dei gpio che gestiscono l'abilitazine/disabilitazione delle schede
local board_id
for board_id in ${SPB16CH_USED_ID[@]}
do
local a=SPB16CH"$board_id"_GPIO
local gpio_n=${!a}
echo "******** Number used board: $board_id - inizializzazione gpio $gpio_n"
$GPIO -g mode $gpio_n out
done
#drv_spb16ch_board_disable_all
# Esegue l'inizializzazione delle schede spb16ch trovate
local address_num=""
local board_num=""
for i in ${!address_used[@]}
do
address_num=${address_used[$i]}
board_num=${SPB16CH_USED_ID[$i]}
drv_spb16ch_board_enable $board_num # Porto alto il reset della scheda e lo mantengo sempre alto
echo "****** Inizializzazione address_num = $address_num - board_num = $board_num *******"
$DIR_SCRIPT/drv/spb16ch/scripts/mux_channel.py $address_num 0
$DIR_SCRIPT/drv/spb16ch/scripts/gpo_init.py 25 255 0
$DIR_SCRIPT/drv/spb16ch/scripts/mux_channel.py $address_num 1
$DIR_SCRIPT/drv/spb16ch/scripts/gpo_init.py 25 255 0
$DIR_SCRIPT/drv/spb16ch/scripts/mux_channel.py $address_num 0
# Disabilito il mux
$DIR_SCRIPT/drv/spb16ch/scripts/mux_disable.py $address_num
#drv_spb16ch_board_disable $board_id
done
}

View File

@@ -0,0 +1,23 @@
#
# Inizializza il sensore di rilevamento pioggia
#
# $i identificativo gpio del sensore di pioggia
#
function drv_spb16ch_rain_sensor_init {
local FOO="bar"
}
#
# Ritorna lo stato del sensore di rilevamento pioggia
#
# $i identificativo gpio del sensore di pioggia
#
function drv_spb16ch_rain_sensor_get {
local FOO="bar"
}

View File

@@ -0,0 +1,76 @@
#
# Inizializzazione rele
#
# $1 identificativo relè da inizializzare
#
function drv_spb16ch_rele_init {
drv_spb16ch_rele_open "$1"
}
#
# Apertura rele
#
# $1 identificativo relè da aprire
#
function drv_spb16ch_rele_open {
local rele_id=`echo $1 | $CUT -d':' -f3,3`
local rele_data=${SPB16CH_RELE_MAP[$rele_id]}
if [[ -z $rele_data ]]; then
local message="Error - Rele map not defined - rele_id=$rele_id - ($1)"
log_write "$message"
message_write "warning" "$message"
fi
local address_num=${rele_data:0:2}
local channel_num=${rele_data:3:1}
local rele_num=${rele_data:5:3}
local board_id=${rele_data:9:1}
#drv_spb16ch_board_enable $board_id
echo address_num=$address_num
echo channel_num=$channel_num
echo rele_num=$rele_num
$DIR_SCRIPT/drv/spb16ch/scripts/mux_channel.py $address_num $channel_num
$DIR_SCRIPT/drv/spb16ch/scripts/gpo_init.py $address_num $rele_num 0
# Disabilito il mux
$DIR_SCRIPT/drv/spb16ch/scripts/mux_disable.py $address_num
#drv_spb16ch_board_disable $board_id
}
#
# Chiusura rele
#
# $1 identificativo relè da chiudere
#
function drv_spb16ch_rele_close {
local rele_id=`echo $1 | $CUT -d':' -f3,3`
local rele_data=${SPB16CH_RELE_MAP[$rele_id]}
if [[ -z $rele_data ]]; then
local message="Error - Rele map not defined - rele_id=$rele_id - ($1)"
log_write "$message"
message_write "warning" "$message"
fi
local address_num=${rele_data:0:2}
local channel_num=${rele_data:3:1}
local rele_num=${rele_data:5:3}
local board_id=${rele_data:9:1}
#drv_spb16ch_board_enable $board_id
echo address_num=$address_num
echo channel_num=$channel_num
echo rele_num=$rele_num
$DIR_SCRIPT/drv/spb16ch/scripts/mux_channel.py $address_num $channel_num
$DIR_SCRIPT/drv/spb16ch/scripts/gpo_init.py $address_num $rele_num 1
# Disabilito il mux
$DIR_SCRIPT/drv/spb16ch/scripts/mux_disable.py $address_num
#drv_spb16ch_board_disable $board_id
}

37
drv/spb16ch/scripts/ee_read.py Executable file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/python
# coding=utf-8
# Read the eeprom 24C16
# I2C Address: 0x50 (24C16)
# sudo ./ee_read.py 0x50 address
# Example: sudo ./ee_read.py 50 0
import time
import argparse
import RPi.GPIO as GPIO
import smbus
def I2C_setup(i2c_address, eeprom_address):
I2C_address = 0x50
if GPIO.RPI_REVISION in [2, 3]:
I2C_bus_number = 1
else:
I2C_bus_number = 0
bus = smbus.SMBus(I2C_bus_number)
#bus.read_byte_data(I2C_address, eeprom_address)
print("24C16 ADDRESS: {}".format(bin(eeprom_address)))
print("24C16 DATA: {}".format(bin(bus.read_byte_data(I2C_address, eeprom_address))))
print("24C16 DATA: {}".format(hex(bus.read_byte_data(I2C_address, eeprom_address))))
def menu():
parser = argparse.ArgumentParser(description='Select address to read data on eeprom 24C16 ')
parser.add_argument('i2c_address', type=int)
parser.add_argument('eeprom_address', type=int)
args = parser.parse_args()
I2C_setup(args.i2c_address, args.eeprom_address)
if __name__ == "__main__":
menu()

35
drv/spb16ch/scripts/ee_write.py Executable file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/python
# coding=utf-8
# Write the eeprom 24C16
# I2C Address: 0x50 (24C16)
# sudo ./ee_write.py 0x50 address data
# Example: sudo ./ee_write.py 50 0 1
import time
import argparse
import RPi.GPIO as GPIO
import smbus
def I2C_setup(i2c_address, eeprom_address, eeprom_data):
I2C_address = 0x50
if GPIO.RPI_REVISION in [2, 3]:
I2C_bus_number = 1
else:
I2C_bus_number = 0
bus = smbus.SMBus(I2C_bus_number)
bus.write_byte_data(I2C_address, eeprom_address, eeprom_data)
def menu():
parser = argparse.ArgumentParser(description='Select address and data to write on eeprom 24C16 ')
parser.add_argument('i2c_address', type=int)
parser.add_argument('eeprom_address', type=int)
parser.add_argument('eeprom_data', type=int)
args = parser.parse_args()
I2C_setup(args.i2c_address, args.eeprom_address, args.eeprom_data)
if __name__ == "__main__":
menu()

View File

@@ -0,0 +1,44 @@
#!/usr/bin/python
# coding=utf-8
# Select address and channel of PCA9571 I2C general purpose outputs
# I2C Address: 0x25 Fixed
# sudo ./gpo_active.py CHANNEL
# Example: sudo ./gpo_active.py 25 255 1 #all relays activates
import time
import argparse
import RPi.GPIO as GPIO
import smbus
def I2C_setup(multiplexer_i2c_address, i2c_channel_setup, state):
I2C_address = 0x25
if GPIO.RPI_REVISION in [2, 3]:
I2C_bus_number = 1
else:
I2C_bus_number = 0
bus = smbus.SMBus(I2C_bus_number)
status_outputs=bus.read_byte(I2C_address)
if state == 1:
i2c_channel_setup=status_outputs|i2c_channel_setup
elif state == 0:
i2c_channel_setup=(-i2c_channel_setup-1)&status_outputs
elif state == -1:
i2c_channel_setup=0
bus.write_byte(I2C_address, i2c_channel_setup)
#time.sleep(0)
file = open("rl1", "r")
address=int(file.readline())
channel_outputs=int(file.readline())
state=int(file.readline())
def menu():
I2C_setup(address, channel_outputs, state)
if __name__ == "__main__":
menu()

44
drv/spb16ch/scripts/gpo_init.py Executable file
View File

@@ -0,0 +1,44 @@
#!/usr/bin/python
# coding=utf-8
# Select address and channel of PCA9571 I2C general purpose outputs
# I2C Address: 0x25 Fixed
# sudo ./gpo_active.py CHANNEL
# Example: sudo ./gpo_active.py 25 255 1 #all relays activates
import time
import argparse
import RPi.GPIO as GPIO
import smbus
def I2C_setup(multiplexer_i2c_address, i2c_channel_setup, state):
I2C_address = 0x25
if GPIO.RPI_REVISION in [2, 3]:
I2C_bus_number = 1
else:
I2C_bus_number = 0
bus = smbus.SMBus(I2C_bus_number)
status_outputs=bus.read_byte(I2C_address)
if state == 1:
i2c_channel_setup=status_outputs|i2c_channel_setup
elif state == 0:
i2c_channel_setup=(-i2c_channel_setup-1)&status_outputs
elif state == -1:
i2c_channel_setup=0
bus.write_byte(I2C_address, i2c_channel_setup)
#time.sleep(0)
def menu():
parser = argparse.ArgumentParser(description='Select channel outputs of PCA9571')
parser.add_argument('address', type=int)
parser.add_argument('channel_outputs', type=int)
parser.add_argument('state', type=int)
args = parser.parse_args()
I2C_setup(args.address, args.channel_outputs, args.state)
if __name__ == "__main__":
menu()

33
drv/spb16ch/scripts/gpo_read.py Executable file
View File

@@ -0,0 +1,33 @@
#!/usr/bin/python
# coding=utf-8
# Select address and channel of PCA9571 I2C general purpose outputs
# I2C Address: 0x25 Fixed
# sudo ./gpo_read.py CHANNEL
# Example: sudo ./gpo_read.py 25
import time
import argparse
import RPi.GPIO as GPIO
import smbus
def I2C_read(multiplexer_i2c_address):
I2C_address = 0x25
if GPIO.RPI_REVISION in [2, 3]:
I2C_bus_number = 1
else:
I2C_bus_number = 0
bus = smbus.SMBus(I2C_bus_number)
status_outputs=bus.read_byte(I2C_address)
time.sleep(0)
# print("PCA9571 sts:{}".format(bin(bus.read_byte(I2C_address))))
print("PCA9571 GPO sts:{}".format(hex(bus.read_byte(I2C_address))))
def menu():
I2C_read(0x25)
if __name__ == "__main__":
menu()

3
drv/spb16ch/scripts/gpo_send Executable file
View File

@@ -0,0 +1,3 @@
25
100
1

1
drv/spb16ch/scripts/gpo_states Executable file
View File

@@ -0,0 +1 @@
PCA9571 GPO sts:0x64

5
drv/spb16ch/scripts/init.sh Executable file
View File

@@ -0,0 +1,5 @@
./mux_channel.py 72 0
./gpo_init.py 25 255 0
./mux_channel.py 72 1
./gpo_init.py 25 255 0
./mux_channel.py 72 0

View File

@@ -0,0 +1,38 @@
#!/usr/bin/python
# coding=utf-8
# Select address and channel of PCA9547 I2C multiplexer
# I2C Address: 0xYY, where YY can be 70 through 77
# Multiplexer Channel: 1 - 8
# sudo ./mux_channel.py ADDRESS CHANNEL
# Example: sudo ./mux_channel.py 70 1
import time
import argparse
import RPi.GPIO as GPIO
import smbus
def I2C_setup(multiplexer_i2c_address, i2c_channel_setup):
I2C_address = 0x70 + multiplexer_i2c_address % 10
if GPIO.RPI_REVISION in [2, 3]:
I2C_bus_number = 1
else:
I2C_bus_number = 0
bus = smbus.SMBus(I2C_bus_number)
i2c_channel_setup=i2c_channel_setup + 0x08
bus.write_byte(I2C_address, i2c_channel_setup)
#time.sleep(0.1)
def menu():
parser = argparse.ArgumentParser(description='Select channel of PCA9547 I2C multiplexer')
parser.add_argument('address', type=int)
parser.add_argument('channel', type=int)
args = parser.parse_args()
I2C_setup(args.address, args.channel)
if __name__ == "__main__":
menu()

View File

@@ -0,0 +1,37 @@
#!/usr/bin/python
# coding=utf-8
# Disable PCA9547 I2C multiplexer
# I2C Address: 0xYY, where YY can be 70 through 77
# sudo ./mux_channel.py ADDRESS CHANNEL
# Example: sudo ./mux_disable.py 70
import time
import argparse
import RPi.GPIO as GPIO
import smbus
def I2C_setup(multiplexer_i2c_address):
I2C_address = 0x70 + multiplexer_i2c_address % 10
if GPIO.RPI_REVISION in [2, 3]:
I2C_bus_number = 1
else:
I2C_bus_number = 0
bus = smbus.SMBus(I2C_bus_number)
i2c_channel_setup=0x00
#i2c_channel_setup=i2c_channel_setup + 0x08
bus.write_byte(I2C_address, i2c_channel_setup)
#time.sleep(0.1)
def menu():
parser = argparse.ArgumentParser(description='Select Address of Disable PCA9547 Multiplexer')
parser.add_argument('address', type=int)
args = parser.parse_args()
I2C_setup(args.address)
if __name__ == "__main__":
menu()

37
drv/spb16ch/scripts/mux_read.py Executable file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/python
# coding=utf-8
# Select address and channel of PCA9547 I2C multiplexer
# I2C Address: 0xYY, where YY can be 70 through 77
# Multiplexer Channel: 1 - 8
# sudo ./mux_read.py ADDRESS
# Example: sudo ./mux_read.py 70
import time
import argparse
import RPi.GPIO as GPIO
import smbus
def I2C_setup(multiplexer_i2c_address):
I2C_address = 0x70 + multiplexer_i2c_address % 10
if GPIO.RPI_REVISION in [2, 3]:
I2C_bus_number = 1
else:
I2C_bus_number = 0
bus = smbus.SMBus(I2C_bus_number)
time.sleep(0.1)
# print("PCA9547 MUX sts:{}".format(bin(bus.read_byte(I2C_address))))
print("PCA9547 MUX sts:{}".format(hex(bus.read_byte(I2C_address))))
def menu():
parser = argparse.ArgumentParser(description='Select channel of PCA9547 I2C multiplexer')
parser.add_argument('address', type=int)
args = parser.parse_args()
I2C_setup(args.address)
if __name__ == "__main__":
menu()

1
drv/spb16ch/scripts/mux_states Executable file
View File

@@ -0,0 +1 @@
PCA9547 MUX sts:0x8

View File

@@ -0,0 +1,6 @@
#!/usr/bin/python
# coding=utf-8
file = open("mux", "r")
line1=file.readline()
print line1

33
drv/spb16ch/scripts/rele1_16 Executable file
View File

@@ -0,0 +1,33 @@
25
1
0
2
0
4
0
8
0
16
1
32
1
64
1
128
1
1
0
2
0
4
0
8
0
16
1
32
1
64
1
128
1

View File

@@ -0,0 +1,95 @@
#!/usr/bin/python
# coding=utf-8
# Select address and channel of PCA9571 I2C general purpose outputs
# I2C Address: 0x25 Fixed
# sudo ./gpo_active.py CHANNEL
# Example: sudo ./gpo_active.py 25 255 1 #all relays activates
import time
import argparse
import subprocess
import RPi.GPIO as GPIO
import smbus
def I2C_setup(multiplexer_i2c_address, i2c_channel_setup, state):
I2C_address = 0x25
if GPIO.RPI_REVISION in [2, 3]:
I2C_bus_number = 1
else:
I2C_bus_number = 0
bus = smbus.SMBus(I2C_bus_number)
status_outputs=bus.read_byte(I2C_address)
if state == 1:
i2c_channel_setup=status_outputs|i2c_channel_setup
elif state == 0:
i2c_channel_setup=(-i2c_channel_setup-1)&status_outputs
elif state == -1:
i2c_channel_setup=0
bus.write_byte(I2C_address, i2c_channel_setup)
#time.sleep(0)
def menu():
while 1==1:
subprocess.call('./mux_channel.py 72 0', shell=True)
#time.sleep(0.1)
file = open("rele1_16", "r")
address=int(file.readline())
channel_outputs1=int(file.readline())
state1=int(file.readline())
channel_outputs2=int(file.readline())
state2=int(file.readline())
channel_outputs3=int(file.readline())
state3=int(file.readline())
channel_outputs4=int(file.readline())
state4=int(file.readline())
channel_outputs5=int(file.readline())
state5=int(file.readline())
channel_outputs6=int(file.readline())
state6=int(file.readline())
channel_outputs7=int(file.readline())
state7=int(file.readline())
channel_outputs8=int(file.readline())
state8=int(file.readline())
channel_outputs9=int(file.readline())
state9=int(file.readline())
channel_outputs10=int(file.readline())
state10=int(file.readline())
channel_outputs11=int(file.readline())
state11=int(file.readline())
channel_outputs12=int(file.readline())
state12=int(file.readline())
channel_outputs13=int(file.readline())
state13=int(file.readline())
channel_outputs14=int(file.readline())
state14=int(file.readline())
channel_outputs15=int(file.readline())
state15=int(file.readline())
channel_outputs16=int(file.readline())
state16=int(file.readline())
I2C_setup(address, channel_outputs1, state1)
I2C_setup(address, channel_outputs2, state2)
I2C_setup(address, channel_outputs3, state3)
I2C_setup(address, channel_outputs4, state4)
I2C_setup(address, channel_outputs5, state5)
I2C_setup(address, channel_outputs6, state6)
I2C_setup(address, channel_outputs7, state7)
I2C_setup(address, channel_outputs8, state8)
subprocess.call('./mux_channel.py 72 1', shell=True)
#time.sleep(0.1)
I2C_setup(address, channel_outputs9, state9)
I2C_setup(address, channel_outputs10, state10)
I2C_setup(address, channel_outputs11, state11)
I2C_setup(address, channel_outputs12, state12)
I2C_setup(address, channel_outputs13, state13)
I2C_setup(address, channel_outputs14, state14)
I2C_setup(address, channel_outputs15, state15)
I2C_setup(address, channel_outputs16, state16)
subprocess.call('./mux_channel.py 72 0', shell=True)
if __name__ == "__main__":
menu()

View File

@@ -0,0 +1,12 @@
#
# Questa funzione viene inviocata dalla funzione "setup_drv" ad ogni avvio di piGarden
# esegue il setup del driver recuperando gli identificativi delle schede sbp16ch usati
#
function drv_spb16ch_setup {
drv_spb16ch_boards_id_load
echo "*********** drv_spb16ch_setup: identificativi schede caricati: ${SPB16CH_USED_ID[@]}"
}

View File

@@ -0,0 +1,34 @@
#
# Inizializza i rele che gestiscono l'alimentazione per le valvole bistabili
#
# $1 identificativo relè
#
function drv_spb16ch_supply_bistable_init {
drv_spb16ch_supply_negative "$1"
}
#
# Imposta l'alimentazione delle elettrovalvole con voltaggio positivo
#
# $1 identificativo relè
#
function drv_spb16ch_supply_positive {
drv_spb16ch_rele_open "$1"
}
#
# Imposta l'alimentazione delle elettrovalvole con voltaggio negativo
#
# $1 identificativo relè
#
function drv_spb16ch_supply_negative {
drv_spb16ch_rele_close "$1"
}

563
include/cron.include.sh Normal file
View File

@@ -0,0 +1,563 @@
#
# Elimina una tipoliga di schedulazione dal crontab dell'utente
# $1 tipologia del crontab
# $2 argomento della tipologia
#
function cron_del {
local CRON_TYPE=$1
local CRON_ARG=$2
if [ -z "$CRON_TYPE" ]; then
echo "Cron type is empty" >&2
log_write "Cron type is empty"
return 1
fi
$CRONTAB -l > "$TMP_CRON_FILE"
local START=`$GREP -n "^# START cron $CRON_TYPE $CRON_ARG$" "$TMP_CRON_FILE"| $CUT -d : -f 1`
local END=`$GREP -n "^# END cron $CRON_TYPE $CRON_ARG$" "$TMP_CRON_FILE"| $CUT -d : -f 1`
local re='^[0-9]+$'
if ! [[ "$START" =~ $re ]] && ! [[ "$END" =~ $re ]] ; then
echo "$1 $2 cron is not present" >&2
return
fi
if ! [[ $START =~ $re ]] ; then
echo "Cron start don't find" >&2
log_write "Cron start don't find"
return 1
fi
if ! [[ $END =~ $re ]] ; then
echo "Cron end cron don't find" >&2
log_write "Cron end cron don't find"
return 1
fi
if [ "$START" -gt "$END" ]; then
echo "Wrong position for start and end in cron" >&2
log_write "Wrong position for start and end in cron"
return 1
fi
$SED "$START,${END}d" "$TMP_CRON_FILE" | $SED '$!N; /^\(.*\)\n\1$/!P; D' | $CRONTAB -
#$CRONTAB "$TMP_CRON_FILE"
rm "$TMP_CRON_FILE"
}
#
# Aggiunge una schedulazione nel crontab dell'utente
# $1 tipologia del crontab
# $2 minuto
# $3 ora
# $4 giorno del mese
# $5 mese
# $6 giorno della settimana
# $7 argomento della tipologia
# $8 secondo argomento della tipologia
#
function cron_add {
local CRON_TYPE=$1
local CRON_M=$2
local CRON_H=$3
local CRON_DOM=$4
local CRON_MON=$5
local CRON_DOW=$6
local CRON_ARG=$7
local CRON_ARG2=$8
local CRON_COMMAND=""
local CRON_DISABLED=""
local PATH_SCRIPT=`$READLINK -f "$DIR_SCRIPT/$NAME_SCRIPT"`
local TMP_CRON_FILE2="$TMP_CRON_FILE-2"
if [ -z "$CRON_TYPE" ]; then
echo "Cron type is empty" >&2
log_write "Cron type is empty"
return 1
fi
$CRONTAB -l > "$TMP_CRON_FILE"
local START=`$GREP -n "^# START cron $CRON_TYPE $CRON_ARG$" "$TMP_CRON_FILE"| $CUT -d : -f 1`
local END=`$GREP -n "^# END cron $CRON_TYPE $CRON_ARG$" "$TMP_CRON_FILE"| $CUT -d : -f 1`
local re='^[0-9]+$'
local NEW_CRON=0
local PREVIUS_CONTENT=""
if ! [[ $START =~ $re ]] && ! [[ $END =~ $re ]] ; then
NEW_CRON=1
else
if ! [[ $START =~ $re ]] ; then
echo "Cron start don't find" >&2
log_write "Cron start don't find"
return 1
fi
if ! [[ $END =~ $re ]] ; then
echo "Cron end cron don't find" >&2
log_write "Cron end cron don't find"
return 1
fi
START=$(($START + 1))
END=$(($END - 1))
if [ "$START" -gt "$END" ]; then
echo "Wrong position for start and end in cron" >&2
log_write "Wrong position for start and end in cron"
return 1
fi
PREVIOUS_CONTENT=`$SED -n "$START,${END}p" "$TMP_CRON_FILE"`
fi
case "$CRON_TYPE" in
init)
CRON_M="@reboot"
CRON_H=""
CRON_DOM=""
CRON_MON=""
CRON_DOW=""
CRON_COMMAND="$PATH_SCRIPT init"
;;
start_socket_server)
CRON_M="@reboot"
CRON_H=""
CRON_DOM=""
CRON_MON=""
CRON_DOW=""
CRON_COMMAND="$PATH_SCRIPT start_socket_server force"
;;
check_rain_online)
CRON_M="*/3"
CRON_H="*"
CRON_DOM="*"
CRON_MON="*"
CRON_DOW="*"
CRON_COMMAND="$PATH_SCRIPT check_rain_online 2> /tmp/check_rain_online.err"
;;
check_rain_sensor)
CRON_M="*"
CRON_H="*"
CRON_DOM="*"
CRON_MON="*"
CRON_DOW="*"
CRON_COMMAND="$PATH_SCRIPT check_rain_sensor 2> /tmp/check_rain_sensor.err"
;;
close_all_for_rain)
CRON_M="*/5"
CRON_H="*"
CRON_DOM="*"
CRON_MON="*"
CRON_DOW="*"
CRON_COMMAND="$PATH_SCRIPT close_all_for_rain 2> /tmp/close_all_for_rain.err 1> /dev/null"
;;
open)
CRON_COMMAND="$PATH_SCRIPT open $CRON_ARG"
if [ "$CRON_ARG2" == "disabled" ]; then
CRON_DISABLED="#"
fi
;;
open_in)
CRON_COMMAND="$PATH_SCRIPT open $CRON_ARG $CRON_ARG2"
;;
open_in_stop)
CRON_COMMAND="$PATH_SCRIPT close $CRON_ARG"
;;
close)
CRON_COMMAND="$PATH_SCRIPT close $CRON_ARG"
if [ "$CRON_ARG2" == "disabled" ]; then
CRON_DISABLED="#"
fi
;;
*)
echo "Wrong cron type: $CRON_TYPE"
log_write "Wrong cron type: $CRON_TYPE"
;;
esac
if [ "$NEW_CRON" -eq "0" ]; then
START=$(($START - 1))
END=$(($END + 1))
$SED "$START,${END}d" "$TMP_CRON_FILE" > "$TMP_CRON_FILE2"
else
cat "$TMP_CRON_FILE" > "$TMP_CRON_FILE2"
fi
if [ "$NEW_CRON" -eq "1" ]; then
echo "" >> "$TMP_CRON_FILE2"
fi
echo "# START cron $CRON_TYPE $CRON_ARG" >> "$TMP_CRON_FILE2"
if [ "$NEW_CRON" -eq "0" ]; then
echo "$PREVIOUS_CONTENT" >> "$TMP_CRON_FILE2"
fi
echo "$CRON_DISABLED$CRON_M $CRON_H $CRON_DOM $CRON_MON $CRON_DOW $CRON_COMMAND" >> "$TMP_CRON_FILE2"
echo "# END cron $CRON_TYPE $CRON_ARG" >> "$TMP_CRON_FILE2"
$CRONTAB "$TMP_CRON_FILE2"
rm "$TMP_CRON_FILE" "$TMP_CRON_FILE2"
}
#
# Legge una tipoliga di schedulazione dal crontab dell'utente
# $1 tipologia del crontab
# $2 argomento della tipologia
#
function cron_get {
local CRON_TYPE=$1
local CRON_ARG=$2
if [ -z "$CRON_TYPE" ]; then
echo "Cron type is empty" >&2
log_write "Cron type is empty"
return 1
fi
$CRONTAB -l > "$TMP_CRON_FILE"
local START=`$GREP -n "^# START cron $CRON_TYPE $CRON_ARG$" "$TMP_CRON_FILE"| $CUT -d : -f 1`
local END=`$GREP -n "^# END cron $CRON_TYPE $CRON_ARG$" "$TMP_CRON_FILE"| $CUT -d : -f 1`
local re='^[0-9]+$'
local PREVIUS_CONTENT=""
if ! [[ $START =~ $re ]] && ! [[ $END =~ $re ]] ; then
PREVIUS_CONTENT=""
else
if ! [[ $START =~ $re ]] ; then
echo "Cron start don't find" >&2
log_write "Cron start don't find"
return 1
fi
if ! [[ $END =~ $re ]] ; then
echo "Cron end cron don't find" >&2
log_write "Cron end cron don't find"
return 1
fi
START=$(($START + 1))
END=$(($END - 1))
if [ "$START" -gt "$END" ]; then
echo "Wrong position for start and end in cron" >&2
log_write "Wrong position for start and end in cron"
return 1
fi
PREVIOUS_CONTENT=`$SED -n "$START,${END}p" "$TMP_CRON_FILE"`
fi
echo "$PREVIOUS_CONTENT"
}
#
# Imposta il cron di inizializzazione della centralina
#
function set_cron_init {
cron_del "init" 2> /dev/null
cron_add "init"
}
#
# Elimina il cron di inizializzazione della centralina
#
function del_cron_init {
cron_del "init"
}
#
# Imposta il cron per l'avvio del socket server
#
function set_cron_start_socket_server {
cron_del "start_socket_server" 2> /dev/null
cron_add "start_socket_server"
}
#
# Elimina il cron per l'avvio del socket server
#
function del_cron_start_socket_server {
cron_del "start_socket_server"
}
#
# Imposta il cron che esegue il controllo di presenza pioggia tramite sensore
#
function set_cron_check_rain_sensor {
cron_del "check_rain_sensor" 2> /dev/null
cron_add "check_rain_sensor"
}
#
# Elimina il cron che esegue il controllo di presenza pioggia tramite sensore
#
function del_cron_check_rain_sensor {
cron_del "check_rain_sensor"
}
#
# Imposta il cron che esegue il controllo di presenza pioggia tramite servizio online
#
function set_cron_check_rain_online {
cron_del "check_rain_online" 2> /dev/null
cron_add "check_rain_online"
}
#
# Elimina il cron che esegue il controllo di presenza pioggia tramite servizio online
#
function del_cron_check_rain_online {
cron_del "check_rain_online"
}
#
# Imposta il cron che gestisce la chiusura delle elettrovalvole in caso di pioggia
#
function set_cron_close_all_for_rain {
cron_del "close_all_for_rain" 2> /dev/null
cron_add "close_all_for_rain"
}
#
# Elimina il cron che gestisce la chiusura delle elettrovalvole in caso di pioggia
#
function del_cron_close_all_for_rain {
cron_del "close_all_for_rain"
}
#
# Aggiunge una schedulazione cron per aprire una elettrovalvola
# $1 alias elettrovalvola
# $2 minuto cron
# $3 ora cron
# $4 giorno del mese cron
# $5 mese cron
# $6 giorno della settimana cron
# $7 disabled
#
function add_cron_open {
local exists=`alias_exists $1`
if [ "check $exists" = "check FALSE" ]; then
log_write "Alias $1 not found"
echo "Alias $1 not found"
return 1
fi
cron_add "open" "$2" "$3" "$4" "$5" "$6" "$1" "$7"
}
#
# Cancella tutte le schedulazioni cron per aprire una elettrovalvola
# $1 alias elettrovalvola
#
function del_cron_open {
local exists=`alias_exists $1`
if [ "check $exists" = "check FALSE" ]; then
log_write "Alias $1 not found"
echo "Alias $1 not found"
return 1
fi
cron_del "open" $1
}
#
# Legge tutte le schedulazioni cron per aprire una elettrovalvola
# $1 alias elettrovalvola
#
function get_cron_open {
local exists=`alias_exists $1`
if [ "check $exists" = "check FALSE" ]; then
log_write "Alias $1 not found"
echo "Alias $1 not found"
return 1
fi
cron_get "open" $1
}
#
# Cancella tutte le schedulazioni cron per aprire/chiudere una elettrovalvola in modo ritardato
# $1 alias elettrovalvola
#
function del_cron_open_in {
local exists=`alias_exists $1`
if [ "check $exists" = "check FALSE" ]; then
log_write "Alias $1 not found"
echo "Alias $1 not found"
return 1
fi
cron_del "open_in" $1
cron_del "open_in_stop" $1
}
#
# Legge tutte le schedulazioni cron per chiudere una elettrovalvola
# $1 alias elettrovalvola
#
function get_cron_close {
local exists=`alias_exists $1`
if [ "check $exists" = "check FALSE" ]; then
log_write "Alias $1 not found"
echo "Alias $1 not found"
return 1
fi
cron_get "close" $1
}
#
# Aggiunge una schedulazione cron per chiudere una elettrovalvola
# $1 alias elettrovalvola
# $2 minuto cron
# $3 ora cron
# $4 giorno del mese cron
# $5 mese cron
# $6 giorno della settimana cron
# $7 disabled
#
function add_cron_close {
local exists=`alias_exists $1`
if [ "check $exists" = "check FALSE" ]; then
log_write "Alias $1 not found"
echo "Alias $1 not found"
return 1
fi
cron_add "close" "$2" "$3" "$4" "$5" "$6" "$1" "$7"
}
#
# Cancella tutte le schedulazioni cron per chiudere una elettrovalvola
# $1 alias elettrovalvola
#
function del_cron_close {
local exists=`alias_exists $1`
if [ "check $exists" = "check FALSE" ]; then
log_write "Alias $1 not found"
echo "Alias $1 not found"
return 1
fi
cron_del "close" $1
}
#
# Disabilita tutte le schedulazioni di apertura e chiusura elettrovalvole
#
function cron_disable_all_open_close {
local a=""
local al=""
local cron=""
#
# Disabilita tutte le schedulazioni di apertura
#
for i in $(seq $EV_TOTAL)
do
a=EV"$i"_ALIAS
al=${!a}
local crons=`get_cron_open $al`
if [[ ! -z "$crons" ]]; then
del_cron_open $al
IFS=$'\n' # make newlines the only separator
for cron in $crons
do
#echo "-- $cron --"
CRON_M=`echo $cron | $CUT -d' ' -f1,1`
CRON_H=`echo $cron | $CUT -d' ' -f2,2`
CRON_DOM=`echo $cron | $CUT -d' ' -f3,3`
CRON_MON=`echo $cron | $CUT -d' ' -f4,4`
CRON_DOW=`echo $cron | $CUT -d' ' -f5,5`
if [[ ${CRON_M:0:1} == "#" ]]; then
CRON_M=${CRON_M:1:${#CRON_M}}
fi
#echo "++ $CRON_M $CRON_H $CRON_DOM $CRON_MON $CRON_DOW ++"
add_cron_open $al "$CRON_M" "$CRON_H" "$CRON_DOM" "$CRON_MON" "$CRON_DOW" "disabled"
done
fi
done
#
# Disabilita tutte le schedulazioni di chiusura
#
for i in $(seq $EV_TOTAL)
do
a=EV"$i"_ALIAS
al=${!a}
local crons=`get_cron_close $al`
if [[ ! -z "$crons" ]]; then
del_cron_close $al
IFS=$'\n' # make newlines the only separator
for cron in $crons
do
#echo "-- $cron --"
CRON_M=`echo $cron | $CUT -d' ' -f1,1`
CRON_H=`echo $cron | $CUT -d' ' -f2,2`
CRON_DOM=`echo $cron | $CUT -d' ' -f3,3`
CRON_MON=`echo $cron | $CUT -d' ' -f4,4`
CRON_DOW=`echo $cron | $CUT -d' ' -f5,5`
if [[ ${CRON_M:0:1} == "#" ]]; then
CRON_M=${CRON_M:1:${#CRON_M}}
fi
#echo "++ $CRON_M $CRON_H $CRON_DOM $CRON_MON $CRON_DOW ++"
add_cron_close $al "$CRON_M" "$CRON_H" "$CRON_DOM" "$CRON_MON" "$CRON_DOW" "disabled"
done
fi
done
}

309
include/drv.include.sh Normal file
View File

@@ -0,0 +1,309 @@
declare -a list_drv
function setup_drv {
#declare -a list_drv
list_drv=()
# Inizializza i driver per le elettrovalvole
for i in $(seq $EV_TOTAL)
do
local a=EV"$i"_GPIO
local gpio="${!a}"
if [[ "$gpio" == drv:* ]]; then
local drv=`echo $gpio | $CUT -d':' -f2,2`
if [[ ! " ${list_drv[@]} " =~ " ${drv} " ]]; then
list_drv+=("$drv")
fi
fi
done
# Inizializza i driver per gli altri gpio
for gpio in "$SUPPLY_GPIO_1" "$SUPPLY_GPIO_2" "$RAIN_GPIO"
do
if [[ "$gpio" == drv:* ]]; then
local drv=`echo $gpio | $CUT -d':' -f2,2`
if [[ ! " ${list_drv[@]} " =~ " ${drv} " ]]; then
list_drv+=("$drv")
fi
fi
done
local file_drv
for drv in "${list_drv[@]}"
do
for callback in config common init rele supply rainsensor setup
do
file_drv="$DIR_SCRIPT/drv/$drv/$callback.include.sh"
if [ -f "$file_drv" ]; then
#drv_avalible[$drv]="${drv_avalible[$drv]}#$callback#"
#echo ${drv_avalible[$drv]}
. "$file_drv"
if [ $callback == "setup" ]; then
local fnc="drv_${drv}_setup"
echo "$(date) $fnc" >> "$LOG_OUTPUT_DRV_FILE"
$fnc >> "$LOG_OUTPUT_DRV_FILE" 2>&1
fi
fi
done
done
}
#
# Restituisce in output il nome del driver callback function da richiamare per una specifica funzione
#
# $1 nome della funzione per il quale si vuore recuperare la callback
# $2 idetificativo del driver
function get_driver_callback {
local fnc="$1"
local idx="$2"
local ret=""
if [[ "$idx" == drv:* ]]; then
local drv=`echo $idx | $CUT -d':' -f2,2`
if [[ ! " ${list_drv[@]} " =~ " ${drv} " ]]; then
ret="drvnotfound"
else
ret="drv_${drv}_${fnc}"
fi
fi
echo "$ret"
}
#
# Inizializza un relè e lo porta nello stato aperto
#
# $1 identificativo relè da inizializzare
#
function drv_rele_init {
local idx="$1"
local fnc=`get_driver_callback "rele_init" "$idx"`
# Nessun driver definito, esegue la chiusura del relè tramite gpio del raspberry
if [ -z "$fnc" ]; then
$GPIO -g write $idx $RELE_GPIO_OPEN # chiude l'alimentazione all'elettrovalvole
$GPIO -g mode $idx out # setta il gpio nella modalita di scrittura
# Il driver definito non è stato trovato
elif [ "$fnc" == "drvnotfound" ]; then
log_write "Driver not found: $idx"
message_write "warning" "Driver not found: $idx"
else
echo "$(date) $fnc arg:$idx" >> "$LOG_OUTPUT_DRV_FILE"
$fnc "$idx" >> "$LOG_OUTPUT_DRV_FILE" 2>&1
fi
}
#
# Chiude un relè
#
# $1 identificativo relè da chiudere
#
function drv_rele_close {
local idx="$1"
local fnc=`get_driver_callback "rele_close" "$idx"`
# Nessun driver definito, esegue la chiusura del relè tramite gpio del raspberry
if [ -z "$fnc" ]; then
$GPIO -g write $idx $RELE_GPIO_CLOSE
# Il driver definito non è stato trovato
elif [ "$fnc" == "drvnotfound" ]; then
log_write "Driver not found: $idx"
message_write "warning" "Driver not found: $idx"
else
echo "$(date) $fnc arg:$idx" >> "$LOG_OUTPUT_DRV_FILE"
$fnc "$idx" >> "$LOG_OUTPUT_DRV_FILE" 2>&1
fi
}
#
# Apre un relè
#
# $1 identificativo relè da aprire
#
function drv_rele_open {
local idx="$1"
local fnc=`get_driver_callback "rele_open" "$idx"`
# Nessun driver definito, esegue la chiusura del relè tramite gpio del raspberry
if [ -z "$fnc" ]; then
$GPIO -g write $idx $RELE_GPIO_OPEN
# Il driver definito non è stato trovato
elif [ "$fnc" == "drvnotfound" ]; then
log_write "Driver not found: $idx"
message_write "warning" "Driver not found: $idx"
else
echo "$(date) $fnc arg:$idx" >> "$LOG_OUTPUT_DRV_FILE"
$fnc "$idx" >> "$LOG_OUTPUT_DRV_FILE" 2>&1
fi
}
#
# Inizializza i rele che gestiscono l'alimentazione per le valvole bistabili
#
# $1 identificativo relè 1
# $2 identificativo relè 2
#
function drv_supply_bistable_init {
local idx1=$1
local idx2=$2
local fnc1=`get_driver_callback "supply_bistable_init" "$idx1"`
local fnc2=`get_driver_callback "supply_bistable_init" "$idx2"`
# Nessun driver definito, esegue l'operazione tramite gpio del raspberry
if [ -z "$fnc1" ]; then
$GPIO -g write $idx1 0
$GPIO -g mode $idx1 out
# Il driver definito non è stato trovato
elif [ "$fnc1" == "drvnotfound" ]; then
log_write "Driver not found: $idx1"
message_write "warning" "Driver not found: $idx1"
return
else
echo "$(date) $fnc1 arg:$idx1" >> "$LOG_OUTPUT_DRV_FILE"
$fnc1 "$idx1" >> "$LOG_OUTPUT_DRV_FILE" 2>&1
fi
# Nessun driver definito, esegue l'operazione tramite gpio del raspberry
if [ -z "$fnc2" ]; then
$GPIO -g write $idx2 0
$GPIO -g mode $idx2 out
# Il driver definito non è stato trovato
elif [ "$fnc2" == "drvnotfound" ]; then
log_write "Driver not found: $idx2"
message_write "warning" "Driver not found: $idx2"
else
echo "$(date) $fnc2 arg:$idx2" >> "$LOG_OUTPUT_DRV_FILE"
$fnc2 "$idx2" >> "$LOG_OUTPUT_DRV_FILE" 2>&1
fi
}
#
# Imposta la tensine positiva per le elettrovalvole bistabili
#
# $1 identificativo rele 1
# $2 identificativo rele 2
#
function drv_supply_positive {
local idx1=$1
local idx2=$2
local fnc1=`get_driver_callback "supply_positive" "$idx1"`
local fnc2=`get_driver_callback "supply_positive" "$idx2"`
# Nessun driver definito, esegue l'operazione tramite gpio del raspberry
if [ -z "$fnc1" ]; then
$GPIO -g write $idx1 $SUPPLY_GPIO_POS
# Il driver definito non è stato trovato
elif [ "$fnc1" == "drvnotfound" ]; then
log_write "Driver not found: $idx1"
message_write "warning" "Driver not found: $idx1"
return
else
echo "$(date) $fnc1 arg:$idx1" >> "$LOG_OUTPUT_DRV_FILE"
$fnc1 "$idx1" >> "$LOG_OUTPUT_DRV_FILE" 2>&1
fi
# Nessun driver definito, esegue l'operazione tramite gpio del raspberry
if [ -z "$fnc2" ]; then
$GPIO -g write $idx2 $SUPPLY_GPIO_POS
# Il driver definito non è stato trovato
elif [ "$fnc2" == "drvnotfound" ]; then
log_write "Driver not found: $idx2"
message_write "warning" "Driver not found: $idx2"
else
echo "$(date) $fnc2 arg:$idx2" >> "$LOG_OUTPUT_DRV_FILE"
$fnc2 "$idx2" >> "$LOG_OUTPUT_DRV_FILE" 2>&1
fi
}
#
# Imposta la tensine neagativa per le elettrovalvole bistabili
#
# $1 identificativo rele 1
# $2 identificativo rele 2
#
function drv_supply_negative {
local idx1=$1
local idx2=$2
local fnc1=`get_driver_callback "supply_negative" "$idx1"`
local fnc2=`get_driver_callback "supply_negative" "$idx2"`
# Nessun driver definito, esegue l'operazione tramite gpio del raspberry
if [ -z "$fnc1" ]; then
$GPIO -g write $idx1 $SUPPLY_GPIO_NEG
# Il driver definito non è stato trovato
elif [ "$fnc1" == "drvnotfound" ]; then
log_write "Driver not found: $idx1"
message_write "warning" "Driver not found: $idx1"
return
else
echo "$(date) $fnc1 arg:$idx1" >> "$LOG_OUTPUT_DRV_FILE"
$fnc1 "$idx1" >> "$LOG_OUTPUT_DRV_FILE" 2>&1
fi
# Nessun driver definito, esegue l'operazione tramite gpio del raspberry
if [ -z "$fnc2" ]; then
$GPIO -g write $idx2 $SUPPLY_GPIO_NEG
# Il driver definito non è stato trovato
elif [ "$fnc2" == "drvnotfound" ]; then
log_write "Driver not found: $idx2"
message_write "warning" "Driver not found: $idx2"
else
echo "$(date) $fnc2 arg:$idx2" >> "$LOG_OUTPUT_DRV_FILE"
$fnc2 "$idx2" >> "$LOG_OUTPUT_DRV_FILE" 2>&1
fi
}
#
# Inizializza il sensore della pioggia
#
# $1 identificativo gpio sensore pioggia
#
function drv_rain_sensor_init {
local idx="$1"
local fnc=`get_driver_callback "rain_sensor_init" "$idx"`
local vret=""
# Nessun driver definito, esegue la lettura del sensore tramite gpio del raspberry
if [ -z "$fnc" ]; then
$GPIO -g mode $idx in
# Il driver definito non è stato trovato
elif [ "$fnc" == "drvnotfound" ]; then
log_write "Driver not found: $idx"
message_write "warning" "Driver not found: $idx"
else
echo "$(date) $fnc arg:$idx" >> "$LOG_OUTPUT_DRV_FILE"
$fnc "$idx" >> "$LOG_OUTPUT_DRV_FILE" 2>&1
fi
}
#
# Legge lo stato del sensore della pioggia
#
# $1 identificativo gpio sensore pioggia
#
function drv_rain_sensor_get {
local idx="$1"
local fnc=`get_driver_callback "rain_sensor_get" "$idx"`
local vret=""
# Nessun driver definito, esegue la lettura del sensore tramite gpio del raspberry
if [ -z "$fnc" ]; then
val=`$GPIO -g read $idx`
# Il driver definito non è stato trovato
elif [ "$fnc" == "drvnotfound" ]; then
log_write "Driver not found: $idx"
message_write "warning" "Driver not found: $idx"
else
echo "$(date) $fnc arg:$idx" >> "$LOG_OUTPUT_DRV_FILE"
vret=`$fnc "$idx"`
fi
echo "$vret"
}

99
include/rain.include.sh Normal file
View File

@@ -0,0 +1,99 @@
#
# 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_PATH/check_rain_online.json
local weather=`cat $TMP_PATH/check_rain_online.json | $JQ -M ".current_observation.weather"`
local current_observation=`cat $TMP_PATH/check_rain_online.json | $JQ -M ".current_observation"`
local local_epoch=`cat $TMP_PATH/check_rain_online.json | $JQ -M -r ".current_observation.local_epoch"`
#echo $weather
#weather="[Light/Heavy] Drizzle"
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
if [[ "$weather" == *"Rain"* ]] ||
[[ "$weather" == *"Snow"* ]] ||
[[ "$weather" == *"Hail"* ]] ||
[[ "$weather" == *"Ice"* ]] ||
[[ "$weather" == *"Thunderstorm"* ]] ||
[[ "$weather" == *"Drizzle"* ]];
then
#echo "ECCOMI!!!!!"
echo $local_epoch > "$STATUS_DIR/last_rain_online"
#return $local_epoch
fi
echo "$current_observation" > "$STATUS_DIR/last_weather_online"
fi
}
#
# Controlla se se piove tramite sensore
#
function check_rain_sensor {
if [ -n "$RAIN_GPIO" ]; then
#local s=`$GPIO -g read $RAIN_GPIO`
local s=`drv_rain_sensor_get $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 solenoid '$al' for rain"
fi
done
fi
}

232
include/socket.include.sh Normal file
View File

@@ -0,0 +1,232 @@
#
# Avvia il socket server
#
function start_socket_server {
rm -f "$TCPSERVER_PID_FILE"
echo $TCPSERVER_PID_SCRIPT > "$TCPSERVER_PID_FILE"
$TCPSERVER -v -RHl0 $TCPSERVER_IP $TCPSERVER_PORT $0 socket_server_command
}
#
# Ferma il socket server
#
function stop_socket_server {
if [ ! -f "$TCPSERVER_PID_FILE" ]; then
echo "Daemon is not running"
exit 1
fi
log_write "stop socket server"
kill -9 $(list_descendants `cat "$TCPSERVER_PID_FILE"`) 2> /dev/null
kill -9 `cat "$TCPSERVER_PID_FILE"` 2> /dev/null
rm -f "$TCPSERVER_PID_FILE"
}
#
# Esegue un comando ricevuto dal socket server
#
function socket_server_command {
RUN_FROM_TCPSERVER=1
local line=""
if [ ! -z "$TCPSERVER_USER" ] && [ ! -z "$TCPSERVER_PWD" ]; then
local user=""
local password=""
read -t 3 user
read -t 3 password
user=$(echo "$user" | $TR -d '[\r\n]')
password=$(echo "$password" | $TR -d '[\r\n]')
if [ "$user" != "$TCPSERVER_USER" ] || [ "$password" != "$TCPSERVER_PWD" ]; then
log_write "socket connection from: $TCPREMOTEIP - Bad socket server credentials - user:$user"
json_error 0 "Bad socket server credentials"
return
fi
fi
read line
line=$(echo "$line " | $TR -d '[\r\n]')
arg1=$(echo "$line " | $CUT -d ' ' -f1)
arg2=$(echo "$line " | $CUT -d ' ' -f2)
arg3=$(echo "$line " | $CUT -d ' ' -f3)
arg4=$(echo "$line " | $CUT -d ' ' -f4)
arg5=$(echo "$line " | $CUT -d ' ' -f5)
arg6=$(echo "$line " | $CUT -d ' ' -f6)
arg7=$(echo "$line " | $CUT -d ' ' -f7)
arg8=$(echo "$line " | $CUT -d ' ' -f8)
log_write "socket connection from: $TCPREMOTEIP - command: $arg1 $arg2 $arg3 $arg4 $arg5 $arg6 $arg7 $arg8"
reset_messages &> /dev/null
case "$arg1" in
status)
json_status $arg2 $arg3 $arg4 $arg5 $arg6 $arg7
;;
open)
if [ "empty$arg2" == "empty" ]; then
json_error 0 "Alias solenoid not specified"
else
ev_open $arg2 $arg3 &> /dev/null
json_status "get_cron_open_in:$arg2"
fi
;;
open_in)
ev_open_in $arg2 $arg3 $arg4 $arg5 &> /dev/null
json_status "get_cron_open_in:$arg4"
;;
close)
if [ "empty$arg2" == "empty" ]; then
json_error 0 "Alias solenoid not specified"
else
ev_close $arg2 &> /dev/null
json_status "get_cron_open_in:$arg2"
fi
;;
close_all)
if [ "$arg2" == "disable_scheduling" ]; then
cron_disable_all_open_close &> /dev/null
fi
close_all &> /dev/null
message_write "success" "All solenoid closed"
json_status
;;
set_general_cron)
local vret=""
for i in $arg2 $arg3 $arg4 $arg5 $arg6 $arg7
do
if [ $i = "set_cron_init" ]; then
vret="$(vret)`set_cron_init`"
elif [ $i = "set_cron_start_socket_server" ]; then
vret="$(vret)`set_cron_start_socket_server`"
elif [ $i = "set_cron_check_rain_sensor" ]; then
vret="$(vret)`set_cron_check_rain_sensor`"
elif [ $i = "set_cron_check_rain_online" ]; then
vret="$(vret)`set_cron_check_rain_online`"
elif [ $i = "set_cron_close_all_for_rain" ]; then
vret="$(vret)`set_cron_close_all_for_rain`"
fi
done
if [[ ! -z $vret ]]; then
json_error 0 "Cron set failed"
log_write "Cron set failed: $vret"
else
message_write "success" "Cron set successfull"
json_status
fi
;;
del_cron_open)
local vret=""
vret=`del_cron_open $arg2`
if [[ ! -z $vret ]]; then
json_error 0 "Cron set failed"
log_write "Cron del failed: $vret"
else
message_write "success" "Cron set successfull"
json_status
fi
;;
del_cron_open_in)
local vret=""
vret=`del_cron_open_in $arg2`
if [[ ! -z $vret ]]; then
json_error 0 "Cron del failed"
log_write "Cron del failed: $vret"
else
message_write "success" "Scheduled start successfully deleted"
json_status "get_cron_open_in:$arg2"
fi
;;
del_cron_close)
local vret=""
vret=`del_cron_close $arg2`
if [[ ! -z $vret ]]; then
json_error 0 "Cron set failed"
log_write "Cron set failed: $vret"
else
message_write "success" "Cron set successfull"
json_status
fi
;;
add_cron_open)
local vret=""
vret=`add_cron_open "$arg2" "$arg3" "$arg4" "$arg5" "$arg6" "$arg7" $arg8`
if [[ ! -z $vret ]]; then
json_error 0 "Cron set failed"
log_write "Cron set failed: $vret"
else
message_write "success" "Cron set successfull"
json_status
fi
;;
add_cron_close)
local vret=""
vret=`add_cron_close "$arg2" "$arg3" "$arg4" "$arg5" "$arg6" "$arg7" $arg8`
if [[ ! -z $vret ]]; then
json_error 0 "Cron set failed"
log_write "Cron set failed: $vret"
else
message_write "success" "Cron set successfull"
json_status
fi
;;
reboot)
message_write "warning" "System reboot is started"
json_status
local PATH_SCRIPT=`$READLINK -f "$DIR_SCRIPT/$NAME_SCRIPT"`
nohup $PATH_SCRIPT reboot > /dev/null 2>&1 &
;;
poweroff)
message_write "warning" "System shutdown is started"
json_status
local PATH_SCRIPT=`$READLINK -f "$DIR_SCRIPT/$NAME_SCRIPT"`
nohup $PATH_SCRIPT poweroff > /dev/null 2>&1 &
;;
*)
json_error 0 "invalid command"
;;
esac
reset_messages &> /dev/null
}

File diff suppressed because it is too large Load Diff

2
scripts/poweroff.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
sudo /sbin/poweroff

2
scripts/reboot.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/bash
sudo /sbin/reboot