代码拉取完成,页面将自动刷新
var net = require('net');
var stream = require('stream')
var tcp_server = net.createServer(); // 创建 tcp server
var Sockets = {};
var SocketID = 1;
var WebSockets = {};
var WebSocketID = 1;
var c = '0001000400080101ff000201ff000300ff000400ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be68'.length
var dataBuff = Buffer.from(`0103a60001000400080101ff000201ff000300ff000400ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be6801033400000003000f00e000000000000000000000000000000000000000000000000000010000ffffffffffffffffffffffffffffffff5b91`, 'hex')
function MODBUS_CRC(data) {
let crcValue = 0xFFFF;
for (let i = 0; i < data.length; i++) {
crcValue ^= data[i] & 0xFFFF
for (let j = 0; j < 8; j++) {
if (crcValue & 0x0001) {
crcValue >>= 1
crcValue ^= 0xA001
} else {
crcValue >>= 1
}
}
}
var buf = Buffer.alloc(2)
var t = crcValue & 0xFF00
t = t >> 8
buf[1] = t
buf[0] = crcValue & 0xFF
var val = buf.toString('hex').toUpperCase()
return val
}
var PumpAddress = {
'1#': '0000'
}
//施肥机寻址
var ApplyFertilizerValveAddress = {
'1#': '0001', //施肥启停
'2#': '0002', //施肥启停
'3#': '0003', //施肥启停
'4#': '0004', //施肥启停
'5#': '0005', //施肥启停
}
//配肥机寻址
var MixFertilizerValveAddress = {
'1#': '0006', //配肥启停
'2#': '0007', //配肥启停
}
//节点水流阀门
var WaterValveAddress = {
'1#-1': '0008',
'1#-2': '0009',
'2#-1': '000A',
'2#-2': '000B',
'3#-1': '000C',
'3#-2': '000D',
'4#-1': '000E',
'4#-2': '000F',
'5#-1': '0010',
'5#-2': '0011',
'6#-1': '0012',
'6#-2': '0013',
'7#-1': '0014',
'7#-2': '0015',
'8#-1': '0016',
'8#-2': '0017',
'9#-1': '0018',
'9#-2': '0019',
'10#-1': '001A',
'10#-2': '001B',
'11#-1': '001C',
'11#-2': '001D',
'12#-1': '001E',
'12#-2': '001F',
'13#-1': '0020',
'13#-2': '0021',
'14#-1': '0022',
'14#-2': '0023',
'15#-1': '0024',
'15#-2': '0025',
'16#-1': '0026',
'16#-2': '0027',
'17#-1': '0028',
'17#-2': '0029',
'18#-1': '002A',
'18#-2': '002B',
'19#-1': '002C',
'19#-2': '002D',
'20#-1': '002E',
'20#-2': '002F',
'21#-1': '0030',
'21#-2': '0031',
'22#-1': '0032',
'22#-2': '0033',
'23#-1': '0034',
'23#-2': '0035',
'24#-1': '0036',
'24#-2': '0037',
'25#-1': '0038',
'25#-2': '0039',
'26#-1': '003A',
'26#-2': '003B',
'27#-1': '003C',
'27#-2': '003D',
'28#-1': '003E',
'28#-2': '003F',
'29#-1': '0040',
'29#-2': '0041',
'30#-1': '0042',
'30#-2': '0043',
'31#-1': '0044',
'31#-2': '0045',
'32#-1': '0046',
'32#-2': '0047',
'33#-1': '0048',
'33#-2': '0049',
'34#-1': '004A',
'34#-2': '004B',
'35#-1': '004C',
'35#-2': '004D',
'36#-1': '004E',
'36#-2': '004F',
'37#-1': '0050',
'37#-2': '0051',
'38#-1': '0052',
'38#-2': '0053',
'39#-1': '0054',
'39#-2': '0055',
'40#-1': '0056',
'40#-2': '0057',
}
var ValveType = {
'sb': PumpAddress,
'sf': ApplyFertilizerValveAddress,
'pf': MixFertilizerValveAddress,
'dcf': WaterValveAddress
}
var FlexBuffer = function(buf) {
this.buf = buf
}
Object.defineProperty(FlexBuffer.prototype, 'length', {
get: function() {
return this.buf.length - this.offset
}
})
FlexBuffer.prototype.buf = null
FlexBuffer.prototype.offset = 0
FlexBuffer.prototype.readUInt16BE = function() {
var val = this.buf.readInt16BE(this.offset)
this.offset += 2
return val
}
FlexBuffer.prototype.readUInt8 = function() {
var val = this.buf.readUInt8(this.offset)
this.offset += 1
return val
}
FlexBuffer.prototype.slice = function(len) {
var f = new FlexBuffer(this.buf.slice(this.offset, this.offset + len))
this.offset += len
return f
}
FlexBuffer.prototype.toString = function(f) {
return this.buf.slice(this.offset).toString('hex')
}
var HeaderPaser = function(buf) {
var header = {}
header.byteLenght = buf.readUInt8() //指令跟随数据字节长度.
var buf2 = buf.slice(header.byteLenght + 2) //加2字节校验码长度.
header.type = buf2.readUInt16BE()
header.pointNum = buf2.readUInt16BE() //有效节点个数
header.wordLenght = buf2.readUInt16BE() // 有效字个数
if (header.type == 0x0000) //首部
{
header.name = '首部'
header.main = {}
header.main.main_pip_press = (buf2.readUInt16BE() / 100).toFixed(3) //主干压力
header.main.pump_op_state = buf2.readUInt8() //水泵操作状态
header.main.pump_work_state = buf2.readUInt8() //水泵工作状态
header.main.main_pip_flow = (buf2.readUInt16BE() / 100).toFixed(3) //主管道流量
header.main.now_flow_sum = (buf2.readUInt16BE() / 100).toFixed(3) //主管道累计
header.main.ec_value = buf2.readUInt16BE() //EC实测值
header.main.total_fei = buf2.readUInt16BE() //总运行区数
header.main.applyNum = header.pointNum & 0xFF
header.main.mixNum = (header.pointNum & 0xFF00) >> 8
} else if (header.type == 0x0001) //节点
{
header.name = '节点'
}
if (header.pointNum * 4 > buf2.length || header.wordLenght * 2 > buf2.length) return null
return [header, buf2]
}
var ApplyFertilizerPaser = function(buf) {
var point = {}
point.work_state = buf.readUInt8() > 0 //施肥开启状态
point.op_state = buf.readUInt8() > 0 //施肥操作状态
point.now_flow = buf.readUInt16BE() //肥管瞬时流量
point.total_flow = buf.readUInt16BE() //肥管本次累计
return point
}
var MixFertilizerPaser = function(buf) {
var point = {}
point.work_state = buf.readUInt8() > 0 //配肥开启状态
point.op_state = buf.readUInt8() > 0 //配肥操作状态
return point
}
var PointPaser = function(buf) {
var point = {}
var op_state = buf.readUInt8() //电磁阀操作状态 高位
point.online = !!buf.readUInt8() //在线状态 低位
var worker_2 = {}
var worker_state2 = buf.readUInt8() //电磁阀#2反馈状态
worker_2.used = worker_state2 != 0xFF //是否使用
worker_2.worker_state = worker_state2 == 0xFF ? 0 : worker_state2 //工作反馈状态
worker_2.op_state = (op_state & 0x02) > 0 //操作状态
var worker_1 = {}
var worker_state1 = buf.readUInt8() //电磁阀#1反馈状态
worker_1.used = worker_state1 != 0xFF //是否使用
worker_1.worker_state = worker_state1 == 0xFF ? 0 : worker_state1 //工作反馈状态
worker_1.op_state = (op_state & 0x01) > 0 //操作状态
point.workers = []
point.workers.push(worker_1)
point.workers.push(worker_2)
return point
}
var PackePaser = function(buf) {
var packe = {}
if (buf.length < 3) return null
var direction = buf.slice(2).toString('hex') //指令
if (direction == '0106') {
//console.log()
packe.msg = '收到指令应答:' + direction + buf.toString()
return packe
}
if (direction != '0103') throw new Error('指令头不正确.')
var [header, buf2] = HeaderPaser(buf)
packe.header = header
var points = []
if (header.type == 0x0000) {
var applyFertilizers = []
for (let index = 0; index < header.main.applyNum; index++) {
var _buf = buf2.slice(6)
applyFertilizers.push(ApplyFertilizerPaser(_buf))
}
packe.applyFertilizers = applyFertilizers
var mixFertilizers = []
for (let index = 0; index < header.main.mixNum; index++) {
var _buf = buf2.slice(2)
mixFertilizers.push(MixFertilizerPaser(_buf))
}
packe.mixFertilizers = mixFertilizers
} else if (header.type == 0x0001) {
for (let index = 0; index < header.pointNum; index++) {
var _buf = buf2.slice(4)
points.push(PointPaser(_buf))
}
packe.points = points
}
return packe
}
var fbuf = new FlexBuffer(dataBuff)
while (fbuf.length > 0) {
var packe = PackePaser(fbuf)
console.log(JSON.stringify(packe))
}
// 监听 端口
tcp_server.listen(5678, '0.0.0.0', function() {
console.log('tcp_server listening 5678');
});
// 处理客户端连接
tcp_server.on('connection', function(socket) {
console.log(socket.address());
Sockets[SocketID] = socket;
socket.id = SocketID
SocketID++;
DealConnect(socket)
})
tcp_server.on('error', function() {
console.log('tcp_server error!');
})
tcp_server.on('close', function() {
console.log('tcp_server close!');
})
var SocketTypes = {
normal: 0,
ctrl: 1,
}
// 处理每个客户端消息
function DealConnect(socket) {
socket.on('data', function(data) {
//data = data.toString();
// 向所有客户端广播消息
//for(var i in Sockets){
// Sockets[i].write(data);
//}
// socket.write(data);
var buf = new Buffer(data)
var hexStr = buf.toString('hex')
console.log(hexStr);
if (socket.type === undefined) {
if (hexStr.startsWith('fefe')) {
socket.type = SocketTypes.normal
console.log('##数据站点模块连接.');
} else if (hexStr.startsWith('fffe')) {
socket.type = SocketTypes.ctrl
console.log('##控制站点模块连接.');
}
return
} else {
console.log('收到数据-Type:' + socket.type)
for (const key in Sockets) {
var s = Sockets[key]
if (s.id == socket.id)
continue
s.write(buf)
}
try {
var packe = PackePaser(new FlexBuffer(buf))
} catch (e) {
console.log(e)
return
}
for (const key in WebSockets) {
var ws = WebSockets[key]
//if (s.id == ws.id)
// continue
ws.send(JSON.stringify(packe))
}
}
})
// 客户端正常断开时执行
socket.on('close', function() {
console.log('client disconneted!');
})
// 客户端正异断开时执行
socket.on("error", function(err) {
console.log('client error disconneted!');
});
}
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({ port: 5679 }); //服务端口8181
wss.on('connection', function(ws) {
console.log('服务端:客户端已连接');
ws.id = WebSocketID
WebSockets[WebSocketID] = ws
WebSocketID++
ws.on('message', function(message) {
//打印客户端监听的消息
console.log(message)
if (!message.startsWith('@')) {
console.log('获取到非指令消息:' + message)
return
}
var direction = message.substr(1)
ws.send('收到指令' + direction)
direction = direction.split(':')
var t = '0106'
try {
if (direction.length != 3)
throw new Error('命令格式不正确.')
var valveAddress = ValveType[direction[1]]
if (valveAddress === undefined)
throw new Error('命令指定设备类型不正确.')
var serise = direction[2]
var addr = valveAddress[serise]
if (addr == undefined)
throw new Error('无法获取设备地址:' + serise)
t += addr
if (direction[0] == 'open') {
t += '0001'
} else if (direction[0] == 'close') {
t += '0000'
} else {
throw new Error('无法识别命令:' + direction[0])
}
var crc = MODBUS_CRC(Buffer.from(t, "hex"))
t += crc
} catch (e) {
ws.send('失败:' + message)
ws.send('错误:' + e.message)
return
}
var buf = new Buffer.from(t, 'hex')
for (const key in Sockets) {
var s = Sockets[key]
//if (s.type === SocketTypes.normal)
s.write(buf)
}
ws.send('成功:' + message)
ws.send('指令:' + t)
});
});
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。