磁吸门锁设备数据上报阿里云

简介: 本文以磁吸门锁作为采集制对象,使用海创微联采集控制系统对磁吸门锁设备数据进行采集控制,然后将采集到的数据上传到阿里云物联网平台,阿里云物联网平台实现数据实时可视化。文章分为3部分:● 设备接线配置磁吸门锁的联网参数配置及实施接线。● 数据采集使用海创微联采集控制系统进行控件的部署、数据采集。● 数据上传阿里云平台物联网平台产品和设备的创建、数据可视化。

本文以磁吸门锁作为采集制对象,使用海创微联采集控制系统对磁吸门锁设备数据进行采集控制,然后将采集到的数据上传到阿里云物联网平台,阿里云物联网平台实现数据实时可视化。
文章分为3部分:

  • 设备接线配置
    磁吸门锁的联网参数配置及实施接线。
  • 数据采集
    使用海创微联采集控制系统进行控件的部署、数据采集。
  • 数据上传
    阿里云平台物联网平台产品和设备的创建、数据可视化。

一 设备接线配置

1.1 准备工具

实现磁吸门锁数据采集控制,主要需要准备以下产品工具:

1.海创Box智能采集网关

2.密码锁

3.磁吸门锁控制板

1.2 设备接线

将网关盒子与磁吸门锁主板都接入交换机,设备上电后,与PC端实现网络通信。

1.3 联网参数配置

打开磁吸门锁软件--管理中心V6.9进行ip配置,实现通信。输入如图所示用户和密码。

打开控制器,搜索局域网络初始ip,配置参数。

1.4 远程开门

通信成功后打开总控制台,选择初始配置的门号,点击远程开门,查看运行信息。

1.5 密码权限修改删除

打开密码管理,输入要设置的密码选择添加,添加完成后前往上传设置,将数据上传。

二 数据采集

使用海创微联采集控制系统对磁吸门锁设备数据进行采集、处理、转发等操作。

打开海创微联采集控制系统,从左边的采集引擎中选择定时器、udp、function、json、调试器和阿里云节点,按下图连接。

2.1.1 定时器配置

定时器周期性触发输入时间戳或者相应的字符,主要当触发流程使用,具体配置如下图

具体代码如下所示:

{

"type": "status",

"address": 62393,

"value": 0

}


具体代码如下所示:

{

"type": "open",

"address": 62393,

"value": 1

}

2.1.2 udp配置

Udp发送msg.payload到指定的UDP主机和端口,支持组播!输入以及输出控件设置如下配置,配置地址以及端口。

2.1.3 function配置

JavaScript函数块,使用js语言,用于定义、赋值、指定规则等等,是最多变的控件。

具体代码如下所示:
解析:

let payload = msg.payload;

let type, value, address, code, data = {};


if (!Buffer.isBuffer(payload)) {

   Node.error(msg, "msg.payload不是Buffer类型");

   return;

}

let dataBuf = payload;

if (dataBuf.length != 34) {

   Node.error(msg, "msg.payload报文解析错误,报文长度不为34:" + dataBuf.toString('hex'));

   return;

}

if (dataBuf[0] != 0x7E || dataBuf[dataBuf.length - 1] != 0x0D) {

   Node.error(msg, "msg.payload报文解析错误,报文头或者报文尾不正确:" + dataBuf.toString('hex'));

   return;

}


let count = 0;

for (let i = 1, len = dataBuf.length - 3; i < len; i++) {

   count += dataBuf[i];

}

if (count != dataBuf.readUInt16LE(dataBuf.length - 3)) {

   Node.error(msg, `msg.payload报文校验失败,累计计算和为${Buffer.allocUnsafe(2).writeUInt16LE(count).toString('hex')},实际收到为:${dataBuf.subarray(dataBuf.length - 3, dataBuf.length - 1)}`);

   return;

}


let success = function (data, message) {

   if (typeof (data) == "undefined") {

       data = {};

       message = "操作成功";

   }

   if (typeof (message) == "undefined") {

       message = "操作成功";

   }

   if (typeof (message) != "string") {

       message = String(message);

   }

   return { "code": 0, "msg": message, "data": data };

}


