From 5e59a6a3b10c0990f494b5a20e1102fd79b0db1b Mon Sep 17 00:00:00 2001
From: doum <doum>
Date: 星期四, 25 十二月 2025 16:43:10 +0800
Subject: [PATCH] 最新版本541200007最新版本541200007

---
 server/system_service/src/main/java/com/doumee/core/utils/Constants.java                                  |   18 
 server/doc/新增断路器设备功能(2025-12-24).sql                                                                      |   27 
 admin/src/components/business/OperaJkSketchLineListWindow.vue                                             |    2 
 server/visits/admin_timer/src/main/resources/bootstrap.yml                                                |    2 
 server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/DeviceDataCloudController.java           |   51 +
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/DeviceDataMapper.java                 |   12 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/DeviceData.java                 |   97 ++
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/DeviceDataService.java            |   98 ++
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/DeviceDataServiceImpl.java   |  161 ++++
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttPushCallback.java   |  141 ++++
 admin/src/assets/style/style.scss                                                                         |   12 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/DeviceServiceImpl.java       |  326 +++++++++
 server/visits/device_service/src/main/java/com/doumee/mqtt/service/MqttToolService.java                   |  109 +++
 server/visits/device_service/src/main/java/com/doumee/mqtt/config/MqttConfig.java                         |   33 
 server/visits/dmvisit_service/pom.xml                                                                     |    5 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttSubServiceImpl.java |   43 +
 server/visits/device_service/src/main/java/com/doumee/Main.java                                           |    7 
 server/visits/device_service/src/main/java/com/doumee/mqtt/config/MqttClientInit.java                     |  136 +++
 admin/src/api/business/deviceData.js                                                                      |    8 
 server/visits/dmvisit_admin/src/main/java/com/doumee/service/impl/DeviceInitServiceImpl.java              |   45 +
 server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/DeviceCloudController.java               |   21 
 server/visits/admin_timer/src/main/java/com/doumee/api/DuanluqiTimerController.java                       |   45 +
 server/system_service/src/main/java/com/doumee/core/utils/CmdContants.java                                |   45 +
 admin/src/components/business/OperaDeviceDataListWindow.vue                                               |  134 +++
 admin/src/views/business/deviceDuanluqi.vue                                                               |  212 ++++++
 server/visits/device_service/pom.xml                                                                      |   32 
 server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java                            |    3 
 server/system_timer/src/main/resources/bootstrap.yml                                                      |    2 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/DeviceService.java                |   10 
 server/pom.xml                                                                                            |    1 
 server/visits/device_service/src/main/java/com/doumee/mqtt/service/MqttBizService.java                    |   28 
 admin/src/components/business/OperaDeviceDuanluqiWindow.vue                                               |  189 +++++
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttClientCache.java    |    9 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Device.java                     |   12 
 admin/src/api/business/device.js                                                                          |    6 
 35 files changed, 2,068 insertions(+), 14 deletions(-)

diff --git a/admin/src/api/business/device.js b/admin/src/api/business/device.js
index 62bd4c3..06e72bf 100644
--- a/admin/src/api/business/device.js
+++ b/admin/src/api/business/device.js
@@ -36,6 +36,12 @@
 export function updateEntranceById (data) {
   return request.post('/visitsAdmin/cloudService/business/device/updateEntranceById', data)
 }
+export function updateUsedById (data) {
+  return request.post('/visitsAdmin/cloudService/business/device/updateUsedById', data)
+}
+export function duanluqiCmd (data) {
+  return request.post('/visitsAdmin/cloudService/business/device/duanluqiCmd', data)
+}
 // 鍙戠敓led灞忓唴瀹�
 export function setLedContent (data) {
   return request.post('/visitsAdmin/cloudService/business/hksync/setLedContent', data)
diff --git a/admin/src/api/business/deviceData.js b/admin/src/api/business/deviceData.js
new file mode 100644
index 0000000..c337434
--- /dev/null
+++ b/admin/src/api/business/deviceData.js
@@ -0,0 +1,8 @@
+import request from '../../utils/request'
+
+// 鏌ヨ
+export function fetchList (data) {
+  return request.post('/visitsAdmin/cloudService/business/deviceData/page', data, {
+    trim: true
+  })
+}
diff --git a/admin/src/assets/style/style.scss b/admin/src/assets/style/style.scss
index a553c72..faa8940 100644
--- a/admin/src/assets/style/style.scss
+++ b/admin/src/assets/style/style.scss
@@ -142,6 +142,18 @@
   }
 }
 
