Doug Wyman
Published

Lighting and Cedar and Pi Oh My!

A Tiger Mountain project for an outdoor light powered by 120 A.C. or 12 VDC With motion control on/off web control, Weather.. Add more?

IntermediateShowcase (no instructions)1,337
Lighting  and Cedar and Pi Oh My!

Things used in this project

Hardware components

Raspberry Pi 1 Model B
Raspberry Pi 1 Model B
×1
90x10mm Quality HEAVY Aluminum Round Spiral Heat Sink for 1-10W LED
×4
AdaFruit BME280
×1
Adafruit BME280
×1
10W watt cool White bright High Power LED light SMD Chips bulb DC9-12V DIY
×1
2.1x5.5MM DC Power connectors male
×2
5133710 NEMA, Screw Cover, Enclosure
×1
2.1x5.5MM DC Power connectors female
×2
Raspberry Pi single board computer
×1
Pi Face Digital
×1
10Watt 12 Volt DC LED
×4
12V 6 Amp DC power supply
×1
DC 4.5-35V to 3-33.5V Buck Converter
×1
1 1/2 inch vented plug
×1
Buck Converter
×1
Raspberry Pi 1 Model B+
Raspberry Pi 1 Model B+
×1

Hand tools and fabrication machines

3 1/2" hole saw
hole saw arbor
Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Code

HTML light control

HTML
Front end web interface for the light
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Front Light</title>
</head>
<body>
    <center>
        <div style="font: font-family: 'Lucida Calligraphy'; font-size: xx-large; font-weight: bold;
            color: #CC0000; font-family: 'Lucida Calligraphy';">
            Front Light
        </div>
    </center>
    <br />
    <br />
    <center>
        <a href="http://192.168.0.151/flon.php" target="didit"><img src="images/greenbuttonmed.png" alt="green" /></a>
        <br />
        <br />
        <a href="http://192.168.0.151/flo.php" target="didit"><img src="images/redbuttonmed

.png" alt="red" /></a>
    </center>
    <iframe name="didit" align="middle" 
        style="width: 100%" frameborder="0"></iframe>
</body>
</html>

inderpalsinghs WiFi maintainer

ActionScript
The Raspberry Pi WiFi has a terrible habit of dropping out and not reconnecting. inderpalsinghs says there is a fix and I am copying that here. I put it in usr/share and call it on boot.
#!/bin/bash

while true ; do
   if ifconfig wlan0 | grep -q "inet addr:" ; then
      sleep 60
   else
      echo "Network connection down! Attempting reconnection."
      ifdown --force wlan0
      sleep 10
      ifup --force wlan0
      sleep 10
    fi
done

AdaFruit BME280 Python code for Tiger Mountain build

Python
This code records the temperature, humidity and barometric pressure to a MySql database for weather history
#!/usr/bin/python
import sys
import httplib2
from Adafruit_BME280 import *

sensor = BME280(mode=BME280_OSAMPLE_8)
degrees = sensor.read_temperature()
pascals = sensor.read_pressure()
hectopascals = pascals / 100
inmercury = pascals *  0.00029530
humidity = sensor.read_humidity()
farenheight = round((((degrees *9)/5) + 32),2)
print (format(str(farenheight)))

print ('Timestamp = {0:0.3f}'.format(sensor.t_fine))
print ('Temp F     = {0:0.3f} deg C'.format(farenheight))
print ('Temp C     = {0:0.3f} deg C'.format(degrees))
print ('Pressure  = {0:0.2f} hPa'.format(hectopascals))
print ('US Pressure = {0:0.2f} inHg'.format(inmercury))
print ('Humidity  = {0:0.2f} %'.format(humidity))

