Monday, March 6, 2017

Result of my Locus test

Locus of Control Test Results
Internal Locus (84%) Individual believes that their life is defined more by their decisions and internal drive.
External Locus (16%) Individual believes that their life is defined more by genetics, environment, fate, or other external factors.
Take Free Locus of Control Test
personality tests by similarminds.com

Thursday, March 2, 2017

Create a home made temperature sensor using Raspberry pi

Problem we are solving here is.

1. User raspberry pi to get the room temperature
2. Store the temp in a sqlite database.
3. Display the results in a neat graph using a webpage.

Hardware required for this project:
DS18B20 Temperature Sensor
Raspberry Pi
4.7 ohm resistor
Soldering rod
Three wires with female connectors on each end

First of all get your pi ready for the work

-- Install SQLite database

sudo apt-get install sqlite3


-- create a database in the home directory of pi user
sqlite3 mydatabase.db

-- Create table to store the temperature readings
BEGIN;
CREATE TABLE temps (temptime DATETIME, temp NUMERIC);
COMMIT;

-- A tip to get some help
sqlite> .help

-- To exit out of sqlite command prompt
sqlite> .exit


-- create get temp.py to get the temperature
#!/usr/bin/env python

import sqlite3

import os
import time
import glob

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


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

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

    # bavita added , 'localtime' to get the local time from machine else it is showing GMT
    curs.execute("INSERT INTO temps values(datetime('now', 'localtime'), (?))", (temp,))

    # commit the changes
    conn.commit()
    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)

if __name__=="__main__":
    main()

-- test apache
open the bowser from a machine other than the pi and type the ip address of pi like below and hit enter

http://192.168.0.2/

The page should display something like below:

-- Solder sensor and resistor as described below and then use the wire to connect them to GPIO.

-- The final product should looks something like below:


-- After the setup perform a quick test on sensor and see if it works and that is done as below:

Here temp is 16687 / 1000 = 16.687 C
Please note that if the black sensor is getting too hot then you have soldered it other way around, change the pins and it should be fine.

-- Enable cgi-bin on apache
We will be writing the code in python and in order for that code to display content on webpage we need to change apache config to enable cgi scripts.

Go to /usr/lib/cgi-bin and create sensor.py with chmod 777

Now go to /etc/apache2/sites-available

edit file called default and add below in red color

<Directory "/usr/lib/cgi-bin">
                AddHandler cgi-script .py
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

Note the bit in blue /usr/lib/cgi-bin this is where your web application sensor.py should go and work in browser.


-- code for sensor.py

#!/usr/bin/env python

import sqlite3
import sys
import cgi
import cgitb


# global variables
speriod=(15*60)-1
#dbname='/var/www/mydatabase.db'
dbname='/home/pi/tempdb/mydatabase.db'

# print the HTTP header
def printHTTPheader():
    print "Content-type: text/html\n\n"

# print the HTML head section
# arguments are the page title and the table for the chart
def printHTMLHead(title, table):
    print "<head>"
    print "    <title>"
    print title
    print "    </title>"
    print_graph_script(table)
    print "</head>"

# get data from the database
# if an interval is passed, 
# return a list of records from the database
def get_data(interval):

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

    if interval == None:
        curs.execute("SELECT * FROM temps")
    else:
        curs.execute("SELECT * FROM temps WHERE temptime>datetime('now','localtime','-%s hours')" % interval)
#        curs.execute("SELECT * FROM temps WHERE temptime>datetime('2013-09-19 21:30:02','-%s hours') AND temptime<=datetime('2013-09-19 21:31:02')" % interval)

    rows=curs.fetchall()
    conn.close()
    return rows

# convert rows from database into a javascript table
def create_table(rows):
    chart_table=""

    for row in rows[:-1]:
        rowstr="['{0}', {1}],\n".format(str(row[0]),str(row[1]))
        chart_table+=rowstr

    row=rows[-1]
    rowstr="['{0}', {1}]\n".format(str(row[0]),str(row[1]))
    chart_table+=rowstr

    return chart_table


