陈拓 chentuo@ms.xab.ac.cn 2019/12/14-2020/01/02

1. 阿里云物联网平台设置

见参考文档《阿里云物联网平台基本设置》https://blog.csdn.net/chentuo2000/article/details/103559553

2. 在树莓派上安装Node.js LTS工具包


PC Win7操作树莓派3B+。

LTS官网描述,https://nodejs.org/en/about/releases/
Node.js的主要版本进入当前发布状态为六个月,这使库作者有时间为其添加支持。六个月后,奇数版本(9、11等)将不再受支持,而偶数版本(10、12等)将变为“活动LTS”状态,并可以用于一般用途。 LTS的发布状态为“长期支持”,通常可以保证关键错误在30个月内得到修复。生产应用程序应仅使用Active LTS或Maintenance LTS版本。

查看最新版本:
https://nodejs.org/en/download/

  • 安装最新版本的Node.js LTS

先根据最新版本号执行命令:

curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -

……

根据提示执行命令:sudo apt-get install -y nodejs

测试:node –v或者nodejs –v

3. 阿里云物联网平台Node.js SDK

看官方文档:

设备接入Link Kit SDK > NodeJS SDK > 环境要求与配置https://help.aliyun.com/document_detail/96618.html?spm=a2c4g.11186623.3.2.9965fb74btNOBv

更新时间:2019-06-25 09:45:26

目前的JS版本的Link Kit SDK最新版本号为1.2.7

Node.js 运行环境,版本需要 >= 4.0.0 。

3.1 安装SDK


通过 npm 包管理工具安装SDK。有两种安装方式。

1) 将SDK安装到Nodejs项目所在目录。

适用于开发者已创建自己的项目,然后集成阿里云的Link Kit SDK:

npm install alibabacloud-iot-device-sdk --save

2) 将SDK进行全局安装

适用于开发者直接编写了一个js文件(该文件引用了阿里云的Link Kit SDK)、然后直接使用node xxx.js运行该js程序的场景。这种情况需要将SDK进行全局安装,命令如下所示:

npm install -g alibabacloud-iot-device-sdk

注:不推荐全局安装的方式,因为扩展性不好。

用第一种安装方式试试。

安装SDK
mkdir PiAliNode

cd PiAliNode

npm install alibabacloud-iot-device-sdk --save

查看:

安装不成功。直接到github去下载。

先删除package-lock.json和node_modules

rm package-lock.json

rm -rf node_modules

github上阿里云IoT官方版本:

https://github.com/aliyun/alibabacloud-iot-device-sdk

下载:pi@raspberrypi:~/PiAliNode $ git clone https://github.com/aliyun/alibabacloud-iot-device-sdk.git

查看:

node程序引用SDK
使用SDK提供的API需要在js代码中加入对SDK的依赖,如下所示:

const iot = require('alibabacloud-iot-device-sdk');

3.2 Nodejs设备快速接入阿里云IoT平台


官方例子:alibabacloud-iot-device-sdk/examples/quickstart/

进入快速启动目录:cd alibabacloud-iot-device-sdk/examples/quickstart

  • 修改device_id_password.json

把注册的设备三元组信息填写进去,设备三元组信息见参考文档《阿里云物联网平台基本设置》 。

我用nano device_id_password.json命令修改。

  • 命令行执行 sh ./start.sh安装SDK

提示npm有新版本,当前版本是6.12.1,可以运行npm install -g npm来更新npm,新版本是6.13.4。嫌麻烦,我们就先不更新了。

start.sh内容:

set -e
你写的每个脚本都应该在文件开头加上set -e,这句语句告诉bash如果任何语句的执行结果不是true则应该退出。

[ -d FILE ]  如果 FILE 存在且是一个目录则为真
if [ ! -d ./node_modules ]; then

  printf "Installing alibabacloud Iot Device SDK...\n"

  npm install

fi

如果./node_modules目录不存在,就用npm install安装。安装完之后:

安装SDK之后就node就可以用

const iot = require('alibabacloud-iot-device-sdk');

