本文主要介绍,如何通过串口获取UPS主机的运行状态,并通过PRTG统计监控和告警。
不同UPS主机厂的串口通信协议不同,但是市面上有一种比较通用的协议,如果你使用的是EATON,山特等等国产UPS,大概率用的都是Q1协议。
本文涉及的知识点:

1、UPS串口通信分析
2、python中的pyserial模块使用。
3、PRTG的lookup值查询功能定义

本文最终实现效果如下:

目录

  • 一、UPS串口协议分析
    • 1、搭建抓包环境
    • 2、开始抓包
    • 3、分析报文内容
  • 二、python中serial模块的使用
  • 三、PRTG中的值查询功能
    • 1、新建值查询定义文件
    • 2、加载定义文件
    • 3、编辑通道,调用定义文件
  • 搞定!

一、UPS串口协议分析

原则上,每家UPS主机厂都多多少少会有一些自己的私有协议。开发文档也不一定公开。但是我们可以稍微分析一下,基本都可以分析得出每家主机厂的通信协议。
本文一一款山特的国产UPS举例,说明如何分析串口通信协议。

1、搭建抓包环境

说到网络抓包,大家都很熟悉。但是如何对串口通信进行抓包?
一种办法是通过串口抓包软件,对本机串口进行抓包。例如Device Monitoring Studio

软件功能比较强大,是收费软件,免费试用15天。从截图可以看出,选择了通信端口以后,可以很轻松监控串口数据。另外从界面上看它还有数据统计等很多其它功能,我没有全部试用,就不多介绍了。需要注意一点,它的启动按钮在界面右侧下方。

另一种办法是如果使用了串口转以太网盒子,可以在网络侧进行抓包。或者利用虚拟串口软件自带的抓包功能。

2、开始抓包

解决了抓包问题后,我们开始尝试通过厂商自带的方式与UPS尝试通信。
因为原厂的管理软件是肯定可以正常可以与UPS通信的,所以我们的思路是尝试去分析原厂软件是如何管理UPS的,并以此设计和编写我们自己的监控脚本。
首先用最正经的方式,下载原厂的UPS管理软件,安装,连接UPS。

当通过原厂的管理软件可以读到UPS后,我们就开始分析此时COM口上的通信内容,并以此分析主机的串口通信协议。

3、分析报文内容

在原厂管理软件在与UPS主机通信的时候,我们抓到了以下关键内容。

