/**
|
* 粮情服务模块
|
* 负责气体浓度数据获取和状态信息数据获取
|
*/
|
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"
|
import pool from "../../dxmodules/dxWorkerPool.js"
|
import * as os from "os"
|
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 - 请求参数,包含mode和btn
|
* @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.227:80/cgi-bin/safeInputAccess"
|
}
|
|
// 存储气体浓度数据
|
let gasDataStorage = null
|
|
/**
|
* 检查气体浓度
|
* @param {function} callback - 回调函数,在气体浓度检测完成后调用
|
* @returns {boolean} true表示气体浓度合格,false表示气体浓度不合格
|
*/
|
grainService.checkGasConcentration = function(callback) {
|
// 使用setTimeout将HTTP请求放入后台执行,避免阻塞主线程
|
std.setTimeout(() => {
|
try {
|
// 确保URL格式正确,添加http://前缀
|
let url = getHttpUrl()
|
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
url = 'http://' + url
|
}
|
|
const timeout = 3000 // 3秒超时
|
|
logger.info(`[grain]: 正在获取气体浓度数据: ${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]: 发送POST请求数据: ${JSON.stringify(postData)}`)
|
|
// 发送HTTP POST请求
|
let response = http.post(url, postData, timeout)
|
|
// logger.info(`[grain]: 气体浓度数据响应: ${JSON.stringify(response)}`)
|
|
// 解析响应数据
|
// 检查response是否为字符串,如果是则解析为对象
|
if (typeof response === 'string') {
|
response = JSON.parse(response)
|
}
|
|
if (response && response.body) {
|
// 解析响应体
|
let gasData
|
try {
|
gasData = JSON.parse(response.body)
|
logger.info(`[grain]: 解析后的气体浓度数据: ${JSON.stringify(gasData)}`)
|
|
// 根据接口返回编码进行日志输出
|
if (gasData.respCode === respCode.success) {
|
logger.info(`[grain]: 气体浓度检测接口调用成功`)
|
} else {
|
logger.error(`[grain]: 气体浓度检测接口调用失败,返回编码: ${gasData.respCode}, 返回信息: ${gasData.respMsg}`)
|
}
|
} catch (parseError) {
|
logger.error(`[grain]: 解析气体浓度数据失败: ${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]: 气体浓度检测接口调用成功`)
|
} else {
|
logger.error(`[grain]: 气体浓度检测接口调用失败,返回编码: ${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"表示不合格(仅用于UI显示)
|
// 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} 存储的气体浓度数据,如果没有则返回null
|
*/
|
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将HTTP请求放入后台执行,避免阻塞主线程
|
std.setTimeout(() => {
|
try {
|
// 确保URL格式正确,添加http://前缀
|
let url = getHttpUrl()
|
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
url = 'http://' + url
|
}
|
|
const timeout = 3000 // 3秒超时
|
|
// logger.info(`[grain]: 正在获取状态信息数据: ${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]: 发送POST请求数据: ${JSON.stringify(postData)}`)
|
|
// 发送HTTP POST请求
|
let response = http.post(url, postData, timeout)
|
|
// logger.info(`[grain]: 状态信息数据响应: ${JSON.stringify(response)}`)
|
|
// 解析响应数据
|
// 检查response是否为字符串,如果是则解析为对象
|
if (typeof response === 'string') {
|
response = JSON.parse(response)
|
}
|
|
if (response && response.body) {
|
// 解析响应体
|
let statusData
|
try {
|
statusData = JSON.parse(response.body)
|
logger.info(`[grain]: 解析后的状态信息数据: ${JSON.stringify(statusData)}`)
|
|
// 根据接口返回编码进行日志输出
|
if (statusData.respCode === respCode.success) {
|
logger.info(`[grain]: 状态信息接口调用成功`)
|
// 检查data是否为空,不为空才触发通知
|
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]: 状态信息接口调用失败,返回编码: ${statusData.respCode}, 返回信息: ${statusData.respMsg}`)
|
// 检查data是否为空,不为空才触发通知
|
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]: 解析状态信息数据失败: ${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]: 状态信息接口调用成功`)
|
// 检查data是否为空,不为空才触发通知
|
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]: 状态信息接口调用失败,返回编码: ${statusData.respCode}, 返回信息: ${statusData.respMsg}`)
|
// 检查data是否为空,不为空才触发通知
|
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表示控制成功,false表示控制失败
|
*/
|
grainService.controlLight = function(params) {
|
// 使用setTimeout将HTTP请求放入后台执行,避免阻塞主线程
|
std.setTimeout(() => {
|
try {
|
// 确保URL格式正确,添加http://前缀
|
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)}`)
|
|
// 发送HTTP POST请求
|
let response = http.post(url, postData, timeout)
|
|
// 解析响应数据
|
// 检查response是否为字符串,如果是则解析为对象
|
if (typeof response === 'string') {
|
response = JSON.parse(response)
|
}
|
|
if (response && response.body) {
|
// 解析响应体
|
let statusData
|
try {
|
statusData = JSON.parse(response.body)
|
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 (parseError) {
|
logger.error(`[grain]: 解析仓内照明联动控制响应数据失败: ${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将HTTP请求放入后台执行,避免阻塞主线程
|
std.setTimeout(() => {
|
try {
|
// 确保URL格式正确,添加http://前缀
|
let url = getHttpUrl()
|
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
url = 'http://' + url
|
}
|
|
const timeout = 3000 // 3秒超时
|
|
logger.info(`[grain]: 正在发送门磁状态消息: ${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)}`)
|
|
// 发送HTTP POST请求
|
let response = http.post(url, postData, timeout)
|
|
// 解析响应数据
|
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]: 解析门磁状态消息响应失败: ${error.message}`)
|
}
|
} else {
|
logger.info(`[grain]: 门磁状态消息响应为空`)
|
}
|
} catch (error) {
|
logger.error(`[grain]: 发送门磁状态消息失败: ${error.message}`)
|
}
|
}, 0)
|
}
|
|
// 监听门磁状态变化事件,只在主线程中注册
|
// 使用更严格的主线程判断,确保只在主线程中注册一次
|
if (typeof os !== 'undefined' && os.Worker && os.Worker.parent === undefined) {
|
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
|