Zachary Kotlarek 13 лет назад
Родитель
Сommit
a73829bdd1
6 измененных файлов с 182 добавлено и 327 удалено
  1. 111 0
      dmx/DMX.pm
  2. 14 66
      dmx/bias.pl
  3. 14 61
      dmx/fan.pl
  4. 15 68
      dmx/leds.pl
  5. 14 66
      dmx/overhead.pl
  6. 14 66
      dmx/rope.pl

+ 111 - 0
dmx/DMX.pm

@@ -0,0 +1,111 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use IO::Socket::UNIX;
+
+# Package name
+package DMX;
+
+# Debug
+my $DEBUG = 0;
+if ($ENV{'DEBUG'}) {
+	$DEBUG = 1;
+}
+
+# Config
+my $SOCK_TIMEOUT = 5;
+my $MAX_CMD_LEN  = 1024;
+my $TEMP_DIR     = `getconf DARWIN_USER_TEMP_DIR`;
+chomp($TEMP_DIR);
+my $DATA_DIR     = $TEMP_DIR . 'plexMonitor/';
+my $DMX_SOCK     = $DATA_DIR . 'DMX.socket';
+my $SUB_SOCK     = $DATA_DIR . 'STATE.socket';
+
+# DMX socket init
+sub dmxSock() {
+	my $dmx_fh = IO::Socket::UNIX->new(
+	        'Peer'    => $DMX_SOCK,
+	        'Type'    => IO::Socket::UNIX::SOCK_DGRAM,
+	        'Timeout' => $SOCK_TIMEOUT
+	) or die('Unable to open socket: ' . $DMX_SOCK . ": ${@}\n");
+	return $dmx_fh;
+}
+
+# Subscribe to state updates
+sub stateSubscribe($) {
+	my ($STATE_SOCK) = @_;
+
+	my $sub_fh = IO::Socket::UNIX->new(
+	        'Peer'    => $SUB_SOCK,
+	        'Type'    => IO::Socket::UNIX::SOCK_DGRAM,
+	        'Timeout' => $SOCK_TIMEOUT
+	) or die('Unable to open state subscription socket: ' . $SUB_SOCK . ": ${@}\n");
+	$sub_fh->send($STATE_SOCK)
+	  or die('Unable to subscribe: ' . $! . "\n");
+	shutdown($sub_fh, 2);
+	undef($sub_fh);
+}
+
+# State client socket init
+sub stateSocket($) {
+	my ($STATE_SOCK) = @_;
+
+	if (-e $STATE_SOCK) {
+	        unlink($STATE_SOCK);
+	}
+	my $state_fh = IO::Socket::UNIX->new(
+	        'Local' => $STATE_SOCK,
+	        'Type'  => IO::Socket::UNIX::SOCK_DGRAM
+	) or die('Unable to open state client socket: ' . $STATE_SOCK . ": ${@}\n");
+
+	my $select = IO::Select->new($state_fh)
+	  or die('Unable to select state client socket: ' . $STATE_SOCK . ": ${!}\n");
+	return $select;
+}
+
+# Parse the state->client comm string
+sub parseState($$) {
+	my ($fh, $exists) = @_;
+
+	# Grab the inbound text
+	my $text = undef();
+	$fh->recv($text, $MAX_CMD_LEN);
+
+	# Parse the string
+	my %tmp = ();
+	%{$exists} = ();
+	my ($cmdState, $exists_text) = $text =~ /^(\w+)(?:\s+\(([^\)]+)\))?/;
+	if (!defined($cmdState)) {
+		print STDERR 'State parse error: ' . $text . "\n";
+		next;
+	}
+	if (defined($exists_text)) {
+		foreach my $exists_val (split(/\s*,\s*/, $exists_text)) {
+			my ($name, $value) = $exists_val =~ /(\w+)\:(0|1)/;
+			if (!defined($name) || !defined($value)) {
+				print STDERR 'State parse error (exists): ' . $text . "\n";
+				next;
+			}
+			$exists->{$name} = $value;
+		}
+	}
+	if ($DEBUG) {
+		my @exists_tmp = ();
+		foreach my $key (keys(%{ $exists })) {
+			push(@exists_tmp, $key . ':' . $exists->{$key});
+		}
+		print STDERR 'Got state: ' . $cmdState . ' (' . join(', ', @exists_tmp) . ")\n";
+	}
+
+
+	# Translate INIT to OFF
+	if ($cmdState eq 'INIT') {
+		$cmdState = 'OFF';
+	}
+
+	# Return the state
+	return $cmdState;
+}
+
+# Always return true
+1;

