Hur man mäter temperatur och hur jag använder det för att styra ett relä som slår av och på värmaren är beskrivet på andra ställen i bloggen men här kommer en sammanställning och uppdatering.
Jag aktiverade 1-wire i raspi-config under uppsättningen av min paj och har anslutit min DS18B20 enligt anvisningarna från Cambridge University. För att den ska hittas och användas behöver två rader läggas till i /etc/modules:
För att kunna presentera data och statistik installerade jag webbservern Apache tillsammans med MRTG som kan presentera historiken grafiskt:
sudo apt-get install apache2 mrtg
För att MRTG ska få data från temperatur-sensorn krävs det en liten fil som jag kallar mrtg.py. Man får byta adressen till filen w1_slave till aktuell adress, varje sensor har sin egen:
#!/usr/bin/python
from time import strftime
tfile = open("/sys/bus/w1/devices/28-011553897dff/w1_slave", 'r')
text = tfile.read()
tfile.close()
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata[2:])
temperature = int(temperature / 10)
print(str(temperature))
print("0")
print(strftime("%Y-%m-%d %H:%M:%S"))
print("Temperatur i kar 3")
Man behöver även byta ut /etc/mrtg.cfg mot en som hämtar data på rätt ställe och visar det som man vill:
######################################################################
# Multi Router Traffic Grapher -- Sample Configuration File
######################################################################
# This file is for use with mrtg-2.5.4c
# Global configuration
WorkDir: /var/www/html/mrtg
WriteExpires: Yes
RunAsDaemon: Yes
Interval: 5
Title[^]: Temperaturstatistik for
Title[kar3]: kar 3
PageTop[kar3]: <h1>Temperaturen i kar 3</h1>
Target[kar3]: `/usr/local/bin/aquacontrol/mrtg.py`
MaxBytes[kar3]: 4000
Options[kar3]: growright,gauge,expscale
Factor[kar3]: 0.01
YLegend[kar3]: Temperatur
YTicsFactor[kar3]: 0.01
ShortLegend[kar3]: C
Legend1[kar3]: Temperatur i grader celcius
Legend2[kar3]:
Legend3[kar3]: Maximal 5 Minute Incoming Traffic
Legend4[kar3]: Maximal 5 Minute Outgoing Traffic
LegendI[kar3]: Temp:
LegendO[kar3]:
För att MRTG ska starta automatiskt behövs ett startscript, skapa filen mrtg i /etc/init.d med följande innehåll:
#! /bin/sh
### BEGIN INIT INFO
# Provides: mrtg
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: mrtg init script
# Description: This file is used to start, stop, restart,
# and determined status of the mrtg daemon.
# Author: iceflatline <iceflatline@gmail.com>
### END INIT INFO
### START OF SCRIPT
set -e
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="mrtg"
NAME=mrtg
DAEMON=/usr/bin/$NAME
DAEMON_ARGS="/etc/mrtg.cfg"
PIDFILE=/etc/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the mrtg package is not installed
[ -x "$DAEMON" ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
# Function that starts the mrtg daemon
start()
{
env LANG=C start-stop-daemon --start --quiet \
--exec $DAEMON -- $DAEMON_ARGS
}
# Function that stops the mrtg daemon
stop()
{
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
--pidfile $PIDFILE
}
case "$1" in
start)
log_daemon_msg "Starting $DESC"
start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;;
esac
;;
stop)
log_daemon_msg "Stopping $DESC"
stop
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;;
esac
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC"
stop
case "$?" in
0|1)
start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;;
esac
;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME"
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}"
;;
esac
exit 0
### END OF SCRIPT
Kör sedan
sudo chmod +x /usr/local/bin/aquacontrol/mrtg.py
sudo chmod +x /etc/init.d/mrtg
sudo systemctl daemon-reload
sudo update-rc.d mrtg defaults
så ska MRTG-biten vara klar. Dags för lite styrning! Följande Python-skript läser av temperaturen varje minut, kollar mot gränsvärden, slår av och på värmaren och larmar via epost om det avviker för mycket. Ange dina egna epostuppgifter och förstås rätt adress till w1_slave-filen som vanligt.
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
import datetime
import syslog
import smtplib
from time import strftime
syslog.openlog('aqua-temp')
syslog.syslog('Aqua-temp started')
# Definiera temperaturgranser
alarmLow = 24
alarmHigh = 27
tempLow = 24.9
tempHigh = 25.1
# Klasser
# Variabler
heatOn = 0
heatOff = 1
heater = 22
tempLarm = False
heatStatus = False
# Funktioner
def sendMail(subject, msg):
fromaddr = 'me self <me@self.com>'
toaddr = 'me self <me@self.com>'
message = ('From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s' % (fromaddr, toaddr, subject, msg))
username = 'username'
password = 'password'
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/temp.html', 'w')
tfile.write('<html><head>')
tfile.write('<title>Info för kar 3</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 3 ä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/kar3.html">Historik</a>')
tfile.write('</body></html>')
tfile.close()
def checkTemp():
global tempLarm
global heatStatus
tfile = open("/sys/bus/w1/devices/28-011553897dff/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 3 ar nu "+str(temperature))
tempLarm = True
else:
if tempLarm:
syslog.syslog('Temp is normal again')
sendMail("Temperaturen ar normal", "Temperaturen i kar 3 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)
För att skriptet ska starta automatiskt behöver man skapa filen aqua-temp.service i /lib/systemd/system med följande innehåll:
[Unit]
Description=Aqua-Temp
After=multi-user.target
[Service]
Type=idle
ExecStart=/usr/local/bin/aquacontrol/aqua-temp.py
[Install]
WantedBy=multi-user.target
Kör sedan
sudo chmod +x /usr/local/bin/aquacontrol/aqua-temp.py
sudo chmod 644 /lib/systemd/system/aqua-temp.service
sudo systemctl daemon-reload
sudo systemctl enable aqua-temp.service
så ska det starta automatiskt vid omstart. Det är praktiskt att få loggen som skapas till en egen fil. Skapa filen /etc/rsyslog.d/aqua-temp.conf med innehållet
if $programname == 'aqua-temp' then /var/log/aqua-temp.log
Överkurs
Ibland kan det vara fiffigt att kunna hämta ut data i JSON-format. Jag har därför följande lilla fil, vid namn temp-xml.py, placerad i /var/www/cgi-bin. Ja, du behöver justera sökvägen till w1_slave…
#!/usr/bin/python
tfile = open("/sys/bus/w1/devices/28-011553897dff/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
print ("Content-type: text/html\n")
print ('<?xml version="1.0" encoding="UTF-8"?>')
print ('<rss version="2.0">')
print (' <item>')
print (' <temp3>'+str(temperature)+'</temp3>')
print (' </item>')
print ('</rss>')
För att Apache ska gå med på att köra python-script, och begripa vad cgi-bin är, behöver dessa rader läggas till i /etc/apache2/sites-available/000-default.conf efter DocumentRoot-raden
ScriptAlias /cgi-bin/ /var/www/cgi-bin/
<Directory "/var/www/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
Kör sedan
sudo chmod +x /var/www/cgi-bin/temp-xml.py
sudo a2enmod cgi
sudo service apache2 restart
så ska det hela rulla.