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/service/grainService.js | 676 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 676 insertions(+), 0 deletions(-)
diff --git a/vf205_access/src/service/grainService.js b/vf205_access/src/service/grainService.js
new file mode 100644
index 0000000..4c5721c
--- /dev/null
+++ b/vf205_access/src/service/grainService.js
@@ -0,0 +1,676 @@
+/**
+ * 绮儏鏈嶅姟妯″潡
+ * 璐熻矗姘斾綋娴撳害鏁版嵁鑾峰彇鍜岀姸鎬佷俊鎭暟鎹幏鍙�
+ */
+import logger from "../../dxmodules/dxLogger.js"
+import config from "../../dxmodules/dxConfig.js"
+import http from "../../dxmodules/dxHttp.js"
+import bus from '../../dxmodules/dxEventBus.js'
+import std from "../../dxmodules/dxStd.js"
+import driver from "../driver.js"
+const grainService = {}
+
+// 浠庨厤缃腑鑾峰彇涓氬姟缂栫爜瀹氫箟
+const functionId = {
+ gasDetection: config.get('functionId.gasDetection') || "1000",
+ safeInputControl: config.get('functionId.safeInputControl') || "2000",
+ lightControl: config.get('functionId.lightControl') || "3000",
+ doorStatus: config.get('functionId.doorStatus') || "4000"
+}
+
+// 浠庨厤缃腑鑾峰彇鎺ュ彛杩斿洖缂栫爜
+const respCode = {
+ success: config.get('respCode.success') || "200",
+ badRequest: config.get('respCode.badRequest') || "400",
+ unauthorized: config.get('respCode.unauthorized') || "401",
+ forbidden: config.get('respCode.forbidden') || "403",
+ notFound: config.get('respCode.notFound') || "404",
+ serverError: config.get('respCode.serverError') || "500"
+}
+
+// 閿欒鐮佸搴旂殑閿欒淇℃伅
+const errorMessages = {
+ "400": "璇锋眰鍙傛暟鏈夎",
+ "401": "鏈櫥褰曪紝鐢ㄦ埛涓嶅瓨鍦�",
+ "403": "鐢ㄦ埛鏃犳潈闄�",
+ "404": "璇锋眰鍔熻兘涓嶅瓨鍦�",
+ "500": "璇锋眰鎵ц寮傚父锛岃鑱旂郴绠$悊鍛�"
+}
+
+// 鎿嶄綔鎸夐挳瀵瑰簲鐨勮闊虫枃浠�
+const voiceFiles = {
+ // 鍏佽杩涗粨妯″紡
+ "11": "btn11.wav", // 鍏佽杩涗粨妯″紡
+ "12": "btn12.wav", // 鍏ヤ粨
+ "13": "btn13.wav", // 鍑轰粨
+ // 鍐閫氶妯″紡
+ "21": "btn21.wav", // 鍐閫氶妯″紡
+ "22": "btn22.wav", // 鍚姩
+ "23": "btn23.wav", // 鍏抽棴
+ // 绂佹杩涗粨妯″紡
+ "31": "btn31.wav", // 绂佹杩涗粨妯″紡
+ "32": "btn32.wav", // 绱ф�ュ叆浠�
+ "33": "btn33.wav", // 鍑轰粨
+ // 鐓ф槑鎺у埗
+ "light_open": "light_open.wav", // 寮�鐏�
+ "light_close": "light_close.wav" // 鍏崇伅
+}
+
+/**
+ * 鏍规嵁閿欒鐮佽幏鍙栭敊璇俊鎭�
+ * @param {string} code - 閿欒鐮�
+ * @returns {string} 閿欒淇℃伅
+ */
+function getErrorMessage(code) {
+ return errorMessages[code] || "鎿嶄綔澶辫触"
+}
+
+/**
+ * 鏍规嵁鎿嶄綔鎸夐挳鍜屽姛鑳界爜鑾峰彇璇煶鏂囦欢
+ * @param {string} functionId - 鍔熻兘鐮�
+ * @param {object} params - 璇锋眰鍙傛暟锛屽寘鍚玬ode鍜宐tn
+ * @returns {string} 璇煶鏂囦欢璺緞
+ */
+function getVoiceFile(functionId, params) {
+ // 鐓ф槑鎺у埗鍔熻兘
+ if (functionId === "3000") {
+ // 寮�鐏�
+ if (String(params.btn) === "1") return voiceFiles["light_open"]
+ // 鍏崇伅
+ if (String(params.btn) === "2") return voiceFiles["light_close"]
+ }
+ // 瀹夊叏鍏ヤ粨鎺у埗鍔熻兘
+ if (functionId === "2000" && params) {
+ const { mode, btn } = params
+ // 妯″紡1: 鍏佽杩涗粨妯″紡
+ if (mode === 1) {
+ if (!btn) return voiceFiles["11"] // 鍏佽杩涗粨妯″紡鎸夐挳
+ if (String(btn) === "1") return voiceFiles["12"] // 鍏ヤ粨鎸夐挳
+ if (String(btn) === "2") return voiceFiles["13"] // 鍑轰粨鎸夐挳
+ }
+ // 妯″紡2: 鍐閫氶妯″紡
+ if (mode === 2) {
+ if (!btn) return voiceFiles["21"] // 鍐閫氶妯″紡鎸夐挳
+ if (String(btn) === "1") return voiceFiles["22"] // 鍚姩鎸夐挳
+ if (String(btn) === "2") return voiceFiles["23"] // 鍏抽棴鎸夐挳
+ }
+ // 妯″紡3: 绂佹杩涗粨妯″紡
+ if (mode === 3) {
+ if (!btn) return voiceFiles["31"] // 绂佹杩涗粨妯″紡鎸夐挳
+ if (String(btn) === "1") return voiceFiles["32"] // 绱ф�ュ叆浠撴寜閽�
+ if (String(btn) === "2") return voiceFiles["33"] // 鍑轰粨鎸夐挳
+ }
+ }
+ return null
+}
+
+// 浠庨厤缃腑鑾峰彇HTTP鎺ュ彛璺緞
+function getHttpUrl() {
+ return config.get('http.safeInputAccess') || "http://192.168.1.199:80/cgi-bin/safeInputAccess"
+}
+
+// 瀛樺偍姘斾綋娴撳害鏁版嵁
+let gasDataStorage = null
+
+/**
+ * 妫�鏌ユ皵浣撴祿搴�
+ * @param {function} callback - 鍥炶皟鍑芥暟锛屽湪姘斾綋娴撳害妫�娴嬪畬鎴愬悗璋冪敤
+ * @returns {boolean} true琛ㄧず姘斾綋娴撳害鍚堟牸锛宖alse琛ㄧず姘斾綋娴撳害涓嶅悎鏍�
+ */
+grainService.checkGasConcentration = function(callback) {
+ // 浣跨敤setTimeout灏咹TTP璇锋眰鏀惧叆鍚庡彴鎵ц锛岄伩鍏嶉樆濉炰富绾跨▼
+ std.setTimeout(() => {
+ try {
+ // 纭繚URL鏍煎紡姝g‘锛屾坊鍔爃ttp://鍓嶇紑
+ let url = getHttpUrl()
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
+ url = 'http://' + url
+ }
+
+ const timeout = 3000 // 3绉掕秴鏃�
+
+ logger.info(`[grain]: 姝e湪鑾峰彇姘斾綋娴撳害鏁版嵁: ${url}`)
+
+ // 鏋勫缓POST璇锋眰鏁版嵁
+ const postData = {
+ sn: config.get("sys.sn") || " ", // 璁惧搴忓垪鍙凤紝浠庨厤缃腑鑾峰彇
+ houseId: "0000", // 浠撳粧缂栫爜锛岄粯璁ゅ~鍏�"0000"
+ outId: "0000", // 鑷畾涔夌紪鐮侊紝榛樿濉厖"0000"
+ functionId: functionId.gasDetection, // 姘斾綋娴撳害妫�娴嬪姛鑳界爜
+ timestamp: Date.now().toString() // 鏃堕棿鎴�
+ }
+
+ logger.info(`[grain]: 鍙戦�丳OST璇锋眰鏁版嵁: ${JSON.stringify(postData)}`)
+
+ // 鍙戦�丠TTP POST璇锋眰
+ let response = http.post(url, postData, timeout)
+
+ // logger.info(`[grain]: 姘斾綋娴撳害鏁版嵁鍝嶅簲: ${JSON.stringify(response)}`)
+
+ // 瑙f瀽鍝嶅簲鏁版嵁
+ // 妫�鏌esponse鏄惁涓哄瓧绗︿覆锛屽鏋滄槸鍒欒В鏋愪负瀵硅薄
+ if (typeof response === 'string') {
+ response = JSON.parse(response)
+ }
+
+ if (response && response.body) {
+ // 瑙f瀽鍝嶅簲浣�
+ let gasData
+ try {
+ gasData = JSON.parse(response.body)
+ logger.info(`[grain]: 瑙f瀽鍚庣殑姘斾綋娴撳害鏁版嵁: ${JSON.stringify(gasData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (gasData.respCode === respCode.success) {
+ logger.info(`[grain]: 姘斾綋娴撳害妫�娴嬫帴鍙h皟鐢ㄦ垚鍔焋)
+ } else {
+ logger.error(`[grain]: 姘斾綋娴撳害妫�娴嬫帴鍙h皟鐢ㄥけ璐ワ紝杩斿洖缂栫爜: ${gasData.respCode}, 杩斿洖淇℃伅: ${gasData.respMsg}`)
+ }
+ } catch (parseError) {
+ logger.error(`[grain]: 瑙f瀽姘斾綋娴撳害鏁版嵁澶辫触: ${parseError.message}`)
+ // 灏濊瘯娓呯悊鍝嶅簲浣撲腑鐨勮浆涔夊瓧绗�
+ try {
+ // 绉婚櫎澶氫綑鐨勮浆涔夊瓧绗�
+ const cleanedBody = response.body.replace(/\\r\\n/g, '').replace(/\\t/g, '').replace(/\"/g, '"')
+ gasData = JSON.parse(cleanedBody)
+ logger.info(`[grain]: 娓呯悊鍚庤В鏋愮殑姘斾綋娴撳害鏁版嵁: ${JSON.stringify(gasData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (gasData.respCode === respCode.success) {
+ logger.info(`[grain]: 姘斾綋娴撳害妫�娴嬫帴鍙h皟鐢ㄦ垚鍔焋)
+ } else {
+ logger.error(`[grain]: 姘斾綋娴撳害妫�娴嬫帴鍙h皟鐢ㄥけ璐ワ紝杩斿洖缂栫爜: ${gasData.respCode}, 杩斿洖淇℃伅: ${gasData.respMsg}`)
+ }
+ } catch (cleanError) {
+ logger.error(`[grain]: 娓呯悊鍚庤В鏋愭皵浣撴祿搴︽暟鎹粛澶辫触: ${cleanError.message}`)
+ // 璋冪敤鍥炶皟鍑芥暟
+ if (callback) {
+ callback()
+ }
+ return
+ }
+ }
+
+ // 瀛樺偍姘斾綋鏁版嵁
+ gasDataStorage = gasData
+
+ // 妫�鏌ユ皵浣撴祿搴︽槸鍚﹀悎鏍�
+ // 鏂版牸寮�: {"value":[{"o2":"20.5","statusO2":"0","co2":"401","statusCo2":"0","ph3":"0","statusPh3":"0"}],"status":"1"}
+ // statusO2/statusCo2/statusPh3: "0"琛ㄧず鍚堟牸锛�"1"琛ㄧず涓嶅悎鏍硷紙浠呯敤浜嶶I鏄剧ず锛�
+ // data.status: "0"琛ㄧず鏈�缁堝悎鏍硷紝"1"琛ㄧず鏈�缁堜笉鍚堟牸
+ const gasValue = gasData.data && gasData.data.value ? gasData.data.value[0] : null
+ const isO2Qualified = gasValue && gasValue.statusO2 === "0"
+ const isCo2Qualified = gasValue && gasValue.statusCo2 === "0"
+ const isPh3Qualified = gasValue && gasValue.statusPh3 === "0"
+
+ // 瑙﹀彂浜嬩欢鏇存柊UI
+ bus.fire('gasConcentrationUpdated', gasData)
+
+ // 鏈�缁堝悎鏍煎垽鏂彧渚濊禆status瀛楁鍊�
+ const isAllQualified = gasData.data && gasData.data.status === "0"
+
+ if (isAllQualified) {
+ logger.info("[grain]: 姘斾綋娴撳害妫�娴嬪悎鏍�")
+ } else {
+ logger.info("[grain]: 姘斾綋娴撳害妫�娴嬩笉鍚堟牸")
+ }
+
+ // 璋冪敤鍥炶皟鍑芥暟
+ if (callback) {
+ callback()
+ }
+ } else {
+ logger.error(`[grain]: 姘斾綋娴撳害鏁版嵁鑾峰彇澶辫触: ${response ? "鏃犲搷搴斾綋" : "鏃犲搷搴�"}`)
+ // 璋冪敤鍥炶皟鍑芥暟
+ if (callback) {
+ callback()
+ }
+ }
+ } catch (error) {
+ logger.error(`[grain]: 姘斾綋娴撳害妫�娴嬮敊璇�: ${error.message}`)
+ // 璋冪敤鍥炶皟鍑芥暟
+ if (callback) {
+ callback()
+ }
+ }
+ }, 0)
+
+ // 绔嬪嵆杩斿洖锛岄伩鍏嶉樆濉炰富绾跨▼
+ return true
+}
+
+/**
+ * 鑾峰彇瀛樺偍鐨勬皵浣撴祿搴︽暟鎹�
+ * @returns {object|null} 瀛樺偍鐨勬皵浣撴祿搴︽暟鎹紝濡傛灉娌℃湁鍒欒繑鍥瀗ull
+ */
+grainService.getGasData = function() {
+ return gasDataStorage
+}
+
+/**
+ * 妫�鏌ヨ澶囩姸鎬佷俊鎭�
+ * @param {object} params - 璇锋眰鍙傛暟
+ * @param {string} params.user1 - 浜鸿劯璇嗗埆鐢ㄦ埛1
+ * @param {string} params.user2 - 浜鸿劯璇嗗埆鐢ㄦ埛2
+ * @param {string} params.mode - 閫夋嫨妯″紡锛�1-鍏佽鍏ヤ粨锛�2-鍐閫氶锛�3-绂佹鍏ヤ粨锛�
+ * @param {string} params.btn - 鎿嶄綔鎸夐挳锛�1-鍏ヤ粨/寮�鍚紱2-鍑轰粨/鍏抽棴锛�
+ * @returns {boolean} true琛ㄧず鐘舵�佷俊鎭幏鍙栨垚鍔燂紝false琛ㄧず澶辫触
+ */
+grainService.checkDevConcentration = function(params) {
+ // 浣跨敤setTimeout灏咹TTP璇锋眰鏀惧叆鍚庡彴鎵ц锛岄伩鍏嶉樆濉炰富绾跨▼
+ std.setTimeout(() => {
+ try {
+ // 纭繚URL鏍煎紡姝g‘锛屾坊鍔爃ttp://鍓嶇紑
+ let url = getHttpUrl()
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
+ url = 'http://' + url
+ }
+
+ const timeout = 3000 // 3绉掕秴鏃�
+
+ // logger.info(`[grain]: 姝e湪鑾峰彇鐘舵�佷俊鎭暟鎹�: ${url}`)
+
+ // 鏋勫缓POST璇锋眰鏁版嵁
+ const postData = {
+ sn: config.get("sys.sn") || " ", // 璁惧搴忓垪鍙凤紝浠庨厤缃腑鑾峰彇
+ houseId: "0000", // 浠撳粧缂栫爜锛岄粯璁ゅ~鍏�"0000"
+ outId: "0000", // 鑷畾涔夌紪鐮侊紝榛樿濉厖"0000"
+ functionId: params && params.functionId ? params.functionId : functionId.safeInputControl, // 鍔熻兘鐮侊紝榛樿涓哄畨鍏ㄥ叆浠撹仈鍔ㄦ帶鍒�
+ timestamp: Date.now().toString(), // 鏃堕棿鎴�
+ data: {}
+ }
+
+ // 娣诲姞鍙�夊弬鏁�
+ if (params) {
+ if (params.user1) postData.data.user1 = params.user1
+ if (params.user2) postData.data.user2 = params.user2
+ if (params.mode) postData.data.mode = params.mode
+ if (params.btn) postData.data.btn = params.btn
+ }
+
+ logger.info(`[grain]: 鍙戦�丳OST璇锋眰鏁版嵁: ${JSON.stringify(postData)}`)
+
+ // 鍙戦�丠TTP POST璇锋眰
+ let response = http.post(url, postData, timeout)
+
+ // logger.info(`[grain]: 鐘舵�佷俊鎭暟鎹搷搴�: ${JSON.stringify(response)}`)
+
+ // 瑙f瀽鍝嶅簲鏁版嵁
+ // 妫�鏌esponse鏄惁涓哄瓧绗︿覆锛屽鏋滄槸鍒欒В鏋愪负瀵硅薄
+ if (typeof response === 'string') {
+ response = JSON.parse(response)
+ }
+
+ if (response && response.body) {
+ // 瑙f瀽鍝嶅簲浣�
+ let statusData
+ try {
+ statusData = JSON.parse(response.body)
+ logger.info(`[grain]: 瑙f瀽鍚庣殑鐘舵�佷俊鎭暟鎹�: ${JSON.stringify(statusData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (statusData.respCode === respCode.success) {
+ logger.info(`[grain]: 鐘舵�佷俊鎭帴鍙h皟鐢ㄦ垚鍔焋)
+ // 妫�鏌ata鏄惁涓虹┖锛屼笉涓虹┖鎵嶈Е鍙戦�氱煡
+ if (Object.keys(postData.data).length > 0) {
+ // 瑙﹀彂鎴愬姛寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: true,
+ message: '*鎵ц鎴愬姛*'
+ })
+
+ // 鎾斁鎴愬姛璇煶鎻愮ず
+ try {
+ const voiceFile = getVoiceFile(postData.functionId, postData.data)
+ if (voiceFile) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/${voiceFile}`)
+ logger.info(`[grain]: 鎾斁鎴愬姛璇煶鎻愮ず: ${voiceFile}`)
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ } else {
+ logger.error(`[grain]: 鐘舵�佷俊鎭帴鍙h皟鐢ㄥけ璐ワ紝杩斿洖缂栫爜: ${statusData.respCode}, 杩斿洖淇℃伅: ${statusData.respMsg}`)
+ // 妫�鏌ata鏄惁涓虹┖锛屼笉涓虹┖鎵嶈Е鍙戦�氱煡
+ if (Object.keys(postData.data).length > 0) {
+ // 瑙﹀彂澶辫触寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: false,
+ message: statusData.respMsg || getErrorMessage(statusData.respCode)
+ })
+ // 鎾斁澶辫触璇煶鎻愮ず
+ try {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/failed.wav`)
+ logger.info(`[grain]: 鎾斁澶辫触璇煶鎻愮ず: failed.wav`)
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ }
+ } catch (parseError) {
+ logger.error(`[grain]: 瑙f瀽鐘舵�佷俊鎭暟鎹け璐�: ${parseError.message}`)
+ // 灏濊瘯娓呯悊鍝嶅簲浣撲腑鐨勮浆涔夊瓧绗�
+ try {
+ // 绉婚櫎澶氫綑鐨勮浆涔夊瓧绗�
+ const cleanedBody = response.body.replace(/\\r\\n/g, '').replace(/\\t/g, '').replace(/\"/g, '"')
+ statusData = JSON.parse(cleanedBody)
+ logger.info(`[grain]: 娓呯悊鍚庤В鏋愮殑鐘舵�佷俊鎭暟鎹�: ${JSON.stringify(statusData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (statusData.respCode === respCode.success) {
+ logger.info(`[grain]: 鐘舵�佷俊鎭帴鍙h皟鐢ㄦ垚鍔焋)
+ // 妫�鏌ata鏄惁涓虹┖锛屼笉涓虹┖鎵嶈Е鍙戦�氱煡
+ if (Object.keys(postData.data).length > 0) {
+ // 瑙﹀彂鎴愬姛寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: true,
+ message: '*鎵ц鎴愬姛*'
+ })
+
+ // 鎾斁鎴愬姛璇煶鎻愮ず
+ try {
+ const voiceFile = getVoiceFile(postData.functionId, postData.data)
+ if (voiceFile) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/${voiceFile}`)
+ logger.info(`[grain]: 鎾斁鎴愬姛璇煶鎻愮ず: ${voiceFile}`)
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ } else {
+ logger.error(`[grain]: 鐘舵�佷俊鎭帴鍙h皟鐢ㄥけ璐ワ紝杩斿洖缂栫爜: ${statusData.respCode}, 杩斿洖淇℃伅: ${statusData.respMsg}`)
+ // 妫�鏌ata鏄惁涓虹┖锛屼笉涓虹┖鎵嶈Е鍙戦�氱煡
+ if (Object.keys(postData.data).length > 0) {
+ // 瑙﹀彂澶辫触寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: false,
+ message: statusData.respMsg || getErrorMessage(statusData.respCode)
+ })
+ // 鎾斁澶辫触璇煶鎻愮ず
+ try {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/failed.wav`)
+ logger.info(`[grain]: 鎾斁澶辫触璇煶鎻愮ず: failed.wav`)
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ }
+ } catch (cleanError) {
+ logger.error(`[grain]: 娓呯悊鍚庤В鏋愮姸鎬佷俊鎭暟鎹粛澶辫触: ${cleanError.message}`)
+ return false
+ }
+ }
+
+ // 瑙﹀彂浜嬩欢鏇存柊UI
+ bus.fire('statusInfoUpdated', statusData)
+
+ return true
+ } else {
+ logger.error(`[grain]: 鐘舵�佷俊鎭暟鎹幏鍙栧け璐�: ${response ? "鏃犲搷搴斾綋" : "鏃犲搷搴�"}`)
+ // 缃戠粶璇锋眰澶辫触鏃讹紝榛樿杩斿洖false锛堝畨鍏ㄨ捣瑙侊級
+ return false
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鐘舵�佷俊鎭娴嬮敊璇�: ${error.message}`)
+ // 鍙戠敓閿欒鏃讹紝榛樿杩斿洖false锛堝畨鍏ㄨ捣瑙侊級
+ return false
+ }
+ }, 0)
+
+ // 绔嬪嵆杩斿洖锛岄伩鍏嶉樆濉炰富绾跨▼
+ return true
+}
+
+/**
+ * 浠撳唴鐓ф槑鑱斿姩鎺у埗
+ * @param {object} params - 璇锋眰鍙傛暟
+ * @param {string} params.user1 - 浜鸿劯璇嗗埆鐢ㄦ埛1
+ * @param {string} params.user2 - 浜鸿劯璇嗗埆鐢ㄦ埛2
+ * @param {string} params.btn - 鎿嶄綔鎸夐挳锛�1-寮�鐏紱2-鍏崇伅锛�
+ * @returns {boolean} true琛ㄧず鎺у埗鎴愬姛锛宖alse琛ㄧず鎺у埗澶辫触
+ */
+grainService.controlLight = function(params) {
+ // 浣跨敤setTimeout灏咹TTP璇锋眰鏀惧叆鍚庡彴鎵ц锛岄伩鍏嶉樆濉炰富绾跨▼
+ std.setTimeout(() => {
+ try {
+ // 纭繚URL鏍煎紡姝g‘锛屾坊鍔爃ttp://鍓嶇紑
+ let url = getHttpUrl()
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
+ url = 'http://' + url
+ }
+
+ const timeout = 3000 // 3绉掕秴鏃�
+
+ // 鏋勫缓POST璇锋眰鏁版嵁
+ const postData = {
+ sn: config.get("sys.sn") || " ", // 璁惧搴忓垪鍙凤紝浠庨厤缃腑鑾峰彇
+ houseId: "0000", // 浠撳粧缂栫爜锛岄粯璁ゅ~鍏�"0000"
+ outId: "0000", // 鑷畾涔夌紪鐮侊紝榛樿濉厖"0000"
+ functionId: functionId.lightControl, // 浠撳唴鐓ф槑鑱斿姩鎺у埗鍔熻兘鐮�
+ timestamp: Date.now().toString(), // 鏃堕棿鎴�
+ data: {}
+ }
+
+ // 娣诲姞鍙�夊弬鏁�
+ if (params) {
+ if (params.user1) postData.data.user1 = params.user1
+ if (params.user2) postData.data.user2 = params.user2
+ if (params.btn) postData.data.btn = params.btn
+ }
+
+ logger.info(`[grain]: 鍙戦�佷粨鍐呯収鏄庤仈鍔ㄦ帶鍒惰姹傛暟鎹�: ${JSON.stringify(postData)}`)
+
+ // 鍙戦�丠TTP POST璇锋眰
+ let response = http.post(url, postData, timeout)
+
+ // 瑙f瀽鍝嶅簲鏁版嵁
+ // 妫�鏌esponse鏄惁涓哄瓧绗︿覆锛屽鏋滄槸鍒欒В鏋愪负瀵硅薄
+ if (typeof response === 'string') {
+ response = JSON.parse(response)
+ }
+
+ if (response && response.body) {
+ // 瑙f瀽鍝嶅簲浣�
+ let statusData
+ try {
+ statusData = JSON.parse(response.body)
+ logger.info(`[grain]: 瑙f瀽鍚庣殑浠撳唴鐓ф槑鑱斿姩鎺у埗鍝嶅簲鏁版嵁: ${JSON.stringify(statusData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (statusData.respCode === respCode.success) {
+ logger.info(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗鎺ュ彛璋冪敤鎴愬姛`)
+ // 瑙﹀彂鎴愬姛寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: true,
+ message: '*鎵ц鎴愬姛*'
+ })
+
+ // 鎾斁鎴愬姛璇煶鎻愮ず
+ try {
+ const voiceFile = getVoiceFile(postData.functionId, postData.data)
+ if (voiceFile) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/${voiceFile}`)
+ logger.info(`[grain]: 鎾斁鎴愬姛璇煶鎻愮ず: ${voiceFile}`)
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ } else {
+ logger.error(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗鎺ュ彛璋冪敤澶辫触锛岃繑鍥炵紪鐮�: ${statusData.respCode}, 杩斿洖淇℃伅: ${statusData.respMsg}`)
+ // 瑙﹀彂澶辫触寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: false,
+ message: statusData.respMsg || getErrorMessage(statusData.respCode)
+ })
+ // 鎾斁澶辫触璇煶鎻愮ず
+ try {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/failed.wav`)
+ logger.info(`[grain]: 鎾斁澶辫触璇煶鎻愮ず: failed.wav`)
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ } catch (parseError) {
+ logger.error(`[grain]: 瑙f瀽浠撳唴鐓ф槑鑱斿姩鎺у埗鍝嶅簲鏁版嵁澶辫触: ${parseError.message}`)
+ // 灏濊瘯娓呯悊鍝嶅簲浣撲腑鐨勮浆涔夊瓧绗�
+ try {
+ // 绉婚櫎澶氫綑鐨勮浆涔夊瓧绗�
+ const cleanedBody = response.body.replace(/\\r\\n/g, '').replace(/\\t/g, '').replace(/\"/g, '"')
+ statusData = JSON.parse(cleanedBody)
+ logger.info(`[grain]: 娓呯悊鍚庤В鏋愮殑浠撳唴鐓ф槑鑱斿姩鎺у埗鍝嶅簲鏁版嵁: ${JSON.stringify(statusData)}`)
+
+ // 鏍规嵁鎺ュ彛杩斿洖缂栫爜杩涜鏃ュ織杈撳嚭
+ if (statusData.respCode === respCode.success) {
+ logger.info(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗鎺ュ彛璋冪敤鎴愬姛`)
+ // 瑙﹀彂鎴愬姛寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: true,
+ message: '*鎵ц鎴愬姛*'
+ })
+
+ // 鎾斁鎴愬姛璇煶鎻愮ず
+ try {
+ const voiceFile = getVoiceFile(postData.functionId, postData.data)
+ if (voiceFile) {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/${voiceFile}`)
+ logger.info(`[grain]: 鎾斁鎴愬姛璇煶鎻愮ず: ${voiceFile}`)
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ } else {
+ logger.error(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗鎺ュ彛璋冪敤澶辫触锛岃繑鍥炵紪鐮�: ${statusData.respCode}, 杩斿洖淇℃伅: ${statusData.respMsg}`)
+ // 瑙﹀彂澶辫触寮圭獥
+ bus.fire('showAccessResult', {
+ faceAuth: true,
+ gasConcentration: true,
+ accessAllowed: false,
+ message: statusData.respMsg || getErrorMessage(statusData.respCode)
+ })
+ // 鎾斁澶辫触璇煶鎻愮ず
+ try {
+ driver.alsa.play(`/app/code/resource/${config.get("base.language") == "CN" ? "CN" : "EN"}/wav/failed.wav`)
+ logger.info(`[grain]: 鎾斁澶辫触璇煶鎻愮ず: failed.wav`)
+ } catch (error) {
+ logger.error(`[grain]: 鎾斁璇煶鎻愮ず澶辫触: ${error.message}`)
+ }
+ }
+ } catch (cleanError) {
+ logger.error(`[grain]: 娓呯悊鍚庤В鏋愪粨鍐呯収鏄庤仈鍔ㄦ帶鍒跺搷搴旀暟鎹粛澶辫触: ${cleanError.message}`)
+ return false
+ }
+ }
+
+ // 瑙﹀彂浜嬩欢鏇存柊UI
+ bus.fire('statusInfoUpdated', statusData)
+
+ return true
+ } else {
+ logger.error(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗璇锋眰澶辫触: ${response ? "鏃犲搷搴斾綋" : "鏃犲搷搴�"}`)
+ // 缃戠粶璇锋眰澶辫触鏃讹紝榛樿杩斿洖false锛堝畨鍏ㄨ捣瑙侊級
+ return false
+ }
+ } catch (error) {
+ logger.error(`[grain]: 浠撳唴鐓ф槑鑱斿姩鎺у埗閿欒: ${error.message}`)
+ // 鍙戠敓閿欒鏃讹紝榛樿杩斿洖false锛堝畨鍏ㄨ捣瑙侊級
+ return false
+ }
+ }, 0)
+
+ // 绔嬪嵆杩斿洖锛岄伩鍏嶉樆濉炰富绾跨▼
+ return true
+}
+
+/**
+ * 鍙戦�侀棬纾佺姸鎬佹秷鎭�
+ * @param {object} doorStatusData - 闂ㄧ鐘舵�佹暟鎹�
+ * @param {number} doorStatusData.status - 闂ㄧ鐘舵�侊紝0琛ㄧず闂ㄥ叧锛�1琛ㄧず闂ㄥ紑
+ * @param {string} doorStatusData.statusText - 闂ㄧ鐘舵�佹枃鏈�
+ * @param {number} doorStatusData.time - 鏃堕棿鎴�
+ */
+grainService.sendDoorStatusMessage = function(doorStatusData) {
+ // 浣跨敤setTimeout灏咹TTP璇锋眰鏀惧叆鍚庡彴鎵ц锛岄伩鍏嶉樆濉炰富绾跨▼
+ std.setTimeout(() => {
+ try {
+ // 纭繚URL鏍煎紡姝g‘锛屾坊鍔爃ttp://鍓嶇紑
+ let url = getHttpUrl()
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
+ url = 'http://' + url
+ }
+
+ const timeout = 3000 // 3绉掕秴鏃�
+
+ logger.info(`[grain]: 姝e湪鍙戦�侀棬纾佺姸鎬佹秷鎭�: ${url}`)
+
+ // 鏋勫缓POST璇锋眰鏁版嵁
+ const postData = {
+ sn: config.get("sys.sn") || " ", // 璁惧搴忓垪鍙凤紝浠庨厤缃腑鑾峰彇
+ houseId: "0000", // 浠撳粧缂栫爜锛岄粯璁ゅ~鍏�"0000"
+ outId: "0000", // 鑷畾涔夌紪鐮侊紝榛樿濉厖"0000"
+ functionId: functionId.doorStatus, // 闂ㄧ鐘舵�佸姛鑳界爜
+ timestamp: Date.now().toString(), // 鏃堕棿鎴�
+ data: {
+ doorStatus: doorStatusData.status // 闂ㄧ鐘舵��
+ }
+ }
+
+ logger.info(`[grain]: 鍙戦�侀棬纾佺姸鎬佹秷鎭暟鎹�: ${JSON.stringify(postData)}`)
+
+ // 鍙戦�丠TTP POST璇锋眰
+ let response = http.post(url, postData, timeout)
+
+ // 瑙f瀽鍝嶅簲鏁版嵁
+ if (typeof response === 'string') {
+ response = JSON.parse(response)
+ }
+
+ if (response && response.body) {
+ let respData
+ try {
+ respData = JSON.parse(response.body)
+ logger.info(`[grain]: 闂ㄧ鐘舵�佹秷鎭搷搴�: ${JSON.stringify(respData)}`)
+ } catch (error) {
+ logger.error(`[grain]: 瑙f瀽闂ㄧ鐘舵�佹秷鎭搷搴斿け璐�: ${error.message}`)
+ }
+ } else {
+ logger.info(`[grain]: 闂ㄧ鐘舵�佹秷鎭搷搴斾负绌篳)
+ }
+ } catch (error) {
+ logger.error(`[grain]: 鍙戦�侀棬纾佺姸鎬佹秷鎭け璐�: ${error.message}`)
+ }
+ }, 0)
+}
+
+// 鐩戝惉闂ㄧ鐘舵�佸彉鍖栦簨浠�
+bus.on('doorStatusChanged', (doorStatusData) => {
+ logger.info(`[grain]: 鎺ユ敹鍒伴棬纾佺姸鎬佸彉鍖栦簨浠�: ${JSON.stringify(doorStatusData)}`)
+ // 璋冪敤鍙戦�侀棬纾佺姸鎬佹秷鎭殑鍑芥暟
+ try {
+ if (typeof grainService.sendDoorStatusMessage === 'function') {
+ grainService.sendDoorStatusMessage(doorStatusData)
+ } else {
+ logger.error('[grain]: sendDoorStatusMessage 涓嶆槸涓�涓嚱鏁�')
+ logger.error('[grain]: grainService.sendDoorStatusMessage =', grainService.sendDoorStatusMessage)
+ }
+ } catch (error) {
+ logger.error('[grain]: 璋冪敤sendDoorStatusMessage鍑洪敊:', error.message)
+ }
+})
+
+export default grainService
\ No newline at end of file
--
Gitblit v1.9.3