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 # 0.5.0 - 12/10/2017
Add kicad electric schemas - 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 ## 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 ## 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 ## 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 ## 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 ## 0.4.0 - 14/06/2017
Add credentials support to socket server (define TCPSERVER_USER and TCPSERVER_PWD in your config file) - 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 - Add management lock/unlock for prevent concurrente call to open/close solenoid
Added the ability to enter an open / close schedule in disabled mode - Added the ability to enter an open / close schedule in disabled mode
Add send statistic information to remote server - Add send statistic information to remote server
During the initialization function, information on the last rain is no longer removed - During the initialization function, information on the last rain is no longer removed
## 0.3.1 - 13/05/2017 ## 0.3.1 - 13/05/2017
Add experimental support for monostable solenoid valve: 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 - 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 ## 0.3.0 - 07/05/2017
Add command "open_in" for scheduling on the fly the opens/close a solenoid - 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 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 - Add api in socket server for command open_in and delete_cron_open_in
Fix minor bug on command "open" - Fix minor bug on command "open"
Changed the path of some temporary files to prevent sd card faults - Changed the path of some temporary files to prevent sd card faults
## 0.2.2 - 25/04/2017 ## 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 ## 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 ## 0.2 (Easter egg) - 17/04/2017
Implementation of socket server for communicate with piGardenWeb - Implementation of socket server for communicate with piGardenWeb
Implementation of messages (error, warning, success) passed to piGardenWeb - Implementation of messages (error, warning, success) passed to piGardenWeb
Added many information in json status to be 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 - Added management cron for scheduling open and closed solenoid, for initialize control unit, for rain control
## 0.1.1 - 24/12/2015 - BugFix ## 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 ## 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 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: 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 bison -y
sudo apt-get install gcc -y sudo apt-get install gcc -y
sudo apt-get install make -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 sudo apt-get install dh-autoreconf -y
wget https://github.com/stedolan/jq/releases/download/jq-1.5/jq-1.5.tar.gz wget https://github.com/stedolan/jq/releases/download/jq-1.5/jq-1.5.tar.gz
tar xfvz 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="/home/pi/piGarden/log/piGarden.log"
LOG_FILE_MAX_SIZE=1048576 # 1MB LOG_FILE_MAX_SIZE=1048576 # 1MB
# Log file for driver output
LOG_OUTPUT_DRV_FILE="/tmp/piGarden.drv.log"
# Status directory # Status directory
STATUS_DIR="/home/pi/piGarden/state" STATUS_DIR="/home/pi/piGarden/state"
@@ -52,8 +55,8 @@ STAT="/usr/bin/stat"
EV_MONOSTABLE=0 EV_MONOSTABLE=0
# Id gpio usati per simulare il doppio deviatore con cui eseguire l'alimentazione alle elettrovalvole # Id gpio usati per simulare il doppio deviatore con cui eseguire l'alimentazione alle elettrovalvole
SUPPLY_GPIO_1=2 SUPPLY_GPIO_1=2 # Physical 3 - wPi 8
SUPPLY_GPIO_2=3 SUPPLY_GPIO_2=3 # Physical 5 - wPi 9
# Stato dei due gpio per impartire l'alimentazione positiva alle elettrovalvole (aperta) # Stato dei due gpio per impartire l'alimentazione positiva alle elettrovalvole (aperta)
SUPPLY_GPIO_POS=0 SUPPLY_GPIO_POS=0
@@ -68,7 +71,7 @@ RELE_GPIO_CLOSE=0
RELE_GPIO_OPEN=1 RELE_GPIO_OPEN=1
# Id del gpio usato per collegare il sensore di rilevamento pioggia # 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 # Valore in ingresso sul gpio definito in RAIN_GPIO che indica lo stato di pioggia
RAIN_GPIO_STATE=0 RAIN_GPIO_STATE=0
@@ -82,22 +85,22 @@ EV_TOTAL=6
# Definizione delle elettrovalvole # Definizione delle elettrovalvole
EV1_ALIAS="1" # EV1_ALIAS="1" #
EV1_GPIO=17 EV1_GPIO=17 # Physical 11 - wPi 0
EV2_ALIAS="2" # EV2_ALIAS="2" #
EV2_GPIO=27 EV2_GPIO=27 # Physical 13 - wPi 2
EV3_ALIAS="3" # EV3_ALIAS="3" #
EV3_GPIO=22 EV3_GPIO=22 # Physical 15 - wPi 3
EV4_ALIAS="4" # EV4_ALIAS="4" #
EV4_GPIO=18 EV4_GPIO=18 # Physical 12 - wPi 1
EV5_ALIAS="5" # EV5_ALIAS="5" #
EV5_GPIO=23 EV5_GPIO=23 # Physical 16 - wPi 4
EV6_ALIAS="6" # 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 # Definisce l'api key e il luogo per recuperare lo stato meteo online
WUNDERGROUND_KEY="" 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