Created
October 21, 2016 11:04
-
-
Save bobvann/51f887f2726fab0e55ab976930120673 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import RPi.GPIO as GPIO | |
import time | |
import _mysql | |
import datetime | |
import urllib | |
import urllib2 | |
############ DEFINIZIONE PIN ############ | |
# PIN GPIO Sensori | |
pinMax = 10 | |
pinMin = 4 | |
pinPavimento = 14 | |
pinCamere = 9 | |
pinMansarda = 11 | |
pinBagni = 8 | |
# PIN GPIO Rele | |
releAccensione = 18 | |
relePavimento = 27 | |
releCamere = 23 | |
releMansarda = 22 | |
releBagni = 24 | |
# PIN Status Led | |
pinLED = 2 | |
########################################## | |
################ CARTELLE FILE ########### | |
#cartella base (slash finale) | |
baseFolder = "/stuff/caldaia/" | |
#cartella file errori (con lo slash finale!) | |
errorFolder = baseFolder + "errors/" | |
#cartella file status (con slash) | |
statusFolder = baseFolder + "status/" | |
#cartella api (col slash) | |
apiFolder = baseFolder + "api/" | |
######################################### | |
############## SETTINGS VARI ############ | |
# tempo di Sleep del While | |
# (ogni quanto controllare sensori e API) | |
tempoSleep = 10 | |
# Database MySQL | |
# è inutile che provate a collegarvi usando queste credenziali | |
# questo sito è hostato su un altro server, non sul RPi ;) | |
mysqlServer = 'localhost' | |
mysqlUser = 'caldaia' | |
mysqlPass = 'caldaia' | |
mysqlDb = 'dbCaldaia' | |
######################################### | |
### Funzione LOG (Status su file e Record MySQL) | |
def log(cosa, come): | |
## DA MODIFICARE !!!!!!!!!!!!!!!!!!!!!! | |
## Query del ultimo stato salvato, se lastState=come, allora non salvo | |
con = _mysql.connect(mysqlServer, mysqlUser, mysqlPass, mysqlDb) | |
con.query("SELECT Cosa FROM tb" + cosa + " WHERE ID = (SELECT MAX(ID) AS ID FROM tb" + cosa + ");") | |
lastState = con.use_result().fetch_row()[0][0] | |
if(int(lastState) != come): | |
con.query("INSERT INTO tb" + cosa + " (Cosa) VALUES (" + str(come) + ");") | |
del con | |
fh = open(statusFolder + "rele/" + cosa, "w") | |
fh.write(str(come)) | |
fh.close() | |
def logSensor(cosa,come): | |
fh = open(statusFolder + "sensors/" + cosa, "w") | |
fh.write(str(come)) | |
fh.close() | |
### Restituisce prima riga file API (0 / 1 / 2) | |
def apiValue(cosa): | |
fh = open(apiFolder + cosa, "r") | |
ap = fh.read() | |
fh.close() | |
return ap[0] | |
## Se API=2 (temporizzata), restituisce il Timestamp di Scadenza (seconda riga del APIfile) | |
def apiEnd(cosa): | |
fh = open(apiFolder + cosa, "r") | |
ap = fh.readline() #salta una riga | |
ap = fh.readline() | |
fh.close() | |
return ap[:10] | |
## Funzione per ogni sensore, eccetto Caldaia | |
## Controlla sensore sul GPIO e apre/chiude, poi fa log | |
def controllo(sottoMin, pin, rele, prevAcceso, testo): | |
# FASI | |
# se temp sotto alla min, SPENTO | |
# 1.Controllo API | |
# 2.Eventuale controllo Sensore | |
onoff = GPIO.input(pin) | |
if (sottoMin): | |
logSensor(testo, onoff) | |
log(testo, 0) | |
GPIO.output(rele, 1) #1 spegne | |
return False | |
else: | |
tmpAcceso = prevAcceso | |
api = apiValue(testo) | |
logSensor(testo, onoff) | |
if (api == '1'): | |
if (not prevAcceso): | |
GPIO.output(rele,0) | |
tmpAcceso = True | |
log(testo, 1) | |
elif (api == '2'): | |
until = apiEnd(testo) | |
if (int(until) < int(time.time())): | |
fh = open(apiFolder + testo, "w") | |
fh.write("0") | |
fh.close | |
else: | |
if (not prevAcceso): | |
GPIO.output(rele,0) | |
tmpAcceso = True | |
log(testo, 1) | |
elif (api == '0'): | |
if (onoff): | |
if (not prevAcceso): | |
GPIO.output(rele,0) | |
tmpAcceso = True | |
log(testo, 1) | |
else : | |
if (prevAcceso): | |
GPIO.output(rele,1) | |
tmpAcceso = False | |
log(testo, 0) | |
return tmpAcceso | |
############ INIZIO PROGRAMMA ################# | |
try: | |
# Numero dei pin in GPIO e Warnings (already used PIN) disabilitati | |
GPIO.setmode(GPIO.BCM) | |
GPIO.setwarnings(False) | |
#SETUP DEI SENSORI COME INPUT | |
GPIO.setup(pinMax, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) | |
GPIO.setup(pinMin, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) | |
GPIO.setup(pinPavimento, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) | |
GPIO.setup(pinCamere, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) | |
GPIO.setup(pinMansarda, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) | |
GPIO.setup(pinBagni, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) | |
#SETUP DEI RELE COME OUTPUT | |
#E APERTURA RELE (1=APERTO=SPENTO, 0=CHIUSO=ACCESO) | |
GPIO.setup(releAccensione, GPIO.OUT) | |
GPIO.output(releAccensione,1) | |
GPIO.setup(relePavimento, GPIO.OUT) | |
GPIO.output(relePavimento,1) | |
GPIO.setup(releCamere, GPIO.OUT) | |
GPIO.output(releCamere,1) | |
GPIO.setup(releMansarda, GPIO.OUT) | |
GPIO.output(releMansarda,1) | |
GPIO.setup(releBagni, GPIO.OUT) | |
GPIO.output(releBagni,1) | |
#LED DI STATO (ACCESO) | |
GPIO.setup(pinLED, GPIO.OUT) | |
GPIO.output(pinLED,1) | |
#Inizializzazione | |
caldaiaOn = 0 | |
pavimentoOn = 0 | |
camereOn = 0 | |
bagniOn = 0 | |
mansardaOn = 0 | |
#Loggo tutto a Spento | |
# se sensori/api accendono -> verra loggato a acceso | |
# altrimenti -> resta loggato a spento | |
log("Caldaia",0) | |
log("Pavimento",0) | |
log("Camere",0) | |
log("Bagni",0) | |
log("Mansarda",0) | |
logSensor("Pavimento", 0) | |
logSensor("Camere", 0) | |
logSensor("Bagni", 0) | |
logSensor("Mansarda", 0) | |
while (True): | |
# controllo Max/Min | |
# max e min NC, chiusi quando sotto alla temp | |
sottoMin = GPIO.input(pinMin) | |
sottoMax = GPIO.input(pinMax) | |
logSensor("sottoMin", sottoMin) | |
logSensor("sottoMax", sottoMax) | |
if (sottoMin): | |
if (not caldaiaOn): | |
GPIO.output(releAccensione,0) | |
caldaiaOn = True | |
log("Caldaia", 1) | |
else : | |
if (not sottoMax): | |
if (caldaiaOn): | |
GPIO.output(releAccensione,1) | |
caldaiaOn = False | |
log("Caldaia", 0) | |
#python non passa per indirizzo, solo per valore, quindi | |
#uso il return della funzione per far variare il valore delle variabili etcOn | |
#controllo Pavimento | |
pavimentoOn = controllo(sottoMin, pinPavimento, relePavimento, pavimentoOn, "Pavimento") | |
#controllo Termosifoni (camere, bagni, mansarda) | |
camereOn = controllo(sottoMin, pinCamere, releCamere, camereOn, "Camere") | |
bagniOn = controllo(sottoMin, pinBagni, releBagni, bagniOn, "Bagni") | |
mansardaOn = controllo(sottoMin, pinMansarda, releMansarda, mansardaOn, "Mansarda") | |
time.sleep(tempoSleep) | |
except: | |
# In caso di errore: | |
# 1. salvo l'errore nel file | |
# 2. invio l'sms di errore | |
# 3. apro tutti i contatti (spengo tutto) | |
# 4. segno lo status di aperto in tutti i contati | |
# 5. lampeggio il led di status | |
now = datetime.datetime.now() | |
stringa = str(now.year) + "/" + str(now.month) + "/" + str(now.day) + " " + str(now.hour) + ":" + str(now.minute) | |
stringa = stringa + " " + str(sys.exc_info()[0]) | |
nomefile = errorFolder + str(now.year) + "-" + str(now.month) + "-" + str(now.day) + "-caldaia.txt" | |
fh = open(nomefile, "a") | |
fh.write(stringa + "\n") | |
fh.close | |
#invio del sms di errore (si tratta di una chiamata POST a un link) | |
errText = "CALDAIA: " + stringa | |
url = "******OMESSO*****" | |
values = { | |
'testo' : errText, | |
'sn' : '|****OMESSO******|', | |
'username' : '****OMESSO******', | |
'password' : '****OMESSO******', | |
'Submit' : 'Invia' | |
} | |
data = urllib.urlencode(values) | |
req = urllib2.Request(url, data) | |
response = urllib2.urlopen(req) | |
GPIO.setmode(GPIO.BCM) | |
GPIO.setup(pinLED, GPIO.OUT) | |
GPIO.setup(releAccensione, GPIO.OUT) | |
GPIO.setup(relePavimento, GPIO.OUT) | |
GPIO.setup(releCamere, GPIO.OUT) | |
GPIO.setup(releMansarda, GPIO.OUT) | |
GPIO.setup(releBagni, GPIO.OUT) | |
GPIO.output(releAccensione, 1) | |
GPIO.output(relePavimento, 1) | |
GPIO.output(releCamere, 1) | |
GPIO.output(releMansarda, 1) | |
GPIO.output(releBagni, 1) | |
fh = open(statusFolder + "rele/Caldaia", "w") | |
fh.write("0") | |
fh.close | |
fh = open(statusFolder + "rele/Pavimento", "w") | |
fh.write("0") | |
fh.close | |
fh = open(statusFolder + "rele/Camere", "w") | |
fh.write("0") | |
fh.close | |
fh = open(statusFolder + "rele/Bagni", "w") | |
fh.write("0") | |
fh.close | |
fh = open(statusFolder + "rele/Mansarda", "w") | |
fh.write("0") | |
fh.close | |
while (True): | |
GPIO.output(pinLED,1) | |
time.sleep(1) | |
GPIO.output(pinLED,0) | |
time.sleep(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Ciao Roberto! Mi piace un sacco il tuo progetto "caldaia" e mi piacerebbe poterlo utilizzare per la gestione del riscaldamento di casa mia con un RPi che ho già. Lo stai ancora sviluppando? Hai una versione completa ed un manualetto di installazione da poter acquistare? Scusa il disturbo e grazie mille!