X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=lib%2FRFID%2FBiblio%2FReader.pm;fp=lib%2FRFID%2FBiblio%2FReader.pm;h=58683114475b1846aeb8c97ec4183d4f57e261e6;hb=9169bf2f8daa31ad3beab0a890ee8d762c92c810;hp=0000000000000000000000000000000000000000;hpb=75a8809d9f67c952c0db9c3941ec615cace3c716;p=Biblio-RFID.git diff --git a/lib/RFID/Biblio/Reader.pm b/lib/RFID/Biblio/Reader.pm new file mode 100644 index 0000000..5868311 --- /dev/null +++ b/lib/RFID/Biblio/Reader.pm @@ -0,0 +1,161 @@ +package RFID::Biblio::Reader; + +use warnings; +use strict; + +use Data::Dump qw(dump); +use Time::HiRes; +use lib 'lib'; +use RFID::Biblio; + +=head1 NAME + +RFID::Biblio::Reader - autodetect supported readers + +=head1 FUNCTIONS + +=head2 new + + my $rfid = RFID::Biblio::Reader->new( 'optional reader filter' ); + +=cut + +sub new { + my ( $class, $filter ) = @_; + my $self = {}; + bless $self, $class; + $self->{_readers} = [ $self->_available( $filter ) ]; + return $self; +} + +=head2 tags + + my @visible = $rfid->tags( + enter => sub {}, + leave => sub {}, + ); + +=cut + +sub tags { + my $self = shift; + my $triggers = {@_}; + + $self->{inventory} ||= {}; + $self->{inventory}->{$_} = 0 foreach keys %{$self->{inventory}}; + my $t = time; + + foreach my $rfid ( @{ $self->{_readers} } ) { + warn "# inventory on $rfid"; + my @tags = $rfid->inventory; + + foreach my $tag ( @tags ) { + + $self->{blocks}->{$tag} ||= $rfid->read_blocks( $tag )->{$tag}; + $self->{afi}->{$tag} ||= $rfid->read_afi( $tag ); + + $triggers->{enter}->( $self, $tag ) if ! $self->{inventory}->{$tag} && $triggers->{enter}; + $self->{inventory}->{$tag} = $t; + + } + + foreach my $tag ( grep { $self->{inventory}->{$_} == 0 } keys %{ $self->{inventory} } ) { + $triggers->{leave}->( $self, $tag ) if $triggers->{leave}; + } + + } + + warn "## tags ",dump($self); + + return grep { $self->{inventory}->{$_} } keys %{ $self->{inventory} }; +} + +=head2 blocks + + my $blocks_arrayref = $rfid->blocks( $tag ); + +=head2 afi + + my $afi = $rfid->afi( $tag ); + +=cut + +sub blocks { $_[0]->{ 'blocks' }->{$_[1]} || die "no blocks for $_[1]"; }; +sub afi { $_[0]->{ 'afi' }->{$_[1]} || die "no afi for $_[1]"; }; + +=head1 PRIVATE + +=head2 _available + +Probe each RFID reader supported and returns succefull ones + + my $rfid_readers = RFID::Biblio::Reader->_available( $regex_filter ); + +=cut + +my @readers = ( '3M810', 'CPRM02', 'librfid' ); + +sub _available { + my ( $self, $filter ) = @_; + + $filter = '' unless defined $filter; + + warn "# filter: $filter"; + + my @rfid; + + foreach my $reader ( @readers ) { + next if $filter && $reader !~ /$filter/i; + my $module = "RFID::Biblio::$reader"; + eval "use $module"; + die $@ if $@; + if ( my $rfid = $module->new( device => '/dev/ttyUSB0' ) ) { + push @rfid, $rfid; + warn "# added $module\n"; + } else { + warn "# ignored $module\n"; + } + } + + die "no readers found" unless @rfid; + + return @rfid; +} + +=head1 AUTOLOAD + +On any other function calls, we just marshall to all readers + +=cut + +# we don't want DESTROY to fallback into AUTOLOAD +sub DESTROY {} + +our $AUTOLOAD; +sub AUTOLOAD { + my $self = shift; + my $command = $AUTOLOAD; + $command =~ s/.*://; + + my @out; + + foreach my $r ( @{ $self->{_readers} } ) { + push @out, $r->$command(@_); + } + + return @out; +} + +1 +__END__ + +=head1 SEE ALSO + +=head2 RFID reader implementations + +L + +L + +L +