let error = function (code, message) {

   if (typeof (code) == "undefined" && typeof (message) == "undefined") {

       code = 500;

       message = "程序发生错误";

   }

   else if (typeof (code) != "undefined" && typeof (message) == "undefined") {

       message = code;

       code = 500;

   }

   if (typeof (message) != "string") {

       message = String(message);

   }

   return { "code": code, "msg": message }

}


let isEror = function (result) {

   if (typeof (result) == "boolean") {

       if (result == true) {

           return false;

       }

       else {

           return true;

       }

   }

   else if (typeof (result) == "object") {

       if (result.code == 0) {

           return false;

       }

       else {

           return true;

       }

   }

   else {

       if (result) {

           return false;

       }

       else {

           return true;

       }

   }

}


let getDateTime = function (dateTimeBuf) {

   if (!Buffer.isBuffer(dateTimeBuf)) {

       dateTimeBuf = Buffer.from(dateTimeBuf, 'hex');

   }

   

   let dateTime, year, month, day, time, min, second;

   if (dateTimeBuf.length == 7) {

       year = "20" + dateTimeBuf.subarray(0, 1).toString('hex');

       month = dateTimeBuf.subarray(1, 2).toString('hex');

       day = dateTimeBuf.subarray(2, 3).toString('hex');

       time = dateTimeBuf.subarray(4, 5).toString('hex');

       min = dateTimeBuf.subarray(5, 6).toString('hex');

       second = dateTimeBuf.subarray(6, 7).toString('hex');

   }

   else if (dateTimeBuf.length == 4) {

       year = (dateTimeBuf.readUInt16LE(0) >> 9) + 2000;

       month = dateTimeBuf.readUInt16LE(0) >> 5 & 0x000F;

       day = dateTimeBuf.readUInt16LE(0) & 0x001F;

       time = dateTimeBuf.readUInt16LE(2) >> 11;

       min = dateTimeBuf.readUInt16LE(2) >> 5 & 0x003F;

       second = dateTimeBuf.readUInt16LE(2) & 0x001F * 2;

   }

   else {

       return error(1, "获取日期报文长度不正确:正确长度为7或者4,得到" + dateTimeBuf.length);

   }

   dateTime = `${year}-${month}-${day} ${time}:${min}:${second}`;

   return success(dateTime);

}


let getBisStatus = function (num) {

   if (typeof (num) != "number") {

       num = Number(num);

   }

   let numArr = (Array(8).join('0') + num.toString(2)).slice(-8).split("");

   // node.log(numArr);

   let data = [];

   numArr.forEach(element => {

       let value = false;

       if (element == "1") {

           value = true;

       }

       data.push(value);

   });

   return data;

}



