I'd appreciate suggestions if it isn't the best solution. It should work for others too.
Step 1 - Create scripts that manually turn off and on the HDMI
- create file hdmi_off.sh
- CODE: SELECT ALL
#!/bin/sh
#hdmi_off.sh - shell script to turn HDMI off - should work universially
tvservice -o
- create file hdmi_on.sh (make sure to set executable permissions on both - 'chmod 755 *sh')
- CODE: SELECT ALL
#!/bin/sh
#hdmi_on.sh - custom script to turn HDMI on
#get the current tv state
tvstate=`tvservice -s | grep HDMI | wc -l`
#only turn on if its not already on
if [ "$tvstate" -eq 0 ]
then
tvservice --explicit="DMT 87"
fbset -depth 8
fbset -depth 16
xrefresh
else
echo "HDMI already on";
fi
exit;
You should make sure these scripts work from the command line for you - all my other script does is call them, so if these do not work it will not work. Stop here until you get them working. You'll have to search the forums to find how to make your screen come on, and start displaying stuff.
Step 2 - Create a perl script to detect the screensaver state
Basically we can use "xscreensaver-command -watch" to follow text output of what xscreensaver is doing. What I do is detect when the screensaver becomes active, then start a timer to determine when to turn the screen off. It is a lot simpler if you just want the screen to power off immediately. But I wanted this dual off approach as it takes the screen longer to come on when its fully off.
- CODE: SELECT ALL
#!/usr/bin/perl
#check_screen_state.pl - perl script to monitor screen state, and turn HDMI on or off
use strict;
use warnings;
use threads;
use Thread::Queue;
$|=1;
my $counter=-1;
#time in seconds
my $time_to_power_off_screen = 1200; #20 minutes
my $hdmi_off_command = "/home/pi/screensaver/hdmi_off.sh";
my $hdmi_on_command = "/home/pi/screensaver/hdmi_on.sh";
#code to run a shell command in a thread, and get output from it
sub pipeCommand {
my $cmd = shift;
my $Q = new Thread::Queue;
async{
my $pid = open my $pipe, $cmd or die $!;
$Q->enqueue( $_ ) while <$pipe>;
$Q->enqueue( undef );
}->detach;
return $Q;
}
my $pipe = pipeCommand(
'xscreensaver-command -watch |'
) or die;
print_("Starting, waiting on input.\n");
while( 1 ) {
if( $pipe->pending ) {
my $line = $pipe->dequeue or last;
print_("$line");
if ($line =~ m/^(BLANK|LOCK)/) {
$counter = $time_to_power_off_screen;
} elsif ($line =~ m/^UNBLANK/) {
if($counter <= 0){
print_( "turn on\n");
print_( `$hdmi_on_command `);
}else{
print_("screen already on\n");
}
$counter=-1;
}
}
else {
sleep 1;
if($counter >0){
$counter--;
}
if($counter == 0){
$counter=-1;
print_( "turn off acter $time_to_power_off_screen seconds\n");
print_(`$hdmi_off_command`);
}
}
}
sub print_{
print "[".localtime(time) . "] @_";
}
Step 3 - make the script run all the time
Make an inittab entry to make the perl script run all the time ('sudo vi /etc/inittab' and add the line to the bottom
- CODE: SELECT ALL
hdmi:2345:respawn:/usr/bin/perl /home/pi/screensaver/check_screen_state.pl > /home/pi/screensaver/hdmi.log
Save the file, exit the editor, and then type 'sudo init q' to make the system re-read the file. 'ps -ef' should now list your script.
2 comments:
Please take a look here-
https://github.com/ramses0/xscreensaver-pi-hdmi
I started with Simon's idea and tightened it up a bit, made a package for debian.
cd xscreensaver-pi-hdmi && dpkg-buildpackage && sudo dpkg -i ../xscreensaver-pi-hdmi_*.deb
You'll need some extra packages prior (maybe apt-get install build-essential) or you can just copy/run the command directly from the bin directory, as it's a single self-contained script.
I'll try to get in touch with Simon directly and see where to take it.
--Robert
Well,The article is much informative which i was searching for
Enrgtech LTD
Post a Comment