if humidity is not None and degrees is not None:
    h = httplib2.Http()
    myStr = 'Temp = {0:0.1f}F {1:0.1f}c Humidity = {2:0.1f}%'.format((((degrees *9)/5) + 32),degrees , humidity)
    myStr = myStr.replace(' ','%20')
    resp, content = h.request("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20'"
                              + myStr + "',Last_Active%20=%20NOW()%20,LastCheck%20=%20NOW()%20WHERE%20Equipment=%20'TMS151_RPI'%20and%20System%20%20=%20'Temp_Outside'", "GET")
    #print ("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20'" + myStr + "',Last_Active%20=%20NOW()%20,LastCheck%20=%20NOW()%20WHERE%20Equipment=%20'Coop_RPI'%20and%20System%20%20=%20'Temp_Coop'")
    print (str(round(humidity,2)))
    reqstr = "http://192.168.0.159/wd-db.php?sqlcmd=INSERT%20INTO%20Environment%20(`Sensor`,%20`datetime`,%20`Temperature`,%20`Humidity`,%20`Barometer`)%20VALUES%20('2',%20NOW(),%20'" + format(str(farenheight)) +"',%20'" + str(round(humidity,2)) + "',%20'" + str(round(inmercury,2)) + "')"
    resp, content = h.request(reqstr , "GET")
    print(reqstr.replace("%20", " "))
else:
    h = httplib2.Http()
    print ('Failed to get reading. Try again!')
    resp, content = h.request("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20'Fail_to_Read',Last_Active%20=%20NOW()%20,LastCheck%20=%20NOW()%20WHERE%20Equipment=%20'TMS151_RPI'%20and%20System%20%20=%20'Temp_Outside'", "GET")

init.d entry for daemon control

ActionScript
This is the init.d entry that starts the frontlight program on system start and stops the code when needed
#! /bin/sh
# /etc/init.d/blah
#
### BEGIN INIT INFO
# Provides: FrontLight
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO

# Some things that run always
#python /mnt/code/frontlight/killfront.py
#python /mnt/code/frontlight/frontlight.py

case "$1" in
     start)
            echo "Starting front light"
           python /mnt/code/frontlight/frontlight.py &
     ;;
     stop)
           echo "Stopping front light"
           python /mnt/code/frontlight/killfront.py
     ;;
   *)
      echo "Usage: /etc/init.d/frontlight {start|stop}"
      exit 1
      ;;
esac
exit 0

Main code block for the Front Light program

Python
This is a multi-threaded python program that monitors the inputs and controls the light
import psutil
import os
import pifacedigitalio
from time import sleep
import time
import mysql.connector
from multiprocessing import Process
import pytz
import datetime
import RPi.GPIO as GPIO
import httplib2
from astral import Astral
a = Astral()

print("starting process")
cnx = mysql.connector.connect(user='light', password='hello',
                              host='localhost',
                              database='frontlight')
cursor = cnx.cursor()
query = ("SELECT `pid` as 'pid'FROM `processes`")
print(query)
cursor.execute(query)
results = cursor.fetchall()
count = cursor.rowcount
cursor.close()
cnx.close()
if count > 0:
    for i in results:
        try:
            print(i[0])
            tmpint = int(i[0])
            if (tmpint <> 0):
                p = psutil.Process(tmpint)
                p.kill()
        except Exception as e:
            print("Error" + str(e))
        cnx = mysql.connector.connect(user='light', password='hello',
                              host='localhost',
                              database='frontlight')
        cursor = cnx.cursor()
        query = ("DELETE FROM `processes` WHERE `pid` = '" + str(tmpint) + "'" )
        print(query)
        cursor.execute(query)
        cnx.commit()
        cursor.close()
        cnx.close()
else:
    print("no processes")