+ 14 - 66
dmx/bias.pl

@@ -2,9 +2,14 @@
 use strict;
 use warnings;
 use IO::Select;
-use IO::Socket::UNIX;
 use File::Temp qw( tempfile );
 
+# Local modules
+use Cwd qw(abs_path);
+use File::Basename qw(dirname);
+use lib dirname(abs_path($0));
+use DMX;
+
 # Prototypes
 sub dim($);
 
@@ -25,14 +30,10 @@ my %DIM = (
 );
 
 # App config
-my $SOCK_TIMEOUT = 5;
 my $TEMP_DIR     = `getconf DARWIN_USER_TEMP_DIR`;
 chomp($TEMP_DIR);
 my $DATA_DIR     = $TEMP_DIR . 'plexMonitor/';
-my $DMX_SOCK     = $DATA_DIR . 'DMX.socket';
-my $SUB_SOCK     = $DATA_DIR . 'STATE.socket';
 my $STATE_SOCK   = $DATA_DIR . 'ROPE.socket';
-my $MAX_CMD_LEN  = 1024;
 my $PUSH_TIMEOUT = 20;
 my $PULL_TIMEOUT = $PUSH_TIMEOUT * 3;
 
@@ -49,38 +50,14 @@ if (!$DELAY) {
 }
 
 # Sanity check