# print the javascript to generate the chart
# pass the table generated from the database info
def print_graph_script(table):

    # google chart snippet
    chart_code="""
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([ ['Time', 'Temperature'],%s ]);
        var options = {
          hAxis: {
          title: 'Time'
        },
        vAxis: {
          title: 'Temperature'
        },
        title: 'Temperature Vs Time',
        backgroundColor: '#f1f8e9'
        };
        var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
        chart.draw(data, options);
      }
    </script>"""

    print chart_code % (table)

# print the div that contains the graph
def show_graph():
    print "<h2>Temperature Chart</h2>"
# Bavita commented below to make the graph bigger
#    print '<div id="chart_div" style="width: 900px; height: 500px;"></div>'

    print '<div id="chart_div" style="width: 1300px; height: 700px;"></div>'

# connect to the db and show some stats
# argument option is the number of hours
def show_stats(option):

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

    if option is None:
        option = str(24)

    curs.execute("SELECT temptime,max(temp) FROM temps WHERE temptime>datetime('now','localtime','-%s hour') AND temptime<=datetime('now','localtime')" % option)
#    curs.execute("SELECT temptime,max(temp) FROM temps WHERE temptime>datetime('2013-09-19 21:30:02','-%s hour') AND temptime<=datetime('2013-09-19 21:31:02')" % option)
    rowmax=curs.fetchone()
    rowstrmax="{0}&nbsp&nbsp&nbsp{1}C".format(str(rowmax[0]),str(rowmax[1]))

    curs.execute("SELECT temptime,min(temp) FROM temps WHERE temptime>datetime('now','localtime','-%s hour') AND temptime<=datetime('now','localtime')" % option)
#    curs.execute("SELECT temptime,min(temp) FROM temps WHERE temptime>datetime('2013-09-19 21:30:02','-%s hour') AND temptime<=datetime('2013-09-19 21:31:02')" % option)
    rowmin=curs.fetchone()
    rowstrmin="{0}&nbsp&nbsp&nbsp{1}C".format(str(rowmin[0]),str(rowmin[1]))

    curs.execute("SELECT avg(temp) FROM temps WHERE temptime>datetime('now','localtime','-%s hour') AND temptime<=datetime('now','localtime')" % option)
#    curs.execute("SELECT avg(temp) FROM temps WHERE temptime>datetime('2013-09-19 21:30:02','-%s hour') AND temptime<=datetime('2013-09-19 21:31:02')" % option)
    rowavg=curs.fetchone()

    curs.execute("select * from temps where temptime =(select max(temptime)  FROM temps WHERE temptime>datetime('now','localtime','-1 hour') AND temptime<=datetime('now','localtime'))")
    rowcurrent=curs.fetchone()
    rowstrcurrent="{0}&nbsp&nbsp&nbsp{1}C".format(str(rowcurrent[0]),str(rowcurrent[1]))


    print "<hr>"
    print "<h2>Current temperature&nbsp</h2>"
    print rowstrcurrent
    print "<h2>Minumum temperature&nbsp</h2>"
    print rowstrmin
    print "<h2>Maximum temperature</h2>"
    print rowstrmax
    print "<h2>Average temperature</h2>"
    print "%.3f" % rowavg+"C"

    print "<hr>"

    print "<h2>In the last hour:</h2>"
    print "<table>"
    print "<tr><td><strong>Date/Time</strong></td><td><strong>Temperature</strong></td></tr>"

    #rows=curs.execute("SELECT * FROM temps WHERE temptime>datetime('now','-1 hour') AND temptime<=datetime('now')")
    # display the temp in last hour under "In the last hour"
    rows=curs.execute("SELECT * FROM temps WHERE temptime>datetime('now','localtime','-1 hour') AND temptime<=datetime('now','localtime')")
#    rows=curs.execute("SELECT * FROM temps WHERE temptime>datetime('2013-09-19 21:30:02','-1 hour') AND temptime<=datetime('2013-09-19 21:31:02')")
    for row in rows:
        rowstr="<tr><td>{0}&emsp;&emsp;</td><td>{1}C</td></tr>".format(str(row[0]),str(row[1]))
        print rowstr
    print "</table>"

    print "<hr>"

    conn.close()

