1-Wire with Leds and Beeps oscar

1-wire-with-leds-and-beeps / software / mod_buzzer.pl

6.0 KB · raw

use constant CHILD_LOG_VERBOSE => 1; # Activate verbose logging 

        $b_new_stdout = FileHandle->new(">> /var/log/".$fname."_child_buz.log") if CHILD_LOG_VERBOSE;
        $b_new_stdout->autoflush(1) if CHILD_LOG_VERBOSE;

# These values are cycles numbers: moltiply for Timer_resolution to obtain the timer duration
use constant LONG_DURATION_OFF => 6; # First prealarm duration : MUST BE PAIR 
use constant DURATION_OFF => 1; # Pause in second prealarm (quicker)
use constant DURATION_ON => 1; # Beep duration
use constant DURATION_FIRST_PREALARM => 15; # First prealarm duration (about 30" with Timer_Resolution = 250000)


# This var is intentionally very high to avoid unnecessary hi-speed loops when there is no pre/alarm.
# When the status change, the var is lowered.
# Note that the response (audible beep) is almost immediate, thanks to the use of signal interrupt :)
my $Timer_Resolution=15000000 ; # 1'000'000 = 1 sec.

# Legal values accepted in FIFO:
my @Commands = (
	"P",	#  - P - Start slow buzzing (it will be quick after DURATION_FIRST_PREALARM number of cycles)
	"A",	#  - A - Alarm, just buzzer fix to ON
	"S" );	#  - S - Silence please...

my $status=0;  # Alarm level: 0=Silence, 1=pre slow, 2=pre quick, 3=continuous;
my $tmp_command="S"; # Value from FIFO: it will be immediately cleaned
my $cycles=0; # Cycles Counter 
my $prealarm_duration=0; # Cycles counter of pre alarm 

# Boolean Switch of buzzer status (on, off)
# Denying the value 1 I get a "", so I have to work by difference: 1-Switch ...
my $buzzer=0;

my $owserver_buzz = undef; 

sub ow_connection {
	$owserver_buzz = OWNet->new( "localhost:4304" ) ;

	my $appo_dir_list = $owserver_buzz->dir('/') || die ("Cannot open OWNet connection");
	print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Initial dir_list to chech owserver connection: $appo_dir_list\n" if CHILD_LOG_VERBOSE;
	print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Succesfully connected to owserver.\n" if CHILD_LOG_VERBOSE;
}

# FIFO startup.
# It needs a first input, else it rest blocked here.
# Conseguently I don't need to define a starting value: I'll get it from the FIFO!
  unless (-p $FIFO_TO_CHILD_BUZ)
  {
    unlink $FIFO_TO_CHILD_BUZ;
    system('mknod', $FIFO_TO_CHILD_BUZ, 'p') && die "can't mknod ".$FIFO_TO_CHILD_BUZ.": $!";
  }

  open (FIFO, "< ".$FIFO_TO_CHILD_BUZ) || die "can't read ".$FIFO_TO_CHILD_BUZ.": $!";

  print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Child Buzzer started. \n" if CHILD_LOG_VERBOSE;

# Main !
  while (1) {

  	print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Child Buzzer looping. \n" if CHILD_LOG_VERBOSE;
	
	if ( $tmp_command ~~ @Commands ) {
		# Usually the buzzer is idle for a long time. When it is time to do something, the connection is gone for timeout.
		# So, if you receive a command, it's time to do so something: first of all, start a new connection!
		# This "problem" is related just to the buzzer, because both the led and the main are alwais reading/writing with owserver, 
		# keeping the connection alive... I lost a lot of time on this... :( :( :( 
		&ow_connection;
		if ( $tmp_command =~ /S/ ) {
        		# Silence Please!!!! :D
        		$owserver_buzz->write( BUZZER_ID , 0 );
  			print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Child Buzzer: 'S'ilent received. \n" if CHILD_LOG_VERBOSE;
			$Timer_Resolution=5000000;
			$buzzer=0;
			$status=0;
		}
		if ( $tmp_command =~ /P/ ) {
			$Timer_Resolution=250000;
  			print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Child Buzzer: 'P'reAlarm received. \n" if CHILD_LOG_VERBOSE;
			$status=1;
		}
		if ( $tmp_command =~ /A/ ) {
        		$owserver_buzz->write( BUZZER_ID , 1 );
  			print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Child Buzzer: 'A'larm received. \n" if CHILD_LOG_VERBOSE;
			$Timer_Resolution=250000;
			$status=3;
			$buzzer=1;
		}
		$tmp_command="";
	}

	
	if ($status > 0 && $status < 3 ) { # If $status = 3 buzzer must play continuosly; $status=0 Silent!
		if ($cycles==0 ) {
			if ( $buzzer ) {
                        	print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " IF! cycles: $cycles - Buzzer: $buzzer - Duration_pre: $prealarm_duration - Status: $status \n" if CHILD_LOG_VERBOSE;

# ########### Code Game Start ###
# Select the piece of code you prefer: code gaming or more traditional/readable :)
############# THIS ##########
		#		$cycles=LONG_DURATION_OFF/$status;
		#		if ($prealarm_duration++ == DURATION_FIRST_PREALARM*$status) {
		#			$status++
		#		}

######### OR THIS :) ###########

				if ( $status == 1 ) {  # Primo Preallarme
					$cycles=LONG_DURATION_OFF; 
					if ($prealarm_duration++ == DURATION_FIRST_PREALARM) {
						$status++;
					}
				} elsif ( $status == 2 ) { # Secondo preallarme
					$cycles=DURATION_OFF;
					if ($prealarm_duration++ == (2*DURATION_FIRST_PREALARM)) {
						$status++;
					}
				}
############ END of Code Game  ############

				$buzzer=0;

			} else {
                        	print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " ELSE! cycles: $cycles - Buzzer: $buzzer - Duration_pre: $prealarm_duration - Status: $status \n" if CHILD_LOG_VERBOSE;
				$cycles=DURATION_ON;
				$buzzer=1;
			}

        		$owserver_buzz->write( BUZZER_ID , $buzzer );
		}
        	print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " cycles: $cycles - Buzzer: $buzzer - Duration_pre: $prealarm_duration - Status: $status \n" if CHILD_LOG_VERBOSE;
		$cycles--;
	}
	if ($status == 3) {
		# I force buzzer to ON without entering in the IF at every cycles
		$tmp_command="A";
	}
	
        usleep($Timer_Resolution); 
  }

  close(FIFO);
  unlink $FIFO_TO_CHILD_BUZ;

	
use sigtrap qw(handler signal_handler normal-signals error-signals old-interface-signals );

# You got mail! Let's go to read it!
use sigtrap 'handler' => \&Buzzing, 'USR1';
sub Buzzing {
	# If the FIFO contains more than one signal, the good one is the last one...
	# Others are outdated, so clean all and get last!
	while (<FIFO>) {
		$tmp_command = $_;
	}
	chomp $tmp_command;
}