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 () { $tmp_command = $_; } chomp $tmp_command; }