detail.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. <template>
  2. <view class="content">
  3. <view class="header">
  4. <view style="position: absolute;right:10rpx;top:30rpx;z-index: 9999">
  5. <u-button @click="reportError" text="上报异常" type="error" size="mini"></u-button>
  6. </view>
  7. <u--form>
  8. <u-form-item style="border:0px"
  9. label="设备名称:"
  10. labelWidth="auto"
  11. :borderBottom="false"
  12. >
  13. <u--input disabled
  14. placeholder="请选择分组"
  15. border="none"
  16. color="gray"
  17. disabledColor="white"
  18. v-model="deviceInfo.deviceName"
  19. ></u--input>
  20. </u-form-item>
  21. <u-form-item style="border:0px"
  22. label="所属机构:"
  23. labelWidth="auto"
  24. :borderBottom="false"
  25. >
  26. <u--input v-if="sysDept != null" disabled
  27. placeholder="请选择分组22"
  28. border="none"
  29. color="gray"
  30. disabledColor="white"
  31. :value="sysDept.deptName"
  32. ></u--input>
  33. <u--input v-else-if="deviceInfo.deptId == -1" disabled
  34. placeholder="请选择分组11"
  35. border="none"
  36. color="gray"
  37. disabledColor="white"
  38. value="已注销"
  39. ></u--input>
  40. <u--input v-else disabled
  41. placeholder="未绑定"
  42. border="none"
  43. color="gray"
  44. disabledColor="white"
  45. value="未绑定"
  46. ></u--input>
  47. </u-form-item>
  48. <u-form-item style="border:0px"
  49. label="设备编号:"
  50. labelWidth="auto"
  51. :borderBottom="false"
  52. ref="item1"
  53. >
  54. <u--input disabled
  55. border="none"
  56. color="gray"
  57. disabledColor="white"
  58. v-model="deviceInfo.serialNumber"
  59. ></u--input>
  60. </u-form-item>
  61. <u-form-item style="border:0px"
  62. label="二维码ID:"
  63. labelWidth="auto"
  64. :borderBottom="false"
  65. ref="item1"
  66. >
  67. <u--input disabled
  68. border="none"
  69. color="gray"
  70. disabledColor="white"
  71. v-model="deviceInfo.qrcodeId"
  72. ></u--input>
  73. </u-form-item>
  74. <u-form-item style="border:0px"
  75. label="激活时间:"
  76. labelWidth="auto"
  77. :borderBottom="false"
  78. ref="item1"
  79. >
  80. <u--input disabled
  81. border="none"
  82. color="gray"
  83. disabledColor="white"
  84. :value="deviceInfo.activeTime"
  85. ></u--input>
  86. </u-form-item>
  87. <u-form-item style="border:0px"
  88. label="运行时长:"
  89. labelWidth="auto"
  90. :borderBottom="false"
  91. ref="item1"
  92. >
  93. <view style="width: 20%">
  94. <u-button @click="seeTime()" type="primary" size="mini" text="查看时长"></u-button>
  95. </view>
  96. </u-form-item>
  97. <u-form-item style="border:0px"
  98. label="位置信息:"
  99. labelWidth="auto"
  100. :borderBottom="false"
  101. ref="item1"
  102. >
  103. <view style="width: 20%">
  104. <u-button @click="openLocation(deviceInfo)" type="primary" size="mini" text="查看位置"></u-button>
  105. </view>
  106. </u-form-item>
  107. <u-form-item style="border:0px"
  108. label="设备信号:"
  109. labelWidth="auto"
  110. :borderBottom="false"
  111. >
  112. <u--input disabled
  113. border="none"
  114. color="gray"
  115. disabledColor="white"
  116. :value="deviceInfo.rssi"
  117. ></u--input>
  118. </u-form-item>
  119. <u-form-item v-if="deviceInfo.networkAddress != null" style="border:0px"
  120. label="设备网络:"
  121. labelWidth="auto"
  122. :borderBottom="false"
  123. ref="item1"
  124. >
  125. <u--input disabled
  126. border="none"
  127. color="gray"
  128. disabledColor="white"
  129. :value="deviceInfo.networkAddress+'('+deviceInfo.networkIp+')'"
  130. ></u--input>
  131. </u-form-item>
  132. <u-form-item style="border:0px"
  133. label="设备状态:"
  134. labelWidth="auto"
  135. :borderBottom="false"
  136. >
  137. <view style="width:90rpx">
  138. <u-tag v-if="deviceInfo.status === 4" text="离线" size="mini" type="info"></u-tag>
  139. <u-tag v-if="deviceInfo.status === 3" text="在线" size="mini" type="success"></u-tag>
  140. <u-tag v-if="deviceInfo.status === 2" text="禁用" size="mini" type="error"></u-tag>
  141. <u-tag v-if="deviceInfo.status === 1" text="未激活" size="mini" type="error"></u-tag>
  142. </view>
  143. </u-form-item>
  144. </u--form>
  145. </view>
  146. <view class="text-area">
  147. <u-tabs :list="summary" keyName="tabName" @change="getDeviceStatus"></u-tabs>
  148. <view class="prop-container" style="background: white;padding:10px ">
  149. <u-form>
  150. <u-form-item style="border:0px;position: relative"
  151. label=" "
  152. labelWidth="auto"
  153. :borderBottom="false"
  154. >
  155. <uni-row class="demo-uni-row">
  156. <uni-col :span="12">
  157. 开机: <u-switch v-model="power.value" :loading ="power.loading" @change="changeProp('PowerControl')"></u-switch>
  158. </uni-col>
  159. <uni-col :span="12">
  160. 锁定: <u-switch v-model="lock.value" :loading ="lock.loading" @change="changeProp('LockControl')"></u-switch>
  161. </uni-col>
  162. </uni-row>
  163. </u-form-item>
  164. <view v-for="item in inputProp" v-if="checkCommonProp(item)">
  165. <uni-row class="demo-uni-row" v-if="item.type === 'integer'">
  166. <uni-col :span="10">
  167. <view class="item">{{item.name}}</view>
  168. </uni-col>
  169. <uni-col :span="10">
  170. <view style="padding:0 10rpx">
  171. <u-input placeholder="请输入整数" v-model="item.shadow">
  172. </u-input>
  173. </view>
  174. </uni-col>
  175. <uni-col :span="4">
  176. <view class="item" style="padding-top:14rpx">
  177. <u-button v-if="deviceInfo.status==3"
  178. @tap="send(item)"
  179. text="发送"
  180. type="success"
  181. size="mini"
  182. ></u-button>
  183. <u-button v-if="deviceInfo.status!=3"
  184. @tap="send(item)"
  185. text="发送"
  186. type="info"
  187. size="mini"
  188. ></u-button>
  189. </view>
  190. </uni-col>
  191. </uni-row>
  192. <uni-row class="demo-uni-row" v-if="item.type === 'string'">
  193. <uni-col :span="10">
  194. <view class="item">{{item.name}}</view>
  195. </uni-col>
  196. <uni-col :span="10">
  197. <view style="padding:0 10rpx">
  198. <u-input placeholder="请输入字符串" v-model="item.shadow">
  199. </u-input>
  200. </view>
  201. </uni-col>
  202. <uni-col :span="4">
  203. <view class="item" style="padding-top:14rpx">
  204. <u-button v-if="deviceInfo.status==3"
  205. @tap="send(item)"
  206. text="发送"
  207. type="success"
  208. size="mini"
  209. ></u-button>
  210. <u-button v-if="deviceInfo.status!=3"
  211. @tap="send(item)"
  212. text="发送"
  213. type="info"
  214. size="mini"
  215. ></u-button>
  216. </view>
  217. </uni-col>
  218. </uni-row>
  219. <uni-row class="demo-uni-row" v-if="item.type === 'array'">
  220. <uni-col :span="10">
  221. <view class="item">{{item.name}}</view>
  222. </uni-col>
  223. <uni-col :span="10">
  224. <view style="padding:0 10rpx">
  225. <u-input placeholder="请使用英文逗号分隔的字符串" v-model="item.shadow">
  226. </u-input>
  227. </view>
  228. </uni-col>
  229. <uni-col :span="4">
  230. <view class="item" style="padding-top:14rpx">
  231. <u-button v-if="deviceInfo.status==3"
  232. @tap="send(item)"
  233. text="发送"
  234. type="success"
  235. size="mini"
  236. ></u-button>
  237. <u-button v-if="deviceInfo.status!=3"
  238. @tap="send(item)"
  239. text="发送"
  240. type="info"
  241. size="mini"
  242. ></u-button>
  243. </view>
  244. </uni-col>
  245. </uni-row>
  246. <uni-row class="demo-uni-row" v-if="item.type === 'enum'">
  247. <uni-col :span="10">
  248. <view class="item">{{item.name}}</view>
  249. </uni-col>
  250. <uni-col :span="10">
  251. <view style="padding:0 10rpx">
  252. <u-cell customStyle="border:0px;" size="mini" @click="chooseItemData(item)" arrow-direction="left" v-if="item.text != null && item.text.length>0" :title="item.text">
  253. <u-icon slot="icon" size="12" name="arrow-down"></u-icon>
  254. </u-cell>
  255. <u-cell customStyle="border:0px;" size="mini" @click="chooseItemData(item)" arrow-direction="down" v-else title="请选择">
  256. <u-icon slot="icon" size="12" name="arrow-down"></u-icon>
  257. </u-cell>
  258. </view>
  259. </uni-col>
  260. <uni-col :span="4">
  261. <view class="item" style="padding-top:14rpx">
  262. <u-button v-if="deviceInfo.status==3"
  263. @tap="send(item)"
  264. text="发送"
  265. type="success"
  266. size="mini"
  267. ></u-button>
  268. <u-button v-if="deviceInfo.status!=3"
  269. @tap="send(item)"
  270. text="发送"
  271. type="info"
  272. size="mini"
  273. ></u-button>
  274. </view>
  275. </uni-col>
  276. </uni-row>
  277. </view>
  278. <u-line></u-line>
  279. <u--text text="属性监控" style="margin-top:20px"></u--text>
  280. <view>
  281. <uni-row class="demo-uni-row" v-if="checkCommonProp(item)" v-for="item in deviceInfo.readOnlyList">
  282. <uni-col :span="10">
  283. <view class="item">{{item.name}}</view>
  284. </uni-col>
  285. <uni-col :span="10">
  286. <view style="padding:0 10rpx">
  287. <u-input placeholder="请输入字符串" disabled="" :value="item.shadow+' '+item.unit">
  288. </u-input>
  289. </view>
  290. </uni-col>
  291. </uni-row>
  292. </view>
  293. </u-form>
  294. </view>
  295. <u-picker @cancel="show=null" :show="show!=null" :columns="columns" @confirm="confirmItemData" keyName="text"></u-picker>
  296. <u-modal @cancel="cancel" :show="showErrDlg" title="异常上报" :showCancelButton="true" @confirm="doReportError" >
  297. <view class="slot-content">
  298. <u--textarea style="width:500rpx" autoheight v-model="errorMsg" placeholder="请输入异常内容" ></u--textarea>
  299. </view>
  300. </u-modal>
  301. <u-modal :show="showTimeDlg" title="查看时长" @confirm="closeTime" >
  302. <view class="slot-content">
  303. <view v-if="timeobj!=null && deviceInfo.status == 3">本次运行时长:{{ timeobj.runtime }}</view>
  304. <view v-if="timeobj!=null ">累计时长:{{ timeobj.alltime }}</view>
  305. <view v-if="timeobj!=null ">平均每天运行时长:{{ timeobj.avgtime }}</view>
  306. </view>
  307. </u-modal>
  308. </view>
  309. </view>
  310. </template>
  311. <script>
  312. import { getDetail,getDeviceStatus,cacheJsonThingsModel,reportError ,getDeviceRunTime} from '@/api/device/device.js'
  313. import UButton from "../../uni_modules/uview-ui/components/u-button/u-button";
  314. import UForm from "../../uni_modules/uview-ui/components/u--form/u--form";
  315. import UInput from "../../uni_modules/uview-ui/components/u--input/u--input";
  316. export default {
  317. components: {UInput, UForm, UButton},
  318. data(){
  319. return {
  320. modelKey:['PowerControl','LockControl'],
  321. power:{
  322. loading:true,
  323. value:0,
  324. },
  325. lock:{
  326. loading:true,
  327. value:0,
  328. },
  329. showTimeDlg:false,
  330. showErrDlg:null,
  331. errorMsg:"",
  332. show:null,
  333. value:"",
  334. deviceInfo:{},
  335. id:0,
  336. summary:[],
  337. activeName:0,
  338. childId:"",
  339. oneToMul:false,
  340. inputProp:[],
  341. watchProp:[],
  342. columns:[],
  343. location:{},
  344. sysDept:null,
  345. timeobj:null,
  346. }
  347. },
  348. onLoad: function(opt) {
  349. this.id = opt.id;
  350. this.connectMqtt();
  351. this.getDetail();
  352. },
  353. destroyed() {
  354. // 取消订阅主题
  355. this.mqttUnSubscribe(this.deviceInfo);
  356. },
  357. methods:{
  358. changeProp(key){
  359. let item = null;
  360. let obj = null;
  361. if(key === "LockControl"){
  362. item = this.lock;
  363. }else if(key === "PowerControl"){
  364. item = this.power;
  365. }
  366. let value = item.value;
  367. obj = item.item;
  368. if(value){
  369. obj.value = 1;
  370. obj.shadow = 1;
  371. }else{
  372. obj.value = 0;
  373. obj.shadow = 0;
  374. }
  375. this.publishThingsModel(this.deviceInfo,obj);
  376. },
  377. checkCommonProp(item){
  378. let id =item.id;
  379. let isCommonKey = this.modelKey.some(res=>{
  380. return id === res;
  381. })
  382. return !isCommonKey;
  383. },
  384. getRunTime(){
  385. let self = this;
  386. getDeviceRunTime(this.id).then(res=>{
  387. self.timeobj = res.data;
  388. })
  389. },
  390. seeTime(){
  391. this.showTimeDlg = true;
  392. this.getRunTime();
  393. },
  394. closeTime(){
  395. this.showTimeDlg = false;
  396. },
  397. cancel(){
  398. this.showErrDlg = false;
  399. },
  400. reportError(){
  401. this.showErrDlg = true;
  402. },
  403. doReportError(){
  404. if(!this.errorMsg){
  405. this.$modal.showToast('异常信息不能为空')
  406. }else{
  407. let self = this;
  408. let errObj = {};
  409. errObj.deviceId = this.deviceInfo.deviceId;
  410. errObj.deviceName = this.deviceInfo.deviceName
  411. errObj.desc = this.errorMsg;
  412. errObj.deptId= this.deviceInfo.deptId;
  413. reportError(errObj).then(res=>{
  414. self.$modal.showToast(res.msg)
  415. self.cancel();
  416. })
  417. }
  418. },
  419. openLocation(){
  420. uni.openLocation({
  421. latitude: this.location.latitude,
  422. longitude: this.location.longitude,
  423. success: function () {
  424. console.log('success');
  425. }
  426. });
  427. },
  428. confirmItemData(e){
  429. let data = e.value[0];
  430. this.show.text = data.text;
  431. this.show.shadow=data.value;
  432. this.show = null;
  433. console.log(data);
  434. },
  435. send(item){
  436. if(this.deviceInfo.status != 3){
  437. uni.showToast({
  438. title:"设备暂未上线",
  439. icon:"error"
  440. })
  441. return;
  442. }
  443. if(!item.shadow){
  444. uni.showToast({
  445. title:"数据不能为空",
  446. icon:"error"
  447. })
  448. return;
  449. }
  450. this.publishThingsModel(this.deviceInfo,item)
  451. },
  452. /** 更新设备状态 */
  453. updateDeviceStatus(device) {
  454. },
  455. chooseItemData(data){
  456. if(this.deviceInfo.status != 3){
  457. uni.showToast({
  458. title:"设备暂未上线",
  459. icon:"error"
  460. })
  461. return;
  462. }
  463. this.columns = [data.enumList];
  464. this.show =data;
  465. },
  466. getDetail(){
  467. let self = this;
  468. getDetail(this.id).then(res=>{
  469. self.deviceInfo = res.data;
  470. self.location = {
  471. latitude: self.deviceInfo.latitude,
  472. longitude: self.deviceInfo.longitude};
  473. self.sysDept = self.deviceInfo.sysDept;
  474. self.parseSummay(res.data.summary)
  475. self.mqttSubscribe(res.data);
  476. self.getDeviceStatus();
  477. });
  478. },
  479. getDeviceStatus(e){
  480. let self = this;
  481. if(!e){
  482. e = {index:0};
  483. }
  484. this.activeName = e.index;
  485. this.childId = this.summary[this.activeName].id;
  486. getDeviceStatus(this.id,this.childId).then(res=>{
  487. let data =res.data;
  488. this.deviceInfo = data;
  489. self.parseStatusData(data)
  490. });
  491. },
  492. parseEnumList(){
  493. let enumList = this.deviceInfo.enumList;
  494. for (let enumListElement of enumList) {
  495. let id = enumListElement.id;
  496. let isCommonKey = this.modelKey.some(res=>{
  497. return id === res;
  498. })
  499. if(isCommonKey){
  500. if(id.indexOf("LockControl") !=-1){
  501. let shadow = enumListElement.shadow;
  502. this.lock.item = enumListElement;
  503. if(shadow == 1){
  504. this.lock.value = true;
  505. this.lock.loading = false;
  506. }else if(shadow == 0){
  507. this.lock.value = false;
  508. this.lock.loading = false;
  509. }else{
  510. this.lock.loading = true;
  511. }
  512. }
  513. if(id.indexOf("PowerControl") !=-1){
  514. let shadow = enumListElement.shadow;
  515. this.power.item = enumListElement;
  516. if(shadow == 1){
  517. this.power.value = true;
  518. this.power.loading = false;
  519. }else if(shadow == 0){
  520. this.power.value = false;
  521. this.power.loading = false;
  522. }else{
  523. this.power.loading = true;
  524. }
  525. }
  526. }
  527. let shadow = enumListElement.shadow
  528. let valueList = enumListElement.enumList;
  529. for (let valueObj of valueList){
  530. if(valueObj.value == shadow){
  531. enumListElement.text = valueObj.text;
  532. }
  533. }
  534. }
  535. },
  536. parseStatusData(data){
  537. let arr = [];
  538. let arrayList = data.arrayList;
  539. arr = arr.concat(arrayList);
  540. let enumList = data.enumList;
  541. arr = arr.concat(enumList);
  542. let integerList = data.integerList;
  543. arr = arr.concat(integerList);
  544. let stringList = data.stringList;
  545. arr = arr.concat(stringList);
  546. this.inputProp = arr;
  547. let readOnlyList = data.readOnlyList;
  548. this.watchProp = readOnlyList;
  549. this.parseEnumList();
  550. },
  551. parseSummay(summary){
  552. let self = this;
  553. if(!summary){
  554. summary = "";
  555. }
  556. if(summary.length>0){
  557. this.summary = JSON.parse(summary);
  558. if(self.summary.length>0){
  559. this.oneToMul = true;
  560. }
  561. for (let i = 0; i < self.summary.length; i++) {
  562. self.summary[i].tabName = self.summary[i].id+"_"+self.summary[i].name
  563. }
  564. let childId = "";
  565. if(this.oneToMul){
  566. let info = self.summary[self.activeName];
  567. childId = info.id;
  568. }
  569. this.childId = childId;
  570. }else{
  571. this.summary = [{tabName:"详情查看"}]
  572. }
  573. },
  574. goDeviceDetail(id){
  575. uni.navigateTo({
  576. url: '/pages/device/detail/detail?id='+id
  577. });
  578. },
  579. async connectMqtt() {
  580. if (this.$mqttTool.client == null) {
  581. await this.$mqttTool.connect(this.vuex_token);
  582. }
  583. this.mqttCallback();
  584. },
  585. /** Mqtt订阅主题 */
  586. mqttSubscribe(device) {
  587. // 订阅当前设备状态和实时监测
  588. let topicStatus = '/' + device.productId + '/' + device.serialNumber + '/status/post';
  589. let topicProperty = '/' + device.productId + '/' + device.serialNumber + '/property/post';
  590. let topicFunction = '/' + device.productId + '/' + device.serialNumber + '/function/post';
  591. let topics = [];
  592. topics.push(topicStatus);
  593. topics.push(topicProperty);
  594. topics.push(topicFunction);
  595. this.$mqttTool.subscribe(topics);
  596. },
  597. /** Mqtt取消订阅主题 */
  598. mqttUnSubscribe(device) {
  599. // 订阅当前设备状态和实时监测
  600. let topicStatus = '/' + device.productId + '/' + device.serialNumber + '/status/post';
  601. let topicProperty = '/' + device.productId + '/' + device.serialNumber + '/property/post';
  602. let topicFunction = '/' + device.productId + '/' + device.serialNumber + '/function/post';
  603. let topics = [];
  604. topics.push(topicStatus);
  605. topics.push(topicProperty);
  606. topics.push(topicFunction);
  607. console.log('取消订阅', topics);
  608. this.$mqttTool.unsubscribe(topics);
  609. },
  610. /* Mqtt回调处理 */
  611. mqttCallback() {
  612. this.$mqttTool.client.on('message', (topic, message, buffer) => {
  613. let topics = topic.split('/');
  614. let productId = topics[1];
  615. let deviceNum = topics[2];
  616. console.log('接收到内容:'+message);
  617. message = JSON.parse(message.toString());
  618. if (topics[3] == 'status') {
  619. console.log('接收到【设备状态-运行】主题:', topic);
  620. console.log('接收到【设备状态-运行】内容:', message);
  621. // 更新列表中设备的状态
  622. if (this.deviceInfo.serialNumber == deviceNum) {
  623. this.deviceInfo.status = message.status;
  624. this.deviceInfo.isShadow = message.isShadow;
  625. this.deviceInfo.rssi = message.rssi;
  626. this.updateDeviceStatus(this.deviceInfo);
  627. }
  628. }
  629. if (topics[3] == 'property' || topics[3] == 'function') {
  630. console.log('接收到【物模型】主题:', topic);
  631. console.log('接收到【物模型】内容:', message);
  632. if(this.oneToMul){
  633. let curTabId = this.summary[this.activeName].id;
  634. let msg = [];
  635. for (let i = 0; i < message.length; i++) {
  636. let curMsg = message[i];
  637. let id = curMsg.id;
  638. let ids = id.split("_");
  639. let value = curMsg.value;
  640. if(ids.length == 2){
  641. if(curTabId == ids[1]){
  642. msg.push({id:ids[0],value:value});
  643. }
  644. }
  645. }
  646. message = msg;
  647. }
  648. // 更新列表中设备的属性
  649. if (this.deviceInfo.serialNumber == deviceNum) {
  650. for (let j = 0; j < message.length; j++) {
  651. let isComplete = false;
  652. // 布尔类型
  653. for (let k = 0; k < this.deviceInfo.boolList.length && !isComplete; k++) {
  654. if (this.deviceInfo.boolList[k].id == message[j].id) {
  655. this.deviceInfo.boolList[k].shadow = message[j].value;
  656. isComplete = true;
  657. break;
  658. }
  659. }
  660. // 枚举类型
  661. for (let k = 0; k < this.deviceInfo.enumList.length && !isComplete; k++) {
  662. if (this.deviceInfo.enumList[k].id == message[j].id) {
  663. this.deviceInfo.enumList[k].shadow = message[j].value;
  664. isComplete = true;
  665. break;
  666. }
  667. }
  668. // 字符串类型
  669. for (let k = 0; k < this.deviceInfo.stringList.length && !isComplete; k++) {
  670. if (this.deviceInfo.stringList[k].id == message[j].id) {
  671. this.deviceInfo.stringList[k].shadow = message[j].value;
  672. isComplete = true;
  673. break;
  674. }
  675. }
  676. // 数组类型
  677. for (let k = 0; k < this.deviceInfo.arrayList.length && !isComplete; k++) {
  678. if (this.deviceInfo.arrayList[k].id == message[j].id) {
  679. this.deviceInfo.arrayList[k].shadow = message[j].value;
  680. isComplete = true;
  681. break;
  682. }
  683. }
  684. // 整数类型
  685. for (let k = 0; k < this.deviceInfo.integerList.length && !isComplete; k++) {
  686. if (this.deviceInfo.integerList[k].id == message[j].id) {
  687. this.deviceInfo.integerList[k].shadow = message[j].value;
  688. isComplete = true;
  689. break;
  690. }
  691. }
  692. // 小数类型
  693. for (let k = 0; k < this.deviceInfo.decimalList.length && !isComplete; k++) {
  694. if (this.deviceInfo.decimalList[k].id == message[j].id) {
  695. this.deviceInfo.decimalList[k].shadow = message[j].value;
  696. isComplete = true;
  697. break;
  698. }
  699. }
  700. // 监测数据
  701. for (let k = 0; k < this.deviceInfo.readOnlyList.length && !isComplete; k++) {
  702. if (this.deviceInfo.readOnlyList[k].id == message[j].id) {
  703. this.deviceInfo.readOnlyList[k].shadow = message[j].value;
  704. // 更新图表
  705. // for (let m = 0; m < this.monitorChart.length; m++) {
  706. // if (message[j].id == this.monitorChart[m].data.id) {
  707. // let data = [{
  708. // value: message[j].value,
  709. // name: this.monitorChart[m].data.name
  710. // }];
  711. // this.monitorChart[m].chart.setOption({
  712. // series: [{
  713. // data: data
  714. // }]
  715. // });
  716. // break;
  717. // }
  718. // }
  719. isComplete = true;
  720. break;
  721. }
  722. }
  723. }
  724. this.parseEnumList();
  725. }
  726. }
  727. });
  728. },
  729. /** 发布物模型 类型(1=属性,2=功能) */
  730. publishThingsModel(device, model) {
  731. // 获取缓存的Json物模型
  732. cacheJsonThingsModel(device.productId).then(response => {
  733. let thingsModel = JSON.parse(response.data);
  734. let type = 0;
  735. for (let i = 0; i < thingsModel.functions.length; i++) {
  736. if (model.id == thingsModel.functions[i].id) {
  737. type = 2;
  738. break;
  739. }
  740. }
  741. if (type == 0) {
  742. for (let i = 0; i < thingsModel.properties.length; i++) {
  743. if (model.id == thingsModel.properties[i].id) {
  744. type = 1;
  745. break;
  746. }
  747. }
  748. }
  749. if (type != 0) {
  750. this.mqttPublish(type, device, model);
  751. }
  752. });
  753. },
  754. notifyError(res){
  755. uni.showToast({
  756. title:res,
  757. icon:"error"
  758. })
  759. },
  760. notifySuccess(res){
  761. uni.showToast({
  762. title:res,
  763. icon:"success"
  764. })
  765. },
  766. /**
  767. * Mqtt发布消息
  768. * @type 类型(1=属性,2=功能,3=OTA升级,4=实时监测)
  769. * @device 设备
  770. * @model 物模型
  771. * */
  772. mqttPublish(type, device, model) {
  773. let topic = "";
  774. let message = ""
  775. let oneToMul = false;
  776. if(this.summary.length>0){
  777. oneToMul = true;
  778. }
  779. let modelId = model.id;
  780. if(oneToMul){
  781. let info = this.summary[this.activeName];
  782. let childId = info.id;
  783. modelId = modelId+"_"+childId;
  784. }
  785. if (type == 1) {
  786. if (device.status == 3) {
  787. // 属性,在线模式
  788. topic = "/" + device.productId + "/" + device.serialNumber + "/property-online/get";
  789. } else if (device.isShadow) {
  790. // 属性,离线模式
  791. topic = "/" + device.productId + "/" + device.serialNumber + "/property-offline/post";
  792. }
  793. message = '[{"id":"' + modelId + '","value":"' + model.shadow + '"}]';
  794. } else if (type == 2) {
  795. if (device.status == 3) {
  796. // 功能,在线模式
  797. topic = "/" + device.productId + "/" + device.serialNumber + "/function-online/get";
  798. } else if (device.isShadow) {
  799. // 功能,离线模式
  800. topic = "/" + device.productId + "/" + device.serialNumber + "/function-offline/post";
  801. }
  802. message = '[{"id":"' + modelId + '","value":"' + model.shadow + '"}]';
  803. } else if (type == 3) {
  804. // OTA升级
  805. topic = "/" + device.productId + "/" + device.serialNumber + "/ota/get";
  806. message = '{"version":' + this.firmware.version + ',"downloadUrl":"' + this.getDownloadUrl(this.firmware.filePath) + '"}';
  807. } else {
  808. return;
  809. }
  810. if (topic != "") {
  811. // 发布
  812. this.$mqttTool.publish(topic, message, model.name).then(res => {
  813. this.notifySuccess(res);
  814. }).catch(res => {
  815. this.notifyError(res);
  816. });
  817. }
  818. },
  819. }
  820. }
  821. </script>
  822. <style>
  823. .header{
  824. width: 100%;
  825. background: white;
  826. padding:0px 20rpx;
  827. position: relative;
  828. }
  829. .content {
  830. display: flex;
  831. flex-direction: column;
  832. align-items: center;
  833. justify-content: center;
  834. }
  835. .logo {
  836. height: 200rpx;
  837. width: 200rpx;
  838. margin-top: 200rpx;
  839. margin-left: auto;
  840. margin-right: auto;
  841. margin-bottom: 50rpx;
  842. }
  843. .text-area {
  844. margin:10px;
  845. padding-bottom: 10px;
  846. justify-content: center;
  847. width: 100%;
  848. }
  849. .grid-text {
  850. font-size: 14px;
  851. color: #909399;
  852. padding: 10rpx 0 20rpx 0rpx;
  853. /* #ifndef APP-PLUS */
  854. box-sizing: border-box;
  855. /* #endif */
  856. }
  857. .title {
  858. font-size: 36rpx;
  859. color: #8f8f94;
  860. }
  861. .item{
  862. height: 80rpx;
  863. line-height: 80rpx;
  864. }
  865. </style>