My page on PIR sensing and the coop mentioned needing to have the PIRs on only after sundown.
The Raspberry Pi’s controlling code for the PIR units is written in Python.
After tying a few methods, I found Astral and the companion time zone
calculation in PYTZ.
Caveat. If the computer does not reset at midnight as mine does,
the code saved sunrisa and sunset will be a day behind and since the current
day’s sunrise and sunset are later than yesterday’s. the PIRs will be active.
A code change has been added to check this
I have added my own latitude and longitude. Seattle is close enough I would not have to do so
but I tend to be a bit anal when it comes to exact locations.
What follows is the Python code with the added Sunrise and Sunset calculations.
#!/usr/bin/python
# -*- coding: utf-8 -*-
from multiprocessing
import Process
import RPi.GPIO as GPIO
import httplib2
import pifacecommon.mcp23s17 as p
import os
import time
import datetime
import pytz
from astral import Astral
a =
Astral()
# This program reads PIR sensors and turns on or off a relay or relays depending on the
# values in the table.
# ==========NOTE!!! The relays this set controls are inverse logic.
# ===================i.e. an inactive output (high) on piface turns the relay on
# =================== and an active low turns it off. This is all dependant on the
# =================== relay board common negative being pulled low by an active
# =================== piface output on the relay board common negative.
# =================== thus on boot the relays are not activated. Until a low is presented
# =================== to the relay board common. Then any relay that does not have an active
# =================== piface output (low) is turned on so the board needs to be activated by
# =================== setting the common negative and both relay controls low at the same time.
# =================== print(“Setting Up”)
# =================== mcp.gpioa.value = mcp.gpioa.value | 28
# =================== print(“Activated GPIO binary 4,8 & 16”)
def pirthread(
id,
pir,
no,
andval,
orval,
):
pir_id = id
pir_no = int(no)
pir_high = int(andval) & 0xff
pir_low = int(orval) & 0xff
lighton = pir + ‘_Light_On‘
lightoff = pir + ‘_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)))
(resp, content) = \
h.request(“http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Action_Formula%20=%20′”
+ str(os.getpid())
+ “‘%20WHERE%20Equipment=%20’Coop_RPI’%20and%20System%20%20=%20′”
+ pir_id + “‘”, ‘GET’)
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′”
+ id
+ “%20Sleeping%20till%20sunset’,Last_Active%20=%20NOW()%20,Active%20=%20’0’%20WHERE%20Equipment=%20’Coop_RPI’%20and%20System%20%20=%20′”
+ pir_id + “‘”, ‘GET’)
print(mydiff.seconds)
time.sleep(mydiff.seconds)
else:
if GPIO.input(pir_no):
print (pir_id + ‘ setting output ‘ + str(pir_no) + ‘ high’)
mcp.gpioa.value = mcp.gpioa.value & pir_high
(resp, content) = \
h.request(“http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20′”
+ id
+ “%20Active’,Last_Active%20=%20NOW()%20,Active%20=%20’1’%20WHERE%20Equipment=%20’Coop_RPI’%20and%20System%20%20=%20′”
+ pir_id + “‘”, ‘GET’)
(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’Coop_RPI’%20and%20System%20%20=%20’Coop_Outside_Lights'” , ‘GET’)
(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(300)
(resp, content) = \
h.request(“http://192.168.0.159/wd-db.php?sqlcmd=UPDATE%20WD_Master%20SET%20Char_Value%20=%20′”
+ id
+ “%20Clear’,Last_Inactive%20=%20NOW()%20,Active%20=%20’0’%20WHERE%20Equipment=%20’Coop_RPI’%20and%20System%20%20=%20′”
+ pir_id + “‘”, ‘GET’)
(resp, content) = \
h.request(‘http://192.168.0.159/getlight.php’, ‘GET’)
print (content.decode())
if (content.decode() == lighton):
print (“Match”)
print (pir_id + ‘ setting output ‘ + str(pir_no) \
+ ‘ low’)
mcp.gpioa.value = mcp.gpioa.value | pir_low
(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’Coop_RPI’%20and%20System%20%20=%20’Coop_Outside_Lights'” )
else:
print (content.decode() + “<>” + lighton)
else:
debounce = True
GPIO.remove_event_detect(pir_no)
except:
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’Coop_RPI’%20and%20System%20%20=%20′”
+ p ir_id + “‘”, ‘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’Coop_RPI’%20and%20System%20%20=%20′”
+ pir_id + “‘”, ‘GET’)
GPIO.cleanup()
mcp = p.MCP23S17()
h = httplib2.Http()
print(“Setting Up”)
mcp.gpioa.value = mcp.gpioa.value | 28
print(“Activated GPIO binary 4,8 & 16”)
process_list = []
(resp, content) = h.request(“http://192.168.0.159/pir-threads.php”, “GET”)
process_values = content.decode().split(“|”)
for myvars in process_values:
if myvars > “”:
tmpvars = myvars.split(“,”)
GPIO.setmode(GPIO.BCM)
GPIO.setup(int(tmpvars[2].strip()), GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
p = Process(target=pirthread,
args=(tmpvars[0].strip(),
tmpvars[1].split()[0].strip(),
tmpvars[2].strip(),
tmpvars[3].strip(),
tmpvars[4].strip()))
process_list.append(p)
# print(tmpvars[0].strip())
# print(tmpvars[1].split()[0].strip())
# print(tmpvars[2].strip())
try:
for Process in process_list:
Process.start()
for Process
in process_list:
Process.join()
except (KeyboardInterrupt,
SystemExit):
for Process in process_list:
Process.terminate()
mcp.gpioa.value = mcp.gpioa.value & 227
GPIO.cleanup()
print (”’
Started PIR daemons
”’)