const recordingStatus = {

   0x00: { "type": "open", "msg": "1号读卡器刷卡开门" },

   0x01: { "type": "open", "msg": "2号读卡器刷卡开门" },

   0x02: { "type": "open", "msg": "3号读卡器刷卡开门" },

   0x03: { "type": "open", "msg": "4号读卡器刷卡开门" },

   0x80: { "type": "prohibit", "msg": "(1)号读卡器刷卡禁止通过: 原因不明" },

   0x81: { "type": "prohibit", "msg": "(2)号读卡器刷卡禁止通过: 原因不明" },

   0x82: { "type": "prohibit", "msg": "(3)号读卡器刷卡禁止通过: 原因不明" },

   0x83: { "type": "prohibit", "msg": "(4)号读卡器刷卡禁止通过: 原因不明" },

   0x90: { "type": "prohibit", "msg": "(1)号读卡器刷卡禁止通过: 没有权限" },

   0x91: { "type": "prohibit", "msg": "(2)号读卡器刷卡禁止通过: 没有权限" },

   0x92: { "type": "prohibit", "msg": "(3)号读卡器刷卡禁止通过: 没有权限" },

   0x93: { "type": "prohibit", "msg": "(4)号读卡器刷卡禁止通过: 没有权限" },

   0xA0: { "type": "prohibit", "msg": "(1)号读卡器刷卡禁止通过: 密码不对" },

   0xA1: { "type": "prohibit", "msg": "(2)号读卡器刷卡禁止通过: 密码不对" },

   0xA2: { "type": "prohibit", "msg": "(3)号读卡器刷卡禁止通过: 密码不对" },

   0xA3: { "type": "prohibit", "msg": "(4)号读卡器刷卡禁止通过: 密码不对" },

   0xB0: { "type": "prohibit", "msg": "(1)号读卡器刷卡禁止通过: 系统有故障" },

   0xB1: { "type": "prohibit", "msg": "(2)号读卡器刷卡禁止通过: 系统有故障" },

   0xB2: { "type": "prohibit", "msg": "(3)号读卡器刷卡禁止通过: 系统有故障" },

   0xB3: { "type": "prohibit", "msg": "(4)号读卡器刷卡禁止通过: 系统有故障" },

   0xC0: { "type": "prohibit", "msg": "(1)号读卡器刷卡禁止通过: 反潜回, 多卡开门或多门互锁" },

   0xC1: { "type": "prohibit", "msg": "(2)号读卡器刷卡禁止通过: 反潜回, 多卡开门或多门互锁" },

   0xC2: { "type": "prohibit", "msg": "(3)号读卡器刷卡禁止通过: 反潜回, 多卡开门或多门互锁" },

   0xC3: { "type": "prohibit", "msg": "(4)号读卡器刷卡禁止通过: 反潜回, 多卡开门或多门互锁" },

   0xC4: { "type": "prohibit", "msg": "(1)号读卡器刷卡禁止通过: 反潜回" },

   0xC5: { "type": "prohibit", "msg": "(2)号读卡器刷卡禁止通过: 反潜回" },

   0xC6: { "type": "prohibit", "msg": "(3)号读卡器刷卡禁止通过: 反潜回" },

   0xC7: { "type": "prohibit", "msg": "(4)号读卡器刷卡禁止通过: 反潜回" },

   0xC8: { "type": "prohibit", "msg": "(1)号读卡器刷卡禁止通过: 多卡" },

   0xC9: { "type": "prohibit", "msg": "(2)号读卡器刷卡禁止通过: 多卡" },

   0xCA: { "type": "prohibit", "msg": "(3)号读卡器刷卡禁止通过: 多卡" },

   0xCB: { "type": "prohibit", "msg": "(4)号读卡器刷卡禁止通过: 多卡" },

   0xCC: { "type": "prohibit", "msg": "(1)号读卡器刷卡禁止通过: 首卡" },

   0xCD: { "type": "prohibit", "msg": "(2)号读卡器刷卡禁止通过: 首卡" },

   0xCE: { "type": "prohibit", "msg": "(3)号读卡器刷卡禁止通过: 首卡" },

   0xCF: { "type": "prohibit", "msg": "(4)号读卡器刷卡禁止通过: 首卡" },

   0xD0: { "type": "prohibit", "msg": "(1)号读卡器刷卡禁止通过: 门为常闭" },

   0xD1: { "type": "prohibit", "msg": "(2)号读卡器刷卡禁止通过: 门为常闭" },

   0xD2: { "type": "prohibit", "msg": "(3)号读卡器刷卡禁止通过: 门为常闭" },

   0xD3: { "type": "prohibit", "msg": "(4)号读卡器刷卡禁止通过: 门为常闭" },

   0xD4: { "type": "prohibit", "msg": "(1)号读卡器刷卡禁止通过: 互锁" },

   0xD5: { "type": "prohibit", "msg": "(2)号读卡器刷卡禁止通过: 互锁" },

   0xD6: { "type": "prohibit", "msg": "(3)号读卡器刷卡禁止通过: 互锁" },

   0xD7: { "type": "prohibit", "msg": "(4)号读卡器刷卡禁止通过: 互锁" },

   0xE0: { "type": "prohibit", "msg": "(1)号读卡器刷卡禁止通过: 卡过期或不在有效时段" },

   0xE1: { "type": "prohibit", "msg": "(2)号读卡器刷卡禁止通过: 卡过期或不在有效时段" },

   0xE2: { "type": "prohibit", "msg": "(3)号读卡器刷卡禁止通过: 卡过期或不在有效时段" },

   0xE3: { "type": "prohibit", "msg": "(4)号读卡器刷卡禁止通过: 卡过期或不在有效时段" }

};