def input1():
    pfd = pifacedigitalio.PiFaceDigital()
    h = httplib2.Http()
    try:
        try:
            while True:
                sleep(.5)
                if pfd.switches[0].value > 0:
                    debounce = 0
                    #sleep(.5)
                    #if pfd.switches[0].value == 0:
                    #    debounce  = 1
                    #sleep(.5)
                    #if pfd.switches[0].value == 0:
                    #    debounce  = debounce  +  1
                    #sleep(.5)
                    if pfd.switches[0].value> 0:
                        if debounce < 2:
                            print("on pressed")
                            pfd.relays[0].value = 1
                            (resp, content) = \
                                h.request("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20'"
                                            + "Switched%20Light%20On',Last_Active%20=%20NOW()%20,Active%20=%20'1'%20WHERE%20Equipment=%20'Front_RPI'%20and%20System%20%20=%20'"
                                            + "PIR_Front_Light'", 'GET')
                            sleep(3)
        except TypeError as exc:
            print (str(exc))
            raise KeyboardInterrupt


    except (KeyboardInterrupt, SystemExit):
        print("\n Ending Process")

def input2():
    pfd = pifacedigitalio.PiFaceDigital()
    h = httplib2.Http()
    try:
        try:
            while True:
                sleep(.5)
                if pfd.switches[1].value > 0:
                    debounce = 0
                    #sleep(.5)
                    #if pfd.switches[1].value == 0:
                    #    debounce  = 1
                    #sleep(.5)
                    #if pfd.switches[1].value == 0:
                    #    debounce  = debounce  +  1
                    #sleep(.5)
                    if pfd.switches[1].value> 0:
                        if debounce < 2:
                            print("off pressed")
                            pfd.relays[0].value = 0
                            (resp, content) = \
                                h.request("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20'"
                                            + "%20Switched%20Light%20Off',Last_Active%20=%20NOW()%20,Active%20=%20'1'%20WHERE%20Equipment=%20'Front_RPI'%20and%20System%20%20=%20'"
                                            + "PIR_Front_Light'", 'GET')
                            sleep(3)
        except TypeError as exc:
            print (str(exc))
            raise KeyboardInterrupt


    except (KeyboardInterrupt, SystemExit):
        print("\n Ending Process")

