使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

0. 成果

使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)
使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

1. 前期准备

  1. 开通 Link Develop 账号:使用阿里云账号或者淘宝账号访问 https://linkdevelop.aliyun.com/,填写开发者入驻表单完成入驻。(即申请即通过
  2. 依赖安装:已预先配置完成。
  3. 项目文件创建与生成:已预先配置完成。

Ruff 硬件开发

一、上云

此步操作设备:电脑

  1. 登录阿里云账号,访问 https://linkdevelop.aliyun.com 创建一个新项目:
  2. 从项目控制台左侧的设备菜单项里找到“产品开发”,点击进入并点击“立即创建产品”。
  3. 按下图填写表单,所属分类选择“智能生活/电工照明/灯”,节点类型选择“设备”,通讯网络选择“Wi-Fi”,数据格式选择“Alink”,然后点“提交”后点击“进入开发”按钮。
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)
  4. 添加一个 RGB 调色的功能定义:点击标准功能一栏右
    侧的“新增”按钮。在弹出的“新增可选功能”对话框左侧列表中,找到 RGB 调色功能并单击进行选择,然后点击“确定”。

使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

  1. 申请测试设备的激活凭证:从“功能定义”的 Tab 切换到“设备开发”的 Tab,点击“设备列表”一栏右侧的“新增测试设备”按钮,点击确定,获得激活凭证三元组:ProductKey、DeviceName 和 DeviceSecret不要关闭该页面!
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

二. 设备端开发

此步使用设备:电脑

  1. 打开电脑终端,进入项目目录:cd ruff-linkdevelop-rgblight
  2. 编辑项目文件 /src/index.js,将 productKey、deviceName、deviceSecret 替换成前一步申请的设备激活凭证:
'use strict';

var aliyunIot = require('aliyun-iot-device-sdk');

// 设备连接到云端
var device = aliyunIot.device({
// 替换为生成的激活凭证三元组
  productKey: '<productKey>',
  deviceName: '<deviceName>',
  deviceSecret: '<deviceSecret>'
});

// 连接成功
device.on('connect', function() {
  console.log('connect successfully!');
  // 点亮
  $('#KY-016').setRGB(0xffffff);
  // 上报属性
  device.postProps({
    LightSwitch: 1,
    RGBColor: {
      Red: 255,
      Green: 255,
      Blue: 255
    }
  });
});

// ruff 初始化完毕
$.ready(function(error) {
  if (error) {
    console.log(error);
    return;
  }
  // 监听云端下行消息
  device.serve('property/set', function(params) {
    console.log('receive params:', params);
    var LightSwitch = params.LightSwitch;
    // 开灯
    if (LightSwitch === 1) {
      $('#KY-016').setRGB(0xffffff);
    }
    // 关灯
    if (LightSwitch === 0) {
      $('#KY-016').setRGB(0x000000);
    }
    // 调色
    var RGBColor = params.RGBColor;
    if (RGBColor) {
      var hexArr = [RGBColor.Red, RGBColor.Green, RGBColor.Blue].map(function(
        x
      ) {
        x = parseInt(x).toString(16);
        return x.length === 1 ? '0' + x : x;
      });
      var color = Number('0x' + hexArr.join(''));
      $('#KY-016').setRGB(color);
    }
    // 上报属性
    device.postProps(params);
  });
});

$.end(function() {
  console.log('disconnect');
  // 断开连接
  device.end();
});

保存退出,项目修改完成!


三、运行和调试

此步使用设备:开发板+电脑

  1. 将开发板通电,等待 1 分钟联网。
  2. 使用电脑打开刚刚的阿里云控制台页面,点击设备列表里的设备“调试”链接,在页面下方的调试功能里选择“RGB调色(RGBColor)”,方法选为“设置”,下方指令区输入

    {"RGBColor":{"Red":255,"Blue":255,"Green":0}}
  3. 点击“发送指令”按钮:
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

小灯变紫——数据下发成功(动图)


Web 应用开发

全程使用设备:电脑

一、创建应用

  1. 从项目控制台左侧菜单进入“应用-Web 应用”,点击右上角的“新增应用”按钮。
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)
  2. 如图所示填写表单,新建一个托管应用,点击提交进入下一步。
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)
  3. 在应用“创建成功”的页面上点击“进入开发”按钮,获取 AppKey 和 AppSecret,用于之后应用开发。(不要关闭此页面!!!
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

二、开通官方物的管理服务

  1. 点击左上角的项目下拉列表,打开项目控制台的首页。
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)
  2. 点击项目控制台首页右上角的“资源管理”按钮。
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)
  3. 切换到“可用服务” Tab,点击右侧的“添加官方”服务,在对话框中勾选“物的管理服务”,然后点击“确定”。
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

三、Web 应用编码

  1. 新建目录,进行项目初始化:

  2. linkdevelop-webapp-rgblight
  3. linkdevelop-webapp-rgblight
  4. init

使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

  1. 安装 @bone/iot-gateway 和 react-color 颜色选择组件:bnpm i --save @bone/iot-gateway react-color
  2. 修改 app/pages/home/index.js 代码,内容如下:
import React, { Component } from 'react';
import { Button, Switch, Form, Grid, Input, Dialog } from '@bone/bone-web-ui';
import IotGateway from '@bone/iot-gateway';
import { HuePicker } from 'react-color';