问询帧1:
HEX:
51 31 0D
ASCII:
Q1
应答帧1:
HEX:
28 32 33 37 2E 31 20 32 33 37 2E 39 20 32 32 30 2E 30 20 30 30 36 20 34 39 2E 39 20 32 2E 32 39 20 32 38 2E 38 20 30 30 30 30 30 30 30 31 0D
ASCII:
(237.1 237.9 220.0 006 49.9 2.29 28.8 00000001

问询帧2:
HEX:
46 0D
ASCII:
F
应答帧2:
HEX:
23 32 32 30 2E 30 20 31 33 36 20 31 39 32 2E 30 20 35 30 2E 30 0D
ASCII:
#220.0 136 192.0 50.0

这其中(237.1 237.9 220.0 006 49.9 2.29 28.8 00000001的这一句,是不是看起来就很像是电压和功率等数据呢?而且,还是用ASCII编码,肉眼可见。
配合原厂的管理软件,多观察一会抓包数据和软件显示的数据,我们大致可以分析出这个应答帧中各个字段的含义。
笔者直接粘分析结果。同时对于市面上大部分用0x51 31 0D做请求帧的UPS,应答帧的解释都是差不多的。

( MMM.M NNN.N PPP.P QQQ RR.R S.SS TT.T U
( 237.1 237.9 220.0 006 49.9 2.29 28.8 00000001
起始码0x28 输入电压 输入故障电压 输出电压 负载% 市电频率Hz 电池电压 温度 状态码

关于故障输入电压:
对于在线式UPS而言,此字段保持位上一次电压瞬变前的电压。例如市电中断时,此字段保持为断电前的输入电压,并一直维持到下一次查询。

关于电池电压:
在线式UPS此电压为单体电池电压。电池组总电压请自行计算乘以电池数量乘以电池cell数量。总电池组用了16节12v铅酸蓄电池串联,每个铅酸蓄电池含6个单体电池。所以总电池组电压是2.29v * 6 * 16=219.84v

关于状态码:
Bit7 1 : Utility Fail ( Immediate )
Bit6 1 : Battery Low
Bit5 1 : Bypass/Boost Active
Bit4 1 : UPS Failed
Bit3 1 : UPS Type is Standby (0 is On-line)
Bit2 1 : Test in Progress
Bit1 1 : Shutdown Active
Bit0 1 : Speaker Config ON

二、python中serial模块的使用

有了数据和解释。接下来写代码。serial模块默认自带,一般不需要单独pip安装
本文给出一个可以用于PRTG前端展示的示例代码,详细解释看注释。

import serial
from time import sleep
import json
import re
import sys
#PORT = '/dev/cu.usbserial-AK08ROD4'
data = json.loads(sys.argv[1])
params=str(data['params']).replace("'",'"')
params = json.loads(params)
PORT = params['PORT']
#PRTG调用时,我们将COM口的编号通过['params']['PORT']字段传递进来。def get_serial_data(serial_session):try:serial_command = bytes.fromhex('51 31 0D')#16进制格式的问询指令serial_session.write(serial_command)#向UPS发送问询指令sleep(1)data =data = serial_session.read_all().decode("gbk")#读取回显serial_session.close()except Exception as err:return '(000 000 000 000 000 000 000 00000001'else:return datadef sort_serial_data(serial_data):#整理数据try:data=serial_data.split()#原始数据切片data[0]=data[0].replace('(','')data_dict={}status_flag=re.findall(r'.{1}', data[7])#状态码切片data_dict['INPUT_Voltage']=[data[0],'V']data_dict['INPUT_Fault_Vlotage']=[data[1],'V']data_dict['OUTPUT_Vlotage']=[data[2],'V']data_dict['OUTPUT_Load']=[data[3],'%']data_dict['OUTPUT_Frequency']=[data[4],'Hz']data_dict['Battery_Vlotage']=[float(data[5])*96,'V']data_dict['UPS_Temperature']=[data[6],'degress C']data_dict['Speaker_Status']=[status_flag[7],'#']data_dict['Shutdown_Active_Status']=[status_flag[6],'#']data_dict['Test_in_Progress']=[status_flag[5],'#']data_dict['UPS_Type']=[status_flag[4],'#']data_dict['UPS_System_Failed']=[status_flag[3],'#']data_dict['Bypass_Status']=[status_flag[2],'#']data_dict['Battery_Low_Alarm']=[status_flag[1],'#']data_dict['Input_Power_Status']=[status_flag[0],'#']except Exception as err:raise errelse:return data_dictdef print_json(value_list):try:data={"prtg": {"result": [{"Channel": "Run Result","CustomUnit": "#","Mode":"Absolute","Float":1,"Value":"0"}]}}for i in value_list:data_channels={"Channel": i,"CustomUnit": value_list[i][1],"Mode":"Absolute","Float":2,"Value":value_list[i][0]}data['prtg']['result'].append(data_channels)print (json.dumps(data, sort_keys=True, indent=2))except Exception as err:raise errdef main():try:serial_session=serial.Serial(port=PORT, baudrate=2400, bytesize=8, parity='N', stopbits=1, xonxoff=0)#定义串口连接参数serial_data=get_serial_data(serial_session)data=sort_serial_data(serial_data)print_json(data)except Exception as err:data={"prtg": {"error": 1,"text": str(err)}}print (json.dumps(data, sort_keys=True, indent=2))if __name__ == "__main__":main()

输出符合PRTG监控系统格式的json结构体数据

{"prtg": {"result": [{"Channel": "Run Result","CustomUnit": "#","Float": 1,"Mode": "Absolute","Value": "0"},{"Channel": "INPUT_Voltage","CustomUnit": "V","Float": 2,"Mode": "Absolute","Value": "234.9"},{"Channel": "INPUT_Fault_Vlotage","CustomUnit": "V","Float": 2,"Mode": "Absolute","Value": "234.9"},{"Channel": "OUTPUT_Vlotage","CustomUnit": "V","Float": 2,"Mode": "Absolute","Value": "220.0"},{"Channel": "OUTPUT_Load","CustomUnit": "%","Float": 2,"Mode": "Absolute","Value": "006"},{"Channel": "OUTPUT_Frequency","CustomUnit": "Hz","Float": 2,"Mode": "Absolute","Value": "50.0"},{"Channel": "Battery_Vlotage","CustomUnit": "V","Float": 2,"Mode": "Absolute","Value": 219.84},{"Channel": "UPS_Temperature","CustomUnit": "degress C","Float": 2,"Mode": "Absolute","Value": "28.9"},{"Channel": "Speaker_Status","CustomUnit": "#","Float": 2,"Mode": "Absolute","Value": "1"},{"Channel": "Shutdown_Active_Status","CustomUnit": "#","Float": 2,"Mode": "Absolute","Value": "0"},{"Channel": "Test_in_Progress","CustomUnit": "#","Float": 2,"Mode": "Absolute","Value": "0"},{"Channel": "UPS_Type","CustomUnit": "#","Float": 2,"Mode": "Absolute","Value": "0"},{"Channel": "UPS_System_Failed","CustomUnit": "#","Float": 2,"Mode": "Absolute","Value": "0"},{"Channel": "Bypass_Status","CustomUnit": "#","Float": 2,"Mode": "Absolute","Value": "0"},{"Channel": "Battery_Low_Alarm","CustomUnit": "#","Float": 2,"Mode": "Absolute","Value": "0"},{"Channel": "Input_Power_Status","CustomUnit": "#","Float": 2,"Mode": "Absolute","Value": "0"}]}
}
Program ended with exit code: 0

三、PRTG中的值查询功能

上面的例子中,我们将UPS的状态码传递给上层监控系统。但是监控系统如何知道状态码为0和为1时候,代表什么意思呢?

{"Channel": "Input_Power_Status","CustomUnit": "#","Float": 2,"Mode": "Absolute","Value": "0"}

例如这个通道的数据中,Value字段表示市电输入状态,为0时表示输入正常,为1时表示市电输入中断。
这时候,我们需要用PRTG的值查询功能,将不同的数值定义成不同的状态。

1、新建值查询定义文件

在PRTG核心服务器的C:\Program Files (x86)\PRTG Network Monitor\lookups\custom目录下,我们新建一个Santak_UPS_RS232_Alarm.ovl文件,并用记事本打开进行编辑,内容如下:

<?xml version="1.0" encoding="UTF-8"?><ValueLookup id="Santak_UPS_RS232_Alarm" desiredValue="1" undefinedState="Warning"><Lookups><SingleInt state="OK" value="0">Run_Status_OK</SingleInt><SingleInt state="Error" value="1">Run_Status_Error</SingleInt></Lookups></ValueLookup>

我们定义:
value=0的时候,文本显示"Run_Status_OK",状态为正常(OK)。
value=1的时候,文本显示"Run_Status_Error",状态为停机(Error)。
value等于其他值的时候,undefinedState=“Warning”,状态为告警(Warning)。

2、加载定义文件

在PRTG控制台中,进入系统->管理工具->点击加载查询和文件列表

3、编辑通道,调用定义文件

点击通道右侧的齿轮图标,打开通道编辑

在编辑通道窗口内,在“值查询”下拉菜单中选中刚才我们新建的定义文件。

然后,这个通道的值就不再是简单的0和1了。而是变成了带有文本描述和告警状态定义的通道状态。

搞定!

往期回顾:
【逗老师带你学IT】PRTG监控通过Python+Modbus RTU获取温湿度传感器数据
【逗老师带你学IT】PRTG监控通过Python+Modbus TCP获取温湿度传感器数据
【逗老师带你学IT】职场数据中心异地出口容灾,H3C的IP上一跳保持技术
【逗老师带你学IT】阿里云监控报警回调+转发企业微信+转发SnmpTrap+PRTG
【逗老师带你学IT】HUAWEI华为防火墙自动化运维Python ssh管理网络设备
【逗老师带你学IT】PRTG获取HUAWEI FusionServer iBMC传感器状态
【逗老师带你学IT】PRTG自定义脚本ssh登录网络设备获负载均衡链路状态
【逗老师带你学IT】Django+IIS+Python构建微软AD域控API管理中心
【逗老师带你学IT】通过企业微信推送AD域密码即将到期提醒
【逗老师带你学IT】AD域控 Dsquery 查询命令实例汇总
【逗老师带你学IT】Google Admin服务账号+API管理G suit内所有网域用户
【逗老师带你学IT】PRTG监控系统通过企业微信推送图文混排告警消息
【逗老师带你学IT】PRTG HTTP API获取指定传感器流量图表图片
【逗老师带你学IT】PRTG监控系统合并多个传感器通道数据
【逗老师带你学IT】PRTG监控系统通过企业微信推送告警消息
【逗老师带你学IT】PRTG监控系统配合树莓派采集企业内部无线网络质量
【逗老师带你学IT】vMware ESXi 6.7合并第三方硬件驱动
【逗老师带你学IT】Kiwi Syslog Server安装和配置教程
【逗老师带你学IT】Kiwi Syslog Web Access与Active Directory集成认证
【逗老师带你学IT】vMware ESXi 6.7合并第三方硬件驱动
【逗老师带你学IT】Windows Server Network Policy Service(NPS)记账与审计
【逗老师带你学IT】Windows Server NPS服务构建基于AD域控的radius认证
【逗老师带你学IT】AD域控和freeradius集成认证环境,PAP,MSCHAPV2
【逗老师带你学IT】深信服SSL远程接入与深信服行为审计同步登陆用户信息

【逗老师带你学IT】PRTG监控通过Python通过串口监控UPS运行状态,PRTG值查询功能定义相关推荐

  1. 【逗老师带你学IT】PRTG监控通过Python+Modbus RTU获取温湿度传感器数据

    前文[逗老师带你学IT]PRTG监控通过Python+TCP Modbus获取温湿度传感器数据中我们讲了如何通过Python读取支持TCP Modbus的传感器数据.本章我们讲解下如何读取Modbus ...

  2. 【逗老师带你学IT】PRTG监控通过Python+TCP Modbus获取温湿度传感器数据

    本文介绍,Python如何通过TCP Modbus协议获取温湿度传感器数据.并在PRTG监控系统中呈现. 本文主要涉及知识点: 1.Python的ModbusTCP客户端实现 2.常见温湿度传感器中, ...

  3. 【逗老师带你学IT】职场数据中心异地出口容灾,H3C的IP上一跳保持技术

    本文介绍,如何通过IP上一跳保持的方式,使多个城市的公网出口可以同时为一台服务器提供DNAT映射,并确保回包路由正确. 目录 一.需求背景和拓扑 二.入站DNAT(Destination Networ ...

  4. 【逗老师带你学IT】HUAWEI华为防火墙自动化运维Python ssh管理网络设备

    本文,介绍一种.通过Django框架,搭建API服务器,并通过此API服务器管理华为防火墙.并以此衍生出,通过Django+Python+ssh的方式管理网络设备的方法. 关于Django环境的搭建, ...

  5. 【逗老师带你学IT】PRTG安装教程-部署简单功能强大的监控软件

    一.PRTG简介 个人总结PRTG的优点: 1.脑残化部署,Windows下直接双击安装,剩下的全靠点点点. 2.脑残化使用,全程点点点即可完成添加加设备.加监控点. 3.强大的性能,支持数万个传感器 ...

  6. 【逗老师带你学IT】PRTG监控系统通过企业微信推送图文混排告警消息

    往期回顾: [逗老师带你学IT]PRTG监控系统通过企业微信推送告警消息 [逗老师带你学IT]PRTG HTTP API获取指定传感器流量图表图片 在往期的文章里,我们讲了 1.如何在PRTG产生告警 ...

  7. 【逗老师带你学IT】PRTG监控系统通过阿里云API获取云产品运行状况

    本文介绍如何使PRTG监控系统通过阿里云监控API获取阿里云产品监控数据.例如网络带宽,ECS性能,RDS产品性能等. 本文主要涉及的技术点: 1.PRTG监控系统高级自定义传感器的使用 2.PRTG ...

  8. 【逗老师带你学IT】PRTG获取HUAWEI FusionServer iBMC传感器状态

    本文介绍如何使PRTG获取HUAWEI FusionServer iBMC传感器状态.以及衍生出如何通过ipmi通用协议监控所有服务器的带外管理状态. 本文主要涉及的技术点: 1.服务器ipmi命令行 ...

  9. 【逗老师带你学IT】PRTG HTTP API获取指定传感器流量图表图片

    PRTG服务器支持通过HTTP API获取监控数据和监控图表.本文主要介绍HTTP API的方式拉取任意传感器流量图表.文章内容翻译和重新整理自PRTG用户手册. 原文链接: PRTG Manual: ...

最新文章

  1. Python基础知识详解
  2. WPF wpf scrollviewer 触屏滚动 窗体弹跳
  3. C++向量 vector动态数组
  4. MATLAB基本操作(七):有关文件路径的几个函数在编程中的作用
  5. mysql 5.1 innodb trx_mysql 优化innodb_flush_log_at_trx_commit的案例介绍
  6. OneNET微信平台授课笔记
  7. IDEA下svn配置与share project
  8. python 高级编程 豆瓣_python 的一些高级编程技巧
  9. Solartimes共识——PowerDesigner设计——引用的命名
  10. android 创建typeface 对象,java – 检查Android中的Typeface对象的族
  11. python基础打卡(9/18)
  12. wordpress主题制作,wordpress主题模板制作
  13. 企业微信服务商第三方应用开发流程
  14. 史上最新最全的ADB命令行
  15. 使用fastdfs上传视频并使用FFmpegFrameGrabberFrameGrabber在上传视频时截图作为封面
  16. 字符串匹配算法之BF算法(即暴力算法)
  17. 大搜车java_记录去大搜车的一道笔试题
  18. intel rst linux 驱动下载,英特尔RST快速存储技术驱动下载_英特尔RST快速存储技术驱动官方下载-太平洋下载中心...
  19. HTTP状态码含义:428、429、431、511431状态码详解
  20. PostgreSQL + Postgis

热门文章

  1. 半导体物理载流子浓度计算思考(统计物理的重要应用)
  2. 黄良会:关于香港汽车社会发展史的那些事(上)
  3. b站电脑客户端_苹果最强电脑和显示器即将发售 / 央视新闻入驻 B 站 / 淘集集启动破产清算...
  4. Python爬虫笔记——字符串的常用方法
  5. STM32F103入门 | 6.工程模板的建立
  6. 自动化运维-ELK搭建
  7. 求数组中满足要求的元素和
  8. Linux文件管理和xfs文件系统的备份恢复
  9. vscode打开html中文乱码,Visual Studio Code 1.44 解决中文代码显示乱码问题(小白图文教程)...
  10. php和吉他哪个难学,良心点评解析红棉和雅马哈的古典吉他有区别没有?哪个好?老手吐槽大实话...