Nah, I had already tried that. Dumper shows that some of %timings's key values do not get changed. I am puzzled, because I am treating them all the same.
#!/usr/bin/perl
use strict;
use Data::Dumper;
#Wed Dec 02 06:22:50 GMT 2015: changed handling of DEBUG
#Mon Nov 30 21:17:12 GMT 2015: done away with status array. Every thi
+ng now stored in %timings hash
my %status;
my $COMPLETE = 0;
my $MAX_SLEEP = 5;
my $MIN_LOG_DELAY = 6; #seconds
my $LOG_DELAY;
my $timings_file = shift;
my $DEBUG = 0;
my $TRUE = 1;
my $FALSE = 0;
my $ON = $TRUE;
my $FINISHED = 2;
my $STARTED = 1;
my $elapsed_seconds = 0;
my $now;
my %timings;
set_timings();
open(LOG, ">control.log") || die "cannot open control.log";
## START ##
$elapsed_seconds = time - $^T;
$now = $elapsed_seconds;
for(;;) {
my $item;
foreach $item (keys %timings) {
warn "Next iteration:";
warn Dumper \%timings;
warn "Processing [$item]";
check($item);
}
$elapsed_seconds = time - $^T;
if (($elapsed_seconds - $now) > $LOG_DELAY) {
show_status();
$now = $elapsed_seconds;
}
$COMPLETE = 1;
foreach $item (keys %timings) {
if ($timings{$item}{STATUS} != '2') {
$COMPLETE = 0;
last;
}
}
if ($COMPLETE) {
show_status();
die "finished\n"
}
}
sub set_timings() {
open(IN, $timings_file) || die "cannot open $timings_file\n";
while (!eof(IN) ) {
$_ = <IN>;
$DEBUG = 1 if ($_ =~ m/^DEBUG/);
if ($_ > 0) {
$LOG_DELAY = $_;
warn "log delay is $LOG_DELAY. This is very low and you risk
+running out of disk space!\n" if $LOG_DELAY < $MIN_LOG_DELAY;
next;
}
next if $_ =~ m/^#/;
next unless s/^(.*?):\s*//;
my $item = $1;
for my $field ( split ) {
(my $key, my $value) = split /=/, $field;
$timings{$item}{$key} = $value;
}
die "$item start: $timings{$item}{START} is less than stop:$timing
+s{$item}{STOP}\n" if $timings{$item}{START} > $timings{$item}{STOP};
}
}
sub check(my $item) {
my $item = shift;
show_status() if ($DEBUG);
$elapsed_seconds = time - $^T;
if (($elapsed_seconds >= $timings{$item}{START}) and ($timings{$it
+em}{STATUS} != '2')) {
switch_on($item);
$timings{$item}{STATUS} = '1';
}
if ($elapsed_seconds > $timings{$item}{STOP}) {
last if $timings{$item}{STATUS} == '2';
switch_off($item);
$timings{$item}{STATUS} = '2'; # keep it off
}
}
sub switch_on(my $item, my $addr) {
my $item = shift;
if ($timings{$item}{STATUS} == '1') { #already on
return(0);
}
if ($timings{$item}{STATUS} == '2') {
return(0);
}
# do print on stuff
}
sub switch_off(my $item, my $addr) {
my $item = shift;
if ($timings{$item}{STATUS} == '2') {
return(0);
}
# do switch off stuff
$timings{$item}{STATUS} = '2';
}
sub show_status() {
foreach my $item (keys %timings) {
if ($DEBUG) {
print "$item, $elapsed_seconds, $timings{$item}{START}, $timin
+gs{$item}{STOP}, $timings{$item}{STATUS}\n";
}
else {
select((select(LOG), $|=1)[0]); # flush the log file
print LOG "$item, $elapsed_seconds, $timings{$item}{START}, $t
+imings{$item}{STOP}, $timings{$item}{STATUS}\n";
}
}
print LOG "##################\n";
}
And here is the data file:
RED: ADDR=1 START=1 STOP=2 STATUS=0
BLUE: ADDR=2 START=1 STOP=2 STATUS=0
GREEN: ADDR=3 START=1 STOP=2 STATUS=0
YELLOW: ADDR=4 START=1 STOP=2 STATUS=0
VIDEO: ADDR=5 START=1 STOP=2 STATUS=0
MOTOR_FORWARD: ADDR=1 START=1 STOP=2 STATUS=0
MOTOR_REVERSE: ADDR=27 START=1 STOP=2 STATUS=0
AUDIO: ADDR=8 START=1 STOP=10 STATUS=0
SPARE: ADDR=9 START=1 STOP=2 STATUS=0
My original assumption about the number of outer iterations is wrong. If the STOP vales are all the same everything works fine. Things go funny if they are different. Obviously there is something wrong with my logic, or my understanding of hashes. |