大一暑假前端vue3基于阿里云物联网平台的单片机数据获取与可视化项目开发历程记录

前言:

基于开发该项目时在网上苦搜教程无果的经历,为了给其他开发者提供思路,也是为了以后面试对于技术文章的需要,更是为了巩固在该项目的学习内容与记录开发成长历程,写下第一篇CSDN文章。

项目背景:

为了拿到暑假留校申请,在学校社交平台找到学校一个项目招前后端开发,需求概括起来也简单:获取阿里云物联网平台中单片机的数据,将数据以图表形式展现在网页上。虽然获取阿里云物联网平台数据和数据转图表没试过,哎没事边学边做嘛 暑假这么长还怕搞不定。

MQTT连接阿里云物联网平台:

项目重点就是获取数据,但是阿里云物联网平台是个啥,总得花时间了解熟悉:

阿里云物联网平台http://t.csdn.cn/zDDck了解熟悉阿里云物联网平台实例产品设备的概念之后,我就在CSDN搜vue怎么获取阿里云物联网数据,就找到这个最符合需求

vue使用MQTT连接阿里云物联网平台获取实时数据http://t.csdn.cn/ueDSi于是我就按他的方法一步步做,但他的代码有bug无法直接用,报的bug看得头晕

经过一番CSDN&百度修bug,终于成功连上阿里云物联网平台收到信息了!

附上MQTT连接阿里云物联网平台代码:(id,用户名,密码,域名这些参数在阿里云物联网平台对应设备信息页找)

<script setup>
import * as mqtt from "mqtt/dist/mqtt.min";
import { ref } from 'vue'

const message = ref("连接mqtt");
const mqttvalue = ref("mqtt接收的值");
let options = {//mqtt连接参数
  connectTimeout: 4000, //超时时间
  clientId: "", //id
  username: "", //用户名
  password: "", //密码
  cleanSession: false,
  keepAlive: 60,//心跳值,心跳值太大可能会连接不成功
};
let client = mqtt.connect(//mqtt连接
  "",//物联网平台中的连接域名
  options
);
const connect = () => {
  client.on("connect", (e) => {
    message.value = `连接成功${e}`;
    console.log("连接成功", e);
    client.subscribe(
      "",//这里是订阅的主题
      { qos: 0 },
      (error) => {
        console.log('error');
      }
    );
  });
};
const duankai = () => {
  client.end();
  console.log("断开");
};
const mqttconnect = (client) => {//连接mqtt
  client.on("error", (error) => {
    console.log("连接出错", error);
  });
  client.on("message", (topic, message) => {//监听mqtt消息
    mqttvalue.value = message.toString();
    mqttvalue.value = JSON.parse(mqttvalue.value)
    console.log(`接收${topic}消息:${message.toString()}`);//这里是接收到设备的消息
    }
  });
};

onMounted(() => {
  mqttconnect(client);
})

</script>

经历连接成功喜悦不久就发现不对劲:收到信息的data里面怎么没有数据?

经过一番摸索才在日志服务发现,阿里云物联网平台是把我网页当成单片机来连了,网页收到的消息是平台发给单片机的,不是单片机发给平台的数据

白高兴一场,辛苦连接几天成功,才发现这条路不通,只能又从头开始找方法获取数据

阿里云物联网平台云产品流转:

在找方法时翻阅阿里云物联网平台的文档,偶然看见这东西

 诶这东西有说法啊,既然通过MQTT让网页被当作设备连上阿里云物联网平台,那单片机连一个设备,我网页再连一个设备,然后阿里云让设备之间相互传输不就好了,妙啊太妙了

说干就干立刻去研究研究云产品流转是怎么个搞法:

阿里云物联网平台如何进行云产品流转http://t.csdn.cn/2mr0S按教程做好之后还是收不到数据,看看日志

原来是单片机传的参数不符合json格式,让学长改了下格式后终于收到了来自单片机的数据 

但还是有问题,单片机传平台数据有三个,平台给网页只有一个数据

 平台怎么还吃数据呢?我iron和proportion去哪了???这种问题搜都不知道怎么搜,只能再去翻阅文档试试运气了

行原来还是json格式的问题,改改就好

 

 数据获取难点攻克!

数据图表可视化:

经过一番寻找,找到一个比较好用的开源可视化图表库:ECharts

ECharts官网http://t.csdn.cn/GzG7C这个比较简单就不贴代码了,详见官网的示例就行

至此一期需求完成。

调用OpenAPI接口获取数据:

新需求:需要查看历史数据

因为上面的方法网页关闭的时候不能获取数据,所以自然不能实现这个需求

那就只能通过后端将数据保存在服务器咯,我前端网页又不能保存数据

