【IoT物联网】IoT小程序在展示中央空调采集数据和实时运行状态上的应用

  利用前端语言实现跨平台应用开发似乎是大势所趋,跨平台并不是一个新的概念,“一次编译、到处运行”是老牌服务端跨平台语言Java的一个基本特性。随着时代的发展,无论是后端开发语言还是前端开发语言,一切都在朝着减少工作量,降低工作成本的方向发展。
  和后端开发语言不同,利用前端语言实现跨平台有先天的优势,比如后端语言Java跨平台需要将源代码编译为class字节码文件后,再放进 Java 虚拟机运行;而前端语言JavaScript是直接将源代码放进JavaScript解释器运行。这就使得以JavaScript为跨平台语言开发的应用,可移植性非常强大。
  目前跨平台技术按照解决方案分类,主要分为 Web 跨平台、容器跨平台、小程序跨平台。这里,我们主要以小程序跨端为例,测试对比IoT小程序和其他小程序在开发和应用上的优缺点。说到小程序,大家肯定想到微信小程序,实际在各大互联网公司:支付宝、百度、头条等等都有自己的小程序,小程序跨平台和Web跨平台十分类似,都是基于前端语言实现,小程序跨平台的优势在于可以调用系统底层能力,例如:蓝牙、相机等,性能方面也优于Web跨平台。
  IoT小程序和大多数小程序一样,它是一套跨平台应用显示框架,它利用JS语言低门槛和API标准化大幅度降低了IoT应用的研发难度,其官方框架介绍如下:
框架介绍
  IoT小程序在前端框架能力、应用框架能力、图形框架能力都进行了适配和优化。那么接下来,我们按照其官方步骤搭建开发环境,然后结合中央空调数据采集和状态显示的实际应用场景开发物联网小程序应用。

一、IoT小程序开发环境搭建

  IoT小程序开发环境搭建一共分为四步,对于前端开发来说,安装NodeJS、配置cnpm、安装VSCode都是轻车熟路,不需要细讲,唯一不同的是按照官方说明安装IoT小程序的模拟器和VSCode开发插件HaaS UI,前期开发环境准备完毕,运行Demo查看一下效果,然后就可以进行IoT小程序应用开发了。

搭建开发环境,安装HaaS UI插件和运行新建项目,出现一下界面说明开发环境搭建成功,就可以进行IoT小程序开发了:
项目运行

二、开发展示中央空调采集数据和运行状态的IoT小程序应用

  • 应用场景

  中央空调的维保单位会对中央空调进行定期维护保养,定期的维护保养可排出故障隐患,减少事故发生,降低运行费用,延长设备的使用寿命,同时保障正常的工作时序。除了定期的维护保养外,还需要实时监测中央空调的运行参数(温度、累计排污量、不锈钢_腐蚀率等)和运行状态,及时发现中央空调运行过程中某些参数低于或高于报警值的问题,以便及时定位诊断中央空调存在的问题,然后进行相应的维护保养操作。

  • 架构实现

  中央空调的数据采集和展示是典型的物联网应用架构,在中央空调端部署采集终端,通过Modbus通信协议采集中央空调设备参数,然后再由采集终端通过MQTT消息发送的我们的云端服务器,云端服务器接收到MQTT消息后转发到消息队列Kafka中,由云服务器上的自定义服务应用订阅Kafka主题,再存储到我们时序数据库中。

  下图展示了物联网应用的整体架构和IoT小程序在物联网架构中的位置:

