Problem: The code below can't access the display when running as a service.
I have my raspi hooked up to a touch screen monitor in the kitchen and I've attached a Passive Infrared sensor to the GPIO pins. The idea is to allow the screen to sleep, but wake when someone is moving around it so that they can easily see the calendar/weather information.
From a functionality standpoint, the code below seems to work, but if I run it interactively, the monitor never actually sleeps. I managed to use xset to force it to sleep while testing.
When I run it as a service, the log looks like this:
2015-06-28 20:33:47,765 INFO Waking from sleep
2015-06-28 20:33:47,771 ERROR Traceback (most recent call last):
2015-06-28 20:33:47,773 ERROR File "/usr/local/bin/pir/pir.py", line 51, in MOTION
2015-06-28 20:33:47,775 ERROR d = dpms.DPMS(":0") # to use the current display, or alternatively DPMS(":1")
2015-06-28 20:33:47,777 ERROR Exception
2015-06-28 20:33:47,779 ERROR :
2015-06-28 20:33:47,781 ERROR Cannot open display
#!/usr/bin/env python
import RPi.GPIO as GPIO
import logging
import logging.handlers
import dpms, time
import sys
# Deafults
LOG_FILENAME = "/tmp/myservice.log"
LOG_LEVEL = logging.INFO # Could be e.g. "DEBUG" or "WARNING"
# Configure logging to log to a file, making a new file at midnight and keeping the last 3 day's data
# Give the logger a unique name (good practice)
logger = logging.getLogger(__name__)
# Set the log level to LOG_LEVEL
logger.setLevel(LOG_LEVEL)
# Make a handler that writes to a file, making a new file at midnight and keeping 3 backups
handler = logging.handlers.TimedRotatingFileHandler(LOG_FILENAME, when="midnight", backupCount=3)
# Format each log message like this
formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s')
# Attach the formatter to the handler
handler.setFormatter(formatter)
# Attach the handler to the logger
logger.addHandler(handler)
# Make a class we can use to capture stdout and sterr in the log
class MyLogger(object):
def __init__(self, logger, level):
"""Needs a logger and a logger level."""
self.logger = logger
self.level = level
def write(self, message):
# Only log if there is a message (not just a new line)
if message.rstrip() != "":
self.logger.log(self.level, message.rstrip())
# Replace stdout with logging to file at INFO level
sys.stdout = MyLogger(logger, logging.INFO)
# Replace stderr with logging to file at ERROR level
sys.stderr = MyLogger(logger, logging.ERROR)
GPIO.setmode(GPIO.BCM)
PIR_PIN = 7
GPIO.setup(PIR_PIN, GPIO.IN)
def MOTION(PIR_PIN):
print " Waking from sleep"
d = dpms.DPMS(":0") # to use the current display, or alternatively DPMS(":1")
d.Enable()
d.ForceLevel(dpms.DPMSModeOn)
print "PIR Module Test (CTRL+C to exit)"
time.sleep(2)
print "Ready"
try:
GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=MOTION)
while 1:
time.sleep(100)
except KeyboardInterrupt:
print " Quit"
GPIO.cleanup()