Source

rfid / attendance

#!/usr/bin/perl
# Generate a CSV of who has attended an event and what time they scanned in.
# Reads IDs from the serial port and looks them up in the CSV database
use warnings;
use strict;
use IO::Handle;

my $dev_file = '/dev/tty.usbmodem12341';
my $csv_in_file = 'users.csv';
my $csv_out_file = 'output.csv';

open CSV, "<$csv_in_file"
	or die "$csv_in_file: Unable to open: $!\n";
my %users;

while (<CSV>)
{
	next if $. == 1;
	chomp;
	my ($last,$first,$id) = split /\s*,\s*/;

	die "$id: Duplicate?\n" if exists $users{$id};
	$users{$id} = [ $last, $first ];
}

open DEV, "<$dev_file"
	or die "$dev_file: Unable to open: $!\n";

my $count = 0;
my $out;

if (-r $csv_out_file)
{
	# File exists; find out how many are already there and add to it
	open IN, "<$csv_out_file"
		or die "$csv_out_file: Unable to read\n";

	$count++ while <IN>;
	$count--; # skip header

	# Start appending to the file now
	close IN;
	open $out, ">>$csv_out_file"
		or die "$csv_out_file: Unable to append: $!\n";
} else {
	open $out, ">$csv_out_file"
		or die "$csv_out_file: Unable to write: $!\n";
	print $out "last,first,time\n";
}

# Force writes to the CSV immediately
$out->autoflush(1);


while (<DEV>)
{
	s/[\r\n]*$//;

	unless (/^[01]+$/)
	{
		warn "Invalid ID? '$_'\n";
		next;
	}

	# Try for a 16 bit ID
	my $id16 = 0;
	for my $bit (split //, substr($_, -17, 16))
	{
		$id16 = ($id16 << 1) | $bit;
	}

	my $user = $users{$id16};

	unless ($user)
	{
		warn "$id16 ($_): Not in database?\n";
		next;
	}

	$count++;
	printf "%d: %s\n", $count, $user->[1];

	my $now = localtime;
	print $out "$user->[0],$user->[1],$now\n";
}

__END__