+.tip-header{
+  font-size: 16px;
+  font-weight: bold;
+  margin-bottom: 20px;
+}
+.tip {
+  em {
+    font-style: normal;
+    color: $primary-color;
+    font-weight: bold;
+  }
+}
 .main_app {
   background-color: #fff;
   margin-top: 10px;
diff --git a/admin/src/components/business/OperaDeviceDataListWindow.vue b/admin/src/components/business/OperaDeviceDataListWindow.vue
new file mode 100644
index 0000000..69c4a7d
--- /dev/null
+++ b/admin/src/components/business/OperaDeviceDataListWindow.vue
@@ -0,0 +1,134 @@
+<template>
+  <GlobalWindow
+      :title="title"
+      width="85%"
+      :visible.sync="visible"
+  >
+    <TableLayout >
+      <!-- 鎼滅储琛ㄥ崟 -->
+      <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
+        <div  style="display: block;margin-bottom: 60px;padding: 20px; border: 1px solid #f2f2f2;">
+          <div style="display: block;font-size: 16px;font-weight: 600;margin-bottom: 20px;">璁惧淇℃伅</div>
+          <div style="display: flex;">
+            <div style="flex: 1"><span class="label">鍚嶇О锛�</span>{{model.name ||''}}</div>
+            <div style="flex: 1"><span  class="label">鏍囧織绗︼細</span>{{model.no ||''}}</div>
+            <div style="flex: 1"><span  class="label">璁惧鍙凤細</span>{{model.doorNo ||'-'}}</div>
+            <div style="flex: 1"><span  class="label">寮�鍏冲簭鍙凤細</span>{{model.channelNo ||'-'}}</div>
+            <div style="flex: 1"><span  class="label">鎺у埗寮�鍏筹細</span>{{model.channelInfo ||'-'}}</div>
+          </div>
+          <div style="display: flex;margin-top: 20px;">
+            <div style="flex: 1"><span  class="label">MQTT IP锛�</span>{{model.doorNameObj.mqttIp ||''}}</div>
+            <div style="flex: 1"><span  class="label">MQTT绔彛锛�</span>{{model.doorNameObj.mqttPort||''}}</div>
+            <div style="flex: 3"> <span class="label">鏈�杩戞帶鍒舵搷浣滐細</span>{{model.remark||''}}</div>
+          </div>
+        </div>
+        <el-form-item label="寮�鍏冲簭鍙�" prop="val1">
+          <el-input v-model="searchForm.val1" placeholder="璇疯緭鍏ュ紑鍏冲簭鍙�" @keypress.enter.native="search"></el-input>
+        </el-form-item>
+        <section>
+          <el-button type="primary" @click="search">鎼滅储</el-button>
+          <el-button @click="reset">閲嶇疆</el-button>
+        </section>
+      </el-form>
+      <!-- 琛ㄦ牸鍜屽垎椤� -->
+      <template v-slot:table-wrap>
+        <el-table
+            :height="tableHeightNew"
+            v-loading="isWorking.search"
+            :data="tableData.list"
+            stripe>
+          <el-table-column prop="happenTime" label="涓婃姤鏃堕棿" min-width="150px"></el-table-column>
+          <el-table-column prop="val1" label="寮�鍏冲簭鍙�" min-width="120px"></el-table-column>
+          <el-table-column prop="val7" label="闂哥姸鎬�" min-width="120px">
+            <template slot-scope="{row}">
+              <span v-if=" row.val7 === '1'" class="green">鍚堥椄</span>
+              <span  v-else-if=" row.val7 === '0'" class="red">鍒嗛椄</span>
+              <span v-else>-</span>
+            </template>
+          </el-table-column>
+          <el-table-column prop="val2" label="鐢垫祦(A)" min-width="120px"></el-table-column>
+          <el-table-column prop="val3" label="鐢靛湩(V)" min-width="120px"></el-table-column>
+          <el-table-column prop="val4" label="娓╁害(鈩�)" min-width="180px" ></el-table-column>
+          <el-table-column prop="val5" label="鏈夊姛鍔熺巼鍊硷紙kW锛�" min-width="120px"></el-table-column>
+        </el-table>
+        <pagination
+            @size-change="handleSizeChange"
+            @current-change="handlePageChange"
+            :pagination="tableData.pagination"
+        >
+        </pagination>
+      </template>
+    </TableLayout>
+    <template   v-slot:footer>
+      <el-button @click="visible=false">杩斿洖</el-button>
+    </template>
+  </GlobalWindow>
+</template>
+
+<script>
+import BaseTable from '@/components/base/BaseTable'
+import TableLayout from '@/layouts/TableLayout'
+import Pagination from '@/components/common/Pagination'
+import GlobalWindow from '@/components/common/GlobalWindow'
+export default {
+  name: 'OperaJkSketchCustomerWindow',
+  extends: BaseTable,
+  components: { GlobalWindow, TableLayout, Pagination },
+  data () {
+    return {
+      // 琛ㄥ崟鏁版嵁
+      visible: false,
+      title: '',
+      model:{},
+      searchForm: {
+        deviceId:  null,
+        val1:''
+      }
+    }
+  },
+  created () {
+    this.config({
+      module: '璁惧鏁版嵁淇℃伅琛�',
+      api: '/business/deviceData',
+      'field.id': 'id',
+      'field.main': 'id'
+    })
+    this.search()
+  },
+  methods: {
+    open (title, row) {
+      this.title = title +' 銆�'+ (row.name)+'銆�'
+      this.searchForm.deviceId = row.id
+      if(!row.doorNameObj) {
+        row.doorNameObj = {}
+      }
+      this.model=row
+      this.visible = true
+      this.tableData = {
+        // 宸查�変腑鐨勬暟鎹�
+        selectedRows: [],
+        // 鎺掑簭鐨勫瓧娈�
+        sorts: [],
+        // 褰撳墠椤垫暟鎹�
+        list: [],
+        // 鍒嗛〉
+        pagination: {
+          pageIndex: 1,
+          pageSize: 10,
+          total: 0
+        }
+      }
+      this.search()
+    }
+  }
+}
+</script>
+<style>
+.label{
+/*  width: 80px;
+  text-align: right;*/
+  color: rgb(102, 102, 102);
+  display: inline-block;
+
+}
+</style>
diff --git a/admin/src/components/business/OperaDeviceDuanluqiWindow.vue b/admin/src/components/business/OperaDeviceDuanluqiWindow.vue
new file mode 100644
index 0000000..99021aa
--- /dev/null
+++ b/admin/src/components/business/OperaDeviceDuanluqiWindow.vue
@@ -0,0 +1,189 @@
+<template>
+    <GlobalWindow
+        :title="title"
+        :visible.sync="visible"
+        width="65%"
+        :confirm-working="isWorking"
+        @confirm="confirm"
+    >
+        <el-form :model="form" ref="form" :rules="rules">
+          <p class="tip-header" >鍩烘湰淇℃伅</p>
+          <el-form-item label="璁惧鍚嶇О" prop="name">
+            <el-input v-model="form.name" placeholder="璇疯緭鍏ュ悕绉�" v-trim/>
+          </el-form-item>
+          <el-form-item label="璁惧鏍囪瘑绗�" prop="no">
+            <el-input v-model="form.no" placeholder="璇疯緭鍏ヨ澶囨爣璇嗙" v-trim/>
+          </el-form-item>
+          <el-form-item label="璁惧鍙�" prop="doorNo">
+            <el-input v-model="form.doorNo" placeholder="璇疯緭鍏ュ簭鍒楀彿" v-trim/>
+          </el-form-item>
+          <el-form-item label="鍘傚晢" prop="manufature">
+            <el-input v-model="form.manufature" placeholder="璇疯緭鍏ユ墍鍦ㄤ綅缃�" v-trim/>
+          </el-form-item>
+          <el-form-item label="瀹夎浣嶇疆" prop="regionPathName">
+            <el-input v-model="form.regionPathName" placeholder="璇疯緭鍏ヨ澶囦綅缃�" v-trim/>
+          </el-form-item>
+          <el-form-item label="杩炴帴IP" prop="ip">
+            <el-input v-model="form.ip" placeholder="璇疯緭鍏ヨ澶囪繛鎺P鍦板潃" v-trim/>
+          </el-form-item>
+          <el-form-item label="杩炴帴绔彛" prop="port">
+            <el-input v-model="form.port" placeholder="璇疯緭鍏ヨ繛鎺ョ鍙�" v-trim/>
+          </el-form-item>
+          <p class="tip-header" >閰嶇疆鍙傛暟</p>
+          <p class="tip-warn" style="width: 100%;"><i class="el-icon-warning"></i>閰嶇疆鍙傛暟璇存槑锛�<br>
+            1.鍏ㄩ儴寮�鍏冲簭鍙凤細鍙傝�冭澶囧疄闄呴厤缃紝澶氫釜鐢ㄨ嫳鏂囬�楀彿闅斿紑锛屽 1,2,3;<br>
+            2.鎺у埗寮�鍏冲簭鍙凤細绯荤粺鏍规嵁閰嶇疆瑙勫垯锛屽垽鏂紑鍏冲綋鍓嶇┖闂蹭腑杩涜銆愯嚜鍔ㄥ垎闂搞��,澶氫釜鐢ㄨ嫳鏂囬�楀彿闅斿紑锛屽 1,2;<br>
+            3.鑷姩鍒嗛椄瑙勫垯锛氶拡瀵规帶鍒跺紑鍏冲簭鍙风殑閰嶇疆锛屽畾鏃舵娴嬨�愮┖闂叉椂闀裤�戝唴婊¤冻寮�鍏崇數娴佸�奸兘鍦ㄣ�愮┖闂茬數娴侀槇鍊笺�戣寖鍥村唴锛屽垯杩涜鑷姩鍒嗛椄鎺у埗;<br>
+            4.绌洪棽鏃堕暱: 璇疯缃嚦灏戠┖闂叉椂闀垮ぇ浜庣瓑浜�300绉掞紙5鍒嗛挓锛夈��
+            5.濡傞渶杩滅▼鎺у埗寮�鍏筹紝璇锋纭~鍐欎笅杩板叏閮ㄥ弬鏁颁俊鎭��
+          </p>
+          <div style="display: flex">
+            <el-form-item label="鍏ㄩ儴寮�鍏冲簭鍙�" prop="channelNo" style="display: inline-block;width:300px;">
+              <el-input v-model="form.channelNo" placeholder="璇疯緭鍏ュ紑鍏冲簭鍙凤紝澶氫釜鐢ㄨ嫳鏂囬�楀彿闅斿紑锛屽 1,2,3" v-trim style="width: 150px;"   />
+            </el-form-item>
+            <el-form-item label="鎺у埗寮�鍏冲簭鍙�"    prop="channelInfo" style="display: inline-block;width:300px;">
+              <el-input v-model="form.channelInfo" placeholder="璇疯緭鍏ユ帶鍒跺紑鍏冲簭鍙凤紝澶氫釜鐢ㄨ嫳鏂囬�楀彿闅斿紑锛屽 1,2,3" v-trim style="width: 150px;"   />
+            </el-form-item>
+          </div>
+          <div style="display: flex">
+            <!--    <el-form-item label="绌洪棽鐢垫祦闃堝��" prop="mqttPassword" style="display: inline-block;width:250px;">
+                <el-input v-model="form.doorNameObj.min" style="width: 150px;" disabled type="number"  maxlength="30" placeholder="鏈�灏忓��"  >
+                   <template slot="append">A</template>
+                 </el-input>
+               </el-form-item>
+               <span style="margin: 5px 10px;">鑷�</span>-->
+            <el-form-item label="绌洪棽鐢垫祦闃堝��" label-width="105px" prop="max" style="display: inline-block;width:300px">
+              <el-input v-model="form.doorNameObj.max" style="width: 150px;" type="number"  maxlength="30" placeholder="鏈�澶у��"   >
+                <template slot="append">A</template>
+              </el-input>
+            </el-form-item>
+            <el-form-item label="绌洪棽鏃堕暱(绉�)" prop="level"   style="display: inline-block;width:350px;margin-left: 0px;">
+              <el-input v-model="form.level" style="width: 180px;" type="number"  maxlength="30" placeholder="璇疯緭鍏ョ┖闂叉椂闀�"   >
+                <template slot="append">绉�</template>
+              </el-input>
+            </el-form-item>
+          </div>
+          <el-form-item label="MQTT鏈嶅姟IP" prop="mqttIp">
+            <el-input v-model="form.doorNameObj.mqttIp" placeholder="璇疯緭鍏ヨ澶囪繛鎺QTT-IP" v-trim/>
+          </el-form-item>
+          <el-form-item label="MQTT鏈嶅姟绔彛" prop="mqttPort">
+            <el-input v-model="form.doorNameObj.mqttPort" placeholder="璇疯緭鍏ヨ繛鎺QTT鏈嶅姟绔彛" v-trim/>
+          </el-form-item>
+          <el-form-item label="MQTT鏈嶅姟璐﹀彿" prop="mqttUsername">
+            <el-input v-model="form.doorNameObj.mqttUsername" placeholder="璇疯緭鍏ヨ澶囪繛鎺QTT鏈嶅姟璐﹀彿" v-trim/>
+          </el-form-item>
+          <el-form-item label="MQTT鏈嶅姟瀵嗙爜" prop="mqttPassword">
+            <el-input v-model="form.doorNameObj.mqttPassword" type="password"  maxlength="30" show-password></el-input>
+          </el-form-item>
+          <p class="tip-warn" style="width: 100%;"><i class="el-icon-warning"></i> 闈炲厖鐢电姸鎬佺數娴佸ぇ灏忔帴鍏ヨ澶囧悗锛屽弬鐓х幇鍦哄疄闄呭満鏅厤缃�;</p>
+        </el-form>
+    </GlobalWindow>
+</template>
+<script>
+import BaseOpera from '@/components/base/BaseOpera'
+import GlobalWindow from '@/components/common/GlobalWindow'
+export default {
+  name: 'OperaDeviceDuanluqiWindow',
+  extends: BaseOpera,
+  components: { GlobalWindow },
+  data () {
+    return {
+      // 琛ㄥ崟鏁版嵁
+      form: {
+        id: null,
+        name: '',
+        regionPathName: '',
+        doorNo: '',
+        no: '',
+        type: 5,
+        ip: '',
+        port: '',
+        level: '',
+        doorName: '',
+        doorId: '',
+        doorNameObj: {
+          mqttUsername: '',
+          mqttPassword: '',
+          mqttIp: '',
+          mqttPort: '',
+          max: null,
+          min: null
+        },
+        channelInfo: '',
+        manufature: '',
+        channelNo: ''
+      },
+      // 楠岃瘉瑙勫垯
+      rules: {
+        name: [
+          { required: true, message: '璇疯緭鍏ヨ澶囧悕绉�' }
+        ],
+      /*  max: [
+          { required: true, message: '璇疯緭鍏ヨ澶囩┖闂茬數娴侀槇鍊�' }
+        ],*/
+        doorId: [
+          { required: true, message: '璇疯緭鍏ヨ澶囪繛鎺ヨ处鍙�' }
+        ],
+        doorName: [
+          { required: true, message: '璇疯緭鍏ヨ澶囪繛鎺ュ瘑鐮�' }
+        ],
+        channelNo: [
+          { required: true, message: '璇疯緭鍏ュ紑鍏冲簭鍙�' }
+        ],
+        doorNo: [
+          { required: true, message: '璇疯緭鍏ヨ澶囧彿' }
+        ],
+        no: [
+          { required: true, message: '璇疯緭鍏ヨ澶囨爣璇嗙' }
+        ]
+      }
+    }
+  },
+  created () {
+    this.config({
+      api: '/business/device',
+      'field.id': 'id'
+    })
+  },
+  methods: {
+    open (title, target) {
+      this.title = title
+      this.visible = true
+      this.form.doorName = ''
+      this.form.doorNameObj = {
+        mqttUsername: '',
+        mqttPassword: '',
+        mqttIp: '',
+        mqttPort: '',
+        max: null,
+        min: 0
+      }
+      // debugger
+      // 鏂板缓
+      if (target == null) {
+        this.$nextTick(() => {
+          this.$refs.form.resetFields()
+          this.form[this.configData['field.id']] = null
+        })
+        if(!this.form.doorNameObj){
+          this.form.doorNameObj = {
+            mqttUsername: '',
+            mqttPassword: '',
+            mqttIp: '',
+            mqttPort: '',
+            max: null,
+            min: 0
+          }
+        }
+        return
+      }
+      // 缂栬緫
+      this.$nextTick(async () => {
+        for (const key in this.form) {
+          this.form[key] = target[key]
+        }
+      })
+    }
+  }
+}
+</script>
diff --git a/admin/src/components/business/OperaJkSketchLineListWindow.vue b/admin/src/components/business/OperaJkSketchLineListWindow.vue
index 4d35f22..a1db0a6 100644
--- a/admin/src/components/business/OperaJkSketchLineListWindow.vue
+++ b/admin/src/components/business/OperaJkSketchLineListWindow.vue
@@ -98,7 +98,7 @@
 import OperaJkSketchLineMapWindow from '@/components/business/OperaJkSketchLineMapWindow'
 import { initOriginDistance } from '@/api/business/jkSketch'
 export default {
-  name: 'OperaJkSketchLineWindow',
+  name: 'OperaDeviceDataListWindow',
   extends: BaseOpera,
   components: { GlobalWindow, OperaJkSketchCustomerWindow ,OperaJkSketchLineMapWindow},
   data () {
diff --git a/admin/src/views/business/deviceDuanluqi.vue b/admin/src/views/business/deviceDuanluqi.vue
new file mode 100644
index 0000000..368c0e3
--- /dev/null
+++ b/admin/src/views/business/deviceDuanluqi.vue
@@ -0,0 +1,212 @@
+<template>
+    <TableLayout :permissions="['business:device:query']">
+        <!-- 鎼滅储琛ㄥ崟 -->
+        <el-form ref="searchForm"  slot="search-form" :model="searchForm" label-width="100px" inline>
+            <el-form-item title="鍚嶇О" prop="name">
+                <el-input v-model="searchForm.name" placeholder="璇疯緭鍏ュ悕绉�" @keypress.enter.native="search"></el-input>
+            </el-form-item>
+            <el-form-item title="鏍囪瘑绗�" prop="no">
+                <el-input v-model="searchForm.no" placeholder="璇疯緭鍏ヨ澶囨爣璇嗙" @keypress.enter.native="search"></el-input>
+            </el-form-item>
+            <el-form-item title="璁惧鍙�" prop="doorNo">
+                <el-input v-model="searchForm.doorNo" placeholder="璇疯緭鍏ヨ澶囧彿" @keypress.enter.native="search"></el-input>
+            </el-form-item>
+            <section>
+                <el-button type="primary" @click="search">鎼滅储</el-button>
+                <el-button @click="reset">閲嶇疆</el-button>
+            </section>
+        </el-form>
+        <!-- 琛ㄦ牸鍜屽垎椤� -->
+        <template v-slot:table-wrap>
+          <ul class="toolbar" v-permissions="['business:device:create', 'business:device:delete']">
+            <li><el-button type="primary" @click="$refs.operaDeviceWindow.open('鏂板缓鏂矾鍣�')" icon="el-icon-plus" v-permissions="['business:device:create']">鏂板缓</el-button></li>
+            <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:device:delete']">鍒犻櫎</el-button></li>
+          </ul>
+            <el-table
+                :height="tableHeightNew"
+                v-loading="isWorking.search"
+                :data="tableData.list"
+                stripe
+            >
+              <el-table-column type="selection" width="55"></el-table-column>
+              <el-table-column prop="name" label="鍚嶇О" fixed min-width="150" align="center"></el-table-column>
+              <el-table-column prop="no" label="璁惧鏍囪瘑绗�" min-width="100" align="center" ></el-table-column>
+              <el-table-column prop="doorNo" label="璁惧鍙�"  min-width="120" align="center" show-overflow-tooltip></el-table-column>
+              <el-table-column prop="channelNo" label="寮�鍏冲簭鍙�" align="center" min-width="100"></el-table-column>
+              <el-table-column prop="manufature" label="鍘傚晢" align="center" min-width="100" show-overflow-tooltip></el-table-column>
+              <el-table-column prop="regionPathName" align="center"  min-width="100" label="鎵�鍦ㄤ綅缃�"></el-table-column>
+              <el-table-column prop="ip" label="IP"  min-width="150" align="center" show-overflow-tooltip ></el-table-column>
+              <el-table-column prop="port" label="绔彛" align="center"  ></el-table-column>
+              <el-table-column prop="isUsed" label="鏄惁浣跨敤">
+                <template slot-scope="{row}">
+                  <el-switch @change="changeUsed($event, row)" v-model="row.isUsed" active-color="#13ce66"
+                             inactive-color="#ff4949" :active-value="0" :inactive-value="1">
+                  </el-switch>
+                </template>
+              </el-table-column>
+              <el-table-column prop="editDate" label="鏈�杩戞洿鏂版椂闂�" align="center" min-width="150"></el-table-column>
+              <el-table-column prop="channelParam" label="鎺у埗寮�鍏冲弬鏁�" align="center" min-width="100">
+                <el-table-column prop="channelInfo" label="鎺у埗寮�鍏冲簭鍙�" align="center" min-width="100"></el-table-column>
+                <el-table-column prop="level" label="绌洪棽鏃堕棿(绉�)" align="center" min-width="100"></el-table-column>
+                <el-table-column label="绌洪棽鐢垫祦闃堝��" align="center" min-width="120">
+                  <template slot-scope="{row}">
+                    <span >{{ row.doorNameObj.max || '-'}}A</span>
+                  </template>
+                </el-table-column>
+              </el-table-column>
+              <el-table-column prop="doorNameObj" label="MQTT閰嶇疆鍙傛暟" align="center">
+                <el-table-column prop="doorNameObj.mqttIp" label="IP" min-width="120" align="center"></el-table-column>
+                <el-table-column prop="doorNameObj.mqttPort" label="绔彛" min-width="80" align="center"></el-table-column>
+                <el-table-column prop="doorNameObj.mqttUsername" label="璐﹀彿" align="center"></el-table-column>
+                <el-table-column prop="doorNameObj.mqttPassword" label="瀵嗙爜" align="center">
+                  <template slot-scope="{row}">
+                    <span :class=" 'blue'">{{row.showPwd?row.doorNameObj.mqttPassword:'******'}}</span>
+                    <el-button  style="margin-left: 10px" v-if="row.doorNameObj.mqttPassword!=null"
+                                @click.native.p.prevent="showPassward(row)" type="text">
+                      <i class="el-icon-view" :class="row.showPwd?'red':'blue'" :title="row.showPwd?'闅愯棌':'鏄剧ず'"></i>
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table-column>
+              <el-table-column
+                  label="鎿嶄綔"
+                  align="center"
+                  min-width="280"
+                  fixed="right"
+              >
+                  <template slot-scope="{row}">
+                    <el-button type="text" @click="$refs.operaDeviceWindow.open('缂栬緫鏂矾鍣�', row)" icon="el-icon-edit" v-permissions="['business:device:update']">缂栬緫</el-button>
+                    <el-button type="text" @click="$refs.operaDeviceDataWindow.open('鏌ョ湅鏂矾鍣ㄦ暟鎹�', row)" icon="el-icon-view" v-permissions="['business:device:update']">鏁版嵁</el-button>
+                    <el-button type="text" @click="send(row,1)" icon="el-icon-circle-check"  v-permissions="['business:device:update']">寮�闂�</el-button>
+                    <el-button type="text" class="red" @click="send(row,0)" icon="el-icon-circle-close"  v-permissions="['business:device:update']">鍏抽椄</el-button>
+                    <el-button type="text" class="red" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:device:delete']">鍒犻櫎</el-button>
+                  </template>
+                </el-table-column>
+            </el-table>
+            <pagination
+                @size-change="handleSizeChange"
+                @current-change="handlePageChange"
+                :pagination="tableData.pagination"
+            >
+            </pagination>
+        </template>
+      <el-dialog
+          :visible.sync="visibleSend"
+          style="z-index: 100000"
+          append-to-body
+          width="50%"
+          height="50%"
+          :title="'鎺у埗寮�鍏�-銆�'+ form.name+'銆�'"
+      >
+        <el-form :model="form" ref="form"  :rules="rules">
+          <el-form-item label="鎵ц鎿嶄綔锛�"  >
+            <b class="green" v-if="form.status ===1">寮�闂�</b>
+            <b class="red" v-else>鍏抽椄</b>
+          </el-form-item>
+          <el-form-item label="寮�鍏冲簭鍙�" prop="channelNo">
+            <el-input v-model="form.channelNo" type="text" placeholder="璇疯緭鍏ュ紑鍏冲簭鍙� 锛屽涓敤鑻辨枃閫楀彿闅斿紑锛屽 1,2,3" v-trim/>
+          </el-form-item>
+          <p class="tip-warn" style="width: 100%;"><i class="el-icon-warning"></i>璁惧鍘熷寮�鍏冲簭鍙蜂俊鎭細{{form.channelNo1}}锛屾帶鍒跺涓紑鍏筹紝璇风敤鑻辨枃閫楀彿闅斿紑锛屽 1,2;</p>
+        </el-form>
+        <template  v-slot:footer  >
+          <el-button @click="sendAction()" type="primary" v-if="form.status === 1" :loading="isWorkSending">纭寮�闂�</el-button>
+          <el-button @click="sendAction()" type="danger" v-if="form.status !== 1" :loading="isWorkSending">纭鍏抽椄</el-button>
+          <el-button @click="sendClose()">杩斿洖</el-button>
+        </template>
+      </el-dialog>
+        <!-- 鏂板缓/淇敼 -->
+    <OperaDeviceDuanluqiWindow ref="operaDeviceWindow" @success="handlePageChange"/>
+    <OperaDeviceDataListWindow ref="operaDeviceDataWindow" @success="handlePageChange"/>
+    </TableLayout>
+</template>
+<script>
+import BaseTable from '@/components/base/BaseTable'
+import TableLayout from '@/layouts/TableLayout'
+import Pagination from '@/components/common/Pagination'
+import OperaDeviceDataListWindow from '@/components/business/OperaDeviceDataListWindow'
+import OperaDeviceDuanluqiWindow from '@/components/business/OperaDeviceDuanluqiWindow'
+export default {
+  name: 'DeviceDuanluqi',
+  extends: BaseTable,
+  components: { TableLayout, Pagination, OperaDeviceDuanluqiWindow ,OperaDeviceDataListWindow},
+  data () {
+    return {
+      // 鎼滅储
+      searchForm: {
+        doorName: '',
+        doorNo: '',
+        no: '',
+        regionPathName: '',
+        type: 5
+      },
+      isWorkSending: false,
+      form: {
+        id: '',
+        name: '',
+        channelNo: '',
+        channelNo1: '',
+        status: null
+      },
+      visibleSend: false,
+      options: [],
+      rules: {
+        channelNo: [{ required: true, message: '璇疯緭鍏ラ渶瑕佹搷浣滅殑寮�鍏冲簭鍙�', trigger: 'blur' }],
+      }
+    }
+  },
+  created () {
+    this.config({
+      module: '璁惧淇℃伅琛�',
+      api: '/business/device',
+      'field.id': 'id',
+      'field.main': 'id'
+    })
+    this.search()
+  },
+  methods: {
+    changeUsed (e, row) {
+      this.api.updateUsedById({
+        id: row.id,
+        isUsed: e
+      })
+    },
+    showPassward (row) {
+      if (!row.showPwd) {
+        this.$set(row, 'showPwd', true)
+      } else {
+        this.$set(row, 'showPwd', false)
+      }
+    },
+    sendAction () {
+      if (!this.form.channelNo) {
+        return
+      }
+      this.$dialog.actionConfirm('纭杩涜鏂矾鍣ㄣ��' + (this.form.status === 1 ? '寮�闂�' : '鍏抽椄') + '銆戞搷浣滃悧锛�', '鎿嶄綔纭鎻愰啋')
+        .then(() => {
+          this.isWorkSending = true
+          this.api.duanluqiCmd(this.form)
+            .then(res => {
+              this.$tip.apiSuccess(res || '璇锋眰鎴愬姛')
+              this.sendClose()
+            })
+            .catch(e => {
+            })
+            .finally(() => {
+              this.isWorkSending = false
+            })
+        })
+        .catch(() => {})
+    },
+    send (row, type) {
+      this.visibleSend = true
+      this.form = { id: row.id, name: row.name, channelNo: row.channelNo, status: type ,channelNo1:row.channelNo}
+    },
+    sendClose () {
+      this.visibleSend = false
+      this.isWorkSending = false
+      this.form = { id: '', name: '', channelNo: '', status: '',channelNo1:'' }
+    }
+
+  }
+}
+</script>
diff --git "a/server/doc/\346\226\260\345\242\236\346\226\255\350\267\257\345\231\250\350\256\276\345\244\207\345\212\237\350\203\275\357\274\2102025-12-24\357\274\211.sql" "b/server/doc/\346\226\260\345\242\236\346\226\255\350\267\257\345\231\250\350\256\276\345\244\207\345\212\237\350\203\275\357\274\2102025-12-24\357\274\211.sql"
new file mode 100644
index 0000000..305191d
--- /dev/null
+++ "b/server/doc/\346\226\260\345\242\236\346\226\255\350\267\257\345\231\250\350\256\276\345\244\207\345\212\237\350\203\275\357\274\2102025-12-24\357\274\211.sql"
@@ -0,0 +1,27 @@
+ALTER TABLE `wuhuyancao`.`device`
+MODIFY COLUMN `door_no` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '闂ㄧ鐐圭紪鍙�' AFTER `install_location`;
+
+INSERT INTO `wuhuyancao`.`quartz_job` (`id`, `bean_name`, `params`, `cron_expres`, `state`, `remark`, `create_time`, `module`) VALUES (NULL, 'visitServiceJob', '{}', '0 0/5 * * * ? *', 1, '銆愭柇璺櫒銆戝紑鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒鍒嗛椄', '2023-07-26 13:17:17', 'autoCloseCmd');
+
+
+CREATE TABLE `device_data` (
+  `ID` int NOT NULL AUTO_INCREMENT COMMENT '涓婚敭',
+  `CREATOR` int DEFAULT NULL COMMENT '鍒涘缓浜虹紪鐮�',
+  `CREATE_DATE` datetime DEFAULT NULL COMMENT '鍒涘缓鏃堕棿',
+  `EDITOR` int DEFAULT NULL COMMENT '鏇存柊浜虹紪鐮�',
+  `EDIT_DATE` datetime DEFAULT NULL COMMENT '鏇存柊鏃堕棿',
+  `ISDELETED` int DEFAULT NULL COMMENT '鏄惁鍒犻櫎0鍚� 1鏄�',
+  `REMARK` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '澶囨敞',
+  `DATA_JSON` text COLLATE utf8mb4_unicode_ci COMMENT '鏁版嵁json瀵硅薄',
+  `DEVICE_ID` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '璁惧缂栫爜锛堝叧鑱攄evice)',
+  `HAPPEN_TIME` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '鍙戠敓鏃堕棿',
+  `VAL1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '灞炴�у��1',
+  `VAL2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '灞炴�у��2',
+  `VAL3` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '灞炴�у��3',
+  `VAL4` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '灞炴�у��4',
+  `VAL5` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '灞炴�у��5',
+  `VAL6` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '灞炴�у��6',
+  `DATA_TYPE` int DEFAULT NULL COMMENT '鏁版嵁鏉ユ簮 0mqtt涓婃姤 1鍏朵粬',
+  PRIMARY KEY (`ID`),
+  UNIQUE KEY `eventIdnex` (`DEVICE_ID`,`HAPPEN_TIME`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=106097 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='闂ㄧ浜嬩欢鎺ㄩ�佽褰曡〃';
\ No newline at end of file
diff --git a/server/pom.xml b/server/pom.xml
index 4050b74..60f3dff 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -17,6 +17,7 @@
       <module>system_timer</module>
       <module>system_gateway</module>
       <module>emaysms</module>
+    <module>visits/device_service</module>
   </modules>
   <parent>
     <groupId>org.springframework.boot</groupId>
diff --git a/server/system_service/src/main/java/com/doumee/core/utils/CmdContants.java b/server/system_service/src/main/java/com/doumee/core/utils/CmdContants.java
new file mode 100644
index 0000000..af0541a
--- /dev/null
+++ b/server/system_service/src/main/java/com/doumee/core/utils/CmdContants.java
@@ -0,0 +1,45 @@
+package com.doumee.core.utils;
+
+/**
+ * 璁惧鎸囦护鍙傛暟闆嗗悎
+ */
+public class CmdContants {
+    public interface T30A{
+        String cmdParam ="{" +
+                "  \"method\": 3," +
+                "  \"dstID\" : 43008827854690816," +//璁惧鍙�
+                "  \"msgCode\": 120," +
+                "  \"timeMS\": 0," +
+                "  \"data\":" +
+                "   [{" +
+                "    \"tag\":305," +
+                "    \"cmd\":\"$CMD\", " +//鎸囦护
+                "    \"count\":3," +
+                "    \"busAddr\":[$BUSADDR]" +//妯″潡鍦板潃
+                "   }]" +
+                "}";
+    }
+
+    /**
+     * 璇存槑锛� 锛�1锛夐拡瀵圭┖寮�璁惧鎿嶄綔锛�  涓�娆′粎鑳芥墽琛屼竴鏉″懡浠わ紝鍥犳鏃犻渶鎻愪緵"busAddr"銆�"devID"鍜�"count"瀛楁锛屽鏋滃懡浠や笉闇�瑕佹惡甯﹀弬鏁帮紝"para"瀛楁涔熷悓鏍锋棤闇�鎻愪緵銆�
+     * 锛�2锛夌┖寮�鎵嬪姩鍒嗛椄浼氳繘鍏ュ紓甯搁攣瀹氭ā寮忥紝闇�瀵瑰搴旂嚎璺澶囦笅鍙戝紓甯歌В閿佹寚浠ゅ悗鎴栨墜鍔ㄥ悎闂哥┖寮�鎵嶈兘杩滅▼鎺у埗銆�
+     */
+    public interface T30ACmd{
+        String do_lock =  "do_lock";//閿佸畾
+        String do_unlock =  "do_unlock";//瑙i攣
+        String do_err_clear =  "do_err_clear";//寮傚父瑙i攣
+        String doLeakageCheck =  "do_leakage_check";//鎵嬪姩婕忕數鑷
+        String do_turn_off =  "do_turn_off";//涓�閿垎闂�
+        String do_turn_on =  "do_turn_on";//涓�閿悎闂�
+        String do_reboot =  "do_reboot";//杩滅▼閲嶅惎
+        String do_refresh_bus =  "do_refresh_bus";//鍒锋柊鎬荤嚎
+        String do_set_factory =  "do_set_factory";//鎭㈠鍑哄巶璁剧疆
+        String do_auto_address =  "do_auto_address";//鑷姩鍒嗛厤鍦板潃
+        String do_mod_passwd =  "do_mod_passwd";//淇敼璁惧瀵嗙爜
+        String do_updrade =  "do_updrade";//鍦ㄧ嚎鍗囩骇鎸囦护
+    }
+
+
+
+
+}
diff --git a/server/system_service/src/main/java/com/doumee/core/utils/Constants.java b/server/system_service/src/main/java/com/doumee/core/utils/Constants.java
index 406fbac..a8a4e93 100644
--- a/server/system_service/src/main/java/com/doumee/core/utils/Constants.java
+++ b/server/system_service/src/main/java/com/doumee/core/utils/Constants.java
@@ -218,6 +218,7 @@
     public static  boolean DEALING_HK_NOTICE_LIST = false;
     public static  boolean DEALING_FROM_HK_VISIT = false;
     public static  boolean DEALING_HK_EMPOWER = false;
+    public static  boolean DEALING_DUANLUQI_CLOSE = false;
     public static  boolean DEALING_HK_EMPOWER_DETAIL = false;
     public static  boolean DEALING_HK_EMPOWER_RESULT = false;
     public static  boolean DEALING_HK_PARKBOOK = false;
@@ -288,6 +289,15 @@
         public static final  int depart = 3;
         public static final  int custom = 4;
         public static final  int self = -1;
+    }
+    //绫诲瀷 0闂ㄧ 1杞﹀簱 2LED 3骞挎挱鐐� 4骞挎挱璁惧 5鏂矾鍣ㄧ┖寮�
+    public interface DEVICE_TYPE{
+        public static final  int door = 0;
+        public static final  int park = 1;
+        public static final  int led = 2;
+        public static final  int broadcaset = 3;
+        public static final  int broadcasetChannel = 4;
+        public static final  int duanluqi = 5;
     }
 
     /**
@@ -1529,6 +1539,14 @@
         return JSONObject.toJSONString(map);
     }
 
+    public  interface MqttTopic{
+        String mts_attr = "/dev/+/+/attr/json";//灞炴�opic
+        String mts_status = "/dev/+/+/status/json";//鐘舵�乼opic
+        String mts_event= "/dev/+/+/event/json";//浜嬩欢topic
+        String mts_echo= "/dev/+/+/echo/json";//娑堟伅鍥炲topic
+        String mts_cmd= "/dev/$CATE/$DEVID/cmd/json";//鍛戒护topic
+        String mts_resp= "/dev/+/+/resp/json";//鍛戒护鍝嶅簲topic
+    }
 
 
     public  enum WarningConfig {
diff --git a/server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java b/server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java
index fd72b31..6d7dee5 100644
--- a/server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java
+++ b/server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java
@@ -118,4 +118,7 @@
     @ApiOperation("銆愰挜鍖欐煖銆戝畾鏃跺彂閫侀挜鍖欐湭鍙婃椂褰掕繕閫氱煡")
     @PostMapping("/timer/jkCabinet/timeOutUnBackAlarm")
     ApiResponse timeOutUnBackAlarm();
+    @ApiOperation("銆愭柇璺櫒銆戝紑鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒鍒嗛椄")
+    @PostMapping("/timer/duanluqi/autoCloseCmd")
+    ApiResponse autoCloseCmd();
 }
diff --git a/server/system_timer/src/main/resources/bootstrap.yml b/server/system_timer/src/main/resources/bootstrap.yml
index 5eb6d62..107b53b 100644
--- a/server/system_timer/src/main/resources/bootstrap.yml
+++ b/server/system_timer/src/main/resources/bootstrap.yml
@@ -1,6 +1,6 @@
 spring:
   profiles:
-    active: test
+    active: dev
   application:
     name: systemTimer
     # 瀹夊叏閰嶇疆
diff --git a/server/visits/admin_timer/src/main/java/com/doumee/api/DuanluqiTimerController.java b/server/visits/admin_timer/src/main/java/com/doumee/api/DuanluqiTimerController.java
new file mode 100644
index 0000000..1a577d8
--- /dev/null
+++ b/server/visits/admin_timer/src/main/java/com/doumee/api/DuanluqiTimerController.java
@@ -0,0 +1,45 @@
+package com.doumee.api;
+
+import com.alibaba.fastjson.JSONObject;
+import com.doumee.biz.system.SystemDictDataBiz;
+import com.doumee.core.utils.Constants;
+import com.doumee.core.utils.HttpsUtil;
+import com.doumee.core.wx.WXConstant;
+import com.doumee.dao.system.model.SystemDictData;
+import com.doumee.service.business.DeviceService;
+import com.doumee.service.business.third.model.ApiResponse;
+import com.doumee.service.system.SystemDictDataService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/30 15:33
+ */
+@Api(tags = "鏂矾鍣ㄨ繙绋嬫帶鍒跺畾鏃跺櫒")
+@RestController
+@RequestMapping("/timer/duanluqi")
+public class DuanluqiTimerController extends BaseController {
+    @Autowired
+    private DeviceService deviceService;
+
+    @ApiOperation("寮�鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒鍒嗛椄")
+    @PostMapping("/autoCloseCmd")
+    public ApiResponse autoCloseCmd() {
+        deviceService.autoCloseCmdTimer();
+        return ApiResponse.success("寮�鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒鍒嗛椄鎴愬姛");
+    }
+
+
+
+}
diff --git a/server/visits/admin_timer/src/main/resources/bootstrap.yml b/server/visits/admin_timer/src/main/resources/bootstrap.yml
index b5b65b7..efae338 100644
--- a/server/visits/admin_timer/src/main/resources/bootstrap.yml
+++ b/server/visits/admin_timer/src/main/resources/bootstrap.yml
@@ -1,6 +1,6 @@
 spring:
   profiles:
-    active: pro
+    active: dev
   application:
     name: visitsTimer
     # 瀹夊叏閰嶇疆
diff --git a/server/visits/device_service/pom.xml b/server/visits/device_service/pom.xml
new file mode 100644
index 0000000..248de40
--- /dev/null
+++ b/server/visits/device_service/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.doumee</groupId>
+        <artifactId>dmvisit</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>device_service</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.eclipse.paho</groupId>
+            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
+            <version>1.2.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/server/visits/device_service/src/main/java/com/doumee/Main.java b/server/visits/device_service/src/main/java/com/doumee/Main.java
new file mode 100644
index 0000000..ada0d0d
--- /dev/null
+++ b/server/visits/device_service/src/main/java/com/doumee/Main.java
@@ -0,0 +1,7 @@
+package com.doumee;
+
+public class Main {
+    public static void main(String[] args) {
+        System.out.println("Hello world!");
+    }
+}
\ No newline at end of file
diff --git a/server/visits/device_service/src/main/java/com/doumee/mqtt/config/MqttClientInit.java b/server/visits/device_service/src/main/java/com/doumee/mqtt/config/MqttClientInit.java
new file mode 100644
index 0000000..745ed38
--- /dev/null
+++ b/server/visits/device_service/src/main/java/com/doumee/mqtt/config/MqttClientInit.java
@@ -0,0 +1,136 @@
+package com.doumee.mqtt.config;
+
+import org.eclipse.paho.client.mqttv3.*;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
+
+public class MqttClientInit {
+        static MqttClient client;
+        static MqttClient subClient;
+        public static synchronized MqttClient getPublishInstance(MqttConfig config ){
+            if(client !=null){
+                if(!client.isConnected()){
+                    try {
+                        client.reconnect();
+                    } catch (MqttException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+                return  client;
+            }
+            try {
+                // host涓轰富鏈哄悕锛宑lientid鍗宠繛鎺QTT鐨勫鎴风ID锛屼竴鑸互鍞竴鏍囪瘑绗﹁〃绀猴紝MemoryPersistence璁剧疆clientid鐨勪繚瀛樺舰寮忥紝榛樿涓轰互鍐呭瓨淇濆瓨
+                String clientId =config.getClientid() +config.getVersion();
+                client = new org.eclipse.paho.client.mqttv3.MqttClient(config.getHost(), clientId,new MemoryPersistence());
+                // MQTT鐨勮繛鎺ヨ缃�
+                MqttConnectOptions   options = new MqttConnectOptions();
+                // 璁剧疆鏄惁娓呯┖session,杩欓噷濡傛灉璁剧疆涓篺alse琛ㄧず鏈嶅姟鍣ㄤ細淇濈暀瀹㈡埛绔殑杩炴帴璁板綍锛岃缃负true琛ㄧず姣忔杩炴帴鍒版湇鍔″櫒閮戒互鏂扮殑韬唤杩炴帴
+                options.setCleanSession(false);
+                // 璁剧疆杩炴帴鐨勭敤鎴峰悕
+                options.setUserName(config.getUsername());
+                // 璁剧疆杩炴帴鐨勫瘑鐮�
+                options.setPassword(config.getPassword().toCharArray());
+                // 璁剧疆瓒呮椂鏃堕棿 鍗曚綅涓虹
+                options.setConnectionTimeout(10);
+                // 璁剧疆浼氳瘽蹇冭烦鏃堕棿 鍗曚綅涓虹 鏈嶅姟鍣ㄤ細姣忛殧1.5*20绉掔殑鏃堕棿鍚戝鎴风鍙戦�佷釜娑堟伅鍒ゆ柇瀹㈡埛绔槸鍚﹀湪绾匡紝浣嗚繖涓柟娉曞苟娌℃湁閲嶈繛鐨勬満鍒�
+                options.setKeepAliveInterval(20);
+                //璁剧疆鏂紑鍚庨噸鏂拌繛鎺�
+                options.setAutomaticReconnect(true);
+                MqttTopic topic = client.getTopic(clientId+"_close");
+                //閬楀槺
+                options.setWill(topic, "close".getBytes(), 1, true);
+                client.connect(options);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return  client;
+        }
+        public static synchronized MqttClient getSubInstance(MqttConfig config, MqttCallback callBack){
+            if(subClient !=null){
+                refreshClient();
+                return  subClient;
+            }
+            try {
+                // host涓轰富鏈哄悕锛宑lientid鍗宠繛鎺QTT鐨勫鎴风ID锛屼竴鑸互鍞竴鏍囪瘑绗﹁〃绀猴紝MemoryPersistence璁剧疆clientid鐨勪繚瀛樺舰寮忥紝榛樿涓轰互鍐呭瓨淇濆瓨
+                String clientId =config.getSubclientid() +config.getVersion();
+                subClient = new org.eclipse.paho.client.mqttv3.MqttClient(config.getHost(), clientId,new MemoryPersistence());
+                // MQTT鐨勮繛鎺ヨ缃�
+                MqttConnectOptions   options = new MqttConnectOptions();
+                // 璁剧疆鏄惁娓呯┖session,杩欓噷濡傛灉璁剧疆涓篺alse琛ㄧず鏈嶅姟鍣ㄤ細淇濈暀瀹㈡埛绔殑杩炴帴璁板綍锛岃缃负true琛ㄧず姣忔杩炴帴鍒版湇鍔″櫒閮戒互鏂扮殑韬唤杩炴帴
+                options.setCleanSession(false);
+                // 璁剧疆杩炴帴鐨勭敤鎴峰悕
+                options.setUserName(config.getUsername());
+                // 璁剧疆杩炴帴鐨勫瘑鐮�
+                options.setPassword(config.getPassword().toCharArray());
+                // 璁剧疆瓒呮椂鏃堕棿 鍗曚綅涓虹
+                options.setConnectionTimeout(10);
+                // 璁剧疆浼氳瘽蹇冭烦鏃堕棿 鍗曚綅涓虹 鏈嶅姟鍣ㄤ細姣忛殧1.5*20绉掔殑鏃堕棿鍚戝鎴风鍙戦�佷釜娑堟伅鍒ゆ柇瀹㈡埛绔槸鍚﹀湪绾匡紝浣嗚繖涓柟娉曞苟娌℃湁閲嶈繛鐨勬満鍒�
+                options.setKeepAliveInterval(20);
+                // 璁剧疆鍥炶皟
+                subClient.setCallback(callBack);
+                //璁剧疆鏂紑鍚庨噸鏂拌繛鎺�
+                options.setAutomaticReconnect(true);
+                MqttTopic topic = subClient.getTopic(clientId+"_close");
+                //閬楀槺
+                options.setWill(topic, "close".getBytes(), 1, true);
+                subClient.connect(options);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return  subClient;
+        }
+    public static synchronized MqttClient getInstance(MqttClient clientModel,MqttConfig config, MqttCallback callBack){
+        if(clientModel !=null){
+            refreshClient(clientModel);
+            return  clientModel;
+        }
+        try {
+            // host涓轰富鏈哄悕锛宑lientid鍗宠繛鎺QTT鐨勫鎴风ID锛屼竴鑸互鍞竴鏍囪瘑绗﹁〃绀猴紝MemoryPersistence璁剧疆clientid鐨勪繚瀛樺舰寮忥紝榛樿涓轰互鍐呭瓨淇濆瓨
+            String clientId =config.getClientid() +config.getVersion();
+            clientModel = new org.eclipse.paho.client.mqttv3.MqttClient(config.getHost(), clientId,new MemoryPersistence());
+            // MQTT鐨勮繛鎺ヨ缃�
+            MqttConnectOptions   options = new MqttConnectOptions();
+            // 璁剧疆鏄惁娓呯┖session,杩欓噷濡傛灉璁剧疆涓篺alse琛ㄧず鏈嶅姟鍣ㄤ細淇濈暀瀹㈡埛绔殑杩炴帴璁板綍锛岃缃负true琛ㄧず姣忔杩炴帴鍒版湇鍔″櫒閮戒互鏂扮殑韬唤杩炴帴
+            options.setCleanSession(false);
+            // 璁剧疆杩炴帴鐨勭敤鎴峰悕
+            options.setUserName(config.getUsername());
+            // 璁剧疆杩炴帴鐨勫瘑鐮�
+            options.setPassword(config.getPassword().toCharArray());
+            // 璁剧疆瓒呮椂鏃堕棿 鍗曚綅涓虹
+            options.setConnectionTimeout(10);
+            // 璁剧疆浼氳瘽蹇冭烦鏃堕棿 鍗曚綅涓虹 鏈嶅姟鍣ㄤ細姣忛殧1.5*20绉掔殑鏃堕棿鍚戝鎴风鍙戦�佷釜娑堟伅鍒ゆ柇瀹㈡埛绔槸鍚﹀湪绾匡紝浣嗚繖涓柟娉曞苟娌℃湁閲嶈繛鐨勬満鍒�
+            options.setKeepAliveInterval(20);
+            // 璁剧疆鍥炶皟
+            clientModel.setCallback(callBack);
+            //璁剧疆鏂紑鍚庨噸鏂拌繛鎺�
+            options.setAutomaticReconnect(true);
+            MqttTopic topic = clientModel.getTopic(clientId+"_close");
+            //閬楀槺
+            options.setWill(topic, "close".getBytes(), 1, true);
+            clientModel.connect(options);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return  clientModel;
+    }
+
+
+        public static synchronized void refreshClient(  ) {
+            try {
+                if(subClient !=null &&  !subClient.isConnected()){
+                    subClient.reconnect();
+                }
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+        }
+        public static synchronized void refreshClient(MqttClient clientModel  ) {
+            try {
+                if(clientModel !=null  &&  !clientModel.isConnected()){
+                    clientModel.reconnect();
+                }
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+        }
+
+}
diff --git a/server/visits/device_service/src/main/java/com/doumee/mqtt/config/MqttConfig.java b/server/visits/device_service/src/main/java/com/doumee/mqtt/config/MqttConfig.java
new file mode 100644
index 0000000..a4bf616
--- /dev/null
+++ b/server/visits/device_service/src/main/java/com/doumee/mqtt/config/MqttConfig.java
@@ -0,0 +1,33 @@
+package com.doumee.mqtt.config;
+
+import lombok.Data;
+
+@Data
+public class MqttConfig {
+        /**
+         *鏈嶅姟鍣ㄥ湴鍧� ip+绔彛锛屽tcp://175.27.187.84:1883
+         */
+        private String host;
+        /**
+         * 瀹㈡埛绔紪鐮�
+         */
+        private String clientid;
+        /**
+         * 瀹㈡埛绔紪鐮佺敤鎴疯闃�
+         */
+        private String subclientid;
+        /**
+         * 鎺堟潈璐﹀彿
+         */
+        private String username ;
+        /**
+         * 鎺堟潈瀵嗙爜
+         */
+        private String password;
+        /**
+         * 瀹㈡埛绔増鏈悗缂�
+         */
+        private String version;
+
+
+}
diff --git a/server/visits/device_service/src/main/java/com/doumee/mqtt/service/MqttBizService.java b/server/visits/device_service/src/main/java/com/doumee/mqtt/service/MqttBizService.java
new file mode 100644
index 0000000..eaba23d
--- /dev/null
+++ b/server/visits/device_service/src/main/java/com/doumee/mqtt/service/MqttBizService.java
@@ -0,0 +1,28 @@
+package com.doumee.mqtt.service;
+
+import com.doumee.mqtt.config.MqttConfig;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+
+/**
+ * 涓庣‖浠跺鎺ユ湇鍔�
+ * @author 姹熻箘韫�
+ * @date 2023/10/09 18:06
+ */
+public interface MqttBizService {
+
+    /**
+     * 鎸夐厤缃闃�
+     * @param config
+     * @param topics
+     */
+    MqttClient subscribe(MqttClient client,MqttConfig config, String[] topics);
+    MqttClient unsubscribe(MqttClient client,MqttConfig config, String[] topics);
+    /**
+     * 鎸夐厤缃彂甯冩秷鎭�
+     * @param config
+     * @param topic
+     */
+    MqttClient publish(MqttClient client,MqttConfig config,String topic,String param);
+
+}
diff --git a/server/visits/device_service/src/main/java/com/doumee/mqtt/service/MqttToolService.java b/server/visits/device_service/src/main/java/com/doumee/mqtt/service/MqttToolService.java
new file mode 100644
index 0000000..47b01e6
--- /dev/null
+++ b/server/visits/device_service/src/main/java/com/doumee/mqtt/service/MqttToolService.java
@@ -0,0 +1,109 @@
+package com.doumee.mqtt.service;
+
+import com.doumee.mqtt.config.MqttClientInit;
+import com.doumee.mqtt.config.MqttConfig;
+import lombok.Data;
+import org.eclipse.paho.client.mqttv3.MqttCallback;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+
+@Data
+public class MqttToolService {
+    /**
+     * 璁㈤槄娑堟伅锛屽惎鍔ㄥ姞杞戒竴娆�
+     * @param topics
+     */
+    public static MqttClient subscribe(MqttClient clientTemp,MqttConfig config,String[]  topics, MqttCallback callBack) {
+        try {
+            //璁㈤槄娑堟伅
+            int[] Qos = new int[topics.length];//0锛氭渶澶氫竴娆� 銆�1锛氭渶灏戜竴娆� 銆�2锛氬彧鏈変竴娆�
+            for (int i = 0; i < Qos.length; i++) {
+                Qos[i] = 1;
+                /*if(i ==2){
+                    Qos[i] = 2;
+                }else{
+                    Qos[i] = 1;
+                }*/
+            }
+            clientTemp =  MqttClientInit.getInstance(clientTemp,config,callBack);
+            try {
+                clientTemp.subscribe(topics, Qos);
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+            return clientTemp;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return clientTemp;
+    }
+    public static MqttClient unsubscribe(MqttClient clientTemp,MqttConfig config,String[]  topics, MqttCallback callBack) {
+        try {
+            //璁㈤槄娑堟伅
+            int[] Qos = new int[topics.length];//0锛氭渶澶氫竴娆� 銆�1锛氭渶灏戜竴娆� 銆�2锛氬彧鏈変竴娆�
+            for (int i = 0; i < Qos.length; i++) {
+                Qos[i] = 1;
+                /*if(i ==2){
+                    Qos[i] = 2;
+                }else{
+                    Qos[i] = 1;
+                }*/
+            }
+            clientTemp =  MqttClientInit.getInstance(clientTemp,config,callBack);
+            try {
+                clientTemp.unsubscribe(topics);
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+            return clientTemp;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return clientTemp;
+    }
+    /**
+     * 娑堟伅鍙戦��
+     * @param message
+     * @param topic
+     */
+    public static MqttClient pubMessage(MqttClient clientTemp,MqttConfig config,String message,String topic, MqttCallback callBack){
+        try {
+            MqttMessage mess = new MqttMessage();
+            mess.setQos(1);
+            mess.setRetained(false);
+            mess.setPayload(message.getBytes());
+            clientTemp =  MqttClientInit.getInstance(clientTemp,config,callBack);
+            try {
+                clientTemp.publish(topic, mess);
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+            return  clientTemp;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return clientTemp;
+    }
+    public static void main(String[] args) {
+        MqttConfig config = (new MqttConfig());
+        config.setHost("tcp://192.168.0.7:1883");
+        config.setClientid("doumee1");
+        config.setPassword("doumee@168");
+        config.setUsername("doumee");
+        config.setVersion("003");
+        MqttToolService.pubMessage(null,config,"{" +
+                "  \"method\": 3," +
+                "  \"dstID\" :43008827854690816," +
+                "  \"msgCode\": 120," +
+                "  \"timeMS\": 0," +
+                "  \"data\":" +
+                "   [{" +
+                "    \"tag\":305," +
+                "    \"cmd\":\"do_turn_off\", " +
+                "    \"count\":3," +
+                "    \"busAddr\":[3]" +
+                "   }]" +
+                "}","/dev/MTS/98CC4D121E5A/cmd/json",null);
+    }
+
+}
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/DeviceCloudController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/DeviceCloudController.java
index 3467c1c..eb3991d 100644
--- a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/DeviceCloudController.java
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/DeviceCloudController.java
@@ -55,9 +55,30 @@
         d.setId(param.getId());
         d.setEditDate(new Date());
         d.setIsEntrance(Constants.formatIntegerNum(param.getIsEntrance()));
+        d.setLoginUserInfo(this.getLoginUser(token));
         deviceService.updateById(d);
         return ApiResponse.success(null);
     }
+    @ApiOperation("淇敼鏄惁绯荤粺浣跨敤")
+    @PostMapping("/updateUsedById")
+    @CloudRequiredPermission("business:company:update")
+    public ApiResponse updateUsedById(@RequestBody Device param,@RequestHeader(Constants.HEADER_USER_TOKEN) String token){
+        Device d = new Device();
+        d.setId(param.getId());
+        d.setEditDate(new Date());
+        d.setLoginUserInfo(this.getLoginUser(token));
+        d.setIsUsed(Constants.formatIntegerNum(param.getIsUsed()));
+        deviceService.updateUsedById(d);
+        return ApiResponse.success(null);
+    }
+    @ApiOperation("鎵ц鏂矾鍣ㄥ紑鍏抽椄鎿嶄綔")
+    @PostMapping("/duanluqiCmd")
+    @CloudRequiredPermission("business:company:update")
+    public ApiResponse duanluqiCmd(@RequestBody Device param,@RequestHeader(Constants.HEADER_USER_TOKEN) String token){
+        param.setLoginUserInfo(this.getLoginUser(token));
+        deviceService.duanluqiCmd(param);
+        return ApiResponse.success(null);
+    }
 
     @ApiOperation("鎵归噺鍒犻櫎")
     @GetMapping("/delete/batch")
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/DeviceDataCloudController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/DeviceDataCloudController.java
new file mode 100644
index 0000000..b872f1c
--- /dev/null
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/DeviceDataCloudController.java
@@ -0,0 +1,51 @@
+package com.doumee.cloud.admin;
+
+import com.doumee.api.BaseController;
+import com.doumee.config.annotation.CloudRequiredPermission;
+import com.doumee.core.annotation.excel.ExcelExporter;
+import com.doumee.core.annotation.pr.PreventRepeat;
+import com.doumee.core.utils.Constants;
+import com.doumee.dao.business.model.Device;
+import com.doumee.dao.business.model.DeviceData;
+import com.doumee.service.business.DeviceDataService;
+import com.doumee.service.business.DeviceService;
+import com.doumee.service.business.third.model.ApiResponse;
+import com.doumee.service.business.third.model.PageData;
+import com.doumee.service.business.third.model.PageWrap;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/30 15:33
+ */
+@Api(tags = "璁惧鏁版嵁淇℃伅琛�")
+@RestController
+@RequestMapping(Constants.CLOUD_SERVICE_URL_INDEX+"/business/deviceData")
+public class DeviceDataCloudController extends BaseController {
+
+    @Autowired
+    private DeviceDataService deviceDataService;
+
+
+    @ApiOperation("鍒嗛〉鏌ヨ")
+    @PostMapping("/page")
+    @CloudRequiredPermission("business:device:query")
+    public ApiResponse<PageData<DeviceData>> findPage (@RequestBody PageWrap<DeviceData> pageWrap,@RequestHeader(Constants.HEADER_USER_TOKEN) String token){
+        return ApiResponse.success(deviceDataService.findPage(pageWrap));
+    }
+
+    @ApiOperation("瀵煎嚭Excel")
+    @PostMapping("/exportExcel")
+    @CloudRequiredPermission("business:device:exportExcel")
+    public void exportExcel (@RequestBody PageWrap<DeviceData> pageWrap, HttpServletResponse response, @RequestHeader(Constants.HEADER_USER_TOKEN) String token){
+        ExcelExporter.build(DeviceData.class).export(deviceDataService.findPage(pageWrap).getRecords(), "璁惧淇℃伅琛�", response);
+    }
+}
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/service/impl/DeviceInitServiceImpl.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/service/impl/DeviceInitServiceImpl.java
new file mode 100644
index 0000000..af14d5e
--- /dev/null
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/service/impl/DeviceInitServiceImpl.java
@@ -0,0 +1,45 @@
+package com.doumee.service.impl;
+
+import com.doumee.biz.system.SystemDictDataBiz;
+import com.doumee.core.haikang.model.HKConstants;
+import com.doumee.core.haikang.model.HKTools;
+import com.doumee.core.haikang.model.param.BaseResponse;
+import com.doumee.core.haikang.model.param.request.EventSubRequest;
+import com.doumee.core.haikang.model.param.respose.OrgInfoResponse;
+import com.doumee.core.haikang.service.HKService;
+import com.doumee.core.utils.Constants;
+import com.doumee.dao.business.WarningMapper;
+import com.doumee.dao.system.model.SystemDictData;
+import com.doumee.service.business.DeviceService;
+import com.doumee.service.business.InterfaceLogService;
+import com.doumee.service.business.impl.hksync.HkSyncBaseServiceImpl;
+import com.hikvision.artemis.sdk.config.ArtemisConfig;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.Date;
+
+/**
+ * 娴峰悍浜嬩欢璁㈤槄琛⊿ervice瀹炵幇
+ * @author 姹熻箘韫�
+ * @date 2023/11/30 15:33
+ */
+@Service
+public class DeviceInitServiceImpl extends HkSyncBaseServiceImpl {
+
+    @Autowired
+    private DeviceService deviceService;
+    @Autowired
+    private InterfaceLogService interfaceLogService;
+    @Autowired
+    private WarningMapper warningMapper;
+
+    @PostConstruct
+    public  int  startDuanluqiMqttJob(){
+        //鑾峰彇鏍圭粍缁囩紪鐮�
+        deviceService.startCheckDuanluqiSubjob();
+        return  0;
+    }
+}
diff --git a/server/visits/dmvisit_service/pom.xml b/server/visits/dmvisit_service/pom.xml
index 0d421a2..f2ae256 100644
--- a/server/visits/dmvisit_service/pom.xml
+++ b/server/visits/dmvisit_service/pom.xml
@@ -23,6 +23,11 @@
             <version>1.0.0-SNAPSHOT</version>
         </dependency>
         <dependency>
+            <groupId>com.doumee</groupId>
+            <artifactId>device_service</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
             <groupId>com.google.ortools</groupId>
             <artifactId>ortools-java</artifactId>
             <version>9.14.6206</version>
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/DeviceDataMapper.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/DeviceDataMapper.java
new file mode 100644
index 0000000..4818344
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/DeviceDataMapper.java
@@ -0,0 +1,12 @@
+package com.doumee.dao.business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.doumee.dao.business.model.DeviceData;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2025/12/25 10:04
+ */
+public interface DeviceDataMapper extends BaseMapper<DeviceData> {
+
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Device.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Device.java
index b95469d..b7d2440 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Device.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Device.java
@@ -1,5 +1,6 @@
 package com.doumee.dao.business.model;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.doumee.core.annotation.excel.ExcelColumn;
 import com.doumee.service.business.third.model.LoginUserModel;
@@ -10,6 +11,7 @@
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 
+import java.math.BigDecimal;
 import java.util.Date;
 
 /**
@@ -71,8 +73,8 @@
     @ExcelColumn(name="鎺掑簭鐮�")
     private Integer sortnum;
 
-    @ApiModelProperty(value = "绫诲瀷 0闂ㄧ 1杞﹀簱 2LED 3骞挎挱鐐� 4骞挎挱璁惧", example = "1")
-    @ExcelColumn(name="绫诲瀷 0闂ㄧ 1杞﹀簱 2LED 3骞挎挱鐐� 4骞挎挱璁惧")
+    @ApiModelProperty(value = "绫诲瀷 0闂ㄧ 1杞﹀簱 2LED 3骞挎挱鐐� 4骞挎挱璁惧 5鏂矾鍣ㄧ┖寮�", example = "1")
+    @ExcelColumn(name="绫诲瀷 0闂ㄧ 1杞﹀簱 2LED 3骞挎挱鐐� 4骞挎挱璁惧 5鏂矾鍣ㄧ┖寮�")
     private Integer type;
     @ApiModelProperty(value = "鏄惁鍥尯鍑哄叆鍙� 0涓嶆槸 1鏄�", example = "1")
     @ExcelColumn(name="鏄惁鍥尯鍑哄叆鍙� 0涓嶆槸 1鏄�")
@@ -154,12 +156,12 @@
     @ApiModelProperty(value = "闂ㄧ鐐瑰悕绉�")
     @ExcelColumn(name="闂ㄧ鐐瑰悕绉�")
     private String doorName;
-
-
     @ApiModelProperty(value = "鎾姤鍐呭")
     @TableField(exist = false)
     private String sendInfo;
-
+    @ApiModelProperty(value = "閰嶇疆鍙傛暟")
+    @TableField(exist = false)
+    private JSONObject doorNameObj;
 
 
 
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/DeviceData.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/DeviceData.java
new file mode 100644
index 0000000..bf917f3
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/DeviceData.java
@@ -0,0 +1,97 @@
+package com.doumee.dao.business.model;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+
+/**
+ * 闂ㄧ浜嬩欢鎺ㄩ�佽褰曡〃
+ * @author 姹熻箘韫�
+ * @date 2025/12/25 10:04
+ */
+@Data
+@ApiModel("闂ㄧ浜嬩欢鎺ㄩ�佽褰曡〃")
+@TableName("`device_data`")
+public class DeviceData {
+
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "涓婚敭", example = "1")
+    @ExcelColumn(name="涓婚敭")
+    private Integer id;
+
+    @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
+    @ExcelColumn(name="鍒涘缓浜虹紪鐮�")
+    private Integer creator;
+
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @ExcelColumn(name="鍒涘缓鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date createDate;
+
+    @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
+    @ExcelColumn(name="鏇存柊浜虹紪鐮�")
+    private Integer editor;
+
+    @ApiModelProperty(value = "鏇存柊鏃堕棿")
+    @ExcelColumn(name="鏇存柊鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date editDate;
+
+    @ApiModelProperty(value = "鏄惁鍒犻櫎0鍚� 1鏄�", example = "1")
+    @ExcelColumn(name="鏄惁鍒犻櫎0鍚� 1鏄�")
+    private Integer isdeleted;
+
+    @ApiModelProperty(value = "澶囨敞")
+    @ExcelColumn(name="澶囨敞")
+    private String remark;
+
+    @ApiModelProperty(value = "鏁版嵁json瀵硅薄", example = "1")
+    @ExcelColumn(name="鏁版嵁json瀵硅薄")
+    private String dataJson;
+
+    @ApiModelProperty(value = "璁惧缂栫爜锛堝叧鑱攄evice)")
+    @ExcelColumn(name="璁惧缂栫爜锛堝叧鑱攄evice)")
+    private String deviceId;
+
+    @ApiModelProperty(value = "鍙戠敓鏃堕棿")
+    @ExcelColumn(name="鍙戠敓鏃堕棿")
+    private String happenTime;
+
+    @ApiModelProperty(value = "灞炴�у��1")
+    @ExcelColumn(name="灞炴�у��1")
+    private String val1;
+
+    @ApiModelProperty(value = "灞炴�у��2")
+    @ExcelColumn(name="灞炴�у��2")
+    private String val2;
+
+    @ApiModelProperty(value = "灞炴�у��3")
+    @ExcelColumn(name="灞炴�у��3")
+    private String val3;
+
+    @ApiModelProperty(value = "灞炴�у��4")
+    @ExcelColumn(name="灞炴�у��4")
+    private String val4;
+
+    @ApiModelProperty(value = "灞炴�у��5")
+    @ExcelColumn(name="灞炴�у��5")
+    private String val5;
+
+    @ApiModelProperty(value = "灞炴�у��6")
+    @ExcelColumn(name="灞炴�у��6")
+    private String val6;
+    @ApiModelProperty(value = "灞炴�у��7")
+    @ExcelColumn(name="灞炴�у��7")
+    private String val7;
+
+    @ApiModelProperty(value = "鏁版嵁鏉ユ簮 0mqtt涓婃姤 1鍏朵粬", example = "1")
+    @ExcelColumn(name="鏁版嵁鏉ユ簮 0mqtt涓婃姤 1鍏朵粬")
+    private Integer dataType;
+
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/DeviceDataService.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/DeviceDataService.java
new file mode 100644
index 0000000..83eb052
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/DeviceDataService.java
@@ -0,0 +1,98 @@
+package com.doumee.service.business;
+
+import com.doumee.dao.business.model.DeviceData;
+import com.doumee.service.business.third.model.PageData;
+import com.doumee.service.business.third.model.PageWrap;
+
+import java.util.List;
+
+/**
+ * 闂ㄧ浜嬩欢鎺ㄩ�佽褰曡〃Service瀹氫箟
+ * @author 姹熻箘韫�
+ * @date 2025/12/25 10:04
+ */
+public interface DeviceDataService {
+
+    /**
+     * 鍒涘缓
+     * 
+     * @param deviceData 瀹炰綋瀵硅薄
+     * @return Integer
+     */
+    Integer create(DeviceData deviceData);
+
+    /**
+     * 涓婚敭鍒犻櫎
+     *
+     * @param id 涓婚敭
+     */
+    void deleteById(Integer id);
+
+    /**
+     * 鍒犻櫎
+     *
+     * @param deviceData 瀹炰綋瀵硅薄
+     */
+    void delete(DeviceData deviceData);
+
+    /**
+     * 鎵归噺涓婚敭鍒犻櫎
+     *
+     * @param ids 涓婚敭闆�
+     */
+    void deleteByIdInBatch(List<Integer> ids);
+
+    /**
+     * 涓婚敭鏇存柊
+     *
+     * @param deviceData 瀹炰綋瀵硅薄
+     */
+    void updateById(DeviceData deviceData);
+
+    /**
+     * 鎵归噺涓婚敭鏇存柊
+     *
+     * @param deviceDatas 瀹炰綋闆�
+     */
+    void updateByIdInBatch(List<DeviceData> deviceDatas);
+
+    /**
+     * 涓婚敭鏌ヨ
+     *
+     * @param id 涓婚敭
+     * @return DeviceData
+     */
+    DeviceData findById(Integer id);
+
+    /**
+     * 鏉′欢鏌ヨ鍗曟潯璁板綍
+     *
+     * @param deviceData 瀹炰綋瀵硅薄
+     * @return DeviceData
+     */
+    DeviceData findOne(DeviceData deviceData);
+
+    /**
+     * 鏉′欢鏌ヨ
+     *
+     * @param deviceData 瀹炰綋瀵硅薄
+     * @return List<DeviceData>
+     */
+    List<DeviceData> findList(DeviceData deviceData);
+  
+    /**
+     * 鍒嗛〉鏌ヨ
+     *
+     * @param pageWrap 鍒嗛〉瀵硅薄
+     * @return PageData<DeviceData>
+     */
+    PageData<DeviceData> findPage(PageWrap<DeviceData> pageWrap);
+
+    /**
+     * 鏉′欢缁熻
+     *
+     * @param deviceData 瀹炰綋瀵硅薄
+     * @return long
+     */
+    long count(DeviceData deviceData);
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/DeviceService.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/DeviceService.java
index ceced8e..3aef46e 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/DeviceService.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/DeviceService.java
@@ -5,6 +5,8 @@
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
 import com.doumee.dao.business.model.Device;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+
 import java.util.List;
 
 /**
@@ -13,6 +15,7 @@
  * @date 2023/11/30 15:33
  */
 public interface DeviceService {
+
 
     /**
      * 鍒涘缓
@@ -109,4 +112,11 @@
 
     void setBroadcaseBobao(Device body);
     String setBroadcaseBobaoHttp(Device body);
+
+    void duanluqiCmd(Device param);
+
+    void updateUsedById(Device d);
+
+    void autoCloseCmdTimer();
+    void startCheckDuanluqiSubjob();
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/DeviceDataServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/DeviceDataServiceImpl.java
new file mode 100644
index 0000000..7f0ef91
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/DeviceDataServiceImpl.java
@@ -0,0 +1,161 @@
+package com.doumee.service.business.impl;
+
+import com.doumee.core.utils.Utils;
+import com.doumee.dao.business.DeviceDataMapper;
+import com.doumee.dao.business.model.DeviceData;
+import com.doumee.service.business.DeviceDataService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.doumee.service.business.third.model.PageData;
+import com.doumee.service.business.third.model.PageWrap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * 闂ㄧ浜嬩欢鎺ㄩ�佽褰曡〃Service瀹炵幇
+ * @author 姹熻箘韫�
+ * @date 2025/12/25 10:04
+ */
+@Service
+public class DeviceDataServiceImpl implements DeviceDataService {
+
+    @Autowired
+    private DeviceDataMapper deviceDataMapper;
+
+    @Override
+    public Integer create(DeviceData deviceData) {
+        deviceDataMapper.insert(deviceData);
+        return deviceData.getId();
+    }
+
+    @Override
+    public void deleteById(Integer id) {
+        deviceDataMapper.deleteById(id);
+    }
+
+    @Override
+    public void delete(DeviceData deviceData) {
+        UpdateWrapper<DeviceData> deleteWrapper = new UpdateWrapper<>(deviceData);
+        deviceDataMapper.delete(deleteWrapper);
+    }
+
+    @Override
+    public void deleteByIdInBatch(List<Integer> ids) {
+        if (CollectionUtils.isEmpty(ids)) {
+            return;
+        }
+        deviceDataMapper.deleteBatchIds(ids);
+    }
+
+    @Override
+    public void updateById(DeviceData deviceData) {
+        deviceDataMapper.updateById(deviceData);
+    }
+
+    @Override
+    public void updateByIdInBatch(List<DeviceData> deviceDatas) {
+        if (CollectionUtils.isEmpty(deviceDatas)) {
+            return;
+        }
+        for (DeviceData deviceData: deviceDatas) {
+            this.updateById(deviceData);
+        }
+    }
+
+    @Override
+    public DeviceData findById(Integer id) {
+        return deviceDataMapper.selectById(id);
+    }
+
+    @Override
+    public DeviceData findOne(DeviceData deviceData) {
+        QueryWrapper<DeviceData> wrapper = new QueryWrapper<>(deviceData);
+        return deviceDataMapper.selectOne(wrapper);
+    }
+
+    @Override
+    public List<DeviceData> findList(DeviceData deviceData) {
+        QueryWrapper<DeviceData> wrapper = new QueryWrapper<>(deviceData);
+        return deviceDataMapper.selectList(wrapper);
+    }
+  
+    @Override
+    public PageData<DeviceData> findPage(PageWrap<DeviceData> pageWrap) {
+        IPage<DeviceData> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
+        QueryWrapper<DeviceData> queryWrapper = new QueryWrapper<>();
+        Utils.MP.blankToNull(pageWrap.getModel());
+        if (pageWrap.getModel().getId() != null) {
+            queryWrapper.lambda().eq(DeviceData::getId, pageWrap.getModel().getId());
+        }
+        if (pageWrap.getModel().getCreator() != null) {
+            queryWrapper.lambda().eq(DeviceData::getCreator, pageWrap.getModel().getCreator());
+        }
+        if (pageWrap.getModel().getCreateDate() != null) {
+            queryWrapper.lambda().ge(DeviceData::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
+            queryWrapper.lambda().le(DeviceData::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
+        }
+        if (pageWrap.getModel().getEditor() != null) {
+            queryWrapper.lambda().eq(DeviceData::getEditor, pageWrap.getModel().getEditor());
+        }
+        if (pageWrap.getModel().getEditDate() != null) {
+            queryWrapper.lambda().ge(DeviceData::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
+            queryWrapper.lambda().le(DeviceData::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
+        }
+        if (pageWrap.getModel().getIsdeleted() != null) {
+            queryWrapper.lambda().eq(DeviceData::getIsdeleted, pageWrap.getModel().getIsdeleted());
+        }
+        if (pageWrap.getModel().getRemark() != null) {
+            queryWrapper.lambda().eq(DeviceData::getRemark, pageWrap.getModel().getRemark());
+        }
+        if (pageWrap.getModel().getDataJson() != null) {
+            queryWrapper.lambda().eq(DeviceData::getDataJson, pageWrap.getModel().getDataJson());
+        }
+        if (pageWrap.getModel().getDeviceId() != null) {
+            queryWrapper.lambda().eq(DeviceData::getDeviceId, pageWrap.getModel().getDeviceId());
+        }
+        if (pageWrap.getModel().getHappenTime() != null) {
+            queryWrapper.lambda().eq(DeviceData::getHappenTime, pageWrap.getModel().getHappenTime());
+        }
+        if (pageWrap.getModel().getVal1() != null) {
+            queryWrapper.lambda().eq(DeviceData::getVal1, pageWrap.getModel().getVal1());
+        }
+        if (pageWrap.getModel().getVal2() != null) {
+            queryWrapper.lambda().eq(DeviceData::getVal2, pageWrap.getModel().getVal2());
+        }
+        if (pageWrap.getModel().getVal3() != null) {
+            queryWrapper.lambda().eq(DeviceData::getVal3, pageWrap.getModel().getVal3());
+        }
+        if (pageWrap.getModel().getVal4() != null) {
+            queryWrapper.lambda().eq(DeviceData::getVal4, pageWrap.getModel().getVal4());
+        }
+        if (pageWrap.getModel().getVal5() != null) {
+            queryWrapper.lambda().eq(DeviceData::getVal5, pageWrap.getModel().getVal5());
+        }
+        if (pageWrap.getModel().getVal6() != null) {
+            queryWrapper.lambda().eq(DeviceData::getVal6, pageWrap.getModel().getVal6());
+        }
+        if (pageWrap.getModel().getDataType() != null) {
+            queryWrapper.lambda().eq(DeviceData::getDataType, pageWrap.getModel().getDataType());
+        }
+        queryWrapper.lambda().orderByDesc(DeviceData::getHappenTime);
+        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
+            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
+                queryWrapper.orderByDesc(sortData.getProperty());
+            } else {
+                queryWrapper.orderByAsc(sortData.getProperty());
+            }
+        }
+        return PageData.from(deviceDataMapper.selectPage(page, queryWrapper));
+    }
+
+    @Override
+    public long count(DeviceData deviceData) {
+        QueryWrapper<DeviceData> wrapper = new QueryWrapper<>(deviceData);
+        return deviceDataMapper.selectCount(wrapper);
+    }
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/DeviceServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/DeviceServiceImpl.java
index d66c345..b72835a 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/DeviceServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/DeviceServiceImpl.java
@@ -11,14 +11,15 @@
 import com.doumee.core.haikang.model.param.request.CustomBroadcastRequest;
 import com.doumee.core.haikang.model.param.request.TransparentChannelSingleRequest;
 import com.doumee.core.haikang.service.HKService;
-import com.doumee.core.utils.HttpsUtil;
+import com.doumee.core.utils.*;
 import com.doumee.dao.business.*;
 import com.doumee.dao.business.model.*;
+import com.doumee.mqtt.config.MqttConfig;
+import com.doumee.mqtt.service.MqttBizService;
+import com.doumee.service.business.impl.mqtt.MqttClientCache;
 import com.doumee.service.business.third.model.LoginUserInfo;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
-import com.doumee.core.utils.Constants;
-import com.doumee.core.utils.Utils;
 import com.doumee.service.business.DeviceService;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -28,11 +29,14 @@
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
 import java.util.*;
+import java.util.Date;
 import java.util.stream.Collectors;
 
 /**
@@ -45,7 +49,11 @@
 public class DeviceServiceImpl implements DeviceService {
 
     @Autowired
+    private MqttBizService mqttBizService;
+    @Autowired
     private DeviceMapper deviceMapper;
+    @Autowired
+    private DeviceDataMapper deviceDataMapper;
     @Autowired
     private PlatformMapper platformMapper;
     @Autowired
@@ -65,6 +73,14 @@
         model.setIsdeleted(Constants.ZERO);
         model.setEditDate(new Date());
         model.setCreateDate(model.getEditDate());
+        if(model.getDoorNameObj()!=null && Constants.equalsInteger(model.getType(),Constants.DEVICE_TYPE.duanluqi)){
+            model.setDoorName(JSONObject.toJSONString(model.getDoorNameObj()));
+            if(StringUtils.isNotBlank(model.getLevel())){
+                if(getNumberByStr(model.getLevel()) <300){
+                    throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"瀵逛笉璧凤紝鎺у埗鏃堕暱蹇呴』澶т簬绛変簬300绉�");
+                }
+            }
+        }
         deviceMapper.insert(model);
         return model.getId();
     }
@@ -99,6 +115,9 @@
     public void updateById(Device device) {
         device.setEdirot(device.getLoginUserInfo().getId()+"");
         device.setEditDate(new Date());
+        if(device.getDoorNameObj()!=null && Constants.equalsInteger(device.getType(),Constants.DEVICE_TYPE.duanluqi)){
+            device.setDoorName(JSONObject.toJSONString(device.getDoorNameObj()));
+        }
         deviceMapper.updateById(device);
     }
 
@@ -114,7 +133,16 @@
 
     @Override
     public Device findById(Integer id) {
-        return deviceMapper.selectById(id);
+        Device d = deviceMapper.selectById(id);
+        if(StringUtils.isNotBlank(d.getDoorName()) &&Constants.equalsInteger(d.getType(),Constants.DEVICE_TYPE.duanluqi)){
+            try {
+                //鏂矾鍣ㄨ澶囧弬鏁�
+                d.setDoorNameObj(JSONObject.parseObject(d.getDoorName()));
+            }catch (Exception e){
+
+            }
+        }
+        return d;
     }
 
     @Override
@@ -138,7 +166,20 @@
                .eq(null !=param.getIsdeleted(),Device::getIsdeleted,param.getIsdeleted())
                .eq(Objects.isNull(param.getIsdeleted()),Device::getIsdeleted,Constants.ZERO)
                .eq(null != param.getHkStatus(),Device::getHkStatus,param.getHkStatus());
-        return deviceMapper.selectList(wrapper);
+        List<Device> list = deviceMapper.selectList(wrapper);
+        if(list!=null){
+            for(Device d : list){
+                if(StringUtils.isNotBlank(d.getDoorName()) &&Constants.equalsInteger(d.getType(),Constants.DEVICE_TYPE.duanluqi)){
+                    try {
+                        //鏂矾鍣ㄨ澶囧弬鏁�
+                        d.setDoorNameObj(JSONObject.parseObject(d.getDoorName()));
+                    }catch (Exception e){
+
+                    }
+                }
+            }
+        }
+        return list;
     }
   
     @Override
@@ -247,7 +288,20 @@
                 queryWrapper.orderByAsc(sortData.getProperty());
             }
         }
-        return PageData.from(deviceMapper.selectPage(page, queryWrapper));
+        IPage<Device> result = deviceMapper.selectPage(page, queryWrapper);
+        if(result!=null){
+            for(Device d : result.getRecords()){
+                if(StringUtils.isNotBlank(d.getDoorName()) &&Constants.equalsInteger(d.getType(),Constants.DEVICE_TYPE.duanluqi)){
+                    try {
+                        //鏂矾鍣ㄨ澶囧弬鏁�
+                        d.setDoorNameObj(JSONObject.parseObject(d.getDoorName()));
+                    }catch (Exception e){
+
+                    }
+                }
+            }
+        }
+        return PageData.from(result);
     }
 
     @Override
@@ -271,6 +325,125 @@
         if(response == null || !StringUtils.equals(response.getCode(), HKConstants.RESPONSE_SUCCEE)){
           throw  new BusinessException(ResponseStatus.SERVER_ERROR.getCode(),"鍙戦�佸け璐ワ細"+ JSONObject.toJSONString(response));
         }
+    }
+
+    @Override
+    public   void updateUsedById(Device param){
+        Device model = deviceMapper.selectById(param.getId());
+        if(model ==null && Constants.equalsInteger(param.getType(),Constants.DEVICE_TYPE.duanluqi)){
+            throw  new BusinessException(ResponseStatus.DATA_EMPTY);
+        }
+
+        MqttConfig config = getMqttConfigByParam(model,"device_");
+        MqttClient mqttClient = MqttClientCache.clientMapCache.get("device"+param.getId());
+        String[] topics =new String[]{Constants.MqttTopic.mts_status,
+                Constants.MqttTopic.mts_attr,
+                Constants.MqttTopic.mts_resp};
+        if(Constants.equalsInteger(param.getIsUsed(),Constants.ONE)){
+            //濡傛灉绯荤粺涓嶇敤浜嗭紝绔彛mqtt杩炴帴
+            try {
+                mqttClient = mqttBizService.unsubscribe(mqttClient,config  ,topics);
+                if(mqttClient ==null){
+                    throw new BusinessException(ResponseStatus.SERVER_ERROR.getCode(),"寤虹珛杩炴帴澶辫触锛�");
+                }
+                if(mqttClient.isConnected()){
+                    mqttClient.disconnect();
+                }
+            }catch (Exception e){
+                log.error("==============绔彛mqtt閾炬帴澶辫触锛�"+model.getName()+e.getMessage());
+            }
+        }else{
+            //濡傛灉寮�濮嬩娇鐢紝寮�濮嬭闃�
+            mqttClient = mqttBizService.subscribe(mqttClient,config ,topics);
+            if(mqttClient ==null){
+                throw new BusinessException(ResponseStatus.SERVER_ERROR.getCode(),"寤虹珛杩炴帴澶辫触锛�");
+            }
+            MqttClientCache.clientMapCache.put("device"+param.getId(),mqttClient);
+        }
+
+        this.updateById(param);
+    }
+    @Override
+    public  void duanluqiCmd(Device param){
+        Device model = deviceMapper.selectById(param.getId());
+        if(model ==null && Constants.equalsInteger(param.getType(),Constants.DEVICE_TYPE.duanluqi)){
+            throw  new BusinessException(ResponseStatus.DATA_EMPTY);
+        }
+        dealDuanluqiCmd(model,param,"device_");
+
+    }
+
+    private void dealDuanluqiCmd(Device model, Device param,String clientIndex) {
+        MqttConfig config = getMqttConfigByParam(model,clientIndex);
+        MqttClient mqttClient = MqttClientCache.clientMapCache.get("device"+param.getId());
+        String cmdTopic = Constants.MqttTopic.mts_cmd.replace("$CATE",model.getNo()).replace("$DEVID",model.getDoorNo());
+        if(Constants.equalsInteger(param.getStatus(),Constants.ONE)){
+            //濡傛灉鏄紑闂革紝鍏堣В閿�
+            String cmdParamAction = CmdContants.T30A.cmdParam.replace("$DEVID", model.getDoorNo())
+                    .replace("$CMD",  CmdContants.T30ACmd.do_err_clear)//寮傚父瑙i攣
+                    .replace("$BUSADDR",model.getChannelNo());
+            mqttClient = mqttBizService.publish(mqttClient,config,cmdTopic, cmdParamAction);//瑙i攣鍛戒护
+            if(mqttClient ==null){
+                throw new BusinessException(ResponseStatus.SERVER_ERROR.getCode(),"鎸囦护鍙戦�佸け璐ワ紒");
+            }
+        }
+        String cmdParamAction =CmdContants.T30A.cmdParam.replace("$DEVID", model.getDoorNo())
+                .replace("$CMD",(Constants.equalsInteger(param.getStatus(),Constants.ONE)?CmdContants.T30ACmd.do_turn_on:CmdContants.T30ACmd.do_turn_off))
+                .replace("$BUSADDR", param.getChannelNo());
+        mqttClient = mqttBizService.publish(mqttClient,config,cmdTopic, cmdParamAction);//寮�鍏抽椄鍛戒护
+        if(mqttClient ==null){
+            throw new BusinessException(ResponseStatus.SERVER_ERROR.getCode(),"鎸囦护鍙戦�佸け璐ワ紒");
+        }
+        MqttClientCache.clientMapCache.put("device"+param.getId(),mqttClient);
+        String curremak = "銆�"+param.getLoginUserInfo().getRealname()
+                +"銆戜簬"+ DateUtil.getPlusTime2(new Date()) +"杩涜浜�"+(Constants.equalsInteger(param.getStatus(),Constants.ONE)?"銆愬紑闂搞��":"銆愬叧闂搞��")+"鎿嶄綔,寮�鍏炽��"+param.getChannelNo()+"銆戯紱";
+        deviceMapper.update(null,new UpdateWrapper<Device>().lambda()
+//                        .setSql("remark = concat(ifnull(remark,''),'"+curremak+"','\n')")
+                .set(Device::getRemark,curremak)
+                .set(Device::getEditDate,new Date())
+                .set(Device::getEdirot,param.getLoginUserInfo().getId())
+                .eq(Device::getId,param.getId()));
+    }
+
+    private MqttConfig getMqttConfigByParam(Device model,String index) {
+        MqttConfig config = new MqttConfig();
+        JSONObject mqtt = new JSONObject();
+        if(StringUtils.isBlank(model.getNo())
+                ||StringUtils.isBlank(model.getDoorNo()) ){
+            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"瀵逛笉璧凤紝璁惧鏍囪瘑绗﹀拰璁惧鍙锋湭閰嶇疆锛�");
+        }
+        if(StringUtils.isNotBlank(model.getDoorName())){
+            try {
+                //鏂矾鍣ㄨ澶囧弬鏁�
+                mqtt = (JSONObject.parseObject(model.getDoorName()));
+            }catch (Exception e){
+            }
+        }
+        if(mqtt == null
+                ||StringUtils.isBlank(mqtt.getString("mqttUsername"))
+                ||StringUtils.isBlank(mqtt.getString("mqttIp"))
+                ||StringUtils.isBlank(mqtt.getString("mqttPort"))
+                ||StringUtils.isBlank(mqtt.getString("mqttPassword"))){
+            throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"瀵逛笉璧凤紝璁惧mqtt鏈嶅姟鍙傛暟閰嶇疆涓嶆纭紒");
+        }
+        /**
+         *   MqttConfig config = (new MqttConfig());
+         *         config.setHost("tcp://192.168.0.7:1883");
+         *         config.setClientid("doumee1");
+         *         config.setPassword("doumee@168");
+         *         config.setUsername("doumee");
+         *         config.setVersion("003");
+         */
+        config.setVersion("003");
+        config.setUsername( mqtt.getString("mqttUsername"));
+        config.setPassword( mqtt.getString("mqttPassword"));
+        config.setHost("tcp://"+ mqtt.getString("mqttIp")+":"+mqtt.getString("mqttPort"));
+        config.setClientid(index+model.getId());
+        return config;
+    }
+    public  void mqttCallbackService(String topic, MqttMessage message){
+       log.error("mqtt鏀跺埌娑堟伅=====topic锛�",topic);
+       log.error("mqtt鏀跺埌娑堟伅=====message锛�",JSONObject.toJSONString(message));
     }
     @Override
     public String setBroadcaseBobaoHttp(Device param){
@@ -382,4 +555,145 @@
         }
         log.error( "灞忓箷鍐呭璁剧疆=======================缁撴潫========" );
     }
+
+
+    /**
+     * 鏈嶅姟寮�鍚闃呬换鍔�
+     */
+    @Override
+    public   void startCheckDuanluqiSubjob() {
+        List<Device> devices = deviceMapper.selectList(new QueryWrapper<Device>().lambda()
+                .eq(Device::getType,Constants.DEVICE_TYPE.duanluqi)//鏂矾鍣�
+                .eq(Device::getIsUsed,Constants.ZERO)
+                .eq(Device::getIsdeleted,Constants.ZERO)
+        );
+        if(devices!=null && devices.size()>0){
+            for (Device model : devices){
+                try {
+                    MqttConfig config = getMqttConfigByParam(model,"device_");
+                    MqttClient mqttClient = MqttClientCache.clientMapCache.get("device"+model.getId());
+                    String[] topics =new String[]{Constants.MqttTopic.mts_status,
+                            Constants.MqttTopic.mts_attr,
+                            Constants.MqttTopic.mts_resp};
+                        //濡傛灉寮�濮嬩娇鐢紝寮�濮嬭闃�
+                    mqttClient = mqttBizService.subscribe(mqttClient,config ,topics);
+                    if(mqttClient ==null){
+                        throw new BusinessException(ResponseStatus.SERVER_ERROR.getCode(),"寤虹珛杩炴帴澶辫触锛�");
+                    }
+                    MqttClientCache.clientMapCache.put("device"+model.getId(),mqttClient);
+                    log.error("=======寮�濮嬭嚜鍔ㄥ畾浜巑qtt浠诲姟瀹屾垚锛�"+model.getName() );
+                }catch (Exception e){
+                    log.error("=======寮�濮嬭嚜鍔ㄥ畾浜巑qtt浠诲姟澶辫触锛�"+model.getName()+e.getMessage());
+                }
+            }
+
+        }
+    }
+    /**
+     * 鏂矾鍣ㄥ垽鏂槸鍚﹂渶瑕佽繙绋嬪垎闂稿畾浜轰换鍔�
+     */
+    @Override
+    public   void autoCloseCmdTimer(){
+        if(Constants.DEALING_DUANLUQI_CLOSE){
+            return;
+        }
+        log.error("寮�鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒寮�濮�=========");
+        Constants.DEALING_DUANLUQI_CLOSE = true;
+        try {
+            List<Device> devices = deviceMapper.selectList(new QueryWrapper<Device>().lambda()
+                    .eq(Device::getType,Constants.DEVICE_TYPE.duanluqi)//鏂矾鍣�
+                    .isNotNull(Device::getLevel)//閰嶇疆浜嗙┖闂叉椂闀块檺鍒�
+                    .isNotNull(Device::getDoorName)//閰嶇疆浜哅QTT鍙傛暟
+                    .isNotNull(Device::getChannelInfo)//閰嶇疆浜嗘帶鍒跺紑鍏冲簭鍙�
+                    .eq(Device::getIsUsed,Constants.ZERO)
+                    .eq(Device::getIsdeleted,Constants.ZERO)
+            );
+            if(devices!=null && devices.size()>0){
+                for(Device device : devices){
+                    try {
+                        long time = (long)getNumberByStr(device.getLevel());//鎺у埗鏃堕暱
+                        if(time < 300 ){
+                            log.error("寮�鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒鍒嗛椄澶辫触=========绌洪棽鏃堕暱鏈纭厤缃�"+time);
+                            continue;
+                        }
+                        double closeDianliu = getCloseDianliuByParam(device);
+                        if(closeDianliu < 0 ){
+                            log.error("寮�鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒鍒嗛椄澶辫触=========绌洪棽鐢垫祦闃堝�艰缃敊璇�"+closeDianliu);
+                            continue;
+                        }
+                        List<String> closeBtn = new ArrayList<>();
+                        String[] btns = device.getChannelInfo().split(",");
+                        Date startDate = new Date((System.currentTimeMillis()-time*1000));//鏌ヨ寮�濮嬫椂闂�
+                        List<DeviceData> dataList = deviceDataMapper.selectList(new QueryWrapper<DeviceData>().lambda()
+                                .eq(DeviceData::getDeviceId,device.getId())
+                                .in(DeviceData::getVal1,btns)
+                                .ge(DeviceData::getHappenTime,DateUtil.getPlusTime2(startDate))
+                                .orderByDesc(DeviceData::getHappenTime));
+                        if(dataList != null && dataList.size()>0 ){
+                           for(String b : btns){
+                               DeviceData last = getLastDataByVal1(b,dataList,closeDianliu);
+                               if(last !=null && StringUtils.equals(last.getVal7(),"1")){
+                                   closeBtn.add(b);//闇�瑕佸垎闂�
+                               }
+                           }
+                           if(StringUtils.equals( dataList.get(0).getVal7(),"0")){
+                               log.error("寮�鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒鍒嗛椄缁撴潫======鍒嗛椄鐘舵�佹棤闇�鎿嶄綔==="+device.getName());
+                               continue;
+                           }
+                        }
+                        if(closeBtn.size()>0){
+                            Device param = new Device();
+                            param.setLoginUserInfo(new LoginUserInfo());
+                            param.getLoginUserInfo().setRealname("绯荤粺鑷姩鎺у埗");
+                            param.setChannelNo(String.join(",",closeBtn));
+                            param.setId(device.getId());
+                            param.setStatus(Constants.ZERO);
+                            dealDuanluqiCmd(device,param,"deviceTimer_");
+                        }
+                    }catch (Exception e){
+                        log.error("寮�鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒鍒嗛椄澶辫触========="+device.getName()+e.getMessage());
+                    }
+                }
+            }
+            log.error("寮�鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒鍒嗛椄鏁伴噺========="+devices.size());
+        }catch (Exception e){
+            log.error("寮�鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒鍒嗛椄寮傚父========="+e.getMessage());
+        }finally {
+            Constants.DEALING_DUANLUQI_CLOSE = false;
+        }
+        log.error("寮�鍚畾鏃惰繙绋嬫帶鍒舵柇璺櫒鍒嗛椄缁撴潫=========");
+    }
+
+    private double getCloseDianliuByParam(Device device) {
+        try {
+            JSONObject json = JSONObject.parseObject(device.getDoorName() );
+            return json.getDouble("max");
+        }catch (Exception e){
+
+        }
+        return 0;
+    }
+
+    private DeviceData getLastDataByVal1(String b, List<DeviceData> dataList,double limit) {
+        List<DeviceData> list = new ArrayList<>();
+        for(DeviceData d :dataList){
+            if(StringUtils.equals(d.getVal1(),b)){
+                if(limit <= getNumberByStr(d.getVal2())){
+                    //濡傛灉鏈夊疄鏃剁數娴佸�煎ぇ浜庣┖闂查槇鍊硷紝鍒欒〃绀哄伐浣滀腑锛屼笉鍋氬鐞�
+                    return null;
+                }
+                list.add(d);
+            }
+        }
+        return list.size()>0?list.get(0):null;
+    }
+
+    private double getNumberByStr(String level) {
+        try {
+            return Double.parseDouble(level);
+        }catch (Exception e){
+
+        }
+        return 0;
+    }
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttClientCache.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttClientCache.java
new file mode 100644
index 0000000..26afe2f
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttClientCache.java
@@ -0,0 +1,9 @@
+package com.doumee.service.business.impl.mqtt;
+
+import org.eclipse.paho.client.mqttv3.MqttClient;
+
+import java.util.LinkedHashMap;
+
+public class MqttClientCache {
+    public static  LinkedHashMap<String, MqttClient> clientMapCache = new LinkedHashMap<>();
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttPushCallback.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttPushCallback.java
new file mode 100644
index 0000000..a4372cf
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttPushCallback.java
@@ -0,0 +1,141 @@
+package com.doumee.service.business.impl.mqtt;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.doumee.core.utils.Constants;
+import com.doumee.core.utils.DateUtil;
+import com.doumee.dao.business.DeviceDataMapper;
+import com.doumee.dao.business.DeviceMapper;
+import com.doumee.dao.business.model.Device;
+import com.doumee.dao.business.model.DeviceData;
+import com.doumee.mqtt.config.MqttClientInit;
+import com.doumee.mqtt.config.MqttConfig;
+import com.doumee.mqtt.service.MqttBizService;
+import com.doumee.service.business.DeviceService;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.util.DataUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.paho.client.mqttv3.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author T14
+ */
+@Service
+@Slf4j
+public class MqttPushCallback implements MqttCallback {
+
+
+        @Autowired
+        private DeviceMapper deviceMapper;
+        @Autowired
+        private DeviceDataMapper deviceDataMapper;
+        @Override
+        public void connectionLost(Throwable cause) {
+            // 杩炴帴涓㈠け鍚庯紝涓�鑸湪杩欓噷闈㈣繘琛岄噸杩�
+           log.error("杩炴帴鏂紑锛岄噸杩炰腑");
+            MqttClientInit.refreshClient();
+        }
+
+        @Override
+        public void deliveryComplete(IMqttDeliveryToken token) {
+           log.error("deliveryComplete---------" + token.isComplete());
+        }
+        @Override
+        public void messageArrived(String topic, MqttMessage message) throws Exception {
+            // subscribe鍚庡緱鍒扮殑娑堟伅浼氭墽琛屽埌杩欓噷闈�
+            try {
+                Date date = new Date();
+               log.error("鎺ユ敹娑堟伅涓婚 : " + DateUtil.getPlusTime2(date) + topic);
+               log.error("鎺ユ敹娑堟伅Qos : " + DateUtil.getPlusTime2(date) +  message.getQos());
+               log.error("鎺ユ敹娑堟伅鍐呭 : " +  DateUtil.getPlusTime2(date) + new String(message.getPayload()));
+                //  ------------TODO-----------鐩戝惉鏁版嵁
+                //-----------------/dev/MTS/98CC4D121E5A/status/json
+                if(StringUtils.contains(topic,"/status/json")){
+                    dealDeviceDataT30A(topic,message);
+                }
+
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+        }
+
+    private void dealDeviceDataT30A(String topic, MqttMessage message) {
+        try {
+            Date date = new Date();
+            //濡傛灉鏄┖寮�涓婃姤鏁版嵁
+            String t[] = topic.replace("/dev/","").replace("/status/json","").split("/");
+            String no =t[0];
+            String doorNo = t[1];
+            Device device = deviceMapper.selectOne(new QueryWrapper<Device>().lambda()
+                    .eq(Device::getNo,no)
+                    .eq(Device::getIsdeleted,no)
+                    .eq(Device::getDoorNo,doorNo));
+            if(device!=null && Constants.equalsInteger(device.getIsUsed(),Constants.ZERO)){
+                //濡傛灉璁惧瀛樺湪骞朵笖璁惧鍦ㄧ敤锛岃褰曚笂鎶ユ暟鎹�
+                List<DeviceData> dataList = new ArrayList<>();
+                JSONObject jsob = JSONObject.parseObject(new String(message.getPayload()));
+                if(jsob.getJSONArray("data")!=null && jsob.getJSONArray("data").size()>0){
+                    for (int i = 0; i <  jsob.getJSONArray("data").size(); i++) {
+                        JSONObject jsonObject = jsob.getJSONArray("data").getJSONObject(i);
+                        DeviceData data = new DeviceData();
+                        data.setDataJson(jsob.toJSONString());
+                        data.setCreateDate(date);
+                        data.setEditDate(date);
+                        data.setVal2("0");//鐢垫祦鍊�
+                        data.setVal3("0");
+                        data.setVal4("0");
+                        data.setVal5("0");
+                        data.setVal6("0");
+                        data.setHappenTime(DateUtil.getPlusTime2(new Date(jsob.getLong("timeMS"))));
+                        //妯″潡搴忓彿
+                        if(jsonObject.getJSONObject("mcbComSta")!=null
+                                && jsonObject.getJSONObject("mcbComSta").getString("busAddr")!=null){
+                            data.setVal1(jsonObject.getJSONObject("mcbComSta").getString("busAddr"));
+                            //<0>琛ㄧず鍒嗛椄锛�<1>琛ㄧず鍚堥椄锛屾棤绗﹀彿
+                            data.setVal7(jsonObject.getJSONObject("mcbComSta").getString("on"));
+                        }
+                        if(jsonObject.getJSONObject("mcbSta")!=null){
+                            //鐢垫祦
+                            if(jsonObject.getJSONObject("mcbSta").getString("cur")!=null){
+                                data.setVal2(jsonObject.getJSONObject("mcbSta").getString("cur"));
+                            }
+                            //鐢靛帇
+                            if(jsonObject.getJSONObject("mcbSta").getString("vol")!=null){
+                                data.setVal3(jsonObject.getJSONObject("mcbSta").getString("vol"));
+                            }
+                            //娓╁害
+                            if(jsonObject.getJSONObject("mcbSta").getString("tmp")!=null){
+                                data.setVal4(jsonObject.getJSONObject("mcbSta").getString("tmp"));
+                            }
+                            //鏈夊姛鍔熺巼鍊硷紝鍗曚綅kW
+                            if(jsonObject.getJSONObject("mcbSta").getString("pwrP")!=null){
+                                data.setVal5(jsonObject.getJSONObject("mcbSta").getString("pwrP"));
+                            }
+                            //N鐩哥數娴佸�硷紝鍗曚綅A
+                            if(jsonObject.getJSONObject("mcbSta").getString("curN")!=null){
+                                data.setVal6(jsonObject.getJSONObject("mcbSta").getString("curN"));
+                            }
+                        }
+                        data.setDeviceId(device.getId().toString());
+                        data.setDataType(Constants.ZERO);
+                        if(StringUtils.isNotBlank(data.getVal1())){
+                            dataList.add(data );
+                        }
+                    }
+                }
+                if(dataList.size()>0){
+                    deviceDataMapper.insert(dataList);
+                }
+            }
+        }catch (Exception e){
+            log.error("===============topic鏁版嵁璁板綍澶辫触:"+topic+e.getMessage());
+        }
+    }
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttSubServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttSubServiceImpl.java
new file mode 100644
index 0000000..a3a9859
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/mqtt/MqttSubServiceImpl.java
@@ -0,0 +1,43 @@
+package com.doumee.service.business.impl.mqtt;
+
+import com.alibaba.fastjson.JSONObject;
+import com.doumee.mqtt.config.MqttConfig;
+import com.doumee.mqtt.service.MqttBizService;
+import com.doumee.mqtt.service.MqttToolService;
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+/**
+ *  涓庣‖浠跺鎺ユ湇鍔�
+ * @author 姹熻箘韫�
+ * @date 2023/10/09 18:06
+ */
+@Service
+@Slf4j
+public class MqttSubServiceImpl implements MqttBizService {
+    @Autowired
+    private MqttPushCallback callBack ;
+    @Override
+    public MqttClient subscribe(MqttClient client,MqttConfig config,String[] topics){
+        log.error("mqtt璁㈤槄寮�濮�========寮�濮�"+ JSONObject.toJSONString(config));
+        client = MqttToolService.subscribe(client,config, topics,callBack);
+        log.error("mqtt璁㈤槄寮�濮�========缁撴潫"+ JSONObject.toJSONString(config));
+        return client;
+    }
+    @Override
+    public MqttClient unsubscribe(MqttClient client,MqttConfig config,String[] topics){
+        log.error("mqtt璁㈤槄寮�濮�========寮�濮�"+ JSONObject.toJSONString(config));
+        client = MqttToolService.unsubscribe(client,config, topics,callBack);
+        log.error("mqtt璁㈤槄寮�濮�========缁撴潫"+ JSONObject.toJSONString(config));
+        return client;
+    }
+
+    @Override
+    public MqttClient publish(MqttClient client,MqttConfig config, String topic, String param){
+        log.error("mqtt鍙戝竷娑堟伅========寮�濮�"+ JSONObject.toJSONString(config)+"\n"+param);
+        client = MqttToolService.pubMessage(client,config,param,topic,callBack);
+        log.error("mqtt鍙戝竷娑堟伅========缁撴潫"+ JSONObject.toJSONString(config));
+        return client;
+    }
+}

--
Gitblit v1.9.3