const noCardRecordingStatus = {

   0: { 0x00: { "type": "button", "msg": "1号门按钮动作" }, 0x03: { "type": "remoteOpen", "msg": "1号门远程开门动作" }, 0x81: { "type": "coercion", "msg": "1号读卡器胁迫报警" }, 0x82: { "type": "noClose", "msg": "1号门长时间未关报警" }, 0x84: { "type": "illegal", "msg": "1号门非法闯入报警" } },

   1: { 0x00: { "type": "button", "msg": "2号门按钮动作" }, 0x03: { "type": "remoteOpen", "msg": "2号门远程开门动作" }, 0x81: { "type": "coercion", "msg": "2号读卡器胁迫报警" }, 0x82: { "type": "noClose", "msg": "2号门长时间未关报警" }, 0x84: { "type": "illegal", "msg": "2号门非法闯入报警" } },

   2: { 0x00: { "type": "button", "msg": "3号门按钮动作" }, 0x03: { "type": "remoteOpen", "msg": "3号门远程开门动作" }, 0x81: { "type": "coercion", "msg": "3号读卡器胁迫报警" }, 0x82: { "type": "noClose", "msg": "3号门长时间未关报警" }, 0x84: { "type": "illegal", "msg": "3号门非法闯入报警" } },

   3: { 0x00: { "type": "button", "msg": "4号门按钮动作" }, 0x03: { "type": "remoteOpen", "msg": "4号门远程开门动作" }, 0x81: { "type": "coercion", "msg": "4号读卡器胁迫报警" }, 0x82: { "type": "noClose", "msg": "4号门长时间未关报警" }, 0x84: { "type": "illegal", "msg": "4号门非法闯入报警" } },

   4: { 0xA0: { "type": "fireAlarm", "msg": "火警动作" } },

   5: { 0x00: { "type": "superOpen", "msg": "1号读卡器超级密码开门" }, 0x01: { "type": "superOpen", "msg": "2号读卡器超级密码开门" }, 0x02: { "type": "superOpen", "msg": "3号读卡器超级密码开门" }, 0x03: { "type": "superOpen", "msg": "4号读卡器超级密码开门" } },

   6: { 0xA0: { "type": "mandatory", "msg": "强制锁门" } },

   8: { 0x00: { "type": "sensorOpen", "msg": "1号门打开[门磁信号]" } },

   9: { 0x00: { "type": "sensorOpen", "msg": "2号门打开[门磁信号]" } },

   10: { 0x00: { "type": "sensorOpen", "msg": "3号门打开[门磁信号]" } },

   11: { 0x00: { "type": "sensorOpen", "msg": "4号门打开[门磁信号]" } },

   12: { 0x00: { "type": "sensorClose", "msg": "1号门关闭[门磁信号]" } },

   13: { 0x00: { "type": "sensorClose", "msg": "2号门关闭[门磁信号]" } },

   14: { 0x00: { "type": "sensorClose", "msg": "3号门关闭[门磁信号]" } },

   15: { 0x00: { "type": "sensorClose", "msg": "4号门关闭[门磁信号]" } }

};



let getErrorCode = function (num) {

   let errorBisArr = getBisStatus(num);

   let result = errorBisArr.slice(0, 5);

   let errorMsg = [

       "系统故障1",

       "系统故障2",

       "控制器时钟有故障",

       "系统故障4",

       "网络芯片有故障"

   ];

   let data = [];

   for (let item in result) {

       if (result[item]) {

           data.push(errorMsg[item]);

       }

   }

   return data;

}


let getRecord = function (recordBuf) {

   if (!Buffer.isBuffer(recordBuf)) {

       recordBuf = Buffer.from(recordBuf, 'hex');

   }

   if (recordBuf.length != 8) {

       return error(1, "获取记录报文长度不正确:正确长度为7,得到" + recordBuf.length);

   }

   if (recordBuf.toString('hex') == "ffffffffffffffff") {

       return success(null);

   }


   let cardId = String(recordBuf[2]) + String(recordBuf.readUInt16LE(0));

   let code, dateTime, message;

   if (Number(cardId) > 100) {

       code = recordingStatus[recordBuf[3]]['type'];

       message = recordingStatus[recordBuf[3]]['msg'];

   }

   else {

       code = noCardRecordingStatus[Number(cardId)][recordBuf[3]]['type'];

       message = noCardRecordingStatus[Number(cardId)][recordBuf[3]]['msg'];

   }

   dateTime = getDateTime(recordBuf.subarray(4));


   if (isEror(dateTime)) {

       return dateTime;

   }

   dateTime = dateTime.data;

   let data = {

       "cardId": cardId,

       "type": code,

       "dateTime": dateTime,

       "msg": message

   }

   return success(data);

}


