APC RS800VA
- From
- Alex Mogilnikov (2:5054/70)
- To
- Oleg Kuznetsov
- Date
- 2005-06-07T13:51:18Z
- Area
- RU.UNIX.BSD
Привет Oleg!
07 Jun 05 10:29, Oleg Kuznetsov писал All:
OK> задача завести usb-шный сабжевый ups под фряху, вчера полдня мучал
OK> apcupsd 3.10.17a, не вышло,пишет что apcupsd FATAL ERROR in bsd-usb.c
OK> at line 781 Cannot find UPS device -- For a link to detailed USB
OK> trouble shooting information, please see
OK> <http://www.apcupsd.com/support.html>.
Тебе удалось его собрать с --enable-usb ? У меня он не находит какие-то файлы и с usb не работает вообще (FreeBSD 4.11).
OK> у кого-нить реально получилось завесети usb-шный упс под фряху, мож
OK> какой другой правильный утиль есть? Oleg
У меня дома APC Back UPS 350 CS, он работает вот с таким перловым скриптом (нашел в где-то в интернете и немного подправил напильником):
=== Cut ===
#! /usr/bin/perl5 -w
# FreeBSD ups monitoring daemon
# Box labeled "APC Battery Backup 500 VA 300 Watts"
# Box labeled "APC Back-UPS ES Series"
# Rumored to be same as the CyberFort 500 (I can't confirm this)
# Shipping section says:
# Supplier Part NO: BE500U
# Supplier Part Description: BK ES USB 500VA 120v
# LICENSE
# BSD style.
#
# You can do what you want with it, commerical or otherwise,
# so long as proper and faithful attribution is kept.
#
# This code has no warrantee - don't sue me.
# FreeBSD uhid0 shows this device when I plug it in:
# 23:56 PDT | jfesler@heaven:~/ % sudo usbdevs
# addr 1: UHCI root hub, Intel
# addr 2: Back-UPS ES 500 FW:2.e2.D USB FW:e2, APC
use Sys::Syslog qw(:DEFAULT setlogsock);
use strict "vars";
use vars qw(%syslog
$line $battery $charge $oline $obattery $ocharge $lasttime $program
);
my $uhid = "/dev/uhid0"; # This would be your USB device (run dmesg)
my $wall = "/usr/bin/wall";
my $usewall = 1;
my $shutdown_at = 20; # Shut down at 20 battery life
my $shutdown = "/sbin/shutdown -h now power_failure";
my $useshutdown = 1;
my $notify = 'root';
my $sendmail = '/usr/sbin/sendmail -t';
my $hostname = `hostname`;
$program = $0;
$program =~ s#.*/##;
$syslog{"actions"} = 'user|alert';
$syslog{"change"} = 'user|alert';
$syslog{"debug"} = 'user|debug';
# Initialize some variables
$line = $battery = $charge = $oline = $obattery = $ocharge = "";
$lasttime = time;
setlogsock('unix');
openlog($program, 'cons,pid', 'user');
# Unbuffer output
select(STDERR); $|=1;
select(STDOUT); $|=1;
# Take the USB device
open(UHID,"<$uhid")||die "Failed to open $uhid : $!";
# Sync up with the data by monitoring the output
# stream and looking at the clock. We are looking for
# groups of 9 characters.
do { print "synchronizing\n"
} while (length(getblock_timebased()) % 9 );
# Read in each block of data, and set status accordigly.
# Afterwords, check the status to see if any reactions are needed.
while(1) {
scan_data();
check_status();
}
sub scan_data {
my $buffer;
read UHID,$buffer,9;
die "Short read on UHID device" unless (length($buffer) == 9);
my @buffer = split(//,$buffer);
my @ord = map ( ord($_), @buffer);
my @hex = map ( sprintf('%02x',$_), @ord);
my $hexstring = join(" ",@hex);
syslog($syslog{"debug"}, '%s', $hexstring);
print "@hex\n";
my($command,$value) = (@ord);
$hexstring =~ m/^0d/ and do {
# $line = "off" if $ord[2] & 2;
# $line = "on" if $ord[2] & 4;
return;
};
$hexstring =~ m/^33 0a/ and do { $battery = "discharging"; $line = "off"; return; };
$hexstring =~ m/^33 0c/ and do { $battery = "full"; $line = "on"; return; };
$hexstring =~ m/^33 0d/ and do { $battery = "charging"; $line = "on"; return; };
$hexstring =~ m/^0c/ and do { $charge = $ord[1]; return; };
print "unexpected: $hexstring\n";
}
sub check_status {
# compare status
if (($lasttime - time < 60) &&
($battery eq $obattery) &&
($charge eq $ocharge) &&
($line eq $oline)
) {
return;
}
$lasttime = time;
# Generate the status string to report. Send it to syslog
# and to stdout.
my $message = "STAT battery=$battery line=$line charge=$charge \%";
print "$message\n";
syslog($syslog{"change"}, '%s', $message);
# Are we on battery?
if ($line eq "off") {
handle_battery() if ($oline eq "on");
handle_percent() if (int($charge / 10) != int($ocharge/10));
handle_halt() if ($charge <= $shutdown_at);
}
# Are we back on the mainline?
if ($line eq "on") {
handle_mainline() if ($oline eq "off");
}
$oline = $line;
$obattery = $battery;
$ocharge = $charge;
}
sub notify($$) {
my($subject,$body) = @_;
if ((defined $notify) && (length($notify))) {
open(SENDMAIL,"|$sendmail");
print SENDMAIL <<"EOF";
To: $notify
Subject: $subject
$body
EOF
close SENDMAIL;
}
}
sub wall($) {
my($message) = @_;
if ($usewall) {
open(WALL,"|wall");
print WALL $message;
close WALL;
print "Sent to WALL: $message\n";
} else {
$message =~ s/[\r\n]+/|/g;
syslog($syslog{"actions"}, '%s', "Would have walled: " . substr($message,0,200));
}
}
sub handle_percent() {
syslog($syslog{"actions"},'%s',"calling handle_percent()");
# notify("UPS at $charge","host $hostname at $charge \% remaining");
my $message = <<"EOF";
We are now on battery power; $charge \% remaining.
At $shutdown_at \% we will halt the computer. Save your work.
You will be notified if the power is restored.
EOF
wall($message);
}
sub handle_halt() {
if ($useshutdown) {
handle_halt_yes();
} else {
handle_halt_no();
}
}
sub handle_halt_no() {
syslog($syslog{"actions"},'%s',"calling handle_halt_no()");
notify("UPS near death at $charge","host $hostname at $charge \% remaining");
my $message = <<"EOF";
The system would shut down now, but shutdowns are currently enabled. In all
likelihood this host will lose power. Please save your work, type "sync".
Log out. If you do not, there is a chance your data will be trashed.
EOF
wall($message);
sleep 30;
}
sub handle_halt_yes() {
syslog($syslog{"actions"},'%s',"calling handle_halt_yes()");
notify("UPS near death at $charge; halting","host $hostname at $charge \% remaining; halting");
my $message = <<"EOF";
We are now halting the system; we are only at $charge % battery
remaining.
EOF
wall($message);
$shutdown = "shutdown -h now" unless (defined $shutdown);
system($shutdown) if ($useshutdown);
sleep 3600;
exit 1; # We hope to be dead by now.
}
sub handle_battery() {
syslog($syslog{"actions"},'%s',"calling handle_battery()");
notify("UPS on battery power","host $hostname at $charge \% remaining");
my $message = <<"EOF";
The UPS has detected a power failure. We are now running on battery.
Please save your work immediately. The battery indicator will count
down from 100 \% to $shutdown_at \% full; at that time this host will be shut down
if power has not yet been restored.
Note: This is a cheap UPS. Don't expect this to last long. SAVE NOW.
EOF
wall($message);
}
sub handle_mainline() {
syslog($syslog{"actions"},'%s',"calling handle_mainline()");
notify("UPS on main power","host $hostname at $charge \% remaining");
my $message = <<"EOF";
The UPS has detected A/C power has been restored. The shutdown
has been canceled.
EOF
wall($message);
}
# Take as many bytes as you can from when you start to get data up to the
# point where you have been idle for more than 2 seconds We will use this to
# attempt to synchronize with the USB serialized stream data
sub getblock_timebased {
local $SIG{"ALRM"} = sub { die "timeout" ;};
alarm(10);
my ($return,$buffer);
eval {
while(my $r = read UHID, $buffer,1) {
alarm(2);
$return .= $buffer;
}
};
alarm(0);
return $return;
}
__END__
# Blocks are 9 bytes each
# Sync using alarm()
# Once synced, things seem OK
# Each output is 9 bytes
# byte 0 = code
# byte 1 = val
# remainder = garbage
# code 0c = charge (0x00? - 0x64)
# code 06 = line state
# 06 08 = line
# 06 10 = battery
# code 33 = charge status
# 33 0d = charge
# 33 0c = full
# 33 0a = discharge
=== Cut ===
К сожалению, та же модель UPS, выпущенная чуть раньше, работать таким образом не стала - UPS почему-то не выдает никаких данных в online.
Попробуй запустить это в терминале и посмотри, что выдает UPS в разных режимах. Возможно, придется исправить некоторые коды (см. scan_data()), или даже длину сообщения.
Всего наилучшего, [Team PCAD 2000]
Алексей М.
... Посетители должны общаться по сети.
---
* Origin: === Сисоп спит - почта идет === (2:5054/70)
SEEN-BY: 5020/545 5054/1 4 8 9 28 35 36 37 63 66 67 70 75 81 84 85
PATH: 5054/70 1 37