-if (!-d $DATA_DIR || !-S $DMX_SOCK || !-S $SUB_SOCK) {
+if (!-d $DATA_DIR) {
 	die("Bad config\n");
 }
 
-# State socket init
-if (-e $STATE_SOCK) {
-	unlink($STATE_SOCK);
-}
-my $state_fh = IO::Socket::UNIX->new(
-	'Local' => $STATE_SOCK,
-	'Type'  => SOCK_DGRAM
-) or die('Unable to open socket: ' . $STATE_SOCK . ": ${@}\n");
-my $select = IO::Select->new($state_fh)
-  or die('Unable to select socket: ' . $STATE_SOCK . ": ${!}\n");
-
-# DMX socket init
-my $dmx_fh = IO::Socket::UNIX->new(
-	'Peer'    => $DMX_SOCK,
-	'Type'    => SOCK_DGRAM,
-	'Timeout' => $SOCK_TIMEOUT
-) or die('Unable to open socket: ' . $DMX_SOCK . ": ${@}\n");
-
-# Subscribe to state updates
-my $sub_fh = IO::Socket::UNIX->new(
-	'Peer'    => $SUB_SOCK,
-	'Type'    => SOCK_DGRAM,
-	'Timeout' => $SOCK_TIMEOUT
-) or die('Unable to open socket: ' . $SUB_SOCK . ": ${@}\n");
-$sub_fh->send($STATE_SOCK)
-  or die('Unable to subscribe: ' . $! . "\n");
-shutdown($sub_fh, 2);
-undef($sub_fh);
+# Sockets
+my $select = DMX::stateSocket($STATE_SOCK);
+DMX::stateSubscribe($STATE_SOCK);
+my $dmx_fh = DMX::dmxSock();
 
 # State
 my $state     = 'INIT';
@@ -105,37 +82,8 @@ while (1) {
 	my @ready_clients = $select->can_read($DELAY);
 	foreach my $fh (@ready_clients) {
 
-		# Grab the inbound text
-		my $text = undef();
-		$fh->recv($text, $MAX_CMD_LEN);
-
-		# Parse the string
-		%exists = ();
-		my ($cmdState, $exists_text) = $text =~ /^(\w+)\s+\(([^\)]+)\)/;
-		if (!defined($cmdState) || !defined($exists_text)) {
-			print STDERR 'State parse error: ' . $text . "\n";
-			next;
-		}
-		foreach my $exists (split(/\s*,\s*/, $exists_text)) {
-			my ($name, $value) = $exists =~ /(\w+)\:(0|1)/;
-			if (!defined($name) || !defined($value)) {
-				print STDERR 'State parse error (exists): ' . $text . "\n";
-				next;
-			}
-			$exists{$name} = $value;
-		}
-		if ($DEBUG) {
-			my @exists_tmp = ();
-			foreach my $key (keys(%exists)) {
-				push(@exists_tmp, $key . ':' . $exists{$key});
-			}
-			print STDERR 'Got state: ' . $cmdState . ' (' . join(', ', @exists_tmp) . ")\n";
-		}
-
-		# Translate INIT to OFF
-		if ($cmdState eq 'INIT') {
-			$cmdState = 'OFF';
-		}
+		# Read the global state
+		my $cmdState = DMX::parseState($fh, \%exists);
 
 		# Only accept valid states
 		if (!defined($DIM{$cmdState})) {
@@ -204,5 +152,5 @@ sub dim($) {
 
 	my $cmd = join(':', $args->{'channel'}, $args->{'time'}, $args->{'value'}, $args->{'delay'});
 	$dmx_fh->send($cmd)
-	  or die('Unable to write command to socket: ' . $DMX_SOCK . ': ' . $cmd . ": ${!}\n");
+	  or die('Unable to write command to DMX socket: ' . $cmd . ": ${!}\n");
 }

+ 14 - 61
dmx/fan.pl

@@ -2,9 +2,14 @@
 use strict;
 use warnings;
 use IO::Select;
-use IO::Socket::UNIX;
 use File::Temp qw( tempfile );
 
+# Local modules
+use Cwd qw(abs_path);
+use File::Basename qw(dirname);
+use lib dirname(abs_path($0));
+use DMX;
+
 # Prototypes
 sub dim($);
 
@@ -19,14 +24,10 @@ my %DIM = (
 );
 
 # App config
-my $SOCK_TIMEOUT = 5;
 my $TEMP_DIR     = `getconf DARWIN_USER_TEMP_DIR`;
 chomp($TEMP_DIR);
 my $DATA_DIR     = $TEMP_DIR . 'plexMonitor/';
-my $DMX_SOCK     = $DATA_DIR . 'DMX.socket';
-my $SUB_SOCK     = $DATA_DIR . 'STATE.socket';
 my $STATE_SOCK   = $DATA_DIR . 'ROPE.socket';
-my $MAX_CMD_LEN  = 1024;
 my $PUSH_TIMEOUT = 20;
 my $PULL_TIMEOUT = $PUSH_TIMEOUT * 3;
 
@@ -43,38 +44,14 @@ if (!$DELAY) {
 }
 
 # Sanity check
-if (!-d $DATA_DIR || !-S $DMX_SOCK || !-S $SUB_SOCK) {
+if (!-d $DATA_DIR) {
 	die("Bad config\n");
 }
 
-# State socket init
-if (-e $STATE_SOCK) {
-	unlink($STATE_SOCK);
-}
-my $state_fh = IO::Socket::UNIX->new(
-	'Local' => $STATE_SOCK,
-	'Type'  => SOCK_DGRAM
-) or die('Unable to open socket: ' . $STATE_SOCK . ": ${@}\n");
-my $select = IO::Select->new($state_fh)
-  or die('Unable to select socket: ' . $STATE_SOCK . ": ${!}\n");
-
-# DMX socket init
-my $dmx_fh = IO::Socket::UNIX->new(
-	'Peer'    => $DMX_SOCK,
-	'Type'    => SOCK_DGRAM,
-	'Timeout' => $SOCK_TIMEOUT
-) or die('Unable to open socket: ' . $DMX_SOCK . ": ${@}\n");
-
-# Subscribe to state updates
-my $sub_fh = IO::Socket::UNIX->new(
-	'Peer'    => $SUB_SOCK,
-	'Type'    => SOCK_DGRAM,
-	'Timeout' => $SOCK_TIMEOUT
-) or die('Unable to open socket: ' . $SUB_SOCK . ": ${@}\n");
-$sub_fh->send($STATE_SOCK)
-  or die('Unable to subscribe: ' . $! . "\n");
-shutdown($sub_fh, 2);
-undef($sub_fh);
+# Sockets
+my $select = DMX::stateSocket($STATE_SOCK);
+DMX::stateSubscribe($STATE_SOCK);
+my $dmx_fh = DMX::dmxSock();
 
 # State
 my $state     = 'INIT';
@@ -99,32 +76,8 @@ while (1) {
 	my @ready_clients = $select->can_read($DELAY);
 	foreach my $fh (@ready_clients) {
 
-		# Grab the inbound text
-		my $text = undef();
-		$fh->recv($text, $MAX_CMD_LEN);
-
-		# Parse the string
-		%exists = ();
-		my ($cmdState, $exists_text) = $text =~ /^(\w+)\s+\(([^\)]+)\)/;
-		if (!defined($cmdState) || !defined($exists_text)) {
-			print STDERR 'State parse error: ' . $text . "\n";
-			next;
-		}
-		foreach my $exists (split(/\s*,\s*/, $exists_text)) {
-			my ($name, $value) = $exists =~ /(\w+)\:(0|1)/;
-			if (!defined($name) || !defined($value)) {
-				print STDERR 'State parse error (exists): ' . $text . "\n";
-				next;
-			}
-			$exists{$name} = $value;
-		}
-		if ($DEBUG) {
-			my @exists_tmp = ();
-			foreach my $key (keys(%exists)) {
-				push(@exists_tmp, $key . ':' . $exists{$key});
-			}
-			print STDERR 'Got state: ' . $cmdState . ' (' . join(', ', @exists_tmp) . ")\n";
-		}
+		# Read the global state
+		my $cmdState = DMX::parseState($fh, \%exists);
 
 		# We don't really care about the master state for the fan
 		# But we have to parse the exists records, so we might as well grab it
@@ -194,5 +147,5 @@ sub dim($) {
 
 	my $cmd = join(':', $args->{'channel'}, $args->{'time'}, $args->{'value'}, $args->{'delay'});
 	$dmx_fh->send($cmd)
-	  or die('Unable to write command to socket: ' . $DMX_SOCK . ': ' . $cmd . ": ${!}\n");
+	  or die('Unable to write command to DMX socket: ' . $cmd . ": ${!}\n");
 }

+ 15 - 68
dmx/leds.pl

@@ -3,10 +3,15 @@ use strict;
 use warnings;
 use IO::Select;
 use Math::Random;
-use IO::Socket::UNIX;
 use File::Temp qw( tempfile );
 use Time::HiRes qw( usleep );
 
+# Local modules
+use Cwd qw(abs_path);
+use File::Basename qw(dirname);
+use lib dirname(abs_path($0));
+use DMX;
+
 # Prototypes
 sub dim($);
 sub red_alert();
@@ -54,14 +59,10 @@ my %DIM            = (
 );
 
 # App config
-my $SOCK_TIMEOUT = 5;
 my $TEMP_DIR     = `getconf DARWIN_USER_TEMP_DIR`;
 chomp($TEMP_DIR);
 my $DATA_DIR     = $TEMP_DIR . 'plexMonitor/';
-my $DMX_SOCK     = $DATA_DIR . 'DMX.socket';
-my $SUB_SOCK     = $DATA_DIR . 'STATE.socket';
 my $STATE_SOCK   = $DATA_DIR . 'LED.socket';
-my $MAX_CMD_LEN  = 1024;
 my $PUSH_TIMEOUT = 20;
 my $PULL_TIMEOUT = 60;
 my %CHANNEL_ADJ  = (
@@ -91,38 +92,14 @@ if (!$DELAY) {
 }
 
 # Sanity check
-if (!-d $DATA_DIR || !-S $DMX_SOCK || !-S $SUB_SOCK) {
+if (!-d $DATA_DIR) {
 	die("Bad config\n");
 }
 
-# State socket init
-if (-e $STATE_SOCK) {
-	unlink($STATE_SOCK);
-}
-my $state_fh = IO::Socket::UNIX->new(
-	'Local' => $STATE_SOCK,
-	'Type'  => SOCK_DGRAM
-) or die('Unable to open socket: ' . $STATE_SOCK . ": ${@}\n");
-my $select = IO::Select->new($state_fh)
-  or die('Unable to select socket: ' . $STATE_SOCK . ": ${!}\n");
-
-# DMX socket init
-my $dmx_fh = IO::Socket::UNIX->new(
-	'Peer'    => $DMX_SOCK,
-	'Type'    => SOCK_DGRAM,
-	'Timeout' => $SOCK_TIMEOUT
-) or die('Unable to open socket: ' . $DMX_SOCK . ": ${@}\n");
-
-# Subscribe to state updates
-my $sub_fh = IO::Socket::UNIX->new(
-	'Peer'    => $SUB_SOCK,
-	'Type'    => SOCK_DGRAM,
-	'Timeout' => $SOCK_TIMEOUT
-) or die('Unable to open socket: ' . $SUB_SOCK . ": ${@}\n");
-$sub_fh->send($STATE_SOCK)
-  or die('Unable to subscribe: ' . $! . "\n");
-shutdown($sub_fh, 2);
-undef($sub_fh);
+# Sockets
+my $select = DMX::stateSocket($STATE_SOCK);
+DMX::stateSubscribe($STATE_SOCK);
+my $dmx_fh = DMX::dmxSock();
 
 # State
 my $state       = 'INIT';
@@ -156,39 +133,8 @@ while (1) {
 	my @ready_clients = $select->can_read($DELAY);
 	foreach my $fh (@ready_clients) {
 
-		# Grab the inbound text
-		my $text = undef();
-		$fh->recv($text, $MAX_CMD_LEN);
-
-		# Parse the string
-		%exists = ();
-		my ($cmdState, $exists_text) = $text =~ /^(\w+)(?:\s+\(([^\)]+)\))?/;
-		if (!defined($cmdState)) {
-			print STDERR 'State parse error: ' . $text . "\n";
-			next;
-		}
-		if (defined($exists_text)) {
-			foreach my $exists (split(/\s*,\s*/, $exists_text)) {
-				my ($name, $value) = $exists =~ /(\w+)\:(0|1)/;
-				if (!defined($name) || !defined($value)) {
-					print STDERR 'State parse error (exists): ' . $text . "\n";
-					next;
-				}
-				$exists{$name} = $value;
-			}
-		}
-		if ($DEBUG) {
-			my @exists_tmp = ();
-			foreach my $key (keys(%exists)) {
-				push(@exists_tmp, $key . ':' . $exists{$key});
-			}
-			print STDERR 'Got state: ' . $cmdState . ' (' . join(', ', @exists_tmp) . ")\n";
-		}
-
-		# Translate INIT to OFF
-		if ($cmdState eq 'INIT') {
-			$cmdState = 'OFF';
-		}
+		# Read the global state
+		my $cmdState = DMX::parseState($fh, \%exists);
 
 		# Only accept valid states
 		if (!defined($DIM{$cmdState}) && !defined($EFFECTS{$cmdState})) {
@@ -353,9 +299,10 @@ sub dim($) {
 		$value = 0;
 	}
 
+	# Send the command
 	my $cmd = join(':', $args->{'channel'}, int($args->{'time'}), $value, int($args->{'delay'}));
 	$dmx_fh->send($cmd)
-	  or die('Unable to write command to socket: ' . $DMX_SOCK . ': ' . $cmd . ": ${!}\n");
+	  or die('Unable to write command to DMX socket: ' . $cmd . ": ${!}\n");
 }
 
 # ======================================

+ 14 - 66
dmx/overhead.pl

@@ -2,9 +2,14 @@
 use strict;
 use warnings;
 use IO::Select;
-use IO::Socket::UNIX;
 use File::Temp qw( tempfile );
 
+# Local modules
+use Cwd qw(abs_path);
+use File::Basename qw(dirname);
+use lib dirname(abs_path($0));
+use DMX;
+
 # Prototypes
 sub dim($);
 
@@ -28,14 +33,10 @@ my %DIM = (
 );
 
 # App config
-my $SOCK_TIMEOUT = 5;
 my $TEMP_DIR     = `getconf DARWIN_USER_TEMP_DIR`;
 chomp($TEMP_DIR);
 my $DATA_DIR     = $TEMP_DIR . 'plexMonitor/';
-my $DMX_SOCK     = $DATA_DIR . 'DMX.socket';
-my $SUB_SOCK     = $DATA_DIR . 'STATE.socket';
 my $STATE_SOCK   = $DATA_DIR . 'ROPE.socket';
-my $MAX_CMD_LEN  = 1024;
 my $PUSH_TIMEOUT = 20;
 my $PULL_TIMEOUT = $PUSH_TIMEOUT * 3;
 
@@ -52,38 +53,14 @@ if (!$DELAY) {
 }
 
 # Sanity check
-if (!-d $DATA_DIR || !-S $DMX_SOCK || !-S $SUB_SOCK) {
+if (!-d $DATA_DIR) {
 	die("Bad config\n");
 }
 
-# State socket init
-if (-e $STATE_SOCK) {
-	unlink($STATE_SOCK);
-}
-my $state_fh = IO::Socket::UNIX->new(
-	'Local' => $STATE_SOCK,
-	'Type'  => SOCK_DGRAM
-) or die('Unable to open socket: ' . $STATE_SOCK . ": ${@}\n");
-my $select = IO::Select->new($state_fh)
-  or die('Unable to select socket: ' . $STATE_SOCK . ": ${!}\n");
-
-# DMX socket init
-my $dmx_fh = IO::Socket::UNIX->new(
-	'Peer'    => $DMX_SOCK,
-	'Type'    => SOCK_DGRAM,
-	'Timeout' => $SOCK_TIMEOUT
-) or die('Unable to open socket: ' . $DMX_SOCK . ": ${@}\n");
-
-# Subscribe to state updates
-my $sub_fh = IO::Socket::UNIX->new(
-	'Peer'    => $SUB_SOCK,
-	'Type'    => SOCK_DGRAM,
-	'Timeout' => $SOCK_TIMEOUT
-) or die('Unable to open socket: ' . $SUB_SOCK . ": ${@}\n");
-$sub_fh->send($STATE_SOCK)
-  or die('Unable to subscribe: ' . $! . "\n");
-shutdown($sub_fh, 2);
-undef($sub_fh);
+# Sockets
+my $select = DMX::stateSocket($STATE_SOCK);
+DMX::stateSubscribe($STATE_SOCK);
+my $dmx_fh = DMX::dmxSock();
 
 # State
 my $state     = 'INIT';
@@ -108,37 +85,8 @@ while (1) {
 	my @ready_clients = $select->can_read($DELAY);
 	foreach my $fh (@ready_clients) {
 
-		# Grab the inbound text
-		my $text = undef();
-		$fh->recv($text, $MAX_CMD_LEN);
-
-		# Parse the string
-		%exists = ();
-		my ($cmdState, $exists_text) = $text =~ /^(\w+)\s+\(([^\)]+)\)/;
-		if (!defined($cmdState) || !defined($exists_text)) {
-			print STDERR 'State parse error: ' . $text . "\n";
-			next;
-		}
-		foreach my $exists (split(/\s*,\s*/, $exists_text)) {
-			my ($name, $value) = $exists =~ /(\w+)\:(0|1)/;
-			if (!defined($name) || !defined($value)) {
-				print STDERR 'State parse error (exists): ' . $text . "\n";
-				next;
-			}
-			$exists{$name} = $value;
-		}
-		if ($DEBUG) {
-			my @exists_tmp = ();
-			foreach my $key (keys(%exists)) {
-				push(@exists_tmp, $key . ':' . $exists{$key});
-			}
-			print STDERR 'Got state: ' . $cmdState . ' (' . join(', ', @exists_tmp) . ")\n";
-		}
-
-		# Translate INIT to OFF
-		if ($cmdState eq 'INIT') {
-			$cmdState = 'OFF';
-		}
+		# Read the global state
+		my $cmdState = DMX::parseState($fh, \%exists);
 
 		# Only accept valid states
 		if (!defined($DIM{$cmdState})) {
@@ -216,5 +164,5 @@ sub dim($) {
 
 	my $cmd = join(':', $args->{'channel'}, $args->{'time'}, $args->{'value'}, $args->{'delay'});
 	$dmx_fh->send($cmd)
-	  or die('Unable to write command to socket: ' . $DMX_SOCK . ': ' . $cmd . ": ${!}\n");
+	  or die('Unable to write command to DMX socket: ' . $cmd . ": ${!}\n");
 }

+ 14 - 66
dmx/rope.pl

@@ -2,9 +2,14 @@
 use strict;
 use warnings;
 use IO::Select;
-use IO::Socket::UNIX;
 use File::Temp qw( tempfile );
 
+# Local modules
+use Cwd qw(abs_path);
+use File::Basename qw(dirname);
+use lib dirname(abs_path($0));
+use DMX;
+
 # Prototypes
 sub dim($);
 
@@ -56,14 +61,10 @@ my %DIM = (
 );
 
 # App config
-my $SOCK_TIMEOUT = 5;
 my $TEMP_DIR     = `getconf DARWIN_USER_TEMP_DIR`;
 chomp($TEMP_DIR);
 my $DATA_DIR     = $TEMP_DIR . 'plexMonitor/';
-my $DMX_SOCK     = $DATA_DIR . 'DMX.socket';
-my $SUB_SOCK     = $DATA_DIR . 'STATE.socket';
 my $STATE_SOCK   = $DATA_DIR . 'ROPE.socket';
-my $MAX_CMD_LEN  = 1024;
 my $PUSH_TIMEOUT = 20;
 my $PULL_TIMEOUT = $PUSH_TIMEOUT * 3;
 
@@ -80,38 +81,14 @@ if (!$DELAY) {
 }
 
 # Sanity check
-if (!-d $DATA_DIR || !-S $DMX_SOCK || !-S $SUB_SOCK) {
+if (!-d $DATA_DIR) {
 	die("Bad config\n");
 }
 
-# State socket init
-if (-e $STATE_SOCK) {
-	unlink($STATE_SOCK);
-}
-my $state_fh = IO::Socket::UNIX->new(
-	'Local' => $STATE_SOCK,
-	'Type'  => SOCK_DGRAM
-) or die('Unable to open socket: ' . $STATE_SOCK . ": ${@}\n");
-my $select = IO::Select->new($state_fh)
-  or die('Unable to select socket: ' . $STATE_SOCK . ": ${!}\n");
-
-# DMX socket init
-my $dmx_fh = IO::Socket::UNIX->new(
-	'Peer'    => $DMX_SOCK,
-	'Type'    => SOCK_DGRAM,
-	'Timeout' => $SOCK_TIMEOUT
-) or die('Unable to open socket: ' . $DMX_SOCK . ": ${@}\n");
-
-# Subscribe to state updates
-my $sub_fh = IO::Socket::UNIX->new(
-	'Peer'    => $SUB_SOCK,
-	'Type'    => SOCK_DGRAM,
-	'Timeout' => $SOCK_TIMEOUT
-) or die('Unable to open socket: ' . $SUB_SOCK . ": ${@}\n");
-$sub_fh->send($STATE_SOCK)
-  or die('Unable to subscribe: ' . $! . "\n");
-shutdown($sub_fh, 2);
-undef($sub_fh);
+# Sockets
+my $select = DMX::stateSocket($STATE_SOCK);
+DMX::stateSubscribe($STATE_SOCK);
+my $dmx_fh = DMX::dmxSock();
 
 # State
 my $state     = 'INIT';
@@ -136,37 +113,8 @@ while (1) {
 	my @ready_clients = $select->can_read($DELAY);
 	foreach my $fh (@ready_clients) {
 
-		# Grab the inbound text
-		my $text = undef();
-		$fh->recv($text, $MAX_CMD_LEN);
-
-		# Parse the string
-		%exists = ();
-		my ($cmdState, $exists_text) = $text =~ /^(\w+)\s+\(([^\)]+)\)/;
-		if (!defined($cmdState) || !defined($exists_text)) {
-			print STDERR 'State parse error: ' . $text . "\n";
-			next;
-		}
-		foreach my $exists (split(/\s*,\s*/, $exists_text)) {
-			my ($name, $value) = $exists =~ /(\w+)\:(0|1)/;
-			if (!defined($name) || !defined($value)) {
-				print STDERR 'State parse error (exists): ' . $text . "\n";
-				next;
-			}
-			$exists{$name} = $value;
-		}
-		if ($DEBUG) {
-			my @exists_tmp = ();
-			foreach my $key (keys(%exists)) {
-				push(@exists_tmp, $key . ':' . $exists{$key});
-			}
-			print STDERR 'Got state: ' . $cmdState . ' (' . join(', ', @exists_tmp) . ")\n";
-		}
-
-		# Translate INIT to OFF
-		if ($cmdState eq 'INIT') {
-			$cmdState = 'OFF';
-		}
+		# Read the global state
+		my $cmdState = DMX::parseState($fh, \%exists);
 
 		# Only accept valid states
 		if (!defined($DIM{$cmdState})) {
@@ -245,5 +193,5 @@ sub dim($) {
 
 	my $cmd = join(':', $args->{'channel'}, $args->{'time'}, $args->{'value'}, $args->{'delay'});
 	$dmx_fh->send($cmd)
-	  or die('Unable to write command to socket: ' . $DMX_SOCK . ': ' . $cmd . ": ${!}\n");
+	  or die('Unable to write command to DMX socket: ' . $cmd . ": ${!}\n");
 }