引用SDK了。

  1. 运行node index.js

thing type: Device 物类型:设备

Connect successfully! 连接成功!

类型错误:TypeError: device.serve is not a function

什么情况?

去看官网https://github.com/aliyun/alibabacloud-iot-device-sdk上的说明:设备的serve方法改成onService啦。查看index.js源代码:

将serve改成onService:

pi@raspberrypi:~/PiAliNode/alibabacloud-iot-device-sdk/examples/quickstart $ nano index.js

改好后再运行node index.js

代码运行正常,每5秒钟发送一条属性信息到阿里云。但是,发送的属性参数是:

{

Status: 1,

   Data: 'Hello, world!'

}

和我们自己的定义不同,下面要按照我们自己的定义发送数据。

4. 发送温度数据到阿里云

4.1 物模型使用

看看https://github.com/aliyun/alibabacloud-iot-device-sdk或者目录:PiAliNode/alibabacloud-iot-device-sdk目录下的 README.md。

LinkPlatform 封装了物模型定义与 Alink 异步协议,SDK 封装使得设备与云端通信时不需要关心 MQTT topic,只需要调用属性上报(iot.device#postProps())、服务监听(iot.device#onService())、事件上报(iot.device#postEvent())等相关 API。

设备属性上报
device.on('connect', () => {

  device.postProps({

    LightSwitch: 0

  }, (res) => {

    console.log(`postProps:`,res);

  });

});

调用 device.postProps() 等同于执行以下代码:

// 发布属性上报 topic

device.publish('/sys/<productKey>/<deviceName>/thing/event/property/post', JSON.stringify({

  {

    id: msgId,

    version: '1.0',

    params: {

      'LightSwitch': 25,

    },

    method: 'thing.event.property.post'

  }

}));

 

// 监听属性上报响应 topic

device.subscribe('/sys/<productKey>/<deviceName>/thing/event/property/post_reply');

device.on('message', function(topic, message){

  const res = message.toString();  // 将buffer转换成字符串

  if (res.id === msgId) {

    // 在这里处理服务端响应

    console.log(res.data);

  }

});

监听云端下发的服务调用消息
// 监听云端设置属性�wakeup_async服务消息

device.onService('wakeup_async', function (res,reply) {

  // 处理服务参数

  console.log('wakeup_async',res);

  // 返回云端异步服务处理消息

  reply({

    "code": 200,

    "data": {out:1}

  });

});

其他更多功能,请查api列表,值得注意的是,更多示例,见源码example文件夹

device继承自mqtt.js的EventEmitter,可以使用其全部方法
gateway可以使用device的全部api
subDevice也可以使用device的全部api

4.2 修改代码发送温度数据到阿里云

在index.js中找到:
const params = {

  Status: 1,

  Data: 'Hello, world!'

};

改成:

const params = {

  RoomTemp: Math.floor((Math.random() * 20) + 10)

};

我们在阿里云为属性定义的DeviceName是RoomTemp,取一个随机数作为温度值发送给属性RoomTemp。

如果有多个属性,用逗号隔开。

运行node index.js

每隔5秒发送一次温度数据。发送5个数据,去阿里云物联网平台看看。

查看设备的运行状态:

查看数据图表:

查看数据表格:

5. node.js读DS18B20数据发送到阿里云

查看参考文档:“树莓派 Zero W+温度传感器DS18B20”。

5.1 启用1-wire interface


1-wire interface是树莓派自带的DS18B20驱动,使用前先启用。

输入命令:sudo raspi-config

选择interfacing options,将1-wire设为enable。

重启树莓派:pi@raspberrypi:~ $ sudo reboot

5.2 查看DS18B20设备

cd /sys/bus/w1/devices/

ls

28-000004d627c6就是温度传感器DS18B20设备,这是传感器的序列号,每个传感器都不一样。

5.3 查看当前温度

依次在终端输入以下命令:

cd 28-000004d627c6

cat w1_slave

第一行最后为CRC校验“YES”表示校验正确,为“NO”则代表校验出错,或读不到温度值。

第二行的t=27000就是当前的温度值,要換算成攝氏度,除以1000,即当前温度为27000/1000=27攝氏度。

5.4 node.js读DS18B20温度传感器数据,并发送


修改代码
pi@raspberrypi:~/PiAliNode/alibabacloud-iot-device-sdk/examples/quickstart $ nano index.js

在最前面加:

const fs = require('fs');

修改setInterval函数如下:

setInterval(() => {

    var data = fs.readFileSync('/sys/bus/w1/devices/28-000004d627c6/w1_slave', $

    var i = data.indexOf('t=');

    var temp = data.substring(i+2, data.length)/1000;

    const params = {

      RoomTemp: temp

    };

    console.log(`Post properties: ${JSON.stringify(params)}`);

    device.postProps(params);

  }, 5000);

运行node index.js

去阿里云物联网平台查看设备的运行状态:

查看数据图表:

查看数据表格:

5.5 属性上报响应

修改index.js代码
pi@raspberrypi:~/PiAliNode/alibabacloud-iot-device-sdk/examples/quickstart $ nano index.js

修改device.postProps()函数:

    device.postProps(

      params,

      (res) => {

      console.log(`postProps:`,res);

    });

运行node index.js

可以看到上报属性的响应,以确认服务端收到了上报数据。

关于物模型的使用,官方文档https://github.com/aliyun/alibabacloud-iot-device-sdk#postEvent有这样的说明:

LinkPlatform 封装了物模型定义与 Alink 异步协议,SDK 封装使得设备与云端通信时不需要关心 MQTT topic,只需要调用属性上报(iot.device#postProps())、服务监听(iot.device#onService())、事件上报(iot.device#postEvent())等相关 API。

设备属性上报

device.on('connect', () => {

  device.postProps({

    LightSwitch: 0

  }, (res) => {

    console.log(`postProps:`,res);

  });

});

调用 device.postProps() 等同于执行以下代码:

// 发布属性上报 topic

device.publish('/sys/<productKey>/<deviceName>/thing/event/property/post', JSON.stringify({

  {

    id: msgId,

    version: '1.0',

    params: {

      'LightSwitch': 25,

    },

    method: 'thing.event.property.post'

  }

}));

 

// 监听属性上报响应 topic

device.subscribe('/sys/<productKey>/<deviceName>/thing/event/property/post_reply');

device.on('message', function(topic, message){

  const res = message.toString();

  if (res.id === msgId) {

    // 在这里处理服务端响应

    console.log(res.data);

  }

});

Index.js完整代码
const fs = require('fs');

const iot = require('alibabacloud-iot-device-sdk'); //加载sdk

const deviceConfig = require('./device_id_password.json');

const device = iot.device(deviceConfig); //创建设备实例

 

device.on('connect', () => {

  console.log('Connect successfully!');

  console.log('Post properties every 5 seconds...');

  setInterval(() => {

    var data = fs.readFileSync('/sys/bus/w1/devices/28-000004d627c6/w1_slave', $

    var i = data.indexOf('t=');

    var temp = data.substring(i+2, data.length)/1000;

    const params = {

      RoomTemp: temp

    };

    console.log(`Post properties: ${JSON.stringify(params)}`);

    device.postProps(

      params,

       (res) => {

      console.log(`postProps:`,res);

    });

  }, 5000);

// 监听云端服务消息

  device.onService('property/set', (data) => {

    console.log('Received a message: ', JSON.stringify(data));

  });

});

 

device.on('error', err => {

  console.error(err);

});

后面的内容见《树莓派连接阿里云物联网平台-服务(nodejs)》https://blog.csdn.net/chentuo2000/article/details/103754860

参考文档:

  1. 阿里云物联网平台基本设置
    https://blog.csdn.net/chentuo2000/article/details/103559553
  2. 树莓派 Zero W+温度传感器DS18B20
    https://blog.csdn.net/chentuo2000/article/details/81051701

      3.树莓派GPIO控制
https://blog.csdn.net/chentuo2000/article/details/81051645