> ## Documentation Index
> Fetch the complete documentation index at: https://doc.lwops.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 10.6. 华为ups监控

#### 配置双串口服务器(计算机和ups之间通信的适配器)

USR-TCP232-410s是一款工业级双串口服务器，实现RS232+485转以太网双向透传功能，两路串口同时独立工作，互不影响；产品采用H7内核，内置精心优化的TCP/IP协议栈；支持Modbus网关功能；支持双重看门狗、多种保活机制；支持注册包+双向心跳包、虚拟串口、自动重连等功能。

![10.6. 华为ups监控 操作截图 1](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-01.png)

配置修改串口服务器IP 1、线缆链接： 1、网口用网线连接计算机 2、RS232口用串口线连接计算机， 3、RS485口从左到右分别为A口、B口和地线，需要用T568B网线连接，先剪掉一个水晶头，将里面的线裸露出来一部分，然后将橙白色和橙色两个线的金属裸露出来，将第一根橙白色连接A口，第二根橙色线连接B口，最后将网线的另一端直接接到ups 4、接上电源

![10.6. 华为ups监控 操作截图 2](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-02.png)

![10.6. 华为ups监控 操作截图 3](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-03.png)

2、 配置计算机地址 计算机要有一个网卡与串口服务器同一网段，而且计算机要同时能上网

![10.6. 华为ups监控 操作截图 4](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-04.png)

![10.6. 华为ups监控 操作截图 5](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-05.png)

![10.6. 华为ups监控 操作截图 6](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-06.png)

