Nu har det första karet varit igång några veckor och har alla växter och invånare på plats. LED-rampen har nio grupper för dagsljus där varje grupp består av fyra dagsljusdioder (10-12000K) och två djupröda (655-660nm). Normalt har jag sex av grupperna tända vilket verkar ge en lagom balans med tanke på algtillväxten. Jag har dessutom en grupp med sex blå dioder (460-470nm) som är tända som månljus ett par timmar före och efter dagsljuset.
Temperaturbiten har byggts på så att doppvärmaren styrs av ett av reläen. Jag vill hålla 26°C i karet så värmaren slås på när det är 25,94°C och av när det är 26,05°C. Värmarens egen termostat är satt på 27°C så fallerar min styrning blir det antingen rumstemperatur eller 27°C, inget av det är katastrofalt. Naturligtvis får jag ett mail om avvikelsen är för stor.
Idag fick även det andra karet en ramp av samma modell. Då kar nummer två är tänkt för malawiciklider (jo, det fattas en del inredning) rekommenderade Oceanakvarium ett blåare ljus. Varje grupp för dagsljus består därför av fyra dagsljusdioder (10-12000K), en djupröd (655-660nm) och en blå diod (460-470nm).
Koden har delats upp i två delar, en för ljuset och en för temperaturen:
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import datetime
import syslog
import smtplib
from random import randint
from time import strftime
syslog.syslog('Aqua-light started')
# Definiera tider
moon_on = datetime.datetime(2015, 1, 1, 8, 30)
sunrise_on = datetime.datetime(2015, 1, 1, 10, 30)
noon_on = datetime.datetime(2015, 1, 1, 15, 30)
noon_off = datetime.datetime(2015, 1, 1, 16, 30)
sunset_on = datetime.datetime(2015, 1, 1, 20, 30)
moon_off = datetime.datetime(2015, 1, 1, 23, 30)
# Klasser
class sunClass:
def __init__(self):
#2,3,17,5,6,7,8,9,10
self.sun = [2,17,5,7,8,10]
self.sunLength = len(self.sun)
self.noon = [3,6,9]
self.noonLength = len(self.noon)
def init(self):
syslog.syslog('sunClass.init called')
for x in range (0, self.sunLength):
GPIO.setup(self.sun[x], GPIO.OUT)
for x in range (0, self.noonLength):
GPIO.setup(self.noon[x], GPIO.OUT)
def off(self):
syslog.syslog('sunClass.off called')
for x in range (0, self.sunLength):
GPIO.output(self.sun[x], LEDOff)
for x in range (0, self.noonLength):
GPIO.output(self.noon[x], LEDOff)
def sunrise(self, runtime):
syslog.syslog('Sunrise started')
for x in range (0, self.sunLength):
GPIO.output(self.sun[x], LEDOn)
if x == 1: moon.off()
if x != self.sunLength - 1: time.sleep(runtime/(self.sunLength-1))
syslog.syslog('Sunrise ended')
def sunset(self, runtime):
syslog.syslog('Sunset started')
for x in range (0, self.sunLength):
GPIO.output(self.sun[x], LEDOff)
if x == self.sunLength-2: moon.on()
if x != self.sunLength - 1: time.sleep(runtime/(self.sunLength-1))
syslog.syslog('Sunset ended')
def middag(self, status):
if (status): syslog.syslog('Noon on')
else: syslog.syslog('Noon off')
for x in range (0, self.noonLength):
if (status):
GPIO.output(self.noon[x], LEDOn)
else:
GPIO.output(self.noon[x], LEDOff)
def shadow(self, runtime):
syslog.syslog('Shadow started')
for x in range (0, self.sunLength+3):
if x < self.sunLength: GPIO.output(self.sun[x], LEDOff)
if x > 2: GPIO.output(self.sun[x - 3], LEDOn)
time.sleep(runtime / (self.sunLength+3))
syslog.syslog('Shadow ended')
class moonClass:
def __init__(self):
self.moon = 11
def init(self):
syslog.syslog('moonClass.init called')
GPIO.setup(self.moon, GPIO.OUT)
def off(self):
syslog.syslog('moonClass.off called')
GPIO.output(self.moon, LEDOff)
def on(self):
syslog.syslog('moonClass.on called')
GPIO.output(self.moon, LEDOn)
# Variabler
sun = sunClass()
moon = moonClass()
LEDOn = 0
LEDOff = 1
# Funktioner
# Initiera GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
sun.init()
moon.init()
syslog.syslog('GPIO initialized')
# Initiera state
now = datetime.datetime.now()
sun.off()
moon.off()
state = 0
if now.time() > moon_on.time(): state = 1
if now.time() > sunrise_on.time(): state = 2
if now.time() > noon_on.time(): state = 3
if now.time() > noon_off.time(): state = 4
if now.time() > sunset_on.time(): state = 5
if now.time() > moon_off.time(): state = 0
if state == 1 or state == 5:
moon.on()
elif state <> 0:
sun.sunrise(0)
if state == 3:
sun.middag(True)
syslog.syslog('Initial state is %d' % state)
# Huvudloop
while True:
now = datetime.datetime.now()
if state == 0:
# Night mode, wait for morning moon
if now.time() > moon_on.time() and now.time() < moon_off.time():
state = 1
syslog.syslog('Entering state 1')
moon.on()
elif state == 1:
# Morning moon, wait for sunrise
if now.time() > sunrise_on.time():
state = 2
syslog.syslog('Entering state 2')
sun.sunrise(3600)
elif state == 2:
# Daytime, random shadows, wait for noon
if randint(1, 60) == 1:
sun.shadow(60)
if now.time() > noon_on.time():
state = 3
syslog.syslog('Entering state 3')
sun.middag(True)
elif state == 3:
# Noon, wait for second daytime
if now.time() > noon_off.time():
state = 4
syslog.syslog('Entering state 4')
sun.middag(False)
elif state == 4:
# Second daytime, random shadows, wait for sunset
if randint(1, 60) == 1:
sun.shadow(60)
if now.time() > sunset_on.time():
state = 5
syslog.syslog('Entering state 5')
sun.sunset(3600)
elif state == 5:
# evening moon, wait for night
if now.time() > moon_off.time():
state = 0
syslog.syslog('Entering state 0')
moon.off()
time.sleep(60)
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import datetime
import syslog
import smtplib
from time import strftime
syslog.syslog('Aqua-temp started')
# Definiera temperaturgranser
alarmLow = 25.5
alarmHigh = 26.5
tempLow = 25.9
tempHigh = 26.1
# Klasser
# Variabler
heatOn = 0
heatOff = 1
heater = 22
tempLarm = False
heatStatus = False
# Funktioner
def sendMail(subject, msg):
fromaddr = 'Rikard Elofsson <elof@elof.com>'
toaddr = 'Rikard Elofsson <elof@elof.com>'
message = ('From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s' % (fromaddr, toaddr, subject, msg))
username = 'rikard.elofsson@gmail.com'
password = 'jättehemligt'
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(username,password)
server.sendmail(fromaddr, toaddr, message)
server.quit()
syslog.syslog('Mail sent')
def writeTemp(temp):
tfile = open('/var/www/html/index.html', 'w')
tfile.write('<html><head>')
tfile.write('<title>Info för kar 1</title>')
tfile.write('<META HTTP-EQUIV="refresh" CONTENT="60">')
tfile.write('</head><body>')
tfile.write(strftime("%Y-%m-%d %H:%M:%S"))
tfile.write('<h1>Temperaturen i kar 1 är '+str(temp)+'°C</h1>')
tfile.write('<h2>Värmaren är ')
if heatStatus: tfile.write('på</h2>')
else: tfile.write('av</h2>')
tfile.write('<p><a href="/mrtg/kar1.html">Historik</a>')
tfile.write('</body></html>')
tfile.close()
def checkTemp():
global tempLarm
global heatStatus
tfile = open("/sys/bus/w1/devices/28-0000065bd235/w1_slave", 'r')
text = tfile.read()
tfile.close()
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata[2:])
temperature = float(int((temperature/100)+0.5))/10
if (temperature < alarmLow or temperature > alarmHigh):
if not tempLarm:
syslog.syslog('Temp is wrong')
sendMail("Temperaturen ar felaktig", "Temperaturen i kar 1 ar nu "+str(temperature))
tempLarm = True
else:
if tempLarm:
syslog.syslog('Temp is normal again')
sendMail("Temperaturen ar normal", "Temperaturen i kar 1 ar nu "+str(temperature))
tempLarm = False
if (temperature <= tempLow):
if not heatStatus:
syslog.syslog('Temp is '+str(temperature)+'. Heater switched on')
GPIO.output(heater, heatOn)
heatStatus = True
if (temperature >= tempHigh):
if heatStatus:
syslog.syslog('Temp is '+str(temperature)+'. Heater switched off')
GPIO.output(heater, heatOff)
heatStatus = False
writeTemp(temperature)
# Initiera GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(heater, GPIO.OUT)
GPIO.output(heater, heatOff)
syslog.syslog('GPIO initialized, heater switched off')
# Huvudloop
while True:
checkTemp()
time.sleep(60)