洗澡的时候正想着这项目,想起来之前用过的日志服务

 这东西证明阿里云会保存设备发给平台的历史数据,如果有办法从日志服务拿到数据不就解决问题了,连服务器都省了。

那怎么拿到日志数据呢,爬虫?不会。搜搜吧,经过一番百度,还真找到了

QueryDevicePropertyDatahttps://next.api.aliyun.com/api/Iot/2018-01-20/QueryDevicePropertyData 开做开做,但这东西怎么调用啊,官网就给个SDK示例我也看不懂啊,文档里的参数要求又多又麻烦,特别是这个签名机制看得我头皮发麻,这是在搞开发还是搞算法?(梦回高中算法竞赛青葱岁月)

 试试求助Chat GPT

 这东西有说法的啊,就靠它写接口了

Chat GTP好是好,bug也多,不是缺参数就是签名出问题又是域名有问题

……………..(此处省略数十条提问记录)

经过整个下午的修福报终于大功告成!

附上成功代码:

<script setup>
import axios from 'axios';
import { HmacSHA1, enc } from 'crypto-js';
import { reactive, ref, onMounted, watch } from 'vue';
// 替换为你自己的阿里云物联网平台 Access Key 和 Access Secret
const accessKey = '';
const accessSecret = '';
//StartTime为当前时间前一小时,EndTime为当前时间
var EndTime = new Date().getTime();
var StartTime = EndTime - 3600000;
var requestParams = {//请求参数
    Action: 'QueryDevicePropertyData',
    // 其他接口参数...
    IotInstanceId: '',
    ProductKey: '',
    DeviceName: '',
    StartTime: StartTime,
    EndTime: EndTime,
    Asc: 1,
    PageSize: 50,
    Identifier: "",
};
const sendRequest = async (params) => {//发送历史数据请求
    const requestParams = {
        ...params,
        Format: 'JSON',
        Version: '2018-01-20',
        AccessKeyId: accessKey,
        SignatureMethod: 'HMAC-SHA1',
        SignatureVersion: '1.0',
        SignatureNonce: generateRandomString(),
        Timestamp: new Date().toISOString(),
        RegionId: 'cn-shanghai',
    };
    const signedParams = signRequest(requestParams, accessSecret);

    const requestPath = buildRequestPath(signedParams);
    const url = `https://iot.cn-shanghai.aliyuncs.com/${requestPath}`;

    try {
const response = await axios.get(url);
return response.data;
} catch (error) {
throw error;
}

};
const generateRandomString = () => {//生成随机字符串
    return Math.random().toString(36).substr(2);
};
const signRequest = (params, accessSecret) => {//拼接签名
    const paramList = Object.keys(params).sort().map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`);
    const stringToSign = `GET&%2F&${encodeURIComponent(paramList.join('&'))}`;
    const signature = HmacSHA1(stringToSign, `${accessSecret}&`).toString(enc.Base64);
    return {
        ...params,
        Signature: signature,
    };
};
const buildRequestPath = (params) => {//构建请求路径
    const queryList = [];
    for (const key in params) {
        if (params.hasOwnProperty(key)) {
            queryList.push(`${key}=${encodeURIComponent(params[key])}`);
        }
    }
    return `?${queryList.join('&')}`;
};
const convertTo24HourFormat = (time) => {// 将毫秒值时间戳转换为24进制时间补足两位
    const date = new Date(time);
    const hour = date.getHours();
    const minute = date.getMinutes();
    const second = date.getSeconds();
    return `${hour < 10 ? '0' + hour : hour}:${minute < 10 ? '0' + minute : minute}:${second < 10 ? '0' + second : second}`;
};
const sendRequestAndChangeData = async (requestParams) => {//发送请求异步函数,递归调用,直到NextValid为false
    const response = await sendRequest(requestParams);
    console.log(response.Data);
}
onMounted(() => {
    sendRequestAndChangeData(requestParams)
})
</script>

OK这样把阿里云物联网平台当后端服务器,连服务器都省了,太妙了。

然后项目指导老师:

 。。。。。。白忙活一场

后记:

因为项目在申请软著,就不方便展示项目页面了

项目不难,却算是我第一个独立开发完成的项目,从一开始对阿里云物联网平台,MQTT协议,ECharts,OpenAPI这些毫不了解,通过不断百度搜索学习,到后面逐渐了解使用。虽然中间走了许多弯路,做了许多无用功,哎没关系,学到东西就不亏。

这里很想贴上初中的时候对洛谷一段很有感触的话:

曾经那个在机房怀揣着梦想的初中生走上了开发的道路, 不知道以后工作再看到这篇技术含量极低的博客时是什么感想呢

作者:cjh_123_

物联沃分享整理
物联沃-IOTWORD物联网 » 大一暑假前端vue3基于阿里云物联网平台的单片机数据获取与可视化项目开发历程记录

发表评论