有必要监视UPS动物园,Ippon,Powercom和Krauler可用。作为监视工具,使用了Zabbix。自然,需要解决的问题是:1)价格便宜2)价格更低,因此带有SNMP模块的选件立即被拒绝。由于具有Ippon和APC的开发经验,因此决定使用串行端口连接。顺便说一句,二级市场上的APC以合理的价格提供了SNMP模块,但是对于便宜的UPS,我只能以11.2万卢布的价格找到新的模块。在工作过程中,设置了以下附加任务:- 查找并检查用于连接每个UPS的电缆,因为该套件中没有电缆
- 要实现某个模块,该模块一方面具有RS-232接口并了解与每个UPS的数据交换协议,另一方面具有网络接口并可以zabbix_trapper的形式发送数据。
- 测试数据收集和传输模型,部分代码以及数据格式。
在第二和第三段的实施过程中,我想在一个地方收集所有数据,这些数据将来将允许为m / c实现单独的设备。因此:没有任何UPS的电缆。原则上,对于可以计算DB9连接器上的联系人的人员而言,第一个任务不会出现问题。事实证明,不仅包括我在内,不仅每个人都知道如何做。F和M连接器上的触点是镜像的,但已签名,如果小心,通常不会出错。- Ippon Smart Winner 2000 back power pro, 2-2, 3-3, 5-5. , .
- Krauler Memo RT 2000 krauler.ru, 2-2,3-3, 5-5.
- Powercom SXL-2000A www.pcm.ru/data/docs/cables.zip, forum.pcm.ru. 2-9, 3-6, 5-7. (-).
一个小的题外话。服务器的骨干网由两个Vmware ESXi主机组成,它们被容纳在具有两个UPS的机架中。某些服务器有2个电源。不幸的是,一部分只是其中之一,这就是为什么他们经常遭受痛苦。 Zabbix当前作为虚拟机托管在其中一台主机上。原则上,在Ubuntu上部署小型虚拟服务器(我使用该平台提供服务)来实现任何任务都不是问题。因此,方案如下:ESXi上的COM端口->虚拟机上的COM端口->从UPS返回数据的C程序->发送zabbix陷阱的脚本或程序。最后两点应在将来合并。虽然它像那样工作。通过为一台UPS连接电缆,为服务器连接一个额外的连接器(其中有两个,再加上一个DB9的rj-45适配器),依次检查连接,检查程序,设置Zabbiks中的组件,依次解决了问题。首先需要选择一个服务器来托管可执行代码。我没有绞尽脑汁,而是将所有这些发布到Zabbix服务器上。其次,我考虑了如何处理数据。由于Bash的设计array=( $(/home/appliance/uniups) )
将字符串分解为数据数组,我决定只返回字符串段MMM.M NNN.N PPP.P QQQ RR.R S.SS TT.T程式码#include <stdio.h> /* / */
#include <string>
#include <iostream>
#include <cstring>
using namespace std;
#include <unistd.h> /* UNIX */
#include <fcntl.h> /* */
#include <errno.h> /* */
#include <termios.h> /* POSIX- */
#include <sys/types.h>
#include <sys/stat.h>
int fd;
char buf[512];
int main (int argc, char* argv[])
{
int iIn,iOut;
string UPSAnswer;
if (argc>=2)
{
fd = open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
printf("error port\n");
perror("open_port: Unable to open port - "); }
else
{
struct termios options;
tcgetattr(fd, &options);
cfsetispeed(&options, B2400);
cfsetospeed(&options, B2400);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
tcsetattr(fd, TCSANOW, &options);
}
char Params[64];
if(argc>=3)
{
if (!strcmp(argv[2],"status"))
{
iOut = write(fd, "Q1\r", 3);
usleep(800000);
if (iOut < 0) fputs("write() of 4 bytes failed!\n", stderr);
iIn=read(fd,buf,250);
strncpy(Params,&buf[38],11);
Params[46]=0;
}
else if (!strcmp(argv[2],"help"))
{
printf (" . !\r\n");
}
else if (!strcmp(argv[2],"name"))
{
iOut = write(fd, "I\r", 3);
usleep(800000);
if (iOut < 0) fputs("write() of 4 bytes failed!\n", stderr);
iIn=read(fd,buf,250);
strncpy(Params,&buf[0],60);
}
else if (!strcmp(argv[2],"stat2"))
{
iOut = write(fd, "F\r", 3);
usleep(800000);
if (iOut < 0) fputs("write() of 4 bytes failed!\n", stderr);
iIn=read(fd,buf,250);
strncpy(Params,&buf[1],60);
Params[20]=0;
}
else
{
printf ("? \r\n");
}
}
else
{
usleep(1800);
iIn=read(fd,buf,250);
usleep(1800);
iOut = write(fd, "Q1\r", 3);
usleep(800000);
if (iOut < 0) fputs("write() of 4 bytes failed!\n", stderr);
iIn=read(fd,buf,250);
strncpy(Params,&buf[1],36);
Params[36]=' ';
}
close(fd);
printf("%s\r\n",Params);
}
else
printf("Usage %s /dev/ttySx", argv[0]);
}
我发现可以在Google中使用该端口,可以从Bash中读取内容,但是从Bash中无法实现稳定的操作。原则上,Linux中的C代码是b。首先对Ippon进行了测试,然后在研究Powercom UPS时启动了端口监视器,这表明PowerCom也可以通过Megatec协议工作,并且本机程序在启动时使用“ I”和“ F”命令轮询UPS,然后循环使用“ Q1”。我将端口名称挂在第一个参数上的形式为“ / dev / ttyS0”或“ / dev / ttyS1”,第二个参数允许您请求其他参数,代码显示。在目录/ home / device /中放置了程序,称为uniups.cpp。已编译g++ -o uniups uniups.cpp
。原则上,结果是这样的(是的,我是在根底下工作,甚至不发表评论)root@zabbix:~
204.4 204.4 204.4 035 49.9 54.8 54.5
root@zabbix:~
I
root@zabbix:~
root@zabbix:~
216.3 216.3 216.3 000 50.0 54.2 30.0
root@zabbix:~
220.0 009 048.0 50.0
root@zabbix:~
重要的是,最终所有的UPS都使用相同的协议,从而允许使用一个程序。使用2400、8N1上的连接,其他所有设备均关闭。美中不足的是,UPS的名称通常仅返回Powercom,Ippon无法理解“ I”命令,而Krauler返回“#R1.1.1”。此外,在文档中,Krauler将电压返回至元件,将其余的UPS返回至电池。SS.S或S.SS对于在线装置,电池电压/电池以S.SS的形式提供。对于备用设备,实际电池电压以SS.S形式提供
有鉴于此,我不得不在脚本上添加补丁。关于它下面。发送此消息后,所有场合都变成了动物园。在服务器上,Zabbix使用zabbix_sender实用程序来加快过程。zabbix_sender -z _ -p 10051 -s ___ -k -o
原则上,对于轮询两个UPS,这已经足够了,但是,到现在,我将拥有第三个,而将来,我将拥有第四个,因此,我选择了第一个,并且偶然地,我选择了第二个Vmware主机上的唯一Linux服务器并将其发送到他的COM端口。我没有使用zabbix代理或复制zabbix_sender,我发现后者的描述在所有盐中都包含在Base64中编码数据。为了检查,我使用了命令echo "<req>\n<host>S3JhdWxlck1lbW9SVDIwMDA=</host>\n<key>RnJlcQ==</key>\n<data>NDkuNA==</data>\n</req>\n" | nc -q 0 192.168.53.23 10051
其中192.168.53.23是Zabbix服务器的地址。她正在工作。我调用了上面的脚本zabbix_sender.pl并将其放置在服务器上,我的脚本如下所示:
use IO::Socket;
use IO::Select;
use MIME::Base64;
my ($zabbixserver,$hostname,$item,$data) = @_;
$zabbixserver= @ARGV[0];
$hostname= @ARGV[1];
$item= @ARGV[2];
$data= @ARGV[3];
my $timeout=10;
my $request=sprintf("<req>\n<host>%s</host>\n<key>%s</key>\n<data>%s</data>\n</req>\n",
encode_base64($hostname),encode_base64($item),encode_base64($data));
my $sock = new IO::Socket::INET ( PeerAddr => $zabbixserver, PeerPort => '10051', Proto => 'tcp', Timeout => $timeout);
die "Could not create socket: $!\n" unless $sock;
$sock->send($request);
my @handles=IO::Select->new($sock)->can_read($timeout);
if (scalar(@handles) > 0)
{
$sock->recv($result,1024);
print "answer from zabbix server $zabbixserver: $result\n";
}
else
{
print "no answer from zabbix server\n";
}
$sock->close();
Perl已经在服务器上。接下来,我们需要一个脚本,该脚本将所有组件链接在一起,并可以放置在Cron中。这是一个端口的示例,对于另一个端口,您可以简单地复制相同的代码并替换为不同的名称。我没有做周期,我几乎无法想象一辆有2个以上COM端口的汽车。#!/bin/bash
array=( $(//uniups /dev/ttyS0) )
Names=( InVolt FaultVolt OutVolt Current Freq UBatt UTemp NA )
correct[5]="24.0"
j=0;
echo "Checking UPS on serial A - ${#array[@]}"
if [ ${#array[@]} -gt "7" ]
then
param=""
for i in "${array[@]}"
do
if [[ ${correct[$j]} ]]
then
param=$( echo "scale = 0; $i * ${correct[$j]}" | bc)
else.
param=$i
fi
//zabbix_sender.pl 192.168.53.23 KraulerMemoRT2000 ${Names[$j]} $param
j=$j+1;
done
else
echo "No data on A"
fi
小意见:- 数组-UPS轮询程序返回的数组,名称-应该在具有相同名称的Zabbix服务器元素上启动名称为Item的数组。KraulerMemoRT2000-不间断的名称,必须与服务器上的主机名匹配。
- , , Zabbix , , , NA, , , .
- ${#array[@]}, . , . : , , . , , . , , .
- 正确的[5] =“ 24.0”是如果UPS返回元件上的电压(电池电压/电池),则电池(阵列中的第5个元件)的电压校正。我电池中有6个元件,串联4个,总共24个。原则上,这在协议中进行了描述。我发现没有必要创建单独的元素,因为我拥有的所有UPS均受模板监控,并且均具有48伏特。当然,当监视不同电压的UPS时,有必要稍微改变其结构,最好将电池参数锤击服务器。
每执行一分钟,就会将上述脚本添加到cron中。本文不考虑Zabbix设置。原则上就是这样。如果收集到的信息对某人有用,我将感到高兴。