Просмотр исходного кода

Add a POSTMOTION mode to avoid rapid decay when coming back to PREMOTION

Zachary Kotlarek 12 лет назад
Родитель
Сommit
6ce5a0ca1b
1 измененных файлов с 32 добавлено и 21 удалено
  1. 32 21
      dmx/stairs.pl

+ 32 - 21
dmx/stairs.pl

@@ -9,13 +9,15 @@ use lib dirname(abs_path($0));
 use DMX;
 
 # User config
-my $MOTION_TIMEOUT = 30;
-my %DIM            = (
-	'OFF'       => [ { 'channel' => 3, 'value' => 0,   'time' => 60000 }, ],
-	'PREMOTION' => [ { 'channel' => 3, 'value' => 32,  'time' => 2500  }, ],
-	'MOTION'    => [ { 'channel' => 3, 'value' => 192, 'time' => 750   }, ],
-	'BRIGHT'    => [ { 'channel' => 3, 'value' => 255, 'time' => 1000  }, ],
-	'ERROR'     => [ { 'channel' => 3, 'value' => 255, 'time' => 100   }, ],
+my $MOTION_TIMEOUT     = 30;
+my $POSTMOTION_TIMEOUT = 60;
+my %DIM                = (
+	'OFF'        => [ { 'channel' => 3, 'value' => 0,   'time' => 60000 }, ],
+	'PREMOTION'  => [ { 'channel' => 3, 'value' => 32,  'time' => 2500 }, ],
+	'MOTION'     => [ { 'channel' => 3, 'value' => 192, 'time' => 750 }, ],
+	'POSTMOTION' => [ { 'channel' => 3, 'value' => 32,  'time' => $POST_MOTION_TIMEOUT * 1000 }, ],
+	'BRIGHT'     => [ { 'channel' => 3, 'value' => 255, 'time' => 1000 }, ],
+	'ERROR'      => [ { 'channel' => 3, 'value' => 255, 'time' => 100 }, ],
 );
 
 # App config
@@ -33,13 +35,14 @@ if ($ENV{'DEBUG'}) {
 }
 
 # State
-my $state     = 'OFF';
-my $stateLast = $state;
-my %exists    = ();
-my %mtime     = ();
-my $pushLast  = 0;
-my $pullLast  = time();
-my $update    = 0;
+my $state      = 'OFF';
+my $stateLast  = $state;
+my %exists     = ();
+my %mtime      = ();
+my $pushLast   = 0;
+my $pullLast   = time();
+my $update     = 0;
+my $lastMotion = 0;
 
 # Always force lights into ERROR at launch
 $state = 'ERROR';
@@ -55,15 +58,18 @@ while (1) {
 	# State is calculated; use newState to gather data
 	my $newState = $state;
 
+	# Avoid repeated calls to time()
+	my $now = time();
+
 	# Wait for state updates
 	my $cmdState = DMX::readState($DELAY, \%exists, \%mtime, undef());
 	if (defined($cmdState)) {
 		$newState = $cmdState;
-		$pullLast = time();
+		$pullLast = $now;
 	}
 
 	# Die if we don't see regular updates
-	if (time() - $pullLast > $PULL_TIMEOUT) {
+	if ($now - $pullLast > $PULL_TIMEOUT) {
 		die('No update on state socket in past ' . $PULL_TIMEOUT . " seconds. Exiting...\n");
 	}
 
@@ -80,17 +86,22 @@ while (1) {
 	$stateLast = $state;
 	if ($exists{'BRIGHT'}) {
 		$newState = 'BRIGHT';
-	} elsif ($mtime{'MOTION_STAIRS'} > time() - $MOTION_TIMEOUT) {
-		$newState = 'MOTION';
+	} elsif ($mtime{'MOTION_STAIRS'} > $now - $MOTION_TIMEOUT) {
+		$newState   = 'MOTION';
+		$lastMotion = $now;
 	} elsif ($newState eq 'PLAY' || $newState eq 'PAUSE' || $newState eq 'MOTION') {
-		$newState = 'PREMOTION';
+		if ($now > $lastMotion + $POST_MOTION_TIMEOUT) {
+			$newState = 'PREMOTION';
+		} else {
+			$newState = 'POSTMOTION';
+		}
 	} else {
 		$newState = 'OFF';
 	}
 	$state = $newState;
 
 	# Force updates on a periodic basis
-	if (!$update && time() - $pushLast > $PUSH_TIMEOUT) {
+	if (!$update && $now - $pushLast > $PUSH_TIMEOUT) {
 		if ($DEBUG) {
 			print STDERR "Forcing periodic update\n";
 		}
@@ -112,7 +123,7 @@ while (1) {
 		DMX::applyDataset($DIM{$state}, $state, $OUTPUT_FILE);
 
 		# Update the push time
-		$pushLast = time();
+		$pushLast = $now;
 
 		# Clear the update flag
 		$update = 0;