基于开发该项目时在网上苦搜教程无果的经历,为了给其他开发者提供思路,也是为了以后面试对于技术文章的需要,更是为了巩固在该项目的学习内容与记录开发成长历程,写下第一篇CSDN文章。
为了拿到暑假留校申请,在学校社交平台找到学校一个项目招前后端开发,需求概括起来也简单:获取阿里云物联网平台中单片机的数据,将数据以图表形式展现在网页上。虽然获取阿里云物联网平台数据和数据转图表没试过,哎没事边学边做嘛 暑假这么长还怕搞不定。
项目重点就是获取数据,但是阿里云物联网平台是个啥,总得花时间了解熟悉:
阿里云物联网平台https://www.aliyun.com/阿里云物联网平台使用指南http://t.csdn.cn/zDDck了解熟悉阿里云物联网平台实例产品设备的概念之后,我就在CSDN搜vue怎么获取阿里云物联网数据,就找到这个最符合需求
vue使用MQTT连接阿里云物联网平台获取实时数据http://t.csdn.cn/ueDSi于是我就按他的方法一步步做,但他的代码有bug无法直接用,报的bug看得头晕
经过一番CSDN&百度修bug,终于成功连上阿里云物联网平台收到信息了!
附上MQTT连接阿里云物联网平台代码:(id,用户名,密码,域名这些参数在阿里云物联网平台对应设备信息页找)
- 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);
- })
-
经历连接成功喜悦不久就发现不对劲:收到信息的data里面怎么没有数据?
经过一番摸索才在日志服务发现,阿里云物联网平台是把我网页当成单片机来连了,网页收到的消息是平台发给单片机的,不是单片机发给平台的数据
白高兴一场,辛苦连接几天成功,才发现这条路不通,只能又从头开始找方法获取数据
在找方法时翻阅阿里云物联网平台的文档,偶然看见这东西
诶这东西有说法啊,既然通过MQTT让网页被当作设备连上阿里云物联网平台,那单片机连一个设备,我网页再连一个设备,然后阿里云让设备之间相互传输不就好了,妙啊太妙了
说干就干立刻去研究研究云产品流转是怎么个搞法:
阿里云物联网平台如何进行云产品流转http://t.csdn.cn/2mr0S按教程做好之后还是收不到数据,看看日志
原来是单片机传的参数不符合json格式,让学长改了下格式后终于收到了来自单片机的数据
但还是有问题,单片机传平台数据有三个,平台给网页只有一个数据
平台怎么还吃数据呢?我iron和proportion去哪了???这种问题搜都不知道怎么搜,只能再去翻阅文档试试运气了
行原来还是json格式的问题,改改就好
数据获取难点攻克!
经过一番寻找,找到一个比较好用的开源可视化图表库:ECharts
ECharts官网https://echarts.apache.org/zh/index.htmlECharts教程http://t.csdn.cn/GzG7C这个比较简单就不贴代码了,详见官网的示例就行
至此一期需求完成。
新需求:需要查看历史数据
因为上面的方法网页关闭的时候不能获取数据,所以自然不能实现这个需求
那就只能通过后端将数据保存在服务器咯,我前端网页又不能保存数据
洗澡的时候正想着这项目,想起来之前用过的日志服务
这东西证明阿里云会保存设备发给平台的历史数据,如果有办法从日志服务拿到数据不就解决问题了,连服务器都省了。
那怎么拿到日志数据呢,爬虫?不会。搜搜吧,经过一番百度,还真找到了
QueryDevicePropertyDatahttps://next.api.aliyun.com/api/Iot/2018-01-20/QueryDevicePropertyData 开做开做,但这东西怎么调用啊,官网就给个SDK示例我也看不懂啊,文档里的参数要求又多又麻烦,特别是这个签名机制看得我头皮发麻,这是在搞开发还是搞算法?(梦回高中算法竞赛青葱岁月)
试试求助Chat GPT
这东西有说法的啊,就靠它写接口了
Chat GTP好是好,bug也多,不是缺参数就是签名出问题又是域名有问题
.................(此处省略数十条提问记录)
经过整个下午的修福报终于大功告成!
附上成功代码:
- 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)
- })
OK这样把阿里云物联网平台当后端服务器,连服务器都省了,太妙了。
然后项目指导老师:
。。。。。。白忙活一场
因为项目在申请软著,就不方便展示项目页面了
项目不难,却算是我第一个独立开发完成的项目,从一开始对阿里云物联网平台,MQTT协议,ECharts,OpenAPI这些毫不了解,通过不断百度搜索学习,到后面逐渐了解使用。虽然中间走了许多弯路,做了许多无用功,哎没关系,学到东西就不亏。
这里很想贴上初中的时候对洛谷一段很有感触的话:
曾经那个在机房怀揣着梦想的初中生走上了开发的道路, 不知道以后工作再看到这篇技术含量极低的博客时是什么感想呢