def pirthread():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    pfd = pifacedigitalio.PiFaceDigital()
    pir_id = "PIR_Front_Light"
    pir_no = int(18)
    lighton = 'PIR_Front_Light_On'
    lightoff = 'PIR_Front_Light_Off'
    debounce = False
    h = httplib2.Http()
    ##############set up times
    city = a['Seattle']
    city_name = 'Tiger Mountain'
    print('Information for %s/%s\n' % (city_name, city.region))
    timezone = city.timezone
    print('Timezone: %s' % timezone)
    mylocal = pytz.timezone(timezone)
    city.latitude = 47.473436
    city.longitude = -122.015253
    sun = city.sun(date=datetime.date.today(), local=True)
    mysunset = sun['sunset']
    mysunrise = sun['sunrise']
    ########### now I can check if it is daylight out
    print("my pid is " + str(os.getpid()))
    while True:
            try:
                if not(debounce):
                    print(pir_id + ' waiting for input ' + str(pir_no) \
                        + ' at ' + str(time.strftime('%H:%M:%S')))

                    # print(str(pir_no) + " is " + str(GPIO.input(pir_no)))
                debounce = False
                GPIO.wait_for_edge(pir_no, GPIO.RISING)
                time.sleep(.2)
                mynow = datetime.datetime.now(mylocal)
                # added code to check to insure we are on the same day
                if mynow.day != mysunset.day:
                    sun = city.sun(date=datetime.date.today(), local=True)
                    mysunset = sun['sunset']
                    mysunrise = sun['sunrise']
                if (mynow > mysunrise) and (mynow < mysunset):
                    print("Its daylight")

                    mydiff = mysunset - mynow
                    (resp, content) = \
                        h.request("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20'"
                                    + "FrontLight%20Sleeping%20till%20sunset',Last_Active%20=%20NOW()%20,Active%20=%20'0'%20WHERE%20Equipment=%20'Front_RPI'%20and%20System%20%20=%20'"
                                    + "PIR_Front_Light'", 'GET')

                    #print(mydiff.seconds)
                    #time.sleep(mydiff.seconds)
                    time.sleep(5)
                    #(resp, content) = \
                    #    h.request("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20'"
                    #                + id
                    #                + "%20ReActivated%20at%20sunset',Last_Active%20=%20NOW()%20,Active%20=%20'0'%20WHERE%20Equipment=%20'Front_RPI'%20and%20System%20%20=%20'"
                    #                + "PIR_Front_Light'", 'GET')
                else:
                    if GPIO.input(pir_no):
                        print ('Turning on FrontLight')
                        print("PIR Detect")
                        pfd.relays[0].value = 1
                        (resp, content) = \
                            h.request('http://192.168.0.159/getfront.php', 'GET')
                        if  (content.decode() != "Switched Light On"):
                            (resp, content) = \
                                h.request("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20'"
                                            + lighton
                                            + "',Last_Active%20=%20NOW()%20,LastCheck%20=%20NOW()%20WHERE%20Equipment=%20'Front_RPI'%20and%20System%20%20=%20'PIR_Front_Light'"
                                            , 'GET')
                        else:
                            print("No Update")
                        (resp, content) = \
                            h.request("http://192.168.0.159/wd-db.php?sqlcmd=INSERT%20INTO%20`pir_alarms`(`pir`,%20`alarm`)%20VALUES%20('"
                                        + lighton + "',%20NOW())", 'GET')
                        print (lighton)

        #                with open("/var/log/pir_log", "a") as f:
        #                    f.write( str(time.strftime("%m-%d %H:%M:%S")) + " - " + pir_id + chr(13) + chr(10))

                        time.sleep(3)
                        (resp, content) = \
                            h.request('http://192.168.0.159/getfront.php', 'GET')
                        print (content.decode())
                        if  (content.decode() == lighton):
                            print ("Match")
                            print ( 'PIR_Front_Light off ' )
                            pfd.relays[0].value = 0
                            h.request("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20'"
                                        + "PIR_Front_Light"
                                        + "%20off',Last_Inactive%20=%20NOW()%20,Active%20=%20'0'%20WHERE%20Equipment=%20'Front_RPI'%20and%20System%20%20=%20'"
                                        + "PIR_Front_Light'", 'GET')
                            (resp, content) = \
                            (resp, content) = \
                                h.request("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20'"
                                            + lightoff
                                            + "',Last_Inactive%20=%20NOW()%20,LastCheck%20=%20NOW()%20WHERE%20Equipment=%20'Front_RPI'%20and%20System%20%20=%20'PIR_Front_Light'"
                                            )
                        else:
                            print (content.decode() + "<>" + lighton)
                else:
                    debounce = True
                GPIO.remove_event_detect(pir_no)
            except TypeError as exc:
                print (str(exc))
                print ('' + pir_id)
                (resp, content) = \
                h.request("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Action_Formula%20=%20'"
                + " shut down" + str(exc)
                + "'%20WHERE%20Equipment=%20'Front_RPI'%20and%20System%20%20=%20'"
                + "PIR_Front_Light'", 'GET')
                GPIO.cleanup()
                break
    print ('' + pir_id)
    (resp, content) = \
    h.request("http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Action_Formula%20=%20'"
    + " shut down"
    + "'%20WHERE%20Equipment=%20'Front_RPI'%20and%20System%20%20=%20'"
    + "PIR_Front_Light'", 'GET')
    GPIO.cleanup()