address = dataBuf.readUInt16LE(1);

code = dataBuf.subarray(3, 5).toString('hex');

data = {

   "address": address,

   "code": code

};


if (dataBuf.readUInt16BE(3) == 0x8110) {

   let dateTimeResult = getDateTime(dataBuf.subarray(5, 12));

   if (isEror(dateTimeResult)) {

       node.error(msg, dateTimeResult.msg);

       return;

   }

   let dateTime = dateTimeResult.data;

   let recordResult = getRecord(dataBuf.subarray(17, 25));

   if (isEror(recordResult)) {

       node.error(msg, recordResult, msg);

       return;

   }

   let record = recordResult.data;

   let swipeCount = dataBuf.readUIntLE(12, 3);

   let authCount = dataBuf.readUInt16LE(15);

   let relayStatus = getBisStatus(dataBuf[25]);

   let doorBtnStatus = getBisStatus(dataBuf[26]);


   let relay = relayStatus.slice(0, 4);

   let doorSensor = doorBtnStatus.slice(0, 4).reverse();

   let button = doorBtnStatus.slice(4);

   let errorMsg = getErrorCode(dataBuf[28]);


   data.dateTime = dateTime;

   data.record = record;

   data.swipeCount = swipeCount;

   data.authCount = authCount;

   data.relay = relay;

   data.doorSensor = doorSensor;

   data.button = button;

   data.errorMsg = errorMsg;

   data.type = "status";


}

else if (dataBuf.readUInt16BE(3) == 0x9D10) {

   value = true;

   if (dataBuf[5] != 0) {

       node.error(msg, "开门失败");

       code = false;

   }

   data.value = value;

   data.type = "open";

}

else if (dataBuf.readUInt16BE(3) == 0x0711) {

   value = true;

   if (dataBuf[5] != 1) {

       node.error(msg, "添加用户权限失败");

       code = false;

   }

   data.value = value;

   data.type = "addUser";

}

else if (dataBuf.readUInt16BE(3) == 0x0811) {

   value = true;

   if (dataBuf[5] != 1) {

       node.error(msg, "删除用户权限失败");

       code = false;

   }

   data.value = value;

   data.type = "deleteUser";

}

else {

   node.error(msg, "功能码不存在:" + dataBuf.subarray(3, 5).toString('hex'));

   return;

}

msg.payload = data;


return msg;

控制

let payload = msg.payload;

if(payload.lock == true){

   return {payload:{"type":"open","address":62393,"value":1}};

}

权限设置

let payload = msg.payload;

let type = payload.type;

let value = payload.value;

let address = payload.address;


if (!type) {

   node.error(msg, "type不能为空!");

   return;

}

if (!address) {

   node.error(msg, "address不能为空!");

   return;

}


let dataBuf = Buffer.alloc(34);

dataBuf[0] = 0x7E;

dataBuf.writeUInt16LE(Number(address), 1);

dataBuf[33] = 0x0D;


if(type == "status"){

  dataBuf[3] = 0x81;

  dataBuf[4] = 0x10;

  if (value) {

     value = Number(value);

     dataBuf.writeUInt32LE(value, 5);

  }

}

else if(type == "open"){

  dataBuf[3] = 0x9d;

  dataBuf[4] = 0x10;

  switch(Number(value))

  {

      case 1:

          dataBuf[5] = 0x01;

          break;

      case 2:

          dataBuf[5] = 0x02;

          break;

      case 3:

          dataBuf[5] = 0x03;

          break;

      case 4:

          dataBuf[5] = 0x04;

          break;

      default:

         node.error(msg, "需要开门的门号值不正确:" + value);

       break;

  }

}