中央空调物联网

  IoT小程序框架作为跨平台应用显示框架,顾名思义,其在物联网应用中主要作为显示框架开发。在传统应用中,我们使用微信小程序实现采集数据和运行状态的展示。而IoT小程序支持部署在AliOS Things、Ubuntu、Linux、MacOS、Window等系统中,这就使得我们可以灵活的将IoT小程序部署到多种设备终端中运行。
  下面将以阿里云ASP-80智显面板为例,把展示中央空调采集数据和运行状态的IoT小程序部署在阿里云ASP-80智显面板中。

  • IoT小程序开发

  我们将从IoT小程序提供的前端框架能力、应用框架能力、图形框架能力来规划相应的功能开发。

  • 前端框架能力
      IoT小程序采用Vue.js(v2.6.12)开源框架,实现了W3C标准的标签和样式子集;定义了四个应用生命周期,分别是:onLaunch,onShow,onHide,onDestroy;定义了十四个前端基础组件,除了基础的CSS样式支持外,还提供了对Less的支持;Net网络请求通过框架内置的JSAPI实现。
      为了快速熟悉IoT小程序框架的开发方式,我们将在VSCode中导入官方公版案例,并以公版案例为基础框架开发我们想要的功能。
    简单实现通过网络请求获取中央空调采集数据并展示:
  1. 在VSCode编辑器中导入从IoT小程序官网下载的公版案例,下载地址。
  2. 因为IoT小程序前端框架使用的是Vue.js框架,所以在新增页面时也是按照Vue.js框架的模式,将页面添加到pages目录。我们是空调项目的IoT小程序,所以这里在pages目录下新增air-conditioning目录用于存放空调IoT小程序相关前端代码。

新增前端代码目录

  1. 在app.json中配置新增的页面,修改pages项,增加"air-conditioning": “pages/air-conditioning/index.vue”。
{"pages": {
......"air-conditioning": "pages/air-conditioning/index.vue",
......},"options": {"style": {"theme": "theme-dark"}}
}
  1. 在air-conditioning目录下新增index.vue前端页面代码,用于展示空调的采集数据是否正常及历史曲线图。设计需要开发的界面如下,页面的元素有栅格布局、Tabs 标签页、Radio单选框、日期选择框、曲线图表等元素。
    采集数据
    曲线图表
  2. 首先是实现Tabs标签页,IoT小程序没有Tabs组件,只能自己设置多个Text组件自定义样式并添加click事件来实现。
    <div class="tab-list"><fl-icon name="back" class="nav-back" @click="onBack" /><textv-for="(item, index) in scenes":key="index":class="'tab-item' + (index === selectedIndex ? ' tab-item-selected' : '')"@click="tabSelected(index)">{{ item }}</text></div>
......data() {return {scenes: ["设备概览", "实时数据", "数据统计", "状态统计"],selectedIndex: 0};},
......

Tabs实现效果

6、添加采集数据显示列表,在其他小程序框架中,尤其是以Vue.js为基础框架的小程序框架,这里有成熟的组件,而IoT小程序也是需要自己来实现。

<template><div class="scene-wrapper" v-if="current"><div class="label-temperature-wrapper top-title"><div class="label-temperature-wrapper left-text"><text class="label-temperature">设备编码:</text><text class="label-temperature-unit">97306000000000005{{content}}</text></div><div class="label-temperature-wrapper right-text"><text class="label-temperature">数据日期:</text><text class="label-temperature-unit">2023-03-11 23:59:59{{content}}</text></div></div><div class="main-wrapper"><div class="section"><div class="demo-block icon-block"><div class="icons-item" v-for="(value, key, index) in IconTypes" :key="index"><div class="label-title-wrapper"><text class="label-title left-text">电导率</text><text class="label-title-unit right-text" style="padding-right: 5px;">正常</text></div><div class="label-zhibiao-wrapper"><text class="label-zhibiao">当前值:</text><text class="label-zhibiao-unit">56.36{{content}}</text></div><div class="label-zhibiao-wrapper" style="margin-bottom: 10px;"><text class="label-zhibiao">目标值:</text><text class="label-zhibiao-unit">63.32{{content}}</text></div></div></div></div></div></div>
</template>