3、下载配置软件修改适配器IP： [【设置软件】（老版本停产）M4系列设置软件410s/N510/520/540/580/668/e2/ed2 -济南有人物联网技术有限公司官网](http://www.usr.cn/Download/230.html) 下载地址

![10.6. 华为ups监控 操作截图 7](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-07.png)

然后安装，打开软件

![10.6. 华为ups监控 操作截图 8](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-08.png)

输入账号密码：admin/admin

![10.6. 华为ups监控 操作截图 9](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-09.png)

在这里配置IP然后重启适配器，就配置成功

![10.6. 华为ups监控 操作截图 10](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-10.png)

其他测试软件网址： [USR-TCP232-410S基本测试通信和使用方案（232串口）-济南有人物联网技术有限公司官网](https://www.usr.cn/Faq/209.html)

![10.6. 华为ups监控 操作截图 11](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-11.png)

4、配置IP完毕，将网口连接计算机那一端的网线拔掉，接到交换机，让双串口服务器可以联网

5、配置双串口服务器参数，直接在浏览器输入上面修改的双串口服务器的IP访问网页登录，配置完成后都要保存 配置然后重启

![10.6. 华为ups监控 操作截图 12](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-12.png)

![10.6. 华为ups监控 操作截图 13](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-13.png)

6、使用 多功能调试助手 工具调试看ups是否能够正常返回数据

![10.6. 华为ups监控 操作截图 14](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-14.png)

在发送区发送modbus-RTU报文，有数据返回就证明双串服务器和ups接线以及配置成功

![10.6. 华为ups监控 操作截图 15](https://lwweb.oss-cn-shenzhen.aliyuncs.com/docs/images/yuque/huawei-ups/image-15.png)

7、modbus报文格式（都为16进制）

信息分两种类型: （1）由主机发出到从机的命令信息（简称命令信息） （2）由从机返回到主机的响应信息（简称响应信息） 比如： 发出报文格式 01 03 00 01 00 02 C4 0B 分别代表： 01 站地址 03 功能码 00 01 起始寄存器 00 02 寄存器长度 C4 0B CRC校验

响应的报文格式 01 03 04 01 46 01 3B 5A 59 分别代表 01 站地址 03 读输出寄存器 04 返回的字节计数 01 46 01 3B 具体四个字节 5A 59 CRC校验

#### 脚本

8、上面配置接线完成，上传脚本和模板就可使用(下面为华为的ups) 脚本需要下载模块 crcmod，才能运行（pip3 install crcmod,如果安装不了需要填写python3的绝对路径）

```plain theme={null}
#!/usr/bin/env python3
#author: aizhen
#version: 0.1
#desc: RTU
#date: 2022-03-21

import socket
import base64
import crcmod
import binascii
import sys

def CRCAdd(read):
'''生成CRC16校验码，CRC16/modbus'''
crc16 = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)
rawdata = read.replace(" ", "")
#修正后数据
#print(rawdata)
#字符串变数
data = binascii.unhexlify(rawdata)
readcrcout = hex(crc16(data)).upper()
#print(readcrcout)
str_list = list(readcrcout)
# print(str_list)
# 位数不足补0，因为一般最少是5个
if len(str_list) == 5:
str_list.insert(2, '0')
#用""把数组的每一位结合起来组成新的字符串
crc_data = "".join(str_list)
#生成CRC校验
#print(crc_data)
#print('CRC16校验: %s' % (crc_data[4:] + ' ' + crc_data[2:4]))
#高低位判断，高位在前，低位在后原则
CRC1=int(crc_data[4:], 16)
CRC2=int(crc_data[2:4], 16)
read = rawdata + crc_data[4:] + crc_data[2:4]
# print(crc_data[4:],crc_data[2:4])
'''
if CRC1 > CRC2:
high_CRC=crc_data[4:]
low_CRC=crc_data[2:4]
else:
high_CRC=crc_data[2:4]
low_CRC=crc_data[4:]
read = rawdata + high_CRC + low_CRC
'''
#    print (read)
#   print (type(read))
#print('增加Modbus_CRC16校验:>>> %s' % read)
#    print(read)
return read

def ModbusRTU():
'''python3 调用socket连接串口服务器（网络适配器）以modbusRTU方式发送16进制报文，进行数据采集，'''
ip  = str(sys.argv[1])
port = int(sys.argv[2])
msg = sys.argv[3]
msg = msg.replace(" ", "")
msg_test = msg
#  print(msg_test[4:8])
# print(msg_test)
msg_test = msg_test[4:8]
#  print(msg_test)
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#增加CRC校验码
msg_CRC = CRCAdd(msg)
#连接超时时间
s.settimeout(5)
s.connect((ip, port))
#将代码转换成16进制字节
msg_CRC = bytes.fromhex(msg_CRC)
#  print(msg_CRC)
# print(type(msg_CRC))
#proint(msg_CRC)
# print(msg_CRC)
s.send(msg_CRC)
rawdata = s.recv(2048)
#  print(rawdata)
# print(rawdata)
#print(rawdata)
#关闭TCP连接
s.close()
#数据处理，将字节转换成16进制
data = base64.b16encode(rawdata).decode('ascii')
#   print(data)
#0404需要转换为二进制
if msg_test =="0404":
#再取一次数据，确保数据没有问题
if data[6:10]!="0003":
msg_test = msg
msg_test = msg_test[4:8]
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
msg_CRC = CRCAdd(msg)
s.settimeout(5)
s.connect((ip, port))
msg_CRC = bytes.fromhex(msg_CRC)
s.send(msg_CRC)
rawdata = s.recv(2048)
s.close()
data = base64.b16encode(rawdata).decode('ascii')

B_count = int(int(data[4:6], 10) / 2)
B_first = 6
B_end = 10
dataInfo = []
B_data = data[6:10]
B_data = int(B_data, 16)
B_data = bin(B_data).replace("0b","")
dataInfo.append(B_data)
B_count-=1
while B_count > 0:
B_first+=4
B_end+=4
B_data = data[B_first:B_end]
B_data = bin(int(B_data, 16)).replace("0b","")
dataInfo.append(B_data)
B_count-=1
else:
B_count = int(int(data[4:6], 10) / 2)
B_first = 6
B_end = 10
dataInfo = []
B_data = data[6:10]
B_data = int(B_data, 16)
B_data = bin(B_data).replace("0b","")
dataInfo.append(B_data)
B_count-=1
while B_count > 0:
B_first+=4
B_end+=4
B_data = data[B_first:B_end]
B_data = bin(int(B_data, 16)).replace("0b","")
dataInfo.append(B_data)
B_count-=1
else:
#获取返回字节数，得到具体个数
B_count = int(int(data[4:6], 10) / 2)
#数据长度为2字节，长度为4
#将数据转化为十进制
B_first = 6
B_end = 10
dataInfo = []
B_data = data[6:10]
B_data = int(B_data, 16)
dataInfo.append(B_data)
#  print(dataInfo)
B_count-=1
while B_count > 0:
B_first+=4
B_end+=4
B_data = data[B_first:B_end]
B_data = int(B_data, 16)
dataInfo.append(B_data)
B_count-=1
#   print(dataInfo)
#print(dataInfo)
#以相关项方式采集数据，以：分割
# print(dataInfo)
#条件判断属于华为告警
# data="11030200087841"

#msg_test取的是基础寄存地址，属于告警的寄存地址
#data[6:10]是返回的数据为16进制，需要转化为二进制
#转化为二进制后0为正常，1为告警
#而且二进制需要反序，查看bit位，需要对应起来,因为bit位最多为16位，就需要补全
# data="1103020012F846"
if msg_test=="9CDB" or msg_test=="9CDC" or msg_test=="9CDE" or msg_test=="9CDF" or msg_test=="9CE0" or msg_test=="9CE1" or msg_test=="9CE3" or msg_test=="9CE4" or msg_test=="9CE5" or msg_test=="9CE8" or msg_test=="9CE9" or msg_test=="9CEA" or msg_test=="9CEB" or msg_test=="9CEC" or msg_test=="9CED" or msg_test=="9CEE" or msg_test=="9CF3" or msg_test=="9CF4" or msg_test=="9CF6" or msg_test=="9CF7":
#再运行一次，确保数据准确性
if data[6:10]!="0000":
#     print("-------")
msg_test = msg
msg_test = msg_test[4:8]
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
msg_CRC = CRCAdd(msg)
s.settimeout(5)
s.connect((ip, port))
msg_CRC = bytes.fromhex(msg_CRC)
s.send(msg_CRC)
rawdata = s.recv(2048)
s.close()
data = base64.b16encode(rawdata).decode('ascii')
#    print("-------")
if data[6:10]=="0000":
#   print(data)
data="0000000000000000"
d=-1
for i in data:
d+=1
print("B%s=%s" % (d,i), end=" ")
else:
# print(data)
data_bin=bin(int(data[6:10],16))[2:]
data_list=list(data_bin)
end_list=[]
for i in range(16-len(data_bin)):
end_list.append(0)
for i in data_list:
end_list.append(i)
end_list.reverse()
d=-1
for i in end_list:
d+=1
print("B%s=%s" % (d,i), end=" ")
if data[6:10]=="0000":
#   print(data)
data="0000000000000000"
d=-1
for i in data:
d+=1
print("B%s=%s" % (d,i), end=" ")

#      else:
#       # print(data)
#        data_bin=bin(int(data[6:10],16))[2:]
#        data_list=list(data_bin)
#        end_list=[]
#        for i in range(16-len(data_bin)):
#          end_list.append(0)
#        for i in data_list:
#          end_list.append(i)
#        end_list.reverse()
#        d=-1
#        for i in end_list:
#          d+=1
#          print("B%s=%s" % (d,i), end=" ")
else:
# print(dataInfo)
for i in dataInfo:
print(i, end=' ')

if __name__ == '__main__':
#脚本执行示例
# python3 modbus-RTU.py '192.168.109.242' 8234 '01 03 00 01 00 01'
ModbusRTU()
```

#### 模板

[华为动环UPS.xml](https://drive.weixin.qq.com/s?k=AAUAJQcEAEkcCixXyIAXcA6wYHAKM)
