First Raspberry Pi Project

First Raspberry Pi Project

Temperature Sensor:
20141009_195856

Just got my self a DS18D20 and I thought it will be good to build a controller to record temperature.

I am using these two websites to help me start:
http://raspberrywebserver.com/cgiscripting/rpi-temperature-logger/building-an-sqlite-temperature-logger.html
https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/temperature/

In the second website I understood the basic to connect a DS18B20 sensor-connection

Then the code in python to get the readings:

#!/usr/bin/env python

import os
import glob
import time

# load the kernel modules needed to handle the sensor
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

# find the path of a sensor directory that starts with 28
devicelist = glob.glob('/sys/bus/w1/devices/28*')
# append the device file name to get the absolute path of the sensor 
devicefile = devicelist[0] + '/w1_slave'

# open the file representing the sensor.
fileobj = open(devicefile,'r')
lines = fileobj.readlines()
fileobj.close()

# print the lines read from the sensor apart from the extra \n chars
#print lines[0][:-1]
#print lines[1][:-1]

# Split the text with new lines (\n) and select the second line. 
secondline = lines[1] 
# Split the line into words, referring to the spaces, and select the 10th word (counting from 0). 
temperaturedata = secondline.split(" ")[9] 
# The first two characters are "t=", so get rid of those and convert the temperature from a string to a number. 
temperature = float(temperaturedata[2:]) 
# Put the decimal point in the right place and display it. 
temperature = temperature / 1000 
print temperature

Then on the other URL I started to log my entries. Here is the script:

#!/usr/bin/env python

import sqlite3

import os
import time
import glob

# global variables
speriod=(15*60)-1
dbname='/home/pi/templog.db'



# store the temperature in the database
def log_temperature(temp):

    conn=sqlite3.connect(dbname)
    curs=conn.cursor()

    curs.execute("INSERT INTO temps values(datetime('now'), (?))", (temp,))

    # commit the changes
    conn.commit()

    conn.close()


# display the contents of the database
def display_data():

    conn=sqlite3.connect(dbname)
    curs=conn.cursor()

    for row in curs.execute("SELECT * FROM temps"):
        print str(row[0])+"	"+str(row[1])

    conn.close()



# get temerature
# returns None on error, or the temperature as a float
def get_temp(devicefile):

    try:
        fileobj = open(devicefile,'r')
        lines = fileobj.readlines()
        fileobj.close()
    except:
        return None

    # get the status from the end of line 1 
    status = lines[0][-4:-1]

    # is the status is ok, get the temperature from line 2
    if status=="YES":
        print status
        tempstr= lines[1][-6:-1]
        tempvalue=float(tempstr)/1000
        print tempvalue
        return tempvalue
    else:
        print "There was an error."
        return None



# main function
# This is where the program starts 
def main():

    # enable kernel modules
    os.system('sudo modprobe w1-gpio')
    os.system('sudo modprobe w1-therm')

    # search for a device file that starts with 28
    devicelist = glob.glob('/sys/bus/w1/devices/28*')
    if devicelist=='':
        return None
    else:
        # append /w1slave to the device file
        w1devicefile = devicelist[0] + '/w1_slave'


#    while True:

    # get the temperature from the device file
    temperature = get_temp(w1devicefile)
    if temperature != None:
        print "temperature="+str(temperature)
    else:
        # Sometimes reads fail on the first attempt
        # so we need to retry
        temperature = get_temp(w1devicefile)
        print "temperature="+str(temperature)

        # Store the temperature in the database
    log_temperature(temperature)

        # display the contents of the database
#    display_data()

#    time.sleep(speriod)


if __name__=="__main__":
    main()

Make sure you go through the steps to create the sqlite db first.

Now I have a crontab job that save my reading every 15 minutes and now I need to show those reading. I used to run my Pi as webserver (LAMP) but I always thought it was a bit too much for a RPi. So I searched the web for a python web REST service and I found this nifty website: http://webpy.org/.

I have to say it work like a charm. The overhead in term of resources is way less then a LAMP and it gets the job done. Is extremely simple and quick to implement.