def print_time_selector(option):

    print """<form action="/cgi-bin/webgui.py" method="POST">
        Show the temperature logs for  
        <select name="timeinterval">"""

    if option is not None:
        if option == "1":
            print "<option value=\"1\" selected=\"selected\">the last 1 hours</option>"
        else:
            print "<option value=\"1\">the last 1 hours</option>"
        if option == "2":
            print "<option value=\"2\" selected=\"selected\">the last 2 hours</option>"
        else:
            print "<option value=\"2\">the last 2 hours</option>"
        if option == "3":
            print "<option value=\"3\" selected=\"selected\">the last 3 hours</option>"
        else:
            print "<option value=\"3\">the last 3 hours</option>"

        if option == "6":
            print "<option value=\"6\" selected=\"selected\">the last 6 hours</option>"
        else:
            print "<option value=\"6\">the last 6 hours</option>"

        if option == "12":
            print "<option value=\"12\" selected=\"selected\">the last 12 hours</option>"
        else:
            print "<option value=\"12\">the last 12 hours</option>"

        if option == "24":
            print "<option value=\"24\" selected=\"selected\">the last 24 hours</option>"
        else:
            print "<option value=\"24\">the last 24 hours</option>"

        if option == "48":
            print "<option value=\"48\" selected=\"selected\">the last 2 Days</option>"
        else:
            print "<option value=\"48\">the last 2 days</option>"

        if option == "168":
            print "<option value=\"168\" selected=\"selected\">the last 7 Days</option>"
        else:
            print "<option value=\"168\">the last 7 days</option>"

        if option == "336":
            print "<option value=\"336\" selected=\"selected\">the last 14 Days</option>"
        else:
            print "<option value=\"336\">the last 14 days</option>"

        if option == "720":
            print "<option value=\"720\" selected=\"selected\">the last 30 Days</option>"
        else:
            print "<option value=\"720\">the last 30 days</option>"

        if option == "4320":
            print "<option value=\"4320\" selected=\"selected\">the last 180 Days</option>"
        else:
            print "<option value=\"4320\">the last 180 days</option>"

    else:
        print """
            <option value="1">the last 1 hours</option>
            <option value="2">the last 2 hours</option>
            <option value="3">the last 3 hours</option>
            <option value="6">the last 6 hours</option>
            <option value="12">the last 12 hours</option>
            <option value="24" selected="selected">the last 24 hours</option>
            <option value="48">the last 2 Day</option>
            <option value="168">the last 7 Day</option>
            <option value="336">the last 14 Day</option>
            <option value="720">the last 30 Day</option>
            <option value="4320">the last 180 Day</option>
            """

    print """        </select>
        <input type="submit" value="Display">
    </form>"""


# check that the option is valid
# and not an SQL injection
def validate_input(option_str):
    # check that the option string represents a number
    if option_str.isalnum():
        # check that the option is within a specific range
        if int(option_str) > 0 and int(option_str) <= 4320:
            return option_str
        else:
            return None
    else: 
        return None

#return the option passed to the script
def get_option():
    form=cgi.FieldStorage()
    if "timeinterval" in form:
        option = form["timeinterval"].value
        return validate_input (option)
    else:
        return None

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

    cgitb.enable()

    # get options that may have been passed to this script
    option=get_option()

    if option is None:
        option = str(24)

    # get data from the database
    records=get_data(option)

    # print the HTTP header
    printHTTPheader()

    if len(records) != 0:
        # convert the data into a table
        table=create_table(records)
    else:
        print "No data found"
        return

    # start printing the page
    print "<html>"
    # print the head section including the table
    # used by the javascript for the chart
    printHTMLHead("Raspberry Pi Temperature Logger", table)

    # print the page body
    print "<body>"
    print "<h1>Raspberry Pi Temperature Logger</h1>"
    print "<hr>"
    print_time_selector(option)
    show_graph()
    show_stats(option)
    print "</body>"
    print "</html>"

    sys.stdout.flush()

if __name__=="__main__":
    main()


-- Test URL
Now we can test the URL as

http://192.168.0.2/cgi-bin/sensor.py