const Row = Grid.Row;
const Col = Grid.Col;
const FormItem = Form.Item;
const formItemLayout = {
  labelCol: {
    fixedSpan: 12
  },
  wrapperCol: {
    span: 12
  }
};
const insetLayout = {
  labelCol: { fixedSpan: 4 }
};

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      switch: false,
      color: '',
      // 刷新页面不用重复输入
      productKey: localStorage.getItem('productKey') || '',
      deviceName: localStorage.getItem('deviceName') || ''
    };
    // 获取初始数据
    this.getProps(props => {
      this.setState({
        switch: props.LightSwitch === 1,
        color: rgbToHex(
          props.RGBColor.Red,
          props.RGBColor.Green,
          props.RGBColor.Blue
        )
      });
    });
  }
  getProps(cb) {
    IotGateway.post({
      url: 'https://api.link.aliyun.com/thing/device/status/query',
      apiVer: '1.0.1',
      params: {
        ProductKey: this.state.productKey,
        DeviceName: this.state.deviceName
      }
    }).then(res => {
      if (res.code !== 200) {
        throw new Error(res.localizedMsg || res.message);
      }
      let props = {};
      res.data.forEach(item => {
        props[item.attribute] = item.value;
      });
      if (cb) {
        cb(props);
      }
      console.log('get props successfully:', props);
    });
  }
  setProps(props) {
    IotGateway.post({
      url: 'https://api.link.aliyun.com/thing/device/properties/set',
      apiVer: '1.0.1',
      params: {
        ThingId: {
          productKey: this.state.productKey,
          deviceName: this.state.deviceName
        },
        Items: props
      }
    }).then(res => {
      if (res.code !== 200) {
        throw new Error(res.localizedMsg || res.message);
      }
      console.log(res);
    });
  }
  showValidationText() {
    Dialog.alert({
      title: '提示',
      content: '请输入设备的 productKey 和 deviceName 才能控制设备哦'
    });
  }
  onChange = checked => {
    if (!this.state.productKey || !this.state.deviceName) {
      this.showValidationText();
      return;
    }
    this.setState({
      switch: checked
    });
    this.setProps({
      LightSwitch: checked ? 1 : 0
    });
  };
  onInput = (field, value) => {
    this.state[field] = value;
    localStorage.setItem(field, value);
    this.setState({
      [field]: value
    });
  };
  onColorChange = color => {
    if (!this.state.productKey || !this.state.deviceName) {
      this.showValidationText();
      return;
    }
    this.setState({
      color: color.hex
    });
    this.setProps({
      RGBColor: hexToRgb(color.hex)
    });
  };
  render() {
    return (
      <div style={{ padding: '30px 0 0 30px' }}>
        <Form style={{ margin: '0 0 0 30px' }} {...formItemLayout}>
          <FormItem label="设备 id">
            <Row>
              <Col>
                <FormItem
                  label="productKey"
                  required={false}
                  labelAlign="inset"
                  {...insetLayout}
                >
                  <Input
                    placeholder="请输入"
                    value={this.state.productKey}
                    onChange={value => this.onInput('productKey', value)}
                  />
                </FormItem>
              </Col>
              <Col>
                <FormItem
                  label="deviceName"
                  required={false}
                  labelAlign="inset"
                  {...insetLayout}
                >
                  <Input
                    placeholder="请输入"
                    value={this.state.deviceName}
                    onChange={value => this.onInput('deviceName', value)}
                  />
                </FormItem>
              </Col>
            </Row>
          </FormItem>
          <FormItem label="开关">
            <Switch onChange={this.onChange} checked={this.state.switch} />
          </FormItem>
          <FormItem label="调色">
            <div style={{ padding: '7px 0 0 10px' }}>
              <HuePicker
                onChangeComplete={this.onColorChange}
                color={this.state.color}
              />
            </div>
          </FormItem>
        </Form>
      </div>
    );
  }
}

function rgbToHex(r, g, b) {
  return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

function hexToRgb(hex) {
  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result
    ? {
        Red: parseInt(result[1], 16),
        Green: parseInt(result[2], 16),
        Blue: parseInt(result[3], 16)
      }
    : null;
}

四、运行调试

  1. 启动项目: bone start
  2. 使用 Chrome 浏览器访问:http://localhost:8000/
  3. 填入『本章节第一步』获取的应用 appKey 和 appSecret:
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

进入Web 控制页面

  1. 之后填入『第一章节上云』步骤中获取的测试设备激活凭证 productKey 以及 deviceName,点击“确认”按钮。

使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

  1. 刷新页面,查看Chrome 浏览器控制台(按 F12 或者 Ctrl+Shift+i),正常情况下设备的属性已经能正常获取。
  2. 点击几下灯的开关,发现能够正常控制灯的开关了,再试一下颜色调色板,发现灯的颜色也可以正常控制了。

至此 RGB 全彩智能灯的 Web 应用已开发完毕。给自己一点掌声~


五、应用发布(附加)

  1. 回到 Link Develop 工作台,在 RGB 小灯的 Web 应用界面上点击“新增版本变更”按钮,完成项目版本创建。
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)
  2. 点击“构建部署”按钮。
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)
  3. 在 Web 项目下执行 bone pack 命令,进行打包。
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)
  4. 在界面上点击“上传构建包”按钮,上传上一步生成的 zip 包文件。
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)
  5. 等待构建完成后,就可以通过域名访问部署好的 Web 应用了。
    使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

使用 Ruff 开发板+ Link Develop 快速开发 IoT 应用(环境预配置版)

上一篇:阿里云视频云「 vPaaS 」演绎了怎样的音视频应用开发「未来图景」?


下一篇:企业如何通过数据可视化为决策提供数据依据