Nodejs中使用net-snmp库读取智慧站房的温湿度、空调等实时数据
前言
最近有一个项目中需要使用SNMP
协议的get
命令读取远程智慧站房的站房温度、湿度等实时数据,并且可以通过set
命令对空调进行开
和关
的控制。
网络走的是V**,知道远程主机的IP地址和community口令,以及对应每个设备的OID,就比较容易获取对应设备的实时数据,以及对空调进行开关控制了。
SNMP协议
概述: SNMP 支持 V1 、V2、V3协议,get,getnext 和 set 三种操作,由于设备所接的监控设备 丌同,扩展的模块多少和类型丌同,对应的监测量丌是固定的,所以设备没有固定的 MIB 库,监测量不 OID 对应的原则如内容所示。可以采用 getnext 遍历整个设备 MIB。对于监 测量的描述信息,采用 OCTET STRING,编码方式为 gb2312,对于开关量(输入和输 出),采用 INTEGER 类型,只有 0 和 1 两个值,对于模拟量(输入和输出),采用 OCTET STRING 表示,默认保留小数点后 4 位小数,对于枚举量,采用 INTEGER 表示,门禁等 信息 OCTET STRING 表示,表示方式遵循设备相应协议。
实时数据和监测点描述信息对应的 OID 结构描述如下图:
监测类型对应关系如下图所示:
空调的相关控制命令:
首先可以使用net-snmp
等工具获取相关的oid信息,我使用的是Snmputilg.exe这个工具获取对应的站房温度、站房湿度、空调红外传感器1、空调红外传感器2的描述oid以及对应的值。对于空调控制来说,需要现场运维人员进行相应的学习:比如说自动模式、关灯指令,具体描述见上面的SNMP文档协议。
nodejs使用net-snmp库实现远程读取温湿度等环境实时数据,控制空调
关于nodejs中snmp
库的选择,目前https://www.npmjs.com/search?q=snmp中比较流行的有如下两个nodejs库:
- net-snmp This module implements versions 1, 2c and 3 of the Simple Network Management Protocol (SNMP).
- snmp-node This is a native SNMP library for Node.js. The purpose is to provide enough functionality to perform large scale monitoring of network equipment. Current features towards this end are:
- Full implementation of SNMPv2c, including 64 bit data types.
- Support for Get, GetNext and Set requests, with optimizations such as GetAll and GetSubtree.
- No unusual external dependencies, no non-JavaScript code.
- Very high performance, unlimited parallellism. (There are always limits. However, there are no arbitrary such imposed by this code and you at least won’t run out of file descriptors.)
- De facto standards compliance. Generated packets are compared against Net-SNMP and should be identical in all relevant aspects.
- Well tested. Test coverage should be at or close to 100% for all important code paths.
我使用的是net-snmp
这个Nodejs库。
使用nodejs和net-snmp的js代码如下:
var snmp = require ("net-snmp");
var moment = require('moment');
const nodemon = require("nodemon");
var session = snmp.createSession ("15.129.13.267", "public");
// 15.129.13.267 靖屏大道站 学习了“开”和“关”两个指令
// 温湿度模块1 模拟量输入(AI1) 站房温度 27.40 无告警 连接正常
// 温湿度模块1 模拟量输入(AI2) 站房湿度 46.40 无告警 连接正常
// 站房温度
// 监测点配置(类型:模拟量输入AI,地址:1,索引:1)
// 1.3.6.1.4.1.50688.2.4.1.1.0
// 站房湿度
// 监测点配置(类型:模拟量输入AI,地址:1,索引:2)
// 1.3.6.1.4.1.50688.2.4.1.2.0
// 命令=GET: OID=1.3.6.1.4.1.50688.2.4.1.2.0; 值=5110
var items = [
{name: '站房温度', oid: '1.3.6.1.4.1.50688.2.4.1.1.0'},
{name: '站房湿度', oid: '1.3.6.1.4.1.50688.2.4.1.2.0'},
{name: '空调控制指令1', oid: '1.3.6.1.4.1.50688.2.9.256.1.0'},
{name: '空调控制指令2', oid: '1.3.6.1.4.1.50688.2.9.256.2.0'}
];
// snmpset 控制空调
// 控制空调之前,需要现场学习对应的指令,目前空调控制器有两个红外探头,有两个通道
// 开空调
// 自动模式 00 自动模式、风速-自动、上下扫风、左右扫风
function openAirCondition() {
this.set('1.3.6.1.4.1.50688.2.9.256.1.0', 0);
}
// 关空调
// 关机 63 可以再任何模式下学习
function closeAirCondition() {
this.set('1.3.6.1.4.1.50688.2.9.256.1.0', 63);
}
function set(strOid, iVal) {
var varbinds = [
{
oid: strOid,
type: netsnmp.ObjectType.Integer,
value: iVal
}
];
this.sessionObj.set (varbinds, function (error, varbinds) {
if (error) {
console.error (error.toString ());
} else {
// for version 1 we can assume all OIDs were successful
console.log (varbinds.oid + "|" + varbinds.value);
// for version 2c we must check each OID for an error condition
if (netsnmp.isVarbindError (varbinds))
console.error (netsnmp.varbindError (varbinds));
else
console.log (varbinds.oid + "|" + varbinds.value);
}
});
}
// 获取数据
function getData() {
var oids = [];
items.forEach((val, index) => {
oids.push(val.oid);
});
session.get (oids, function (error, varbinds) {
if (error) {
console.error (error);
} else {
for (var i = 0; i < varbinds.length; i++)
if (snmp.isVarbindError (varbinds[i]))
console.error (snmp.varbindError (varbinds[i]))
else
console.log (varbinds[i].oid + " = " + varbinds[i].value);
}
//session.close ();
});
}
session.trap (snmp.TrapType.LinkDown, function (error) {
if (error)
console.error (error);
});
// 每隔2秒钟获取一次当前站房的温湿度、空调红外传感器1和空调红外传感器2的值
setInterval(()=>{
let nowTime = moment().format('YYYY-MM-DD HH:mm:ss');
console.log('当前时间为:', nowTime);
getData();
}, 2000);
运行结果如下图所示:
参考资料
- http://www.net-snmp.org/
- https://www.npmjs.com/package/net-snmp
- https://www.npmjs.com/package/snmp-node
- Thinking in SQL系列之:数据挖掘K均值聚类算法与城市分级
- 设计模式专题(二十) ——职责链模式
- 设计模式专题(二十一) ——中介者模式
- 设计模式专题(二十二) ——享元模式
- 设计模式专题(二十三) ——解释器模式
- Thinking in SQL系列之数据挖掘C4.5决策树算法
- 设计模式专题(二十四) ——访问者模式
- PHP实用功能——modern PHP读书笔记(一)
- ModernPHP读书笔记(二) ——PHP开发标准
- iBatis.Net(6):Data Map(深入)
- iBatis.Net(5):Data Map(了解)
- ModernPHP读书笔记(三)——PHP的良好实践
- PHP开发过程的那些坑(一) ——对象拷贝
- PHP开发过程的那些坑(二) ——PHP empty函数
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法