手机可以访问的网站怎么做,电销app,赣州人才招聘网,响应式网站的意义智能电表数据接入物联网平台实践 设备接线准备设备调试代码实现Modbus TCP Client 读取电表数据读取寄存器数据转成32bit Float格式然后使用modbusTCP Client 读取数据 使用mqtt协议接入物联网平台最终代码实现 设备接线准备 设备调试
代码实现
Modbus TCP Client 读取电表数… 智能电表数据接入物联网平台实践 设备接线准备设备调试代码实现Modbus TCP Client 读取电表数据读取寄存器数据转成32bit Float格式然后使用modbusTCP Client 读取数据 使用mqtt协议接入物联网平台最终代码实现 设备接线准备 设备调试
代码实现
Modbus TCP Client 读取电表数据
读取寄存器数据转成32bit Float格式
原理
/*** * 17038, 7864
参考 https://blog.csdn.net/qq_36270361/article/details/115823294SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
0100 0010 1000 1110 0000 1111 0101 1100s 0
e (1000 0101)转10进制 133 - 127 6
尾数
000 1110 0000 1111 0101 1100
4#在尾数的左边有一个省略的小数点和1,这个1在浮点数的保存中经常省略,
1.000 1110 0000 1111 0101 1100
指数值e 6因此小数点向右移动6位得到尾数值如下
1000111.0 0000 1111 0101 1100整数1 *2^6 0 *2^5 0 *2^4 0 *2^3 1* 2^2 1 *2^1 1*2^0
64 000 4 2 1
71
小数部分前面0太多可以忽略不记了0 * 2^-1 0 * 2^-2 0 * 2^-3 0 * 2^-4 0 * 2^-5 ....
浮点数值 整数 小数 71 0 71
*/ function toFloat(s1, s2)
{// s1第一个寄存器地址数据s2第二个寄存器地址数据//将输入数值short转化为无符号unsigned shortconst us1 s1, us2 s2; // intif (s1 0) us1 65536;if (s2 0) us2 65536;//sign: 符号位, exponent: 阶码, mantissa:尾数let sign, exponent; // intlet mantissa; // float//计算符号位sign parseInt(us1 / 32768); // js中只需要整数//去掉符号位let emCode us1 % 32768; // int//计算阶码exponent parseInt(emCode / 128);//计算尾数mantissa (emCode % 128 * 65536 us2) / 8388608; // float//代入公式 fValue (-1) ^ S x 2 ^ (E - 127) x (1 M)const S Math.pow(-1, sign)const E Math.pow(2, exponent - 127)const M (1 mantissa)return S * E * M;
}然后使用modbusTCP Client 读取数据
// create an empty modbus client
const ModbusRTU require(modbus-serial);
const client new ModbusRTU();// open connection to a tcp line
client.connectTCP(10.0.0.251, { port: 24 });
client.setID(1);
// read the values of 10 registers starting at address 0
// on device number 1. and log the values to the console.
setInterval(() {console.log(-----read-----)client.readHoldingRegisters(4157, 10, (err, data) {// data: {// data: [17038, 7864]// buffer // buffer 数据 实际上转换出来就是data数组// } if (data?.data){console.log(data.data);const powerData toFloat(data.data[0], data.data[1])console.log(-------powerData------, powerData)}});
}, 3000);
使用mqtt协议接入物联网平台
const mqtt require(mqtt);
const md5 require(js-md5);const secureId admin;
const secureKey adminkey;
const timestamp new Date().getTime()
const username ${secureId}|${timestamp}
const password md5(username | secureKey)
const config {url: mqtt://10.0.0.108:1883,productId: 1696816545212956672,clientId: 1704681506453053440, // 电表设备idhost: 10.0.0.108,port: 1883
}const mqttClient mqtt.connect({clientId: config.clientId,username,password,host: config.host,port: config.port,protocol: mqtt
}); //指定服务端地址和端口// 推送数据
function publishData (key, value) {const msg {deviceId: config.clientId,properties: {[key]: value}}mqttClient.publish(/${config.productId}/${config.clientId}/properties/report,JSON.stringify(msg))
}//连接成功
mqttClient.on(connect, function() {console.log(服务器连接成功);publishData(online_time, new Date().getTime()) // 上报一条上线的消息});最终代码实现
function toFloat(s1, s2)
{// s1第一个寄存器地址数据s2第二个寄存器地址数据//将输入数值short转化为无符号unsigned shortconst us1 s1, us2 s2; // intif (s1 0) us1 65536;if (s2 0) us2 65536;//sign: 符号位, exponent: 阶码, mantissa:尾数let sign, exponent; // intlet mantissa; // float//计算符号位sign parseInt(us1 / 32768); // js中只需要整数//去掉符号位let emCode us1 % 32768; // int//计算阶码exponent parseInt(emCode / 128);//计算尾数mantissa (emCode % 128 * 65536 us2) / 8388608; // float//代入公式 fValue (-1) ^ S x 2 ^ (E - 127) x (1 M)const S Math.pow(-1, sign)const E Math.pow(2, exponent - 127)const M (1 mantissa)return S * E * M;
}
// create an empty modbus client
const ModbusRTU require(modbus-serial);
const client new ModbusRTU();// open connection to a tcp line
client.connectTCP(10.0.0.251, { port: 24 });
client.setID(1);const mqtt require(mqtt);
const md5 require(js-md5);const secureId admin;
const secureKey adminkey;
const config {url: mqtt://10.0.0.108:1883,productId: 1696816545212956672,clientId: 1704681506453053440, // 电表设备idhost: 10.0.0.108,port: 1883
}
let mqttClient null
let reconnectInterval 1000;
let reconnectTimer null;// 推送数据
function publishData (key, value) {const msg {deviceId: config.clientId,properties: {[key]: value}}mqttClient?.publish(/${config.productId}/${config.clientId}/properties/report,JSON.stringify(msg))
}function createClient() {if(mqttClient){return;}const timestamp new Date().getTime()const username ${secureId}|${timestamp}const password md5(username | secureKey)mqttClient mqtt.connect({clientId: config.clientId,username,password,host: config.host,port: config.port,protocol: mqtt,}); //指定服务端地址和端口//连接成功mqttClient?.on(connect, function() {console.log(服务器连接成功);publishData(online_time, new Date().getTime())});// 断线重连mqttClient.on(error, (error) {console.log(error:,new Date().getTime(), error);reconnect();});mqttClient.on(end, () {console.log(end-------:, new Date().getTime());reconnect();});
}function reconnect() {console.log(reconnecting in ${reconnectInterval}ms...);reconnectTimer setTimeout(createClient, reconnectInterval);reconnectInterval Math.min(reconnectInterval * 2, 30000);
}// 创建链接
createClient()// read the values of 10 registers starting at address 0
// on device number 1. and log the values to the console.
setInterval(() {console.log(-----read-----)client.readHoldingRegisters(4157, 2, (err, data) {if (data?.buffer){console.log(data.data);const powerData toFloat(data.data[0], data.data[1])console.log(------powerData-------, powerData)publishData(total_working_energy, powerData)}});
},5 * 60 * 1000);效果预览