Skip to content

Instantly share code, notes, and snippets.

@bobvann
Created October 21, 2016 11:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bobvann/51f887f2726fab0e55ab976930120673 to your computer and use it in GitHub Desktop.
Save bobvann/51f887f2726fab0e55ab976930120673 to your computer and use it in GitHub Desktop.
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)
@simotro
Copy link

simotro commented Oct 31, 2019

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment