Zabbix में Megatec प्रोटोकॉल के साथ UPS की सामूहिक कृषि निगरानी

यूपीएस चिड़ियाघर की निगरानी करने की आवश्यकता थी, इपोन, पावरकॉम और क्रॉलर उपलब्ध थे। एक निगरानी उपकरण के रूप में Zabbix का उपयोग किया।

स्वाभाविक रूप से, समस्या को हल करने की आवश्यकता 1) सस्ते 2) यहां तक ​​कि सस्ता है, इसलिए एसएनएमपी मॉड्यूल के साथ विकल्प तुरंत अस्वीकार कर दिया गया था। सीरियल पोर्ट कनेक्शन का उपयोग करने का निर्णय लिया गया था, क्योंकि इपोन और एपीसी के लिए विकास का अनुभव था। वैसे, माध्यमिक बाजार में एपीसी के पास उचित मूल्य पर एसएनएमपी मॉड्यूल हैं, लेकिन सस्ती यूपीएस के लिए, मैं केवल 11-20 हजार रूबल की कीमत पर नए मॉड्यूल पा सकता हूं।

कार्य के दौरान, निम्नलिखित अतिरिक्त कार्य निर्धारित किए गए थे:

  1. प्रत्येक यूपीएस को जोड़ने के लिए केबलों को ढूंढें और जांचें, क्योंकि किट में कोई भी नहीं था
  2. एक मॉड्यूल को लागू करें जिसमें एक तरफ RS-232 इंटरफ़ेस होगा और प्रत्येक यूपीएस के साथ डेटा विनिमय प्रोटोकॉल को समझेगा, और दूसरे पर, नेटवर्क इंटरफ़ेस होगा और zabbix_trapper के रूप में डेटा भेज सकता है।
  3. डेटा संग्रह और ट्रांसमिशन मॉडल, कोड भागों और डेटा प्रारूप का परीक्षण करें।


दूसरे और तीसरे पैराग्राफ के कार्यान्वयन के दौरान, मैं एक जगह सभी डेटा इकट्ठा करना चाहता था जो भविष्य में मी / सी के लिए एक अलग डिवाइस को लागू करने की अनुमति देगा।

तो:

  • 1. केबल्स

किसी भी यूपीएस के लिए केबल नहीं थे। सिद्धांत रूप में, पहला कार्य उन लोगों के लिए एक समस्या पेश नहीं करता है जो DB9 कनेक्टर पर संपर्क गिन सकते हैं। जैसा कि यह निकला, न केवल सभी जानते हैं कि कैसे, मेरे सहित। एफ और एम कनेक्टर्स पर संपर्क मिरर किए गए हैं, लेकिन हस्ताक्षर किए हैं, सामान्य तौर पर, गलती करना असंभव है, अगर आप सावधान रहें।



एक छोटा सा ऑफटॉपिक। सर्वर की रीढ़ दो Vmware ESXi होस्ट से बना है, जो दो UPS के साथ रैक में रखे गए हैं। कुछ सर्वरों में 2 बिजली की आपूर्ति होती है। और भाग, दुर्भाग्य से, केवल एक है, यही वजह है कि वे समय-समय पर पीड़ित होते हैं। Zabbix वर्तमान में एक मेजबान पर एक वर्चुअल मशीन के रूप में होस्ट किया गया है। सिद्धांत रूप में, किसी भी कार्य को लागू करने के लिए उबंटू (मैं सेवाओं के लिए इस मंच का उपयोग करता हूं) पर एक छोटा आभासी सर्वर तैनात करना कोई समस्या नहीं है।

इस प्रकार, योजना विकसित हुई: ईएसएक्सआई पर COM पोर्ट -> वर्चुअल मशीन पर कॉम पोर्ट -> सी प्रोग्राम जो यूपीएस से डेटा लौटाता है -> स्क्रिप्ट या प्रोग्राम जो ज़ैबिक्स जाल भेजता है। भविष्य में अंतिम दो बिंदुओं को संयुक्त किया जाना चाहिए। हालांकि यह उस तरह काम करता है।

समस्या को क्रमिक रूप से हल किया गया था, एक यूपीएस के लिए केबल को वायरिंग करके, सर्वर के लिए एक अतिरिक्त कनेक्टर को तार करके (उनमें से दो हैं, प्लस rj-45 एडॉप्टर से DB9), कनेक्शन की जांच करना, प्रोग्राम की जांच करना, Zabbiks में तत्वों को सेट करना।

  • 2. कार्यक्रम द्वारा COM पोर्ट की पूछताछ

निष्पादन योग्य कोड की मेजबानी के लिए एक सर्वर चुनने के लिए सबसे पहली जरूरत थी। मैंने अपने दिमाग को रैक नहीं किया और यह सब ज़ैबिक्स सर्वर पर पोस्ट किया।
दूसरा, मैंने सोचा कि डेटा को कैसे प्रोसेस किया जाए। बाश में डिजाइन के कारण
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); /*'open_port()' -    */
        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; /* 2- ,  1 */
         options.c_cflag &= ~CSIZE; /*  */
         options.c_cflag |= CS8; /* 8*/
         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
        {
           /*    Q1 */
                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 में पोर्ट के साथ काम मिला, आप बैश से पढ़ सकते हैं, लेकिन बैश से स्थिर संचालन को प्राप्त करना संभव नहीं था। सिद्धांत रूप में, linux में C कोड b है। पहले Ippon का परीक्षण किया गया था, फिर Powercom UPS के अध्ययन के दौरान एक पोर्ट मॉनीटर लॉन्च किया गया था, जिससे पता चला कि PowerCom, Megatec प्रोटोकॉल के माध्यम से भी काम करता है, और नेटिव प्रोग्राम "I" और "F" कमांड के साथ स्टार्टअप पर UPS को पोल करता है, और फिर चक्रीय रूप से "Q1"। मैंने पहले तर्क पर "/ dev / ttyS0" या "/ dev / ttyS1" के रूप में पोर्ट नाम लटका दिया, दूसरा तर्क आपको अतिरिक्त मापदंडों का अनुरोध करने की अनुमति देता है, कोड दिखाता है।

डायरेक्टरी / होम / अप्लायंस / प्रोग्राम में रखा गया, इसे यूनीपेस्कैप कहा जाता है। संकलन
g++ -o uniups uniups.cpp 


सिद्धांत रूप में, परिणाम कुछ इस तरह है (हाँ, मैं रूट के तहत काम करता हूं, टिप्पणी भी नहीं करता)

root@zabbix:~# ./uniups /dev/ttyS0
204.4 204.4 204.4 035 49.9 54.8 54.5
root@zabbix:~# ./uniups /dev/ttyS0 name
I
root@zabbix:~# ./uniups /dev/ttyS1 name
#POWERCOM        SXL-2000A  LCD  V4.3
root@zabbix:~# ./uniups /dev/ttyS1
216.3 216.3 216.3 000 50.0 54.2 30.0
root@zabbix:~# ./uniups /dev/ttyS1 stat2
220.0 009 048.0 50.0
root@zabbix:~#

क्या महत्वपूर्ण है, अंत में यह पता चला कि सभी यूपीएस एक ही प्रोटोकॉल का उपयोग करते हैं, जिसने एक कार्यक्रम के उपयोग की अनुमति दी। 2400, 8N1 पर कनेक्शन का उपयोग किया जाता है, बाकी सब बंद है। मरहम में एक मक्खी थी, यूपीएस का नाम आम तौर पर केवल पावरकॉम में लौटता है, इप्पन "I" कमांड को नहीं समझता है, और क्रॉलर "# R1.1.1" देता है।

इसके अलावा, Krauler तत्व को वोल्टेज लौटाता है, और शेष यूपीएस को बैटरी में, प्रलेखन में इसे वर्णित किया जाता है
एसएसएस या एसएसएस ऑन-लाइन इकाइयों के लिए बैटरी वोल्टेज / सेल एसएसएस में प्रदान किया जाता है। स्टैंडबाई इकाइयों के लिए वास्तविक बैटरी वोल्टेज एसएसएस के रूप में प्रदान की जाती है

इसे देखते हुए मुझे पटकथा पर पैच लगाना पड़ा। इसके बारे में नीचे।

  • 3. Zabbix को डेटा भेजना

भेजने के साथ यह सभी अवसरों के लिए एक चिड़ियाघर बन गया। सर्वर पर, ज़ैबिक्स ने प्रक्रिया को गति देने के लिए zabbix_sender उपयोगिता का उपयोग किया।
zabbix_sender -z _ -p 10051 -s ___ -k  -o 

सिद्धांत रूप में, दो यूपीएस के मतदान के लिए, यह पर्याप्त है, इस क्षण तक, हालांकि, मेरे पास एक तीसरा होगा, और भविष्य में मेरे पास एक चौथा होगा, इसलिए मैंने पहले एक का चयन किया और, एक अजीब संयोग से, दूसरे Vmware होस्ट पर एकमात्र लिनक्स सर्वर और इसे भेजा। उसे COM बंदरगाहों।

मैंने zabbix एजेंट का उपयोग नहीं किया है या zabbix_sender की प्रतिलिपि बनाता हूं, मैंने पाया कि

सभी नमक पर बाद का वर्णन बेस 64 में डेटा को एन्कोडिंग में समाहित करता है। जांच करने के लिए, मैंने कमांड का उपयोग किया

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 को कॉल किया और इसे सर्वर पर रखा, मेरी स्क्रिप्ट इस तरह दिखती है:
#!/usr/bin/perl

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 पहले से ही सर्वर पर था।

अगला, हमें एक ऐसी स्क्रिप्ट की जरूरत थी जो सभी घटकों को एक साथ जोड़े और इसे क्रोन में रखा जा सके।

यहां एक पोर्ट के लिए एक उदाहरण दिया गया है, दूसरे पोर्ट के लिए आप बस एक ही कोड कॉपी कर सकते हैं और एक अलग नाम रख सकते हैं। मैंने चक्र नहीं किया था, मैं शायद ही कभी 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 सर्वर तत्वों पर आइटम के साथ एक सरणी, शुरू किया जाना चाहिए। KraulerMemoRT2000 - निर्बाध का नाम, सर्वर पर होस्ट नाम से मेल खाना चाहिए।
  • , , Zabbix , , , NA, , , .
  • ${#array[@]}, . , . : , , . , , . , , .
  • सही [5] = "24.0" बैटरी के लिए वोल्टेज सुधार है (सरणी में 5 वां तत्व) यदि यूपीएस तत्व (बैटरी वोल्टेज / सेल) पर वोल्टेज लौटाता है। मेरे पास बैटरी में 6 तत्व हैं, श्रृंखला में 4 टुकड़े हैं, कुल 24. सिद्धांत में, यह प्रोटोकॉल में वर्णित है। मुझे एक अलग तत्व बनाने के लिए यह अनावश्यक लगा, क्योंकि मेरे पास जितने भी यूपीएस हैं, उनकी निगरानी टेम्पलेट द्वारा की गई है और सभी में 48 वोल्ट हैं। जब विभिन्न वोल्टेज की यूपीएस की निगरानी करते हैं, तो निश्चित रूप से, संरचना को थोड़ा बदलना आवश्यक होगा, यह सर्वर पर बैटरी मापदंडों को हथौड़ा करने के लिए इष्टतम हो सकता है।


उपरोक्त स्क्रिप्ट को हर मिनट निष्पादन के लिए क्रोन में जोड़ा जाता है। इस लेख में Zabbix सेटिंग पर विचार नहीं किया गया है।

सिद्धांत रूप में, वह सब है। मुझे खुशी होगी अगर एकत्र की गई जानकारी किसी के लिए उपयोगी है।

Source: https://habr.com/ru/post/hi397637/


All Articles