detail.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  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. <view style="margin:10px">
  299. <textarea auto-height ="true" v-model="errorMsg" placeholder="请输入异常内容" ></textarea>
  300. </view>
  301. </view>
  302. </u-modal>
  303. <u-modal :show="showTimeDlg" title="查看时长" @confirm="closeTime" >
  304. <view class="slot-content">
  305. <view v-if="timeobj!=null && deviceInfo.status == 3">本次运行时长:{{ timeobj.runtime }}</view>
  306. <view v-if="timeobj!=null ">累计时长:{{ timeobj.alltime }}</view>
  307. <view v-if="timeobj!=null ">平均每天运行时长:{{ timeobj.avgtime }}</view>
  308. </view>
  309. </u-modal>
  310. </view>
  311. </view>
  312. </template>
  313. <script>
  314. import { getDetail,getDeviceStatus,cacheJsonThingsModel,reportError ,getDeviceRunTime} from '@/api/device/device.js'
  315. import UButton from "../../uni_modules/uview-ui/components/u-button/u-button";
  316. import UForm from "../../uni_modules/uview-ui/components/u--form/u--form";
  317. import UInput from "../../uni_modules/uview-ui/components/u--input/u--input";
  318. export default {
  319. components: {UInput, UForm, UButton},
  320. data(){
  321. return {
  322. modelKey:['PowerControl','LockControl'],
  323. power:{
  324. loading:true,
  325. value:0,
  326. },
  327. lock:{
  328. loading:true,
  329. value:0,
  330. },
  331. showTimeDlg:false,
  332. showErrDlg:null,
  333. errorMsg:"asdasdasdasd",
  334. show:null,
  335. value:"",
  336. deviceInfo:{},
  337. id:0,
  338. summary:[],
  339. activeName:0,
  340. childId:"",
  341. oneToMul:false,
  342. inputProp:[],
  343. watchProp:[],
  344. columns:[],
  345. location:{},
  346. sysDept:null,
  347. timeobj:null,
  348. }
  349. },
  350. onLoad: function(opt) {
  351. this.id = opt.id;
  352. this.connectMqtt();
  353. this.getDetail();
  354. },
  355. destroyed() {
  356. // 取消订阅主题
  357. this.mqttUnSubscribe(this.deviceInfo);
  358. },
  359. methods:{
  360. changeProp(key){
  361. let item = null;
  362. let obj = null;
  363. if(key === "LockControl"){
  364. item = this.lock;
  365. }else if(key === "PowerControl"){
  366. item = this.power;
  367. }
  368. let value = item.value;
  369. obj = item.item;
  370. if(value){
  371. obj.value = 1;
  372. obj.shadow = 1;
  373. }else{
  374. obj.value = 0;
  375. obj.shadow = 0;
  376. }
  377. this.publishThingsModel(this.deviceInfo,obj);
  378. },
  379. checkCommonProp(item){
  380. let id =item.id;
  381. let isCommonKey = this.modelKey.some(res=>{
  382. return id === res;
  383. })
  384. return !isCommonKey;
  385. },
  386. getRunTime(){
  387. let self = this;
  388. getDeviceRunTime(this.id).then(res=>{
  389. self.timeobj = res.data;
  390. })
  391. },
  392. seeTime(){
  393. this.showTimeDlg = true;
  394. this.getRunTime();
  395. },
  396. closeTime(){
  397. this.showTimeDlg = false;
  398. },
  399. cancel(){
  400. this.showErrDlg = false;
  401. },
  402. reportError(){
  403. this.showErrDlg = true;
  404. },
  405. doReportError(){
  406. if(!this.errorMsg){
  407. this.$modal.showToast('异常信息不能为空')
  408. }else{
  409. let self = this;
  410. let errObj = {};
  411. errObj.deviceId = this.deviceInfo.deviceId;
  412. errObj.deviceName = this.deviceInfo.deviceName
  413. errObj.desc = this.errorMsg;
  414. errObj.deptId= this.deviceInfo.deptId;
  415. reportError(errObj).then(res=>{
  416. self.$modal.showToast(res.msg)
  417. self.cancel();
  418. })
  419. }
  420. },
  421. openLocation(){
  422. uni.openLocation({
  423. latitude: this.location.latitude,
  424. longitude: this.location.longitude,
  425. success: function () {
  426. console.log('success');
  427. }
  428. });
  429. },
  430. confirmItemData(e){
  431. let data = e.value[0];
  432. this.show.text = data.text;
  433. this.show.shadow=data.value;
  434. this.show = null;
  435. console.log(data);
  436. },
  437. send(item){
  438. if(this.deviceInfo.status != 3){
  439. uni.showToast({
  440. title:"设备暂未上线",
  441. icon:"error"
  442. })
  443. return;
  444. }
  445. if(!item.shadow){
  446. uni.showToast({
  447. title:"数据不能为空",
  448. icon:"error"
  449. })
  450. return;
  451. }
  452. this.publishThingsModel(this.deviceInfo,item)
  453. },
  454. /** 更新设备状态 */
  455. updateDeviceStatus(device) {
  456. },
  457. chooseItemData(data){
  458. if(this.deviceInfo.status != 3){
  459. uni.showToast({
  460. title:"设备暂未上线",
  461. icon:"error"
  462. })
  463. return;
  464. }
  465. this.columns = [data.enumList];
  466. this.show =data;
  467. },
  468. getDetail(){
  469. let self = this;
  470. getDetail(this.id).then(res=>{
  471. self.deviceInfo = res.data;
  472. self.location = {
  473. latitude: self.deviceInfo.latitude,
  474. longitude: self.deviceInfo.longitude};
  475. self.sysDept = self.deviceInfo.sysDept;
  476. self.parseSummay(res.data.summary)
  477. self.mqttSubscribe(res.data);
  478. self.getDeviceStatus();
  479. });
  480. },
  481. getDeviceStatus(e){
  482. let self = this;
  483. if(!e){
  484. e = {index:0};
  485. }
  486. this.activeName = e.index;
  487. this.childId = this.summary[this.activeName].id;
  488. getDeviceStatus(this.id,this.childId).then(res=>{
  489. let data =res.data;
  490. this.deviceInfo = data;
  491. self.parseStatusData(data)
  492. });
  493. },
  494. parseEnumList(){
  495. let enumList = this.deviceInfo.enumList;
  496. for (let enumListElement of enumList) {
  497. let id = enumListElement.id;
  498. let isCommonKey = this.modelKey.some(res=>{
  499. return id === res;
  500. })
  501. if(isCommonKey){
  502. if(id.indexOf("LockControl") !=-1){
  503. let shadow = enumListElement.shadow;
  504. this.lock.item = enumListElement;
  505. if(shadow == 1){
  506. this.lock.value = true;
  507. this.lock.loading = false;
  508. }else if(shadow == 0){
  509. this.lock.value = false;
  510. this.lock.loading = false;
  511. }else{
  512. this.lock.loading = true;
  513. }
  514. }
  515. if(id.indexOf("PowerControl") !=-1){
  516. let shadow = enumListElement.shadow;
  517. this.power.item = enumListElement;
  518. if(shadow == 1){
  519. this.power.value = true;
  520. this.power.loading = false;
  521. }else if(shadow == 0){
  522. this.power.value = false;
  523. this.power.loading = false;
  524. }else{
  525. this.power.loading = true;
  526. }
  527. }
  528. }
  529. let shadow = enumListElement.shadow
  530. let valueList = enumListElement.enumList;
  531. for (let valueObj of valueList){
  532. if(valueObj.value == shadow){
  533. enumListElement.text = valueObj.text;
  534. }
  535. }
  536. }
  537. },
  538. parseStatusData(data){
  539. let arr = [];
  540. let arrayList = data.arrayList;
  541. arr = arr.concat(arrayList);
  542. let enumList = data.enumList;
  543. arr = arr.concat(enumList);
  544. let integerList = data.integerList;
  545. arr = arr.concat(integerList);
  546. let stringList = data.stringList;
  547. arr = arr.concat(stringList);
  548. this.inputProp = arr;
  549. let readOnlyList = data.readOnlyList;
  550. this.watchProp = readOnlyList;
  551. this.parseEnumList();
  552. },
  553. parseSummay(summary){
  554. let self = this;
  555. if(!summary){
  556. summary = "";
  557. }
  558. if(summary.length>0){
  559. this.summary = JSON.parse(summary);
  560. if(self.summary.length>0){
  561. this.oneToMul = true;
  562. }
  563. for (let i = 0; i < self.summary.length; i++) {
  564. self.summary[i].tabName = self.summary[i].id+"_"+self.summary[i].name
  565. }
  566. let childId = "";
  567. if(this.oneToMul){
  568. let info = self.summary[self.activeName];
  569. childId = info.id;
  570. }
  571. this.childId = childId;
  572. }else{
  573. this.summary = [{tabName:"详情查看"}]
  574. }
  575. },
  576. goDeviceDetail(id){
  577. uni.navigateTo({
  578. url: '/pages/device/detail/detail?id='+id
  579. });
  580. },
  581. async connectMqtt() {
  582. if (this.$mqttTool.client == null) {
  583. await this.$mqttTool.connect(this.vuex_token);
  584. }
  585. this.mqttCallback();
  586. },
  587. /** Mqtt订阅主题 */
  588. mqttSubscribe(device) {
  589. // 订阅当前设备状态和实时监测
  590. let topicStatus = '/' + device.productId + '/' + device.serialNumber + '/status/post';
  591. let topicProperty = '/' + device.productId + '/' + device.serialNumber + '/property/post';
  592. let topicFunction = '/' + device.productId + '/' + device.serialNumber + '/function/post';
  593. let topics = [];
  594. topics.push(topicStatus);
  595. topics.push(topicProperty);
  596. topics.push(topicFunction);
  597. this.$mqttTool.subscribe(topics);
  598. },
  599. /** Mqtt取消订阅主题 */
  600. mqttUnSubscribe(device) {
  601. // 订阅当前设备状态和实时监测
  602. let topicStatus = '/' + device.productId + '/' + device.serialNumber + '/status/post';
  603. let topicProperty = '/' + device.productId + '/' + device.serialNumber + '/property/post';
  604. let topicFunction = '/' + device.productId + '/' + device.serialNumber + '/function/post';
  605. let topics = [];
  606. topics.push(topicStatus);
  607. topics.push(topicProperty);
  608. topics.push(topicFunction);
  609. console.log('取消订阅', topics);
  610. this.$mqttTool.unsubscribe(topics);
  611. },
  612. /* Mqtt回调处理 */
  613. mqttCallback() {
  614. this.$mqttTool.client.on('message', (topic, message, buffer) => {
  615. let topics = topic.split('/');
  616. let productId = topics[1];
  617. let deviceNum = topics[2];
  618. console.log('接收到内容:'+message);
  619. message = JSON.parse(message.toString());
  620. if (topics[3] == 'status') {
  621. console.log('接收到【设备状态-运行】主题:', topic);
  622. console.log('接收到【设备状态-运行】内容:', message);
  623. // 更新列表中设备的状态
  624. if (this.deviceInfo.serialNumber == deviceNum) {
  625. this.deviceInfo.status = message.status;
  626. this.deviceInfo.isShadow = message.isShadow;
  627. this.deviceInfo.rssi = message.rssi;
  628. this.updateDeviceStatus(this.deviceInfo);
  629. }
  630. }
  631. if (topics[3] == 'property' || topics[3] == 'function') {
  632. console.log('接收到【物模型】主题:', topic);
  633. console.log('接收到【物模型】内容:', message);
  634. if(this.oneToMul){
  635. let curTabId = this.summary[this.activeName].id;
  636. let msg = [];
  637. for (let i = 0; i < message.length; i++) {
  638. let curMsg = message[i];
  639. let id = curMsg.id;
  640. let ids = id.split("_");
  641. let value = curMsg.value;
  642. if(ids.length == 2){
  643. if(curTabId == ids[1]){
  644. msg.push({id:ids[0],value:value});
  645. }
  646. }
  647. }
  648. message = msg;
  649. }
  650. // 更新列表中设备的属性
  651. if (this.deviceInfo.serialNumber == deviceNum) {
  652. for (let j = 0; j < message.length; j++) {
  653. let isComplete = false;
  654. // 布尔类型
  655. for (let k = 0; k < this.deviceInfo.boolList.length && !isComplete; k++) {
  656. if (this.deviceInfo.boolList[k].id == message[j].id) {
  657. this.deviceInfo.boolList[k].shadow = message[j].value;
  658. isComplete = true;
  659. break;
  660. }
  661. }
  662. // 枚举类型
  663. for (let k = 0; k < this.deviceInfo.enumList.length && !isComplete; k++) {
  664. if (this.deviceInfo.enumList[k].id == message[j].id) {
  665. this.deviceInfo.enumList[k].shadow = message[j].value;
  666. isComplete = true;
  667. break;
  668. }
  669. }
  670. // 字符串类型
  671. for (let k = 0; k < this.deviceInfo.stringList.length && !isComplete; k++) {
  672. if (this.deviceInfo.stringList[k].id == message[j].id) {
  673. this.deviceInfo.stringList[k].shadow = message[j].value;
  674. isComplete = true;
  675. break;
  676. }
  677. }
  678. // 数组类型
  679. for (let k = 0; k < this.deviceInfo.arrayList.length && !isComplete; k++) {
  680. if (this.deviceInfo.arrayList[k].id == message[j].id) {
  681. this.deviceInfo.arrayList[k].shadow = message[j].value;
  682. isComplete = true;
  683. break;
  684. }
  685. }
  686. // 整数类型
  687. for (let k = 0; k < this.deviceInfo.integerList.length && !isComplete; k++) {
  688. if (this.deviceInfo.integerList[k].id == message[j].id) {
  689. this.deviceInfo.integerList[k].shadow = message[j].value;
  690. isComplete = true;
  691. break;
  692. }
  693. }
  694. // 小数类型
  695. for (let k = 0; k < this.deviceInfo.decimalList.length && !isComplete; k++) {
  696. if (this.deviceInfo.decimalList[k].id == message[j].id) {
  697. this.deviceInfo.decimalList[k].shadow = message[j].value;
  698. isComplete = true;
  699. break;
  700. }
  701. }
  702. // 监测数据
  703. for (let k = 0; k < this.deviceInfo.readOnlyList.length && !isComplete; k++) {
  704. if (this.deviceInfo.readOnlyList[k].id == message[j].id) {
  705. this.deviceInfo.readOnlyList[k].shadow = message[j].value;
  706. // 更新图表
  707. // for (let m = 0; m < this.monitorChart.length; m++) {
  708. // if (message[j].id == this.monitorChart[m].data.id) {
  709. // let data = [{
  710. // value: message[j].value,
  711. // name: this.monitorChart[m].data.name
  712. // }];
  713. // this.monitorChart[m].chart.setOption({
  714. // series: [{
  715. // data: data
  716. // }]
  717. // });
  718. // break;
  719. // }
  720. // }
  721. isComplete = true;
  722. break;
  723. }
  724. }
  725. }
  726. this.parseEnumList();
  727. }
  728. }
  729. });
  730. },
  731. /** 发布物模型 类型(1=属性,2=功能) */
  732. publishThingsModel(device, model) {
  733. // 获取缓存的Json物模型
  734. cacheJsonThingsModel(device.productId).then(response => {
  735. let thingsModel = JSON.parse(response.data);
  736. let type = 0;
  737. for (let i = 0; i < thingsModel.functions.length; i++) {
  738. if (model.id == thingsModel.functions[i].id) {
  739. type = 2;
  740. break;
  741. }
  742. }
  743. if (type == 0) {
  744. for (let i = 0; i < thingsModel.properties.length; i++) {
  745. if (model.id == thingsModel.properties[i].id) {
  746. type = 1;
  747. break;
  748. }
  749. }
  750. }
  751. if (type != 0) {
  752. this.mqttPublish(type, device, model);
  753. }
  754. });
  755. },
  756. notifyError(res){
  757. uni.showToast({
  758. title:res,
  759. icon:"error"
  760. })
  761. },
  762. notifySuccess(res){
  763. uni.showToast({
  764. title:res,
  765. icon:"success"
  766. })
  767. },
  768. /**
  769. * Mqtt发布消息
  770. * @type 类型(1=属性,2=功能,3=OTA升级,4=实时监测)
  771. * @device 设备
  772. * @model 物模型
  773. * */
  774. mqttPublish(type, device, model) {
  775. let topic = "";
  776. let message = ""
  777. let oneToMul = false;
  778. if(this.summary.length>0){
  779. oneToMul = true;
  780. }
  781. let modelId = model.id;
  782. if(oneToMul){
  783. let info = this.summary[this.activeName];
  784. let childId = info.id;
  785. modelId = modelId+"_"+childId;
  786. }
  787. if (type == 1) {
  788. if (device.status == 3) {
  789. // 属性,在线模式
  790. topic = "/" + device.productId + "/" + device.serialNumber + "/property-online/get";
  791. } else if (device.isShadow) {
  792. // 属性,离线模式
  793. topic = "/" + device.productId + "/" + device.serialNumber + "/property-offline/post";
  794. }
  795. message = '[{"id":"' + modelId + '","value":"' + model.shadow + '"}]';
  796. } else if (type == 2) {
  797. if (device.status == 3) {
  798. // 功能,在线模式
  799. topic = "/" + device.productId + "/" + device.serialNumber + "/function-online/get";
  800. } else if (device.isShadow) {
  801. // 功能,离线模式
  802. topic = "/" + device.productId + "/" + device.serialNumber + "/function-offline/post";
  803. }
  804. message = '[{"id":"' + modelId + '","value":"' + model.shadow + '"}]';
  805. } else if (type == 3) {
  806. // OTA升级
  807. topic = "/" + device.productId + "/" + device.serialNumber + "/ota/get";
  808. message = '{"version":' + this.firmware.version + ',"downloadUrl":"' + this.getDownloadUrl(this.firmware.filePath) + '"}';
  809. } else {
  810. return;
  811. }
  812. if (topic != "") {
  813. // 发布
  814. this.$mqttTool.publish(topic, message, model.name).then(res => {
  815. this.notifySuccess(res);
  816. }).catch(res => {
  817. this.notifyError(res);
  818. });
  819. }
  820. },
  821. }
  822. }
  823. </script>
  824. <style>
  825. .header{
  826. width: 100%;
  827. background: white;
  828. padding:0px 20rpx;
  829. position: relative;
  830. }
  831. .content {
  832. display: flex;
  833. flex-direction: column;
  834. align-items: center;
  835. justify-content: center;
  836. }
  837. .logo {
  838. height: 200rpx;
  839. width: 200rpx;
  840. margin-top: 200rpx;
  841. margin-left: auto;
  842. margin-right: auto;
  843. margin-bottom: 50rpx;
  844. }
  845. .text-area {
  846. margin:10px;
  847. padding-bottom: 10px;
  848. justify-content: center;
  849. width: 100%;
  850. }
  851. .grid-text {
  852. font-size: 14px;
  853. color: #909399;
  854. padding: 10rpx 0 20rpx 0rpx;
  855. /* #ifndef APP-PLUS */
  856. box-sizing: border-box;
  857. /* #endif */
  858. }
  859. .title {
  860. font-size: 36rpx;
  861. color: #8f8f94;
  862. }
  863. .item{
  864. height: 80rpx;
  865. line-height: 80rpx;
  866. }
  867. </style>