else if(type == "addUser"){

  //功能码

  dataBuf[3] = 0x07;

  dataBuf[4] = 0x11;

  //权限索引

  dataBuf[5] = 0x00;

  dataBuf[6] = 0x00;

  //卡ID

  let cardId = Number(value.cardId);

  if(cardId >= 10000)

  {

    node.error(msg, "添加权限卡号值不正确,值要小于10000:" + cardId);

       return;  

  }

  dataBuf[7] = cardId & 0x00ff;

  dataBuf[8] = cardId >> 8;

  dataBuf[9] = 0x00;

  //门号 1~4

  switch(Number(value.door))

  {

      case 1:

          dataBuf[10] = 0x01;

          break;

      case 2:

          dataBuf[10] = 0x02;

          break;

      case 3:

          dataBuf[10] = 0x03;

          break;

      case 4:

          dataBuf[10] = 0x04;

          break;

      default:

         node.error(msg, "需要开门的门号值不正确:" + value);

       return;

  }

  //起始时间

  dataBuf[11] = 0x21;

  dataBuf[12] = 0x00;

  //终止时间

  dataBuf[13] = 0x9f;

  dataBuf[14] = 0x29;

  //时段

  dataBuf[15] = 0x01;

  //密码

  dataBuf[16] = 0x00;

  dataBuf[17] = 0x00;

  dataBuf[18] = 0x00;

 

}

else if(type == "deleteUser"){

  //功能码

  dataBuf[3] = 0x08;

  dataBuf[4] = 0x11;

  //权限索引

  dataBuf[5] = 0x00;

  dataBuf[6] = 0x00;

  //卡ID

  let cardId = Number(value.cardId);

  if(cardId >= 10000)

  {

    node.error(msg, "删除权限卡号值不正确,值要小于10000:" + cardId);

       return;  

  }

  dataBuf[7] = cardId & 0x00ff;

  dataBuf[8] = cardId >> 8;

  dataBuf[9] = 0x00;

  //门号 1~4

  switch(Number(value.door))

  {

      case 1:

          dataBuf[10] = 0x01;

          break;

      case 2:

          dataBuf[10] = 0x02;

          break;

      case 3:

          dataBuf[10] = 0x03;

          break;

      case 4:

          dataBuf[10] = 0x04;

          break;

      default:

         node.error(msg, "门号值不正确:" + value);

       return;

  }

}

else {

   node.error(msg, "编码类型不存在:" + type);

   return;

}


//校验和计算 计算位 bit1~bit30

let check_sum = 0;

for(let index = 1;index < 31;index++)

{

   check_sum += dataBuf[index];

}

dataBuf.writeUInt16LE(check_sum, 31);

msg.payload = dataBuf;


return msg;

2.1.4 json配置

JOSN格式在任一方向上在JSON字符串及其JavaScript对象表示之间进行转换!

全部节点设置后,连线,点击部署,设置定时器将消息注入流中,点击触发可以观察到流程调试成功。

三 数据上传

阿里云物联网平台能够与海创微联采集控制系统进行联动,将采集到的数据可视化。

3.1 产品创建

登录阿里云物联网平台,在左侧导航栏,选择设备管理 > 产品,单击创建产品。

在新建产品页签,按照页面提示填写信息,然后单击确认。

3.2 设备创建

在左侧导航栏,选择设备管理 > 设备。在设备页面,单击添加设备。

在添加设备对话框中,输入设备信息,单击确认。

返回选择设备管理 > 设备,即可查看设备详情。

3.3 采集量的定义

返回查看刚刚创建的产品,在功能定义中,点击编辑草稿。

点击添加自定义功能。

标识符一定要和调试窗口中的字段一致。在功能定义中创建需要上传云端的数据标识符,创建完成后点击左下角的发布上线。

返回查看创建的设备,点击下图位置的查看按钮,复制好设备的3个标识符,即ProductKey(产品标识)、DeviceKey(设备标识)、DeviceSecret(设备密钥)。

3.4 数据可视化

前往海创微联采集控制系统,在阿里云IOT输入3个唯一标识。

点击部署,阿里云IOT连接成功。