I started with some good examples:
http://www.milocreek.com/wiki/index.php/GettingStarted
http://www.dreamsyssoft.com/blog/blog.php?/archives/6-Create-a-simple-REST-web-service-with-Python.html

I created a rest service to broadcast reading to my web server:

#!/usr/bin/env python
import web
from web.template import render

db = web.database(dbn='sqlite', db='/home/pi/templog.db')

urls = (
  '/', 'index',
  '/(.*)','get_temp'
)

app = web.application(urls, globals())

class index:
    def GET(self):
    temps = db.query("select * from temps where timestamp>datetime('now','-24 hours')") #select('temps')
        output= ''
        for temp in temps:
            output += ",['"+str(temp.timestamp)+"',"+str(temp.temp)+"]"

    return output

class get_temp:
    def GET(self,hours):
    temps = db.query("select * from temps where timestamp>datetime('now','-%s hours')" % hours) #select('temps')
        output= ''
        for temp in temps:
            output += ",['"+str(temp.timestamp)+"',"+str(temp.temp)+"]"

    return output


if __name__ == "__main__":
    app.run()

The rest service will be broadcast on port 8080 by default. Just type http://piipaddress:8080 and you will see the data.

To start the rest service when the Pi reboot just call the python code above to  crontap:

sudo crontab -e

Then add the code below to the bottom of the script.

@reboot /home/pi/rest.py

 

The last step is pick the data up from my webserver (LAMP) and use Google API to present some fancy graphic. Here is the code:

 <!DOCTYPE html>
<html>
<head>
    <title>Temperature Log</title>
    <meta http-equiv="refresh" content="900" />
    <link rel="stylesheet" type="text/css" href="local.css" />
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script>
        $(document).ready(function(){             
          <?php if(!isset($_REQUEST['interval'])) { echo "$('#interval option[value=24]').attr('selected', 'selected');"; } ?>
            $('#intDis').html($('#interval option:selected').text());
          $('#interval').change(function () {
            location.href =  'http://home.robertomignucci.co.uk?interval=' + $('#interval option:selected').val()
          });
        });

      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Time', 'Temperature']

<?php
    if (isset($_REQUEST['interval']))
    {
      // param was set in the query string
       if(!empty($_REQUEST['interval']))
       {
            $hours = $_GET['interval'];
        echo file_get_contents("http://RPiIPaddress:8080/" . $hours);
        //echo $hours;
       }
    }
    else
    {
        echo file_get_contents("http://RPiIPaddress:8080/");
    }
    
?>
        ]);

        var options = {
          title: 'Temperature Log'
        };

        var chart = new google.visualization.LineChart
                        (document.getElementById('chart_div'));
        chart.draw(data, options);
      }

    </script>
</head>
<body>
    <h1>Temperature Report</h1>
    <div>
    Selected time span:&nbsp;<select id="interval">
      <option value="6" <?php if(isset($_REQUEST['interval'])) {if ($_GET['interval'] == 6) {echo "selected";}} ?> >6hrs</option>
      <option value="12" <?php if(isset($_REQUEST['interval'])) {if ($_GET['interval'] == 12) {echo "selected";}} ?> >12hrs</option>
      <option value="24" <?php if(isset($_REQUEST['interval'])) {if ($_GET['interval'] == 24) {echo "selected";}} ?> >24hrs</option>
      <option value="48" <?php if(isset($_REQUEST['interval'])) {if ($_GET['interval'] == 48) {echo "selected";}} ?>  >48hrs</option>
      <option value="168" <?php if(isset($_REQUEST['interval'])) {if ($_GET['interval'] == 168) {echo "selected";}} ?>>1 week</option>
      <option  value="236" <?php if(isset($_REQUEST['interval'])) {if ($_GET['interval'] == 236) {echo "selected";}} ?> >2 weeks</option>
    </select> &nbsp;&nbsp;last <span id="intDis"></span> (UCT)</div>
    <div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html> 

Here is the result: http://home.robertomignucci.co.uk/

Untitled

 

I hope this will be useful to you. Have fun with it!

Comments are closed.