1

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()
0

It depends what you are using.

If it is PiTFT, then there is simpler way that should work: https://github.com/elParaguayo/PiTFT_Screen -package controlling pitft display backlight. Im not sure if it does turn off entirely without backlight, but You should be able to read win documentation which PIN does and edit that package to your liking.

However you're using HDMI diplay, then perhaps some more hardware-like solution would be ok? (http://raspi.tv/2015/hacking-hdmipi-power-switch) GPIO pins are easy to control and you cold solder some wire to display power button. It all depends on what vlotage does it work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.