返回阿里云物联网平台,设备显示在线。在设备的物模型数据中实时显示磁吸门锁设备数据。

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
目录
相关文章
|
4月前
|
传感器 监控 自动驾驶
智能犁具与播种设备
智能犁具与播种设备
28 2
|
传感器 存储
多功能手持VH501TC采集仪连接传感器与读数
振弦与温度传感器 振弦传感器和温度传感器(NTC)均为无源传感,不需要连接电源线。 根据前述“设备组成和接口定义” 用对应颜色的鳄鱼夹分别连接振弦传感器线圈和温度传感器两端即可。传感器连接后,屏幕自动显示实时的测量结果。一般情况下,设备配套传感测线为一根 4 芯线,红黑线连接振弦线圈,另外两根连接温度传感器。
多功能手持VH501TC采集仪连接传感器与读数
|
传感器 算法 测试技术
ESP32-C3 应用 篇(实例一、通过MQTT协议连接ONENET上报传感器数据,云平台下发灯光调色)
ESP32-C3学到现在,我们已经掌握了从基本外设到网络服务端的相关知识, 这篇文章就是做一个简单的应用,使用开发板连接ONENET云平台, 使用MQTT协议,上报温湿度和光照数据,平台下发命令控制全彩灯颜色切换。
940 0
ESP32-C3 应用 篇(实例一、通过MQTT协议连接ONENET上报传感器数据,云平台下发灯光调色)
|
传感器 算法 安全
雨量预警广播拉网分布遥测仪远程命令语音播报自动化数据平台
全自动监测预警设备,集现场数据采发、区域化广播预警的监测预警功能,可进行多通道的多种传感类型采集,包括电压、电流、数字、脉冲等。内嵌预警算法,可在达到预警条件时实现现场区域化广播预警。支持多种无线数据传输,包括区域自建射频、远程 GSM/GPRS 。
雨量预警广播拉网分布遥测仪远程命令语音播报自动化数据平台
|
存储 传感器
手持VH501TC采集仪如何处理监测到的数据
在实时数据显示窗口, 长按【存储】按键即可保存当前显示的传感数据,当听到蜂鸣器提示后表示存储完成,同时屏幕底部的已保存数量值自动加 1。 VH501TC 支持对传感器进行编号的功能,以便在导出数据时区分出某条数据对应哪个传感器。传感器编号需要在保存数据操作前设置,具体方法为:短按【电源/上一个】或者【存储/下一个】按键,屏幕底部数据存储指示区域会显示传感器编号。在数据保存前,还应确认屏幕显示的实时日期、时间是否正确,数据保存时会将时间信息、传感器编号以及屏幕显示的频率、频模、温度、信号质量、电压、电流一并保存为一条数据。 若外接了 U 盘,保存数据操作会自动将本条数据进行同步存储。
手持VH501TC采集仪如何处理监测到的数据
|
传感器 物联网 智能硬件
IoT设备与手机App之间实时消息通信解决方案
PLC 工控机和管理人员 App 的联动
1384 0
IoT设备与手机App之间实时消息通信解决方案
|
传感器
手持便携振弦VH501TC采集仪的常见问题
1.不能开机 检查电池是否有电,检查电池安装极性是否正确。 2.不显示振弦传感器测量值 检查传感器连线是否正确,详见“传感器接口定义” ;尝试不同的振弦激励方法,详见“振弦传感器激方法修改” 。
手持便携振弦VH501TC采集仪的常见问题
|
存储 传感器
多功能手持VH501TC采集仪如何处理监测数据
VH501TC 支持对传感器进行编号的功能,以便在导出数据时区分出某条数据对应哪个传感器。传感器编号需要在保存数据操作前设置,具体方法为:短按【电源/上一个】或者【存储/下一个】按键,屏幕底部数据存储指示区域会显示传感器编号。在数据保存前,还应确认屏幕显示的实时日期、时间是否正确,数据保存时会将时间信息、传感器编号以及屏幕显示的频率、频模、温度、信号质量、电压、电流一并保存为一条数据。 若外接了 U 盘,保存数据操作会自动将本条数据进行同步存储。
多功能手持VH501TC采集仪如何处理监测数据
|
数据采集 JSON 数据可视化
测温人脸机数据上报阿里云
本文介绍测温人脸机的对接实例,使用海创微联采集控制系统对人脸机数据进行采集,然后将采集到的数据上传至阿里云物联网平台,实现实时数据可视化。
589 0
测温人脸机数据上报阿里云