#!/bin/env perl

# Load CA module
use strict;
use lib '/APSshare/epics/base-3.14.12.4/lib/perl';
use CA;

# Get my user-name
my $user = $ENV{USER};

my $debug;
my $exit;

# Add a Control-C handler for orderly shutdown
$SIG{INT} = \&interrupt;

my %subscribed;
my %opened_at;
my %open_for;

my @beamlines;
push @beamlines, sprintf("id%02d", $_) for (1..36);

# Connect to PVs
CA->new("$_:shutter", \&connection) for @beamlines;
CA->flush_io;

# Process CA events until told to stop
CA->pend_event(0.1) until $exit;

exit 0;

# ------------- Callback subroutines -------------

# Connect/disconnect handler
sub connection {
    my ($chan, $up) = @_;
    my $name = $chan->name;

    print "connection($name, $up)\n" if $debug;
    if ($up && !$subscribed{$chan}) {
        # Start monitoring channel
        $subscribed{$chan} =
            $chan->create_subscription('v', \&value, 'DBR_TIME_LONG');
        CA->flush_io;
    }
}

# New value handler
sub value {
    my ($chan, $status, $data) = @_;
    my $name = $chan->name;

    print "value($name, $status, $data)\n" if $debug;
    if ($status) {
        printf "%-30s %s\n", $chan->name, $status;
    } else {
        my $val = $data->{value};
        my $stamp = $data->{stamp} + $data->{stamp_fraction};
        if ($val) {
            $opened_at{$chan} = $stamp;
            print "$name opened\n";
        } elsif ($opened_at{$chan}) {
            my $exposure = $stamp - $opened_at{$chan};
            $open_for{$name} += $exposure;
            printf "%s closed after %.0f seconds\n", $name, $exposure;
        }
    }
}

# Control-C handler
sub interrupt {
    print " -- Interrupt --\n";
    for my $name (sort keys %open_for) {
        my $total = $open_for{$name};
        printf "%s total %.0f seconds\n", $name, $total if $total;
    }
    $_->clear for values %subscribed;
    CA->flush_io;
    $exit = 1;
}