采集数据展示界面

  在开发过程中发现,IoT小程序对样式的支持不是很全面,本来想将 组件放置在同一行,一般情况下,只需要使用标准CSS样式display: inline就可以实现,但这里没有效果只能通过Flexbox进行布局在同一行。在设置字体方面,本来想把采集数据显示的描述字段加粗,用于突出显示,但是使用CSS样式font-weight无效,无论是设置数值还是blod,没有一点加粗效果。
7. 界面实现之后,需要发送数据请求,来查询采集数据并显示在界面上。IoT小程序通过框架内置JSAPI的Net网络提供网络请求工具。目前从官方文档和代码中来看,官方框架只提供了http请求,没有提供物联网中常用的WebSocket和MQTT工具,估计需要自定义扩展系统JSAPI实现其他网络请求。

  created() {const http = $falcon.jsapi.httphttp.request({url: 'http://服务域名/device/iot/query/data/point',data: {'deviceId': '97306000000000005','rangeType': 'mo','lastPoint': '1','beginDateTime': '2023-02-10+16:09:42','endDateTime': '2023-03-12+16:09:42'},header: {'Accept': 'application/json;charset=UTF-8','Accept-Encoding': 'gzip, deflate, br','Content-Type': 'application/json;charset=UTF-8','Authorization': '有效token'}}, (response) => {console.log(response)var obj = JSON.parse(response.result)console.log(obj.success)console.log(JSON.parse(obj.data))});},

  按照官方要求编写http请求,发现默认未开启https请求:Protocol “https” not supported or disabled in libcurl。切换为http请求,返回数据为乱码,设置Accept-Encoding和Accept为application/json;charset=UTF-8仍然无效,且返回数据为JSON字符串,需要自己手动使用JSON.parse()进行转换,对于习惯于应用成熟框架的人来说,十分不友好。想了解更多关于 $falcon.jsapi.http的相关配置和实现,但是官方文档只有寥寥几句,没有详细的说明如何使用和配置,以及http请求中遇到一些常见问题的解决方式。
8. IoT小程序框架提供画布组件,原则上来讲可以实现常用的曲线图表功能,但是如果使用其基础能力从零开始开发一套图表系统,耗时又耗力,所以这里尝试引入常用的图表组件库ECharts,使用ECharts在IoT小程序上显示曲线图表。

  • 执行cnpm install echarts --save安装echarts组件
cnpm install echarts --save
  • 新建echarts配置文件,按需引入
// 加载echarts,注意引入文件的路径
import echarts from 'echarts/lib/echarts'// 再引入你需要使用的图表类型,标题,提示信息等
import 'echarts/lib/chart/bar'
import 'echarts/lib/chart/pie'
import 'echarts/lib/component/legend'
import 'echarts/lib/component/title'
import 'echarts/lib/component/tooltip'export default echarts
  • 新增echarts组件ChartDemo.vue
<template><div ref="chartDemo" style="height:200px;" ></div>
</template>
<script>import echarts from '@/utils/echarts-config.js'const ChartDemo = {name: 'ChartDemo',data() {return {chart: null}},watch: {option: {handler(newValue, oldValue) {this.chart.setOption(newValue)},deep: true}},mounted() {this.chart = echarts.init(this.$refs.chartDemo)},methods: {setOption(option) {this.chart && this.chart.setOption(option)},throttle(func, wait, options) {let time, context, argslet previous = 0if (!options) options = {}const later = function() {previous = options.leading === false ? 0 : new Date().getTime()time = nullfunc.apply(context, args)if (!time) context = args = null}const throttled = function() {const now = new Date().getTime()if (!previous && options.leading === false) previous = nowconst remaining = wait - (now - previous)context = thisargs = argumentsif (remaining <= 0 || remaining > wait) {if (time) {clearTimeout(time)time = null}previous = nowfunc.apply(context, args)if (!time) context = args = null} else if (!time && options.trailing !== false) {time = setTimeout(later, remaining)}}return throttled}}}export default ChartDemo
</script>
  • 在base-page.js中注册全局组件
