#!/usr/bin/perl -w
use strict;

package UPS;

sub new {
	my $proto = shift;
	my $class = ref($proto) || $proto;
	my $self = {};
	my %args = @_;
	bless $self, $class;
	$self->device($args{-device}) if $args{-device};
	$self->debug($args{-debug}) if $args{-debug};
	$self->msg_end_char($args{'-end-char'}||"\n");
	return $self;
	}
sub device {
	my $self = shift;
	if (@_) {
		my $new_device = shift;
		if (-e $new_device) {
			$self->{'device'} = $new_device;
			}
		else {
			warn "Device $new_device does not exist";
			return;
			}
		}
	return $self->{'device'};
	}

sub debug {
	my $self = shift;
	if (@_) {
		my $new_debug = shift;
		if ($new_debug =~ /^\d+$/) {
			$self->{'debug'} = $new_debug;
			}
		else {
			warn "Debug not numeric: $new_debug";
			return;
			}
		}
	return $self->{'debug'};
	}

sub msg_end_char {
	my $self = shift;
	if (@_) {
		my $char = shift;
		$self->{'end_char'} = $char;
		}
	return $self->{'end_char'};
	}

sub upsopen {
	my $self = shift;
	print "upsopen()\n" if $self->debug;
	open UPS, $self->device or die("Cannot open " . $self->device);
	$self->{'fd'} = *UPS;
	}

sub upsclose {
	my $self = shift;
	print "upclose()\n" if $self->debug;
	close $self->{'fd'};
	}

sub _fd {
	my $self = shift;
	return $self->{'fd'};
	}

sub upssend {
	my $self = shift;
	my $message = shift;
	print {$self->_fd} $message;
	}

sub upsread {
	my $self = shift;
	my $alarm = 0;
	my $message;
	my $char;

	while (not $alarm) {
		my $ready = select (\($self->_fd), undef, undef, 1);
		if ($ready) {
			read $ready, $char, 1;
			if ($char == $self->msg_end_char) {
				$alarm = 1;
				}
			else {
				print "Got $char\n" if $self->debug;
				$message.= $char;
				}
			}
		else {
			print "Alarm!\n" if $self->debug;
			$alarm = 1;
			}
		}
	print "Done.\n" if $self->debug;
	return $message;
	}

package main;

my $u = UPS->new(-device => "/dev/ttyS0");
$u->debug(1);
$u->upsopen;
my $message = $u->upsread();
print "Message: $message\n" if $message;
$u->upsclose;