process_list = []
p1 = Process(target=input1, args=())
process_list.append(p1)
p2 = Process(target=input2, args=())
process_list.append(p2)
p3 = Process(target=pirthread, args=())
process_list.append(p3)
try:
    print("Initializing")
    myPID = os.getpid()
    print("myid is " + str(myPID))
    p = psutil.Process(myPID)
    print(p.cmdline())
    cnx = mysql.connector.connect(user='light', password='hello',
                                  host='localhost',
                                  database='frontlight')
    cursor = cnx.cursor()
    query = ("INSERT INTO `processes`(`pid`, `datetime`) VALUES ('" + str(myPID) + "', NOW())")
    print(query)
    cursor.execute(query)
    cnx.commit()
    cursor.close()
    cnx.close()

    for Process in process_list:
        print("Joining")
        Process.start()
        cnx = mysql.connector.connect(user='light', password='hello',
                                host='localhost',
                                database='frontlight')
        cursor = cnx.cursor()
        query = ("INSERT INTO `processes`(`pid`, `datetime`) VALUES ('" + str(Process.ident) + "', NOW())")
        print(query)
        cursor.execute(query)
        cnx.commit()
        cursor.close()
        cnx.close()
        print ( str(Process.ident))


    for Process in process_list:
        Process.join()
        print("process")

except (KeyboardInterrupt, SystemExit):
    for Process in process_list:
        Process.terminate()
    mcp.gpioa.value = mcp.gpioa.value & 227
    GPIO.cleanup()
    print ('''

 Started PIR daemons

''')

Program to kill the main program

Python
The main program can leave behind processes so we store the process numbers on start and this program stops them and turns off the light
import psutil
import os
import pifacedigitalio
from time import sleep
import mysql.connector

cnx = mysql.connector.connect(user='light', password='hello',
                              host='localhost',
                              database='frontlight')
cursor = cnx.cursor()
query = ("SELECT `pid` as 'pid'FROM `processes`")
print(query)
cursor.execute(query)
results = cursor.fetchall()
count = cursor.rowcount
cursor.close()
cnx.close()
if count > 0:
    for i in results:
        try:
            print(i[0])
            tmpint = int(i[0])
            if tmpint <> 0:
                p = psutil.Process(tmpint)
                p.kill()
        except Exception as e:
            print("Error" + str(e))
        cnx = mysql.connector.connect(user='light', password='hello',
                              host='localhost',
                              database='frontlight')
        cursor = cnx.cursor()
        query = ("DELETE FROM `processes` WHERE `pid` = '" + str(tmpint) + "'" )
        print(query)
        cursor.execute(query)
        cnx.commit()
        cursor.close()
        cnx.close()
else:
    print("no processes")
pfd = pifacedigitalio.PiFaceDigital()
pfd.relays[0].value = 0
print("shutoff")

PHP code to turn light on

PHP
The web interface calls this short PHP entry to turn on the light
<?php
use Pkj\Raspberry\PiFace\PiFaceCommon;

use Pkj\Raspberry\PiFace\PiFaceDigital;
require __DIR__ . '/vendor/autoload.php';
dl("spi.so");


// Init anew PiFaceDigital object. Note that Spi extension must be compiled and added!

if (!class_exists('\Spi')) {
    echo "Error";
	die ("Spi extension must be installed (https://github.com/frak/php_spi)/n");
}

$dev = PiFaceDigital::create();

// Run once.
$dev->init();
echo "<center>Turned front light on</center>";
?>

PHP code to turn light off

PHP
This is called by the web interface to turn off the light
<?php
use Pkj\Raspberry\PiFace\PiFaceCommon;

use Pkj\Raspberry\PiFace\PiFaceDigital;
require __DIR__ . '/vendor/autoload.php';
dl("spi.so");


// Init anew PiFaceDigital object. Note that Spi extension must be compiled and added!

if (!class_exists('\Spi')) {
    echo "Error";
	die ("Spi extension must be installed (https://github.com/frak/php_spi)/n");
}

$dev = PiFaceDigital::create();

// Run once.
$dev->init();
echo "<center>Turned front light off</center>";
?>

Credits

Doug Wyman

Doug Wyman

3 projects • 15 followers
Been playing with computers since 1962. Still learning.

Comments