......
import ChartDemo from './components/ChartDemo.vue';
export class BasePage extends $falcon.Page {constructor() {super()}beforeVueInstantiate(Vue) {......Vue.component('ChartDemo', ChartDemo);}
}
  • 新建空调采集数据展示页history-charts.vue,用于展示Echarts图表
<template><div class="scene-wrapper" v-if="current"><div class="brightness-wrap"><ChartBlock ref="chart2"></ChartBlock></div></div>
</template><script>
let option2 = {title: {text: '某站点用户访问来源',subtext: '纯属虚构',left: 'center'},tooltip: {trigger: 'item',formatter: '{a} <br/>{b} : {c} ({d}%)'},legend: {orient: 'vertical',left: 'left',data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎']},series: [{name: '访问来源',type: 'pie',radius: '55%',center: ['50%', '60%'],data: [{ value: 335, name: '直接访问' },{ value: 310, name: '邮件营销' },{ value: 234, name: '联盟广告' },{ value: 135, name: '视频广告' },{ value: 1548, name: '搜索引擎' }],emphasis: {itemStyle: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'}}}]
}export default {props:{current:{type:Boolean,default:false}},data() {return {};},methods: {},mounted: function() {this.$refs.chart2.setOption(option2)}
};
</script>
  • 执行HaaS UI: Build-Debug ,显示打包成功
    打包成功

  • 执行HaaS UI: Simulator ,显示“当前HaaS UI: Simulator任务正在执行,请稍后再试”
    稍后再试

  本来想在模拟器上看一下Echarts显示效果,但是执行HaaS UI: Simulator时一直显示任务正在执行。然后以为是系统进程占用,但是重启、关闭进程等操作一系列操作下来,仍然显示此提示,最后将Echarts代码删除,恢复到没有Echarts的状态,又可以执行了。这里不清楚是否是IoT小程序不支持引入第三方图表组件,从官方文档中没有找到答案。后来又使用echarts的封装组件v-charts进行了尝试,结果依然不能展示。
  如果不能使用第三方组件,那么只能使用IoT官方小程序提供的画布组件来自己实现图表功能,官方提供的画布曲线图示例。
9. 通过IoT小程序提供的组件分别实现显示中央空调采集数据的实时数据、数据统计、状态统计图表。
-实现实时数据折线图

