From e491cdb48129752324c4e3764f99bd9203c56dec Mon Sep 17 00:00:00 2001
From: lgq <1015864684@qq.com>
Date: 星期二, 31 三月 2026 09:48:44 +0800
Subject: [PATCH] 1.新增VF205门禁机代码

---
 vf205_access/src/driver.js | 1226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1,226 insertions(+), 0 deletions(-)

diff --git a/vf205_access/src/driver.js b/vf205_access/src/driver.js
new file mode 100644
index 0000000..bda4f7c
--- /dev/null
+++ b/vf205_access/src/driver.js
@@ -0,0 +1,1226 @@
+/**
+ * 椹卞姩妯″潡鏂囦欢
+ * 鍖呭惈绯荤粺鎵�鏈夌‖浠堕┍鍔ㄧ殑鍒濆鍖栧拰鎿嶄綔鏂规硶锛屾槸绯荤粺涓庣‖浠朵氦浜掔殑鏍稿績妯″潡
+ */
+import * as os from "os"
+import capturer from '../dxmodules/dxCapturer.js'
+import cameraCalibration from '../dxmodules/dxCameraCalibration.js'
+import face from '../dxmodules/dxFace.js'
+import std from '../dxmodules/dxStd.js'
+import common from '../dxmodules/dxCommon.js'
+import utils from './common/utils/utils.js'
+import alsa from '../dxmodules/dxAlsa.js'
+import config from '../dxmodules/dxConfig.js'
+import pwm from '../dxmodules/dxPwm.js'
+import net from '../dxmodules/dxNet.js'
+import ntp from '../dxmodules/dxNtp.js'
+import mqtt from '../dxmodules/dxMqtt.js'
+import dxMap from '../dxmodules/dxMap.js'
+import logger from '../dxmodules/dxLogger.js'
+import sqliteService from "./service/sqliteService.js"
+import mqttService from "./service/mqttService.js"
+import gpio from "../dxmodules/dxGpio.js"
+import map from "../dxmodules/dxMap.js"
+import eid from "../dxmodules/dxEid.js"
+import nfc from "../dxmodules/dxNfc.js"
+import bus from "../dxmodules/dxEventBus.js"
+import dxUart from "../dxmodules/dxUart.js"
+import watchdog from "../dxmodules/dxWatchdog.js"
+import base64 from "../dxmodules/dxBase64.js"
+import dxGpioKey from "../dxmodules/dxGpioKey.js"
+import dxDriver from "../dxmodules/dxDriver.js"
+const driver = {}
+
+/**
+ * 闊抽椹卞姩妯″潡
+ * 璐熻矗闊抽鎾斁鍜岃闊冲悎鎴�
+ */
+driver.alsa = alsa
+
+/**
+ * 閰嶇疆椹卞姩妯″潡
+ * 璐熻矗鍒濆鍖栫郴缁熼厤缃紝璁剧疆绯荤粺鍩烘湰淇℃伅
+ */
+driver.config = {
+    /**
+     * 鍒濆鍖栭厤缃�
+     * 鍒濆鍖栭厤缃ā鍧楋紝璁剧疆绯荤粺MAC銆乁UID銆丼N绛夊熀鏈俊鎭�
+     */
+    init: function () {
+        config.init()
+        let mac = common.getUuid2mac(19)
+        let uuid = common.getSn(19)
+        if (!config.get('sys.mac') && mac) {
+            config.set('sys.mac', mac)
+        }
+        if (!config.get('sys.uuid') && uuid) {
+            config.set('sys.uuid', uuid)
+        }
+        //濡傛灉 sn 涓虹┖鍏堢敤璁惧 uuid
+        if (!config.get('sys.sn') && uuid) {
+            config.set('sys.sn', uuid)
+        }
+        if (!config.get('mqtt.clientId') && uuid) {
+            config.set('mqtt.clientId', uuid)
+        }
+        config.save()
+    }
+}
+/**
+ * 灞忓箷椹卞姩妯″潡
+ * 璐熻矗灞忓箷鐩稿叧鐨勪簨浠惰Е鍙戝拰鎿嶄綔
+ */
+driver.screen = {
+    /**
+     * 閫氳澶辫触
+     * 瑙﹀彂閫氳澶辫触浜嬩欢
+     */
+    accessFail: function () {
+        bus.fire('accessRes', false)
+    },
+    
+    /**
+     * 閫氳鎴愬姛
+     * 瑙﹀彂閫氳鎴愬姛浜嬩欢
+     */
+    accessSuccess: function () {
+        bus.fire('accessRes', true)
+    },
+    
+    /**
+     * 鍗囩骇
+     * 瑙﹀彂鍗囩骇浜嬩欢
+     * @param {object} data - 鍗囩骇鏁版嵁
+     */
+    upgrade: function (data) {
+        bus.fire('upgrade', data)
+    },
+    
+    /**
+     * 鑾峰彇鍗$墖
+     * 鎾斁璇诲崱澹伴煶骞惰Е鍙戣幏鍙栧崱鐗囦簨浠�
+     * @param {string} card - 鍗$墖淇℃伅
+     */
+    getCard: function (card) {
+        driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/read.wav`)
+        bus.fire('getCard', card)
+    },
+    
+    /**
+     * 闅愯棌SN
+     * 瑙﹀彂闅愯棌SN浜嬩欢
+     * @param {object} data - 浜嬩欢鏁版嵁
+     */
+    hideSn: function (data) {
+        bus.fire('hideSn', data)
+    },
+    
+    /**
+     * 搴旂敤妯″紡
+     * 瑙﹀彂搴旂敤妯″紡浜嬩欢
+     * @param {object} data - 妯″紡鏁版嵁
+     */
+    appMode: function (data) {
+        bus.fire('appMode', data)
+    },
+    
+    /**
+     * 闅愯棌IP
+     * 瑙﹀彂闅愯棌IP浜嬩欢
+     * @param {object} data - 浜嬩欢鏁版嵁
+     */
+    hideIp: function (data) {
+        bus.fire('hideIp', data)
+    },
+    
+    /**
+     * 鍒囨崲璇█
+     * 瑙﹀彂璇█鍒囨崲浜嬩欢
+     */
+    changeLanguage: function () {
+        bus.fire('changeLanguage')
+    }
+}
+/**
+ * SQLite椹卞姩妯″潡
+ * 璐熻矗鏁版嵁搴撳垵濮嬪寲鍜岀鐞�
+ */
+driver.sqlite = {
+    /**
+     * 鍒濆鍖栨暟鎹簱
+     * 纭繚鏁版嵁搴撹矾寰勫瓨鍦ㄥ苟鍒濆鍖朣QLite鏈嶅姟
+     */
+    init: function () {
+        std.ensurePathExists('/app/data/db/app.db')
+        sqliteService.init('/app/data/db/app.db')
+    }
+}
+
+/**
+ * PWM椹卞姩妯″潡
+ * 璐熻矗鎺у埗琛ュ厜鐏殑浜害
+ */
+driver.pwm = {
+    /**
+     * 鍒濆鍖朠WM
+     * 鍒濆鍖栫櫧鑹茶ˉ鍏夌伅鍜岀孩澶栬ˉ鍏夌伅鐨凱WM閫氶亾
+     */
+    init: function () {
+        // 鐧界伅
+        let luminanceWhite = config.get('base.luminanceWhite') ?? 80
+        pwm.request(dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL);
+        pwm.setPeriodByChannel(dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL, dxDriver.PWM.WHITE_SUPPLEMENT_PERIOD_NS)
+        pwm.enable(dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL, true);
+        pwm.setDutyByChannel(dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL, dxDriver.PWM.WHITE_SUPPLEMENT_PERIOD_NS - (dxDriver.PWM.WHITE_SUPPLEMENT_PERIOD_NS * (luminanceWhite / 100)))
+        // 绾㈠
+        let luminanceNir = config.get('base.luminanceNir') ?? 80
+        pwm.request(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL);
+        pwm.setPeriodByChannel(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL, dxDriver.PWM.NIR_SUPPLEMENT_PERIOD_NS)
+        pwm.enable(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL, true);
+        pwm.setDutyByChannel(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL, dxDriver.PWM.NIR_SUPPLEMENT_PERIOD_NS - (dxDriver.PWM.NIR_SUPPLEMENT_PERIOD_NS * (luminanceNir / 100)))
+    },
+    
+    /**
+     * 璋冭妭鐧借壊琛ュ厜鐏寒搴�
+     * @param {number} value - 浜害鍊硷紝鑼冨洿0-100
+     */
+    luminanceWhite: function (value) {
+        if (value < 0 || value > 100) {
+            logger.error("[driver.pwm]: value should be between 0 and 100")
+            return
+        }
+        pwm.setDutyByChannel(dxDriver.PWM.WHITE_SUPPLEMENT_CHANNEL, dxDriver.PWM.WHITE_SUPPLEMENT_PERIOD_NS - (dxDriver.PWM.WHITE_SUPPLEMENT_PERIOD_NS * (value / 100)))
+    },
+    
+    /**
+     * 璋冭妭绾㈠琛ュ厜鐏寒搴�
+     * @param {number} value - 浜害鍊硷紝鑼冨洿0-100
+     */
+    luminanceNir: function (value) {
+        if (value < 0 || value > 100) {
+            logger.error("[driver.pwm]: value should be between 0 and 100")
+            return
+        }
+        pwm.setDutyByChannel(dxDriver.PWM.NIR_SUPPLEMENT_CHANNEL, dxDriver.PWM.NIR_SUPPLEMENT_PERIOD_NS - (dxDriver.PWM.NIR_SUPPLEMENT_PERIOD_NS * (value / 100)))
+    }
+}
+
+/**
+ * ALSA椹卞姩妯″潡
+ * 璐熻矗闊抽鎾斁鍜岄煶閲忔帶鍒�
+ */
+driver.alsa = {
+    /**
+     * 鍒濆鍖栭煶棰�
+     * 鍒濆鍖朅LSA闊抽妯″潡骞惰缃煶閲�
+     */
+    init: function () {
+        alsa.init()
+        this.volume(config.get("base.volume"))
+    },
+    
+    /**
+     * 鎾斁闊抽鏂囦欢
+     * @param {string} src - 闊抽鏂囦欢璺緞
+     */
+    play: function (src) {
+        alsa.play(src)
+    },
+    
+    /**
+     * 鏂囨湰杞闊虫挱鏀�
+     * @param {string} text - 瑕佹挱鏀剧殑鏂囨湰
+     */
+    ttsPlay: function (text) {
+        alsa.ttsPlay(text)
+    },
+    
+    /**
+     * 鑾峰彇鎴栬缃煶閲�
+     * @param {number} [volume] - 闊抽噺鍊硷紝鑼冨洿1-100
+     * @returns {number} 褰撳墠闊抽噺鍊硷紙褰撴湭鎻愪緵鍙傛暟鏃讹級
+     */
+    volume: function (volume) {
+        if (volume === undefined || volume === null) {
+            return alsa.getVolume()
+        } else {
+            function mapScore(input) {
+                // 纭繚杈撳叆鍊煎湪1-100涔嬮棿
+                if (input < 1 || input > 100) {
+                    throw new Error('杈撳叆鍊煎繀椤诲湪1鍒�100涔嬮棿');
+                }
+                if (input < 60 && input > 30) {
+                    input = input * 1.2
+                }
+                if (input < 30 && input > 1) {
+                    input = input * 2
+                }
+                return input
+            }
+            alsa.setVolume(mapScore(volume))
+        }
+    }
+}
+
+/**
+ * 鎽勫儚澶撮┍鍔ㄦā鍧�
+ * 璐熻矗鎽勫儚澶寸殑鍒濆鍖栧拰鎿嶄綔锛屽寘鎷僵鑹叉憚鍍忓ご鍜岀孩澶栨憚鍍忓ご
+ */
+driver.capturer = {
+    /**
+     * 褰╄壊鎽勫儚澶撮厤缃�
+     */
+    options1: {
+        id: "rgb",
+        path: dxDriver.CAPTURER.RGB_PATH,
+        width: dxDriver.CAPTURER.RGB_WIDTH,
+        height: dxDriver.CAPTURER.RGB_HEIGHT,
+        preview_width: dxDriver.CAPTURER.RGB_HEIGHT,
+        preview_height: dxDriver.CAPTURER.RGB_WIDTH,
+        preview_mode: 2,
+        preview_screen_index: 0 // 鍏堝悗椤哄簭锛屾暟瀛楄秺澶ц秺鍦ㄥ墠闈�
+    },
+    
+    /**
+     * 绾㈠鎽勫儚澶撮厤缃�
+     */
+    options2: {
+        id: "nir",
+        path: dxDriver.CAPTURER.NIR_PATH,
+        width: dxDriver.CAPTURER.NIR_WIDTH,
+        height: dxDriver.CAPTURER.NIR_HEIGHT,
+        preview_width: 150,
+        preview_height: 200,
+        preview_mode: 1,
+        preview_left: 605,
+        preview_top: 80,
+        preview_screen_index: 1 // 鍏堝悗椤哄簭锛屾暟瀛楄秺澶ц秺鍦ㄥ墠闈�
+    },
+
+    /**
+     * 鍒濆鍖栨憚鍍忓ご
+     * 鍒濆鍖栧僵鑹叉憚鍍忓ご鍜岀孩澶栨憚鍍忓ご
+     */
+    init: function () {
+        capturer.worker.beforeLoop(this.options1)
+        capturer.worker.beforeLoop(this.options2)
+
+        this.showNir(config.get("face.showNir"))
+    },
+    
+    /**
+     * 鏄剧ず鎴栭殣钘忕孩澶栨憚鍍忓ご棰勮
+     * @param {boolean} enable - 鏄惁鍚敤绾㈠鎽勫儚澶撮瑙�
+     */
+    showNir: function (enable) {
+        capturer.capturerEnable(enable, this.options2.id)
+    },
+    
+    /**
+     * 灏嗗浘鐗囨暟鎹浆鎹负鍥惧儚
+     * @param {string} base64Data - Base64缂栫爜鐨勫浘鐗囨暟鎹�
+     * @returns {number} 鍥惧儚ID
+     */
+    pictureDataToImage: function (base64Data) {
+        return capturer.pictureDataToImage(base64Data, base64Data.length, 1)
+    },
+    
+    /**
+     * 灏嗗浘鍍忎繚瀛樹负鏂囦欢
+     * @param {number} imageId - 鍥惧儚ID
+     * @param {string} savePath - 淇濆瓨璺緞
+     * @returns {boolean} 鏄惁淇濆瓨鎴愬姛
+     */
+    imageToPictureFile: function (imageId, savePath) {
+        return capturer.imageToPictureFile(imageId, 1, 0, 24, savePath)
+    },
+    
+    /**
+     * 灏嗗浘鍍忎繚瀛樹负鏂囦欢锛堥珮璐ㄩ噺锛�
+     * @param {number} imageId - 鍥惧儚ID
+     * @param {string} savePath - 淇濆瓨璺緞
+     * @returns {boolean} 鏄惁淇濆瓨鎴愬姛
+     */
+    imageToPictureFile2: function (imageId, savePath) {
+        return capturer.imageToPictureFile(imageId, 1, 0, 100, savePath)
+    },
+    
+    /**
+     * 璋冩暣鍥惧儚鍒嗚鲸鐜�
+     * @param {number} imageId - 鍥惧儚ID
+     * @param {number} width - 鐩爣瀹藉害
+     * @param {number} height - 鐩爣楂樺害
+     * @returns {number} 璋冩暣鍚庣殑鍥惧儚ID
+     */
+    imageResizeResolution: function (imageId, width, height) {
+        return capturer.imageResizeResolution(imageId, width, height, 0)
+    },
+    
+    /**
+     * 鎽勫儚澶村惊鐜�
+     * 鎵ц鎽勫儚澶寸殑寰幆鎿嶄綔
+     */
+    loop: function () {
+        capturer.worker.loop(this.options1)
+        capturer.worker.loop(this.options2)
+    }
+}
+/**
+ * NFC椹卞姩妯″潡
+ * 璐熻矗NFC鍗$墖鐨勮鍙栧拰澶勭悊
+ */
+driver.nfc = {
+    /**
+     * NFC閰嶇疆閫夐」
+     */
+    options: { m1: true, psam: false },
+    
+    /**
+     * 鍒濆鍖朜FC
+     * 鍒濆鍖朜FC妯″潡锛屾牴鎹厤缃喅瀹氭槸鍚﹀惎鐢�
+     */
+    init: function () {
+        if (!config.get('sys.nfc')) {
+            logger.debug("鍒峰崱宸插叧闂�")
+            return
+        }
+        this.options.useEid = config.get("sys.nfcIdentityCardEnable") == 3 ? 1 : 0
+        nfc.worker.beforeLoop(this.options)
+    },
+    
+    /**
+     * 鍒濆鍖朎ID锛堢數瀛愯韩浠借瘉锛�
+     * 鏇存柊EID閰嶇疆
+     */
+    eidInit: function () {
+        if (!config.get('sys.nfc')) {
+            return
+        }
+        if (config.get("sys.nfcIdentityCardEnable") == 3) {
+            nfc.eidUpdateConfig({ appid: "1621503", sn: config.get("sys.sn"), device_model: config.get("sys.appVersion") })
+        }
+    },
+    
+    /**
+     * NFC寰幆
+     * 鎵цNFC鐨勫惊鐜搷浣滐紝鏍规嵁閰嶇疆鍐冲畾鏄惁鍚敤
+     */
+    loop: function () {
+        if (!config.get('sys.nfc')) {
+            this.loop = () => { }
+        } else {
+            this.loop = () => nfc.worker.loop(this.options)
+        }
+    }
+}
+/**
+ * 浜鸿劯璇嗗埆椹卞姩妯″潡
+ * 璐熻矗浜鸿劯璇嗗埆銆佹敞鍐屽拰鐩稿叧鍔熻兘鐨勭鐞�
+ */
+driver.face = {
+    /**
+     * 鍒濆鍖栦汉鑴歌瘑鍒�
+     * 鍒濆鍖栦汉鑴告ā鍧楋紝璁剧疆鐩稿叧鍙傛暟鍜岄厤缃�
+     */
+    init: function () {
+        common.systemBrief('mkdir -p /app/data/user/temp/')
+        let options = {
+            dbPath: "/app/data/db/face.db",
+            rgbPath: "/dev/video3",
+            nirPath: "/dev/video0",
+            capturerRgbId: "rgb",
+            capturerNirId: "nir",
+            dbMax: 5000, //浜鸿劯娉ㄥ唽涓婇檺
+            score: config.get("face.similarity"),
+            picPath: "/app/data/user/temp",
+            gThumbnailHeight: 1280 / 6,
+            gThumbnailWidth: 800 / 6,
+            // 鏄惁寮�鍚噸妫�
+            recgFaceattrEnable: 1,
+            // 娲讳綋寮�鍏�
+            livingCheckEnable: config.get("face.livenessOff"),
+            // 娲讳綋妫�娴嬮槇鍊�
+            livingScore: config.get("face.livenessVal"),
+            // 鍙g僵妫�娴嬪紑鍏�
+            detectMaskEnable: config.get("face.detectMask"),
+            // 閲嶆闂撮殧
+            recheckIntervalTime: 5000,
+            // 妫�娴嬭秴鏃�
+            detectTimeoutTime: 1000
+        }
+        face.worker.beforeLoop(options)
+
+        // 榛樿涓轰汉鑴歌瘑鍒ā寮�
+        this.mode(0)
+        // 鍏抽棴鎵�鏈変汉鑴稿姛鑳�
+        this.status(false)
+
+        // 灞忓箷浜害
+        this.setDisplayBacklight(config.get("base.brightness"))
+
+        this.screenStatus(1)
+        
+        // 琛ュ厜鐏姸鎬佽窡韪�
+        let isLightOn = true
+
+        // 灞忓箷浜害鑷姩璋冭妭
+        std.setInterval(() => {
+            // 鐔勫睆鍒ゆ柇
+            let screenOff = map.get("screenOff")
+            if (screenOff.get("status") == 1) {
+                this.setDisplayBacklight(0)
+                this.screenStatus(0)
+                // 鍏抽棴琛ュ厜鐏紙浠呭綋琛ュ厜鐏綋鍓嶆槸寮�鍚姸鎬佹椂锛�
+                if (isLightOn) {
+                    driver.pwm.luminanceWhite(0)
+                    driver.pwm.luminanceNir(0)
+                    logger.info("[driver.face]: 鐔勫睆锛屽叧闂ˉ鍏夌伅")
+                    isLightOn = false
+                }
+            }
+
+            // 鍋滄鐔勫睆
+            if (screenOff.get("status") != 1) {
+                if (config.get("base.brightnessAuto") == 1) {
+                    // 鑷姩璋冭妭灞忓箷浜害
+                    let brightness = Math.floor(face.getEnvBrightness() / 10)
+                    brightness = brightness > 100 ? 100 : brightness
+                    this.setDisplayBacklight(brightness)
+                } else {
+                    this.setDisplayBacklight(config.get("base.brightness"))
+                }
+                // 寮�鍚ˉ鍏夌伅锛堜粎褰撹ˉ鍏夌伅褰撳墠鏄叧闂姸鎬佹椂锛�
+                if (!isLightOn) {
+                    let luminanceWhite = config.get('base.luminanceWhite') ?? 80
+                    let luminanceNir = config.get('base.luminanceNir') ?? 80
+                    driver.pwm.luminanceWhite(luminanceWhite)
+                    driver.pwm.luminanceNir(luminanceNir)
+                    logger.info(`[driver.face]: 閫�鍑虹唲灞忥紝寮�鍚ˉ鍏夌伅锛堢櫧鐏�: ${luminanceWhite}%, 绾㈠: ${luminanceNir}%锛塦)
+                    isLightOn = true
+                }
+            }
+        }, 1000)
+    },
+    
+    /**
+     * 鑾峰彇浜鸿劯璺熻釜妗�
+     * @returns {object} 璺熻釜妗嗕俊鎭�
+     */
+    getTrackingBox: function () {
+        return face.getTrackingBox()
+    },
+    
+    /**
+     * 浜鸿劯璇嗗埆寰幆
+     * 鎵ц浜鸿劯璇嗗埆鐨勫惊鐜搷浣�
+     */
+    loop: function () {
+        // 妫�鏌ュ睆骞曟槸鍚﹀浜庣唲灞忕姸鎬�
+        let screenOff = map.get("screenOff")
+        if (screenOff && screenOff.get("status") == 1) {
+            // 鐔勫睆鐘舵�佷笅涓嶈繘琛屼汉鑴歌瘑鍒�
+            return
+        }
+        face.worker.loop()
+    },
+    
+    /**
+     * 浜鸿劯绾跨▼鍚敤寮�鍏�
+     * @param {boolean} flag - 鏄惁鍚敤浜鸿劯妫�娴�
+     */
+    status: function (flag) {
+        console.log('---浜鸿劯妫�娴�' + (flag ? '寮�鍚�' : '鏆傚仠') + '---');
+        face.faceSetEnable(flag)
+    },
+    
+    /**
+     * 璁剧疆浜鸿劯璇嗗埆妯″紡
+     * @param {number} value - 妯″紡鍊硷紝0涓鸿瘑鍒ā寮忥紝1涓烘敞鍐屾ā寮�
+     */
+    mode: function (value) {
+        console.log('---浜鸿劯' + (value ? '娉ㄥ唽' : '璇嗗埆') + '妯″紡---');
+        face.setRecgMode(value)
+    },
+    
+    /**
+     * 浜鸿劯娉ㄥ唽
+     * @param {string} id - 鐢ㄦ埛ID
+     * @param {string} feature - 浜鸿劯鐗瑰緛
+     * @returns {boolean} 鏄惁娉ㄥ唽鎴愬姛
+     */
+    reg: function (id, feature) {
+        return face.addFaceFeatures(id, feature);
+    },
+    
+    /**
+     * 鏇存柊浜鸿劯閰嶇疆
+     * @param {object} options - 閰嶇疆閫夐」
+     */
+    faceUpdateConfig: function (options) {
+        console.log("鏇存柊浜鸿劯閰嶇疆", JSON.stringify(options));
+        face.faceUpdateConfig(options)
+    },
+    
+    /**
+     * 璁剧疆灞忓箷浜害
+     * @param {number} brightness - 浜害鍊�
+     */
+    setDisplayBacklight: function (brightness) {
+        brightness = brightness < 2 ? 2 : brightness
+        face.setDisplayBacklight(brightness)
+    },
+    
+    /**
+     * 閫氳繃鍥剧墖鏂囦欢娉ㄥ唽浜鸿劯
+     * @param {string} userId - 鐢ㄦ埛ID
+     * @param {string} picPath - 鍥剧墖璺緞
+     * @returns {boolean} 鏄惁娉ㄥ唽鎴愬姛
+     */
+    registerFaceByPicFile: function (userId, picPath) {
+        return face.registerFaceByPicFile(userId, picPath)
+    },
+    
+    /**
+     * 娓呯┖浜鸿劯鏁版嵁
+     * @returns {boolean} 鏄惁娓呯┖鎴愬姛
+     */
+    clean: function () {
+        // 娓呯┖浜鸿劯锛岄渶瑕佸湪鍒濆鍖栦汉鑴哥粍浠朵箣鍓嶆墠鑳芥墽琛岋紝鍚﹀垯鎶ラ敊
+        face.faceFeaturesClean()
+        common.systemBrief("rm -rf /app/data/db/face.db")
+        return !std.exist("/app/data/db/face.db")
+    },
+    
+    /**
+     * 鍒犻櫎鎸囧畾鐢ㄦ埛鐨勪汉鑴告暟鎹�
+     * @param {string} userId - 鐢ㄦ埛ID
+     * @returns {boolean} 鏄惁鍒犻櫎鎴愬姛
+     */
+    delete: function (userId) {
+        return face.deleteFaceFeatures(userId)
+    },
+    
+    /**
+     * 璁剧疆灞忓箷鐘舵��
+     * @param {boolean} status - 鏄惁鍚敤灞忓箷
+     */
+    screenStatus: function (status) {
+        if (status) {
+            face.setPowerMode(0)
+        } else {
+            face.setPowerMode(1)
+        }
+        face.setEnableStatus(status)
+    },
+    
+    /**
+     * 灏嗘枃浠惰浆鎹负base64缂栫爜
+     * @param {string} filePath - 鏂囦欢璺緞
+     * @returns {string} Base64缂栫爜鐨勬枃浠跺唴瀹�
+     */
+    fileToBase64: function (filePath) {
+        function fileToUint8Array(filename) {
+            // 璇诲彇鏂囦欢
+            const file = std.open(filename, "rb");
+            if (!file) {
+                throw new Error("鏃犳硶鎵撳紑鏂囦欢");
+            }
+
+            // 鑾峰彇鏂囦欢澶у皬
+            const size = std.seek(file, 0, std.SEEK_END)
+            std.seek(file, 0, std.SEEK_SET)
+            
+            // 妫�鏌ユ枃浠跺ぇ灏忔槸鍚︽湁鏁�
+            if (size <= 0) {
+                std.close(file);
+                throw new Error("鏂囦欢澶у皬鏃犳晥");
+            }
+            
+            // 鍒涘缓 ArrayBuffer 骞惰鍙栨枃浠跺唴瀹�
+            const buffer = new ArrayBuffer(size);
+            const array = new Uint8Array(buffer);
+            std.read(file, array.buffer, 0, size);
+
+            std.close(file);
+
+            return array;
+        }
+
+        try {
+            // 妫�鏌ユ枃浠惰矾寰勬槸鍚﹀瓨鍦�
+            if (!filePath) {
+                throw new Error("鏂囦欢璺緞涓虹┖");
+            }
+            const data = fileToUint8Array(filePath);
+            return base64.fromUint8Array(data);
+        } catch (error) {
+            logger.info("鏂囦欢杞珺ase64澶辫触: " + error.message);
+            return "";
+        }
+    }
+}
+
+/**
+ * 缃戠粶椹卞姩妯″潡
+ * 璐熻矗缃戠粶杩炴帴鍜岀鐞�
+ */
+driver.net = {
+    /**
+     * 鍒濆鍖栫綉缁�
+     * 鍒濆鍖栫綉缁滄ā鍧楋紝璁剧疆缃戠粶閰嶇疆
+     */
+    init: function () {
+        let dns = config.get("net.dns").split(",")
+        let option = {
+            type: config.get("net.type"),
+            dhcp: config.get("net.dhcp"),
+            ip: config.get("net.ip"),
+            gateway: config.get("net.gateway"),
+            netmask: config.get("net.mask"),
+            dns0: dns[0],
+            dns1: dns[1],
+            macAddr: common.getUuid2mac()
+        }
+        logger.info("鏇存柊鑱旂綉閰嶇疆锛�", JSON.stringify(option));
+        net.worker.beforeLoop(option)
+        config.set("net.mac", common.getUuid2mac())
+        if (config.get("net.type") == 2) {
+            //wifi鍙栭厤缃枃浠跺幓杩炴帴
+            let ssid = utils.isEmpty(config.get('net.ssid')) ? "ssid" : config.get('net.ssid')
+            let psk = utils.isEmpty(config.get('net.psk')) ? "psk" : config.get('net.psk')
+            driver.net.netConnectWifiSsid(ssid, psk)
+        }
+        // 瑙e喅缃戠粶鍒囨崲鐘舵�佷笉瀵�
+        std.setInterval(() => {
+            let status = net.getStatus()
+            if (status.status != map.get("NET").get("status")) {
+                status.type = config.get("net.type")
+                bus.fire(net.STATUS_CHANGE, status)
+            }
+        }, 1000)
+    },
+    
+    /**
+     * 鍒囨崲缃戠粶绫诲瀷
+     * 鍒囨崲缃戠粶绫诲瀷骞堕厤缃浉搴旂殑缃戠粶鍙傛暟
+     */
+    changeNetType: function () {
+        // 鍔犻攣
+        if (map.get("NET").get("changeType") == "Y") {
+            return
+        }
+        map.get("NET").put("changeType", "Y")
+        let type = config.get("net.type")
+        logger.info("鍒囨崲缃戠粶", type);
+        [1, 2, 4].filter(v => v != type).forEach(v => {
+            logger.info("鍏抽棴缃戝崱", v, net.cardEnable(v, false));
+        })
+        logger.info("璁剧疆涓荤綉鍗�", type, net.setMasterCard(type));
+        logger.info("寮�鍚綉鍗�", type, net.cardEnable(type, true));
+        if (type == 2) {
+            //wifi鍙栭厤缃枃浠跺幓杩炴帴
+            let ssid = utils.isEmpty(config.get('net.ssid')) ? "ssid" : config.get('net.ssid')
+            let psk = utils.isEmpty(config.get('net.psk')) ? "psk" : config.get('net.psk')
+            logger.info("杩炴帴wifi", ssid, psk);
+            net.netConnectWifiSsid(ssid, psk)
+            
+            // 绛夊緟WiFi杩炴帴鎴愬姛鍚庡啀璁剧疆缃戠粶妯″紡
+            std.setTimeout(() => {
+                let dns = config.get("net.dns").split(",")
+                net.setModeByCard(type, config.get("net.dhcp"), config.get("net.dhcp") == 1 ? {
+                    ip: config.get("net.ip"),
+                    gateway: config.get("net.gateway"),
+                    netmask: config.get("net.mask"),
+                    dns0: dns[0],
+                    dns1: dns[1],
+                } : undefined)
+            }, 3000); // 绛夊緟3绉掕WiFi杩炴帴鎴愬姛
+        } else if (type == 1) {
+            // 浠ュお缃戠洿鎺ヨ缃綉缁滄ā寮�
+            let dns = config.get("net.dns").split(",")
+            net.setModeByCard(type, config.get("net.dhcp"), config.get("net.dhcp") == 1 ? {
+                ip: config.get("net.ip"),
+                gateway: config.get("net.gateway"),
+                netmask: config.get("net.mask"),
+                dns0: dns[0],
+                dns1: dns[1],
+            } : undefined)
+        }
+        map.get("NET").del("changeType")
+    },
+    
+    /**
+     * 鍒濆鍖朎ID缃戠粶
+     * 閫�鍑虹綉缁滃苟閲嶅惎鐩稿叧鏈嶅姟
+     */
+    eidInit: function () {
+        net.exit();
+        common.systemWithRes(`pkill -9 -f 'wpa_supplicant|udhcpc'`, 5)
+    },
+    
+    /**
+     * 鑾峰彇缃戠粶鐘舵��
+     * @returns {boolean} 鏄惁杩炴帴鎴愬姛
+     */
+    getStatus: function () {
+        let status = net.getStatus()
+        if (status.connected == true && status.status == 4) {
+            return true
+        } else {
+            return false
+        }
+
+    },
+    
+    /**
+     * 杩炴帴WiFi
+     * @param {string} ssid - WiFi鍚嶇О
+     * @param {string} psk - WiFi瀵嗙爜
+     */
+    netConnectWifiSsid: function (ssid, psk) {
+        net.netConnectWifiSsid(ssid, psk, "")
+    },
+    
+    /**
+     * 鑾峰彇WiFi鍒楄〃
+     * @returns {array} WiFi鍒楄〃
+     */
+    netGetWifiSsidList: function () {
+        if (!driver.net.getStatus()) {
+            //濡傛灉 wifi 杩炴帴澶辫触  鑾峰彇鍒楄〃浼氬け璐ラ渶瑕佸厛閿�姣�
+            net.netDisconnetWifi()
+        }
+        let result = net.netGetWifiSsidList(1000, 5)
+        if (!result || !result.results || result.results.length === 0) {
+            return [];
+        }
+        let wifiList = []; // 鍒濆鍖杦ifiList涓烘暟缁�
+        result.results.forEach(element => wifiList.push(element.ssid)); // 浣跨敤push鏂规硶娣诲姞ssid鍒版暟缁�
+        return wifiList;
+    },
+    
+    /**
+     * 閲嶇疆缃戝崱
+     */
+    cardReset: function () {
+        // net.netCardReset(2,1)
+    },
+    
+    /**
+     * 缃戠粶寰幆
+     * 鎵ц缃戠粶鐨勫惊鐜搷浣�
+     */
+    loop: function () {
+        net.worker.loop()
+    }
+}
+
+/**
+ * NTP椹卞姩妯″潡
+ * 璐熻矗缃戠粶鏃堕棿鍚屾
+ */
+driver.ntp = {
+    /**
+     * NTP寰幆
+     * 鍒濆鍖朜TP妯″潡骞舵墽琛屾椂闂村悓姝ユ搷浣�
+     */
+    loop: function () {
+        // 姣忕閽熷垽鏂椂闂达紝濡傛灉鏃跺樊澶т簬2绉掑垯杩涜浜嗗鏃�
+        let last = new Date().getTime()
+        dxMap.get("NTP_SYNC").put("syncTime", last)
+        std.setInterval(() => {
+            let now = new Date().getTime()
+            let diff = now - last
+            if (diff > 2000) {
+                dxMap.get("NTP_SYNC").put("syncTime", now)
+                last = now
+            }
+        }, 1000)
+
+        ntp.beforeLoop(config.get("ntp.server"), 9999999999999)
+        this.ntpHour = config.get('ntp.hour')
+        this.flag = true
+        driver.ntp.loop = () => {
+            if (config.get("ntp.ntp")) {
+                ntp.loop()
+                if (new Date().getHours() == this.ntpHour && this.flag) {
+                    // 瀹氭椂鍚屾锛岀珛鍗冲悓姝ヤ竴娆℃椂闂�
+                    ntp.syncnow = true
+                    this.flag = false
+                }
+                if (new Date().getHours() != this.ntpHour) {
+                    // 绛夎繃浜嗚繖涓皬鏃跺啀娆″厑璁稿鏃�
+                    this.flag = true
+                }
+            }
+        }
+    }
+}
+/**
+ * 鍚屾椹卞姩妯″潡
+ * 鎻愪緵寮傛杞悓姝ョ殑瀹炵幇
+ */
+driver.sync = {
+    /**
+     * 寮傛杞悓姝ヨ姹�
+     * @param {string} topic - 涓婚
+     * @param {number} timeout - 瓒呮椂鏃堕棿锛堟绉掞級
+     * @returns {any} 鍝嶅簲鏁版嵁
+     */
+    request: function (topic, timeout) {
+        let map = dxMap.get("SYNC")
+        let count = 0
+        let data = map.get(topic)
+        while (utils.isEmpty(data) && count * 10 < timeout) {
+            data = map.get(topic)
+            std.sleep(10)
+            count += 1
+        }
+        let res = map.get(topic)
+        map.del(topic)
+        return res
+    },
+    
+    /**
+     * 鍚屾鍝嶅簲
+     * @param {string} topic - 涓婚
+     * @param {any} data - 鍝嶅簲鏁版嵁
+     */
+    response: function (topic, data) {
+        let map = dxMap.get("SYNC")
+        map.put(topic, data)
+    }
+}
+/**
+ * MQTT椹卞姩妯″潡
+ * 璐熻矗MQTT閫氫俊鍜屾秷鎭鐞�
+ */
+driver.mqtt = {
+    /**
+     * 鍒濆鍖朚QTT
+     * 鍒濆鍖朚QTT妯″潡锛岃缃繛鎺ュ弬鏁�
+     */
+    init: function () {
+        mqtt.run({ mqttAddr: config.get("mqtt.addr"), clientId: config.get('mqtt.clientId'), subs: mqttService.getTopics(), username: config.get("mqtt.username"), password: config.get("mqtt.password"), qos: config.get("mqtt.qos"), willTopic: config.get("mqtt.willTopic"), willMessage: JSON.stringify({ "uuid": config.get("sys.uuid") }) })
+    },
+    
+    /**
+     * 鍒濆鍖朎ID鐨凪QTT
+     * 閿�姣丮QTT杩炴帴
+     */
+    eidInit: function () {
+        mqtt.destroy()
+    },
+    
+    /**
+     * 鍙戦�丮QTT娑堟伅
+     * @param {string} topic - 娑堟伅涓婚
+     * @param {any} payload - 娑堟伅杞借嵎
+     */
+    send: function (topic, payload,) {
+        logger.info("[driver.mqtt] send :", topic)
+        mqtt.send(topic, payload)
+    },
+    
+    /**
+     * 鑾峰彇鍦ㄧ嚎妫�鏌�
+     * @returns {any} 鍦ㄧ嚎妫�鏌ョ粨鏋�
+     */
+    getOnlinecheck: function () {
+        let timeout = config.get("mqtt.timeout")
+        timeout = utils.isEmpty(timeout) ? 2000 : timeout
+        return driver.sync.request("mqtt.getOnlinecheck", timeout)
+    },
+    
+    /**
+     * 鍦ㄧ嚎妫�鏌ュ洖澶�
+     * @param {any} data - 鍥炲鏁版嵁
+     */
+    getOnlinecheckReply: function (data) {
+        driver.sync.response("mqtt.getOnlinecheck", data)
+    },
+    
+    /**
+     * 鑾峰彇MQTT杩炴帴鐘舵��
+     * @returns {boolean} 鏄惁杩炴帴鎴愬姛
+     */
+    getStatus: function () {
+        return mqtt.isConnected()
+    },
+    
+    /**
+     * MQTT蹇冭烦
+     * 鍙戦�佸績璺虫秷鎭紝淇濇寔杩炴帴
+     */
+    heartbeat: function () {
+        if (utils.isEmpty(this.heart_en)) {
+            let heart_en = config.get('sys.heart_en')
+            this.heart_en = utils.isEmpty(heart_en) ? 0 : heart_en
+            let heart_time = config.get('sys.heart_time')
+            this.heart_time = utils.isEmpty(heart_time) ? 30 : heart_time < 30 ? 30 : heart_time
+        }
+        if (utils.isEmpty(this.lastHeartbeat)) {
+            this.lastHeartbeat = 0
+        }
+        if (this.heart_en === 1 && (new Date().getTime() - this.lastHeartbeat >= (this.heart_time * 1000))) {
+            this.lastHeartbeat = new Date().getTime()
+            driver.mqtt.send("access_device/v2/event/heartbeat", JSON.stringify(mqttService.mqttReply(std.genRandomStr(10), undefined, mqttService.CODE.S_000)))
+        }
+    }
+}
+
+/**
+ * GPIO椹卞姩妯″潡
+ * 璐熻矗GPIO璁惧鐨勬帶鍒讹紝涓昏鏄户鐢靛櫒鎺у埗
+ */
+driver.gpio = {
+    /**
+     * 鍒濆鍖朑PIO
+     * 鍒濆鍖朑PIO妯″潡骞惰姹傜户鐢靛櫒寮曡剼
+     */
+    init: function () {
+        gpio.init()
+        gpio.request(dxDriver.GPIO.RELAY0)
+    },
+    
+    /**
+     * 鎵撳紑缁х數鍣�
+     * 鎵撳紑缁х數鍣ㄥ苟鍦ㄦ寚瀹氭椂闂村悗鑷姩鍏抽棴
+     */
+    open: function () {
+        logger.info("[GPIO]: 鎵撳紑缁х數鍣�")
+        let result = gpio.setValue(dxDriver.GPIO.RELAY0, 1);
+        logger.info("[GPIO]: 鎵撳紑缁х數鍣ㄧ粨鏋�: " + result)
+
+        let relayTime = config.get("access.relayTime")
+
+        std.setTimeout(() => {
+            logger.info("[GPIO]: 鍏抽棴缁х數鍣�")
+            let closeResult = gpio.setValue(dxDriver.GPIO.RELAY0, 0);
+            logger.info("[GPIO]: 鍏抽棴缁х數鍣ㄧ粨鏋�: " + closeResult)
+        }, relayTime)
+    },
+    
+    /**
+     * 鍏抽棴缁х數鍣�
+     * 绔嬪嵆鍏抽棴缁х數鍣�
+     */
+    close: function () {
+        gpio.setValue(dxDriver.GPIO.RELAY0, 0)
+    }
+}
+
+/**
+ * UART485椹卞姩妯″潡
+ * 璐熻矗UART485閫氫俊
+ */
+driver.uart485 = {
+    /**
+     * UART485 ID
+     */
+    id: 'uart485',
+    
+    /**
+     * 鍒濆鍖朥ART485
+     * 鍒濆鍖朥ART485妯″潡骞惰缃�氫俊鍙傛暟
+     */
+    init: function () {
+        dxUart.runvg({ id: this.id, type: dxUart.TYPE.UART, path: '/dev/ttySLB2', result: 0, passThrough: false })
+        std.sleep(2000)
+        dxUart.ioctl(6, '115200-8-N-1', this.id)
+    },
+    
+    /**
+     * 鎺у埗UART485
+     * @param {string} data - 鎺у埗鏁版嵁
+     */
+    ioctl: function (data) {
+        dxUart.ioctl(6, data, this.id)
+    },
+    
+    /**
+     * 鍙戦�佹暟鎹�
+     * @param {string} data - 瑕佸彂閫佺殑鏁版嵁
+     */
+    send: function (data) {
+        dxUart.send(data, this.id)
+    },
+    
+    /**
+     * 鍙戦�乂G鏁版嵁
+     * @param {object|string} data - 瑕佸彂閫佺殑鏁版嵁
+     */
+    sendVg: function (data) {
+        if (typeof data == 'object') {
+            data.length = data.length ? data.length : (data.data ? data.data.length / 2 : 0)
+        }
+        dxUart.sendVg(data, this.id)
+    }
+}
+
+/**
+ * UARTCode椹卞姩妯″潡
+ * 璐熻矗UART鏉$爜鎵弿閫氫俊
+ */
+driver.uartCode = {
+    /**
+     * UARTCode ID
+     */
+    id: 'uartCode',
+    
+    /**
+     * 鍒濆鍖朥ARTCode
+     * 鍒濆鍖朥ARTCode妯″潡骞惰缃�氫俊鍙傛暟
+     */
+    init: function () {
+        dxUart.runvg({ id: this.id, type: dxUart.TYPE.UART, path: '/dev/ttySLB1', result: 0, passThrough: false })
+        std.sleep(500)
+        dxUart.ioctl(6, '115200-8-N-1', this.id)
+    },
+    
+    /**
+     * 鎺у埗UARTCode
+     * @param {string} data - 鎺у埗鏁版嵁
+     */
+    ioctl: function (data) {
+        dxUart.ioctl(6, data, this.id)
+    },
+    
+    /**
+     * 鍙戦�佹暟鎹�
+     * @param {string} data - 瑕佸彂閫佺殑鏁版嵁
+     */
+    send: function (data) {
+        dxUart.send(data, this.id)
+    },
+    
+    /**
+     * 鍙戦�乂G鏁版嵁
+     * @param {object|string} data - 瑕佸彂閫佺殑鏁版嵁
+     */
+    sendVg: function (data) {
+        if (typeof data == 'object') {
+            data.length = data.length ? data.length : (data.data ? data.data.length / 2 : 0)
+        }
+        dxUart.sendVg(data, this.id)
+    },
+}
+
+/**
+ * EID椹卞姩妯″潡
+ * 璐熻矗鐢靛瓙韬唤璇佺浉鍏虫搷浣�
+ */
+driver.eid = {
+    /**
+     * EID ID
+     */
+    id: "eid",
+    
+    /**
+     * 婵�娲籈ID
+     * @param {string} sn - 璁惧SN
+     * @param {string} version - 鐗堟湰鍙�
+     * @param {string} mac - MAC鍦板潃
+     * @param {string} codeMsg - 婵�娲荤爜
+     * @returns {boolean} 鏄惁婵�娲绘垚鍔�
+     */
+    active: function (sn, version, mac, codeMsg) {
+        return eid.active(sn, version, mac, codeMsg)
+    },
+    
+    /**
+     * 鑾峰彇EID鐗堟湰
+     * @returns {string} EID鐗堟湰
+     */
+    getVerion: function () {
+        return eid.getVersion()
+    }
+}
+/**
+ * GPIO鎸夐敭椹卞姩妯″潡
+ * 璐熻矗GPIO鎸夐敭鐨勫垵濮嬪寲鍜屽惊鐜鐞�
+ */
+driver.gpiokey = {
+    /**
+     * 鍒濆鍖朑PIO鎸夐敭
+     * 鍒濆鍖朑PIO鎸夐敭妯″潡
+     */
+    init: function () {
+        dxGpioKey.worker.beforeLoop()
+    },
+    
+    /**
+     * GPIO鎸夐敭寰幆
+     * 鎵цGPIO鎸夐敭鐨勫惊鐜搷浣�
+     */
+    loop: function () {
+        dxGpioKey.worker.loop()
+    },
+}
+/**
+ * 鐪嬮棬鐙楅┍鍔ㄦā鍧�
+ * 璐熻矗绯荤粺鐪嬮棬鐙楃殑鍒濆鍖栧拰鍠傜嫍鎿嶄綔
+ */
+driver.watchdog = {
+    /**
+     * 鍒濆鍖栫湅闂ㄧ嫍
+     * 鍒濆鍖栫湅闂ㄧ嫍妯″潡
+     */
+    init: function () {
+        // watchdog.open(1)
+        // watchdog.enable(1)
+        // watchdog.start(20000)
+    },
+    
+    /**
+     * 鐪嬮棬鐙楀惊鐜�
+     * 鎵ц鐪嬮棬鐙楃殑寰幆鎿嶄綔
+     */
+    loop: function () {
+        // watchdog.loop(1)
+    },
+    
+    /**
+     * 鍠傜嫍
+     * 鍚戠湅闂ㄧ嫍鍙戦�佸杺鐙椾俊鍙凤紝闃叉绯荤粺閲嶅惎
+     * @param {string} flag - 鍠傜嫍鏍囧織
+     * @param {number} timeout - 瓒呮椂鏃堕棿
+     */
+    feed: function (flag, timeout) {
+        // if (utils.isEmpty(this["feedTime" + flag]) || new Date().getTime() - this["feedTime" + flag] > 2000) {
+        //     // 闄嶄綆鍠傜嫍棰戠巼锛岄棿闅�2绉掑杺涓�娆�
+        //     this["feedTime" + flag] = new Date().getTime()
+        //     watchdog.feed(flag, timeout)
+        // }
+    }
+}
+
+/**
+ * 鑷姩閲嶅惎椹卞姩妯″潡
+ * 璐熻矗绯荤粺鐨勮嚜鍔ㄩ噸鍚姛鑳�
+ */
+driver.autoRestart = {
+    /**
+     * 涓婃閲嶅惎妫�鏌ョ殑灏忔椂鏁�
+     */
+    lastRestartCheck: new Date().getHours(),  // 鍒濆鍖栦负褰撳墠灏忔椂鏁帮紝鑰屼笉鏄�0
+    
+    /**
+     * 鍒濆鍖栬嚜鍔ㄩ噸鍚�
+     * 鍒濆鍖栬嚜鍔ㄩ噸鍚ā鍧楋紝璁剧疆瀹氭椂閲嶅惎鍔熻兘
+     */
+    init: function () {
+        // std.setInterval(() => {        // 妫�鏌ユ槸鍚﹂渶瑕佹暣鐐归噸鍚�
+        //     const now = new Date()
+        //     const currentHour = now.getHours()
+        //     // 鍙湁褰撳皬鏃舵暟绛変簬璁惧畾鍊硷紝涓斾笉鏄笂娆℃鏌ヨ繃鐨勫皬鏃舵椂鎵嶆墽琛�
+        //     if (currentHour === 3 && currentHour !== this.lastRestartCheck && now.getMinutes() === 0) {
+        //         common.systemBrief('reboot')
+        //     }
+        //     // 鏇存柊涓婃妫�鏌ョ殑灏忔椂鏁�
+        //     this.lastRestartCheck = currentHour
+        // }, 60000)
+    }
+}
+
+export default driver

--
Gitblit v1.9.3