<template><div class="scene-wrapper"  v-show="current"><div class="main-wrapper"><div class="label-temperature-wrapper top-title"><div class="label-temperature-wrapper left-text"><text class="label-temperature">设备编码:</text><text class="label-temperature-unit">97306000000000005</text></div><div class="label-temperature-wrapper right-text"><text class="label-temperature">数据日期:</text><text class="label-temperature-unit">2023-03-11 23:59:59</text></div></div><canvas ref="c2" class="canvas" width="650" height="300"></canvas></div></div>
</template><script>export default {name: "canvas",props: {},data() {return {};},mounted() {this.c2();},methods: {c2() {let ctx = typeof createCanvasContext === "function" ? createCanvasContext(this.$refs.c2) : this.$refs.c1.getContext("2d");let arr = [{key:'01:00',value:61.68},{key:'02:00',value:83.68},{key:'03:00',value:56.68},{key:'04:00',value:86.68},{key:'05:00',value:53.68},{key:'06:00',value:41.68},{key:'07:00',value:33.68}];this.drawStat(ctx, arr);},//该函数用来绘制折线图drawStat(ctx, arr) {//画布的款高var cw = 700;var ch = 300;//内间距paddingvar padding = 35;//原点,bottomRight:X轴终点,topLeft:Y轴终点var origin = {x:padding,y:ch-padding};var bottomRight = {x:cw-padding,y:ch-padding};var topLeft = {x:padding,y:padding};ctx.strokeStyle='#FF9500';ctx.fillStyle='#FF9500';//绘制X轴ctx.beginPath();ctx.moveTo(origin.x,origin.y);ctx.lineTo(bottomRight.x,bottomRight.y);//绘制X轴箭头ctx.lineTo(bottomRight.x-10,bottomRight.y-5);ctx.moveTo(bottomRight.x,bottomRight.y);ctx.lineTo(bottomRight.x-10,bottomRight.y+5);//绘制Y轴ctx.moveTo(origin.x,origin.y);ctx.lineTo(topLeft.x,topLeft.y);//绘制Y轴箭头ctx.lineTo(topLeft.x-5,topLeft.y+10);ctx.moveTo(topLeft.x,topLeft.y);ctx.lineTo(topLeft.x+5,topLeft.y+10);//设置字号var color = '#FF9500';ctx.fillStyle=color;ctx.font = "13px scans-serif";//设置字体//绘制X方向刻度//计算刻度可使用的总宽度var avgWidth = (cw - 2*padding - 50)/(arr.length-1);for(var i=0;i<arr.length;i++){//循环绘制所有刻度线if(i > 0){//移动刻度起点ctx.moveTo(origin.x+i*avgWidth,origin.y);//绘制到刻度终点ctx.lineTo(origin.x+i*avgWidth,origin.y-10);}//X轴说明文字:1月,2月...var txtWidth = 35;ctx.fillText(arr[i].key,origin.x+i*avgWidth-txtWidth/2 + 10,origin.y+20);}//绘制Y方向刻度//最大刻度maxvar max = 0;for(var i=0;i<arr.length;i++){if(arr[i].value>max){max=arr[i].value;}}console.log(max);/*var max = Math.max.apply(this,arr);console.log(max);*/var avgValue=Math.floor(max/5);var avgHeight = (ch-padding*2-50)/5;for(var i=1;i<arr.length;i++){//绘制Y轴刻度ctx.moveTo(origin.x,origin.y-i*avgHeight);ctx.lineTo(origin.x+10,origin.y-i*avgHeight);//绘制Y轴文字var txtWidth = 40;ctx.fillText(avgValue*i,origin.x-txtWidth-5,origin.y-i*avgHeight+6);}//绘制折线for(var i=0;i<arr.length;i++){var posY = origin.y - Math.floor(arr[i].value/max*(ch-2*padding-50));if(i==0){ctx.moveTo(origin.x+i*avgWidth,posY);}else{ctx.lineTo(origin.x+i*avgWidth,posY);}//具体金额文字ctx.fillText(arr[i].value,origin.x+i*avgWidth,posY)}ctx.stroke();//绘制折线上的小圆点ctx.beginPath();for(var i=0;i<arr.length;i++){var posY = origin.y - Math.floor(arr[i].value/max*(ch-2*padding-50));ctx.arc(origin.x+i*avgWidth,posY,4,0,Math.PI*2);//圆心,半径,画圆ctx.closePath();}ctx.fill();}}};</script>

实时数据折线图
-数据统计图表

<template><div class="scene-wrapper"  v-show="current"><div class="main-wrapper"><div class="label-temperature-wrapper top-title"><div class="label-temperature-wrapper left-text"><text class="label-temperature">设备编码:</text><text class="label-temperature-unit">97306000000000005</text></div><div class="label-temperature-wrapper right-text"><text class="label-temperature">数据日期:</text><text class="label-temperature-unit">2023-03-13 20:29:36</text></div></div><canvas ref="c1" class="canvas" width="650" height="300"></canvas></div></div>
</template>
<script>export default {name: "canvas",props: {},data() {return {};},mounted() {this.c1();},methods: {c1() {let ctx = typeof createCanvasContext === "function" ? createCanvasContext(this.$refs.c1) : this.$refs.c1.getContext("2d");this.draw(ctx);},draw(ctx){var x0=30,//x轴0处坐标y0=280,//y轴0处坐标x1=700,//x轴顶处坐标y1=30,//y轴顶处坐标dis=30;//先绘制X和Y轴ctx.beginPath();ctx.lineWidth=1; ctx.strokeStyle='#FF9500';ctx.fillStyle='#FF9500';ctx.moveTo(x0,y1);//笔移动到Y轴的顶部ctx.lineTo(x0,y0);//绘制Y轴ctx.lineTo(x1,y0);//绘制X轴ctx.stroke();//绘制虚线和Y轴值  var yDis = y0-y1;var n=1;ctx.fillText(0,x0-20,y0);//x,y轴原点显示0while(yDis>dis){ctx.beginPath();//每隔30划一个虚线ctx.setLineDash([2,2]);//实线和空白的比例ctx.moveTo(x1,y0-dis);ctx.lineTo(x0,y0-dis);ctx.fillText(dis,x0-20,y0-dis);//每隔30划一个虚线dis+=30;ctx.stroke();}var xDis=30,//设定柱子之前的间距width=40;//设定每个柱子的宽度//绘制柱状和在顶部显示值for(var i=0;i<12;i++){//假设有8个月ctx.beginPath();var color = '#' + Math.random().toString(16).substr(2, 6).toUpperCase();//随机颜色ctx.fillStyle=color;ctx.font = "13px scans-serif";//设置字体var height = Math.round(Math.random()*220+20);//在一定范围内随机高度var rectX=x0+(width+xDis)*i,//柱子的x位置rectY=height;//柱子的y位置ctx.color='#FF9500';ctx.fillText((i+1)+'月份',rectX,y0+15);//绘制最下面的月份稳住ctx.fillRect(rectX,y0, width, -height);//绘制一个柱状ctx.fillText(rectY,rectX+10,280-rectY-5);//显示柱子的值}},}};
</script>

数据统计图表
-状态统计图表

<template><div class="scene-wrapper"  v-show="current"><div class="main-wrapper"><div class="label-temperature-wrapper top-title"><div class="label-temperature-wrapper left-text"><text class="label-temperature">设备编码:</text><text class="label-temperature-unit">97306000000000005</text></div><div class="label-temperature-wrapper right-text"><text class="label-temperature">数据日期:</text><text class="label-temperature-unit">2023-03-13 20:29:36</text></div></div><canvas ref="c3" class="canvas" width="600" height="300"></canvas></div></div>
</template>
<script>export default {name: "canvas",props: {},data() {return {};},mounted() {this.c3();},methods: {c3() {let ctx = typeof createCanvasContext === "function" ? createCanvasContext(this.$refs.c3) : this.$refs.c3.getContext("2d");this.drawPie(ctx);},drawPie(pen){//假数据var deg = Math.PI / 180var arr = [{name: "开机",time: 8000,color: '#7CFF00'},{name: "关机",time: 1580,color: '#737F9C'},{name: "空闲",time: 5790,color: '#0ECC9B'},{name: "故障",time: 4090,color: '#893FCD'},{name: "报警",time: 2439,color: '#EF4141'},];//总价pen.translate(30,-120);arr.tatol = 0;for (let i = 0; i < arr.length; i++) {arr.tatol = arr.tatol + arr[i].time}var stardeg = 0arr.forEach(el => {pen.beginPath()var r1 = 115pen.fillStyle = el.colorpen.strokeStyle='#209AAD';pen.font = "15px scans-serif";//求出每个time的占比var angle = (el.time / arr.tatol) * 360//利用占比来画圆弧pen.arc(300, 300, r1, stardeg * deg, (stardeg + angle) * deg)//将圆弧与圆心相连接,形成扇形pen.lineTo(300, 300)var r2 = r1+10;if(el.name === '关机' || el.name === '空闲'){r2 = r1+30}//给每个扇形添加数组的namevar y1 = 300 + Math.sin((stardeg + angle) * deg-angle*deg/2 ) *( r2)var x1 = 300 + Math.cos((stardeg + angle) * deg-angle*deg/2 ) * (r2)pen.fillText(`${el.name}`, x1, y1)stardeg = stardeg + anglepen.fill()pen.stroke()});},}};
</script>

状态统计图表

三、将IoT小程序更新到ASP-80智显面板查看运行效果

  将IoT小程序更新到ASP-80智显面板,在硬件设备上查看IoT应用运行效果。如果是使用PC端初次连接,那么需要安装相关驱动和配置,否则无法使用VSCode直接更新IoT小程序到ASP-80智显面板。

  1. 如果使用Win10将IoT小程序包更新到ASP-80智显面板上,必须用到CH340串口驱动,第一次通过TypeC数据线连接设备,PC端设备管理器的端口处不显示端口,这时需要下载Windows版本的CH340串口驱动下载链接 。
    不显示端口
    下载链接
  2. 将下载的驱动文件CH341SER.ZIP解压并安装之后,再次查看PC端设备管理器端口就有了USB Serial CH340端口。

驱动安装成功

USB Serial CH340端口

  1. 使用SourceCRT连接ASP-80智显面板,按照官方文档说明,修改配置文件,连接好WiFi无线网,下一步通过VSCode直接更新IoT小程序到ASP-80智显面板上查看测试。

连接ASP-80智显面板

获取ASP-80智显面板的IP地址
4. 所有准备工作就绪后,点击VSCode的上传按钮HaaS UI: Device,将应用打包并上传至ASP-80智显面板。在选择ip地址框的时候,输入我们上一步获取到的ip地址192.168.1.112,其他参数保持默认即可,上传成功后,VSCode控制台提示安装app成功。
app安装成功提示

  1. IoT小程序安装成功之后就可以在ASP-80智显面板上查看运行效果了。
    设备概览
    实时数据
    数据统计
    状态统计

  综上所述,IoT小程序框架在跨系统平台(AliOS Things、Ubuntu、Linux、MacOS、Window等)方面提供了非常优秀的基础能力,应用的更新升级提供了多种方式,在实际业务开发过程中可以灵活选择。IoT小程序框架通过JSAPI提供了调用系统底层应用的能力,同时提供了自定义JSAPI扩展封装的方法,这样就足够业务开发通过自定义的方式满足特殊的业务需求。
  虽然多家互联网公司都提供了小程序框架,但在128M 128M这样的低资源设备里输出,IoT小程序是比较领先的,它不需要另外下载APP作为小程序的容器,降低了资源的消耗,这一点是其他小程序框架所不能比拟的。
  但是在前端框架方面,实用组件太少。其他小程序已发展多年,基于基础组件封装并开源的前端组件应用场景非常丰富,对于中小企业来说,习惯于使用成熟的开源组件,如果使用IoT小程序开发物联网应用可能需要耗费一定的人力物力。既然是基于Vue.js的框架,却没有提供引入其他优秀组件的文档说明和示例,不利于物联网应用的快速开发,希望官方能够完善文档,详细说明IoT小程序开发框架配置项,将来能够提供更多的实用组件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/17979.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL库表操作的作业

1.创建数据库 create database Market&#xff1b; mysql> show databases; -------------------- | Database | -------------------- | information_schema | | Market | | db1 | | mysql | | performance_schema | | …

如何用一部手机进行人体全身三维扫描

人体建模的应用真的是涵盖到了我们生活中的方方面面&#xff0c;真人潮玩、服饰定制、医疗康复、3D数字人等等领域&#xff0c;都离不开人体建模。 提到给人体建模&#xff0c;大家脑海里第一个浮现的画面&#xff0c;大多会是坐在电脑屏幕前&#xff0c;打开某个熟悉的建模的…

制作搭建宠物商城小程序,打造便捷的宠物购物体验

随着汽车行业的快速发展&#xff0c;越来越多的消费者开始关注汽车零配件的购买。为了提供更好的购物体验和便利&#xff0c;许多汽配商城开始关注并制作汽配商城小程序。那么&#xff0c;什么是汽配商城小程序&#xff1f;它又有哪些好处呢&#xff1f;本文将为您简单介绍汽配…

Transformer网络学习记录——基于空间约束自注意力和Transformer的RGB-D显著性检测方法研究

基于图半监督学习和图卷积的目标分割与跟踪算法研究 (wanfangdata.com.cn) 只能说看不懂&#xff0c;记录是为了有耐心慢消化 原文&#xff1a; 网络整体为通用的编码器-解码器架构 &#xff0c;总体上由骨干编码器、交互编码器、RGB 解码器、深度解码器组成。 具体来说&#…

操作系统接口 MIT 6.828 - 1. Lab 01: Xv6 and Unix utilities

本文会将lab1中的思路以及知识点进行分析&#xff0c;并作为作者学习MIT 6.828的一个学习总结&#xff0c;希望能够帮助到学习该lab的同学们 中文版书籍&#xff1a;中文版书籍 实验教案地址&#xff1a;教案地址 操作系统接口 在操作系统中&#xff0c;为了能够有效地与操作系…

【SCI征稿】计算机算法、通信、人工智能、网络、物联网、机器学习等领域,13本期刊影响因子上涨,这几本期刊录用快

2023年JCR发布后&#xff0c;计算机领域SCI期刊有13本影响因子上涨&#xff0c;审稿周期短&#xff0c;进展顺利&#xff1a; 1️⃣IF&#xff1a;6.0-7.0↑&#xff0c;JCR2区&#xff0c;中科院3区&#xff0c;SCI&EI 双检&#xff0c;CCF-C类 征稿领域&#xff1a;概率…

邮箱推荐和(警告)使用qq邮箱的坏处

qq如果发布违规消息&#xff0c;比如群聊无意发布会导致你账号封号&#xff0c;而且随着次数增多&#xff0c;会导致永久封号&#xff0c;你的qq音乐&#xff0c;qq浏览器&#xff0c;qq游戏&#xff0c;{qq邮箱}&#xff0c;全部会无法登录&#xff0c;比如需要登陆邮箱验证码…

【Java】面向对象基础 之 静态字段和静态方法

1、静态字段 在一个class中定义的字段&#xff0c;我们称之为实例字段。实例字段的特点是&#xff0c;每个实例都有独立的字段&#xff0c;各个实例的同名字段互不影响。 还有一种字段&#xff0c;是用static修饰的字段&#xff0c;称为静态字段&#xff1a;static field。 …

网络编程【TCP单向通信、TCP双向通信、一对多应用、一对多聊天服务器】(二)-全面详解(学习总结---从入门到深化)

目录 Java网络编程中的常用类 TCP通信的实现和项目案例 TCP通信入门案例 TCP单向通信 TCP双向通信 创建点对点的聊天应用 一对多应用 一对多聊天服务器 Java网络编程中的常用类 Java为了跨平台&#xff0c;在网络应用通信时是不允许直接调用操作系统接 口的&#xff0…

【ARIMA-SSA-LSTM】合差分自回归移动平均方法-麻雀优化-长短期记忆神经网络研究(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

允许Traceroute探测漏洞和ICMP timestamp请求响应漏洞解决方法(三)

目录 服务器检测出了漏洞需要修改 1.允许Traceroute探测漏洞解决方法 2、ICMP timestamp请求响应漏洞 服务器检测出了漏洞需要修改 1.允许Traceroute探测漏洞解决方法 详细描述 本插件使用Traceroute探测来获取扫描器与远程主机之间的路由信息。攻击者也可以利用这些信息来…

word自动编号变黑块的亲测解决方案

具体问题如下&#xff1a; 出现这种情况就是word的自动编号字体出错&#xff0c;可以在word中运行脚本来解决&#xff1a; Sub repair()For Each templ In ActiveDocument.ListTemplates For Each lev In templ.ListLevels lev.Font.Reset Next lev Next templEnd Sub代码如上…