Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Q
qingdaoMuseumPlatform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
node_server
qingdaoMuseumPlatform
Commits
37602267
Commit
37602267
authored
Jun 18, 2026
by
PC-20251223ZVQQ\Administrator
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
客流数据接入
parent
8874fba1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
157 additions
and
13 deletions
+157
-13
serverConfig.xml
serverConfig.xml
+2
-1
device.ts
src/biz/device.ts
+0
-0
mqttClient.ts
src/biz/mqttClient.ts
+117
-1
running.ts
src/biz/running.ts
+1
-1
serverConfig.ts
src/config/serverConfig.ts
+4
-3
systemClass.ts
src/config/systemClass.ts
+2
-1
device.ts
src/routers/device.ts
+14
-0
mqttInit.ts
src/service/mqttInit.ts
+17
-6
No files found.
serverConfig.xml
View file @
37602267
...
...
@@ -19,7 +19,8 @@
<mqttsrv>
<mqttHost>
10.100.48.16
</mqttHost>
<mqttPort>
1883
</mqttPort>
<mqttTopic>
/milesight/uplink/2026
</mqttTopic>
<mqttTopic1>
/milesight/uplink/2026
</mqttTopic1>
<mqttTopic2>
/milesight/uplink/2026_crowd
</mqttTopic2>
<username>
admin
</username>
<password>
admin123
</password>
</mqttsrv>
...
...
src/biz/device.ts
View file @
37602267
This diff is collapsed.
Click to expand it.
src/biz/mqttClient.ts
View file @
37602267
...
...
@@ -38,7 +38,7 @@ export async function processDeviceData(message) {
console
.
log
(
'收到数据:'
,
data
);
// 提取关键字段
const
devEUI
=
data
.
devEUI
;
const
devEUI
=
data
.
devEUI
?
data
.
devEUI
.
toUpperCase
()
:
null
;
if
(
!
devEUI
)
{
console
.
warn
(
'消息缺少devEUI字段,跳过'
);
return
;
...
...
@@ -93,6 +93,122 @@ export async function processDeviceData(message) {
}
}
/**
* 处理接收到的客流设备数据,并存入数据库
*
* 消息示例:
* {
* device_info: {
* device_mac: 'C0:BA:1F:02:98:F6',
* device_name: 'People Counter',
* device_sn: '6537F53875140008',
* firmware_version: 'V_125-LW.1.0.3-r4',
* hardware_version: 'V1.1',
* ip_address: '192.168.125.114',
* running_time: 4764787,
* wlan_mac: 'C0:BA:1F:02:98:F7'
* },
* region_trigger_data: { region_count_data: [ { region: 1, region_name: 'Region1', region_uuid: 'b63ffafc-857f-4d12-9dc7-d7fddfeb5f0f', total: { current_total: 9 } } ] },
* time_info: {
* dst_status: false,
* enable_dst: false,
* time: '2026-06-18T05:19:23-00:00',
* time_zone: 'UTC-0:00 Western European Time (WET), Greenwich Mean Time (GMT)'
* }
* }
*/
export
async
function
customerDeviceData
(
message
)
{
try
{
// 解析JSON消息
const
msgStr
=
message
.
toString
();
let
data
:
any
;
try
{
data
=
JSON
.
parse
(
msgStr
);
}
catch
(
e
)
{
console
.
error
(
'消息不是合法JSON,跳过:'
,
msgStr
);
return
;
}
console
.
log
(
'收到客流数据:'
,
data
);
// 提取设备信息
const
deviceInfo
=
data
.
device_info
;
if
(
!
deviceInfo
)
{
console
.
warn
(
'消息缺少device_info字段,跳过'
);
return
;
}
const
deviceSn
=
deviceInfo
.
device_sn
?
deviceInfo
.
device_sn
.
toUpperCase
()
:
null
;
// 设备序列号,转大写作为设备标识
if
(
!
deviceSn
)
{
console
.
warn
(
'消息缺少device_info.device_sn字段,跳过'
);
return
;
}
const
deviceMac
=
deviceInfo
.
device_mac
;
const
deviceName
=
deviceInfo
.
device_name
||
`客流设备_
${
deviceSn
.
slice
(
-
6
)}
`
;
// 提取设备时间
const
timeInfo
=
data
.
time_info
;
const
deviceTime
=
timeInfo
&&
timeInfo
.
time
?
new
Date
(
timeInfo
.
time
)
:
new
Date
();
// ===== 提取客流数据 =====
const
regionTriggerData
=
data
.
region_trigger_data
;
if
(
!
regionTriggerData
||
!
regionTriggerData
.
region_count_data
||
regionTriggerData
.
region_count_data
.
length
===
0
)
{
console
.
warn
(
'消息缺少客流区域数据,跳过'
);
return
;
}
const
regionCountData
=
regionTriggerData
.
region_count_data
;
const
now
=
new
Date
();
// ===== 设备校验/新增 =====
const
deviceRow
=
await
selectOneDataByParam
(
TABLENAME
.
设备表
,
{
device_id
:
deviceSn
}
);
if
(
!
deviceRow
)
{
// 设备不存在,为每个区域创建一条设备记录
for
(
const
regionData
of
regionCountData
)
{
await
addData
(
TABLENAME
.
设备表
,
{
device_id
:
deviceSn
,
region_key
:
regionData
.
region
,
device_type
:
'客流传感器'
,
device_name
:
deviceName
,
control_params
:
data
,
created_at
:
now
,
updated_at
:
now
,
}
);
console
.
log
(
`客流设备已创建:
${
deviceSn
}
, 区域
${
regionData
.
region
}
`
);
}
}
// 遍历每个区域的客流数据,逐条入库
for
(
const
regionData
of
regionCountData
)
{
const
regionUuid
=
regionData
.
region_uuid
;
const
regionName
=
regionData
.
region_name
||
''
;
const
regionNumber
=
regionData
.
region
;
const
currentTotal
=
regionData
.
total
?.
current_total
??
0
;
await
addData
(
TABLENAME
.
设备数据表
,
{
device_id
:
deviceSn
,
data
:
regionData
.
total
,
received_time
:
now
,
device_time
:
deviceTime
,
created_at
:
now
,
}
);
console
.
log
(
`客流数据入库成功: 设备
${
deviceSn
}
, 区域
${
regionName
||
regionUuid
}
, 当前人数
${
currentTotal
}
`
);
}
console
.
log
(
`客流数据处理完成: 设备
${
deviceSn
}
, 共入库
${
regionCountData
.
length
}
条区域数据`
);
}
catch
(
error
)
{
console
.
error
(
'客流数据处理失败:'
,
error
);
}
}
// ==================== 数据解析与入库函数 ====================
/**
* 将Base64编码的payload解码为十六进制字符串
...
...
src/biz/running.ts
View file @
37602267
...
...
@@ -659,7 +659,7 @@ export async function controlAcRunning(params: {}) {
let
device
=
await
selectOneDataByParam
(
TABLENAME
.
设备表
,
{
device_id
:
deviceId
},
[
"device_id"
,
"region_key"
,
"device_name"
,
"device_ad"
,
"control_params"
]
[
"
id"
,
"
device_id"
,
"region_key"
,
"device_name"
,
"device_ad"
,
"control_params"
]
);
if
(
!
device
.
data
||
!
device
.
data
.
id
)
{
throw
new
BizError
(
ERRORENUM
.
未找到数据
,
`设备
${
deviceId
}
未注册`
);
...
...
src/config/serverConfig.ts
View file @
37602267
...
...
@@ -40,12 +40,13 @@ export async function initConfig() {
// mqtt
if
(
mqttsrv
)
{
let
configInfo
=
mqttsrv
[
0
];
systemConfig
.
mqttsrv
=
{
host
:
''
,
port
:
0
,
topic
:
''
,
username
:
''
,
password
:
''
};
systemConfig
.
mqttsrv
=
{
host
:
''
,
port
:
0
,
topic
_env
:
''
,
topic_crowd
:
''
,
username
:
''
,
password
:
''
};
if
(
configInfo
.
mqttHost
&&
configInfo
.
mqttPort
&&
configInfo
.
mqttTopic
)
{
if
(
configInfo
.
mqttHost
&&
configInfo
.
mqttPort
&&
(
configInfo
.
mqttTopic1
||
configInfo
.
mqttTopic2
)
)
{
systemConfig
.
mqttsrv
.
host
=
configInfo
.
mqttHost
[
0
];
systemConfig
.
mqttsrv
.
port
=
parseInt
(
configInfo
.
mqttPort
[
0
]);
systemConfig
.
mqttsrv
.
topic
=
configInfo
.
mqttTopic
[
0
];
systemConfig
.
mqttsrv
.
topic_env
=
configInfo
.
mqttTopic1
[
0
];
systemConfig
.
mqttsrv
.
topic_crowd
=
configInfo
.
mqttTopic2
[
0
];
systemConfig
.
mqttsrv
.
username
=
configInfo
.
username
[
0
];
systemConfig
.
mqttsrv
.
password
=
configInfo
.
password
[
0
];
}
...
...
src/config/systemClass.ts
View file @
37602267
...
...
@@ -18,7 +18,8 @@ export class ServerConfig {
mqttsrv
:
{
host
:
string
,
port
:
number
,
topic
:
string
,
topic_env
:
string
,
topic_crowd
:
string
,
username
:
string
,
password
:
string
}
...
...
src/routers/device.ts
View file @
37602267
...
...
@@ -38,6 +38,8 @@ export function setRouter(httpServer) {
/** 停止数据集成 */
httpServer
.
post
(
'/api/qdm/run/stop/schedule'
,
asyncHandler
(
stopSchedule
));
/** 获取环境监测数据 */
httpServer
.
post
(
'/api/qdm/device/environment'
,
asyncHandler
(
getEnvironmentData
));
}
/**
...
...
@@ -157,6 +159,18 @@ async function stopSchedule(req, res) {
res
.
success
(
result
);
}
/**
* 获取环境监测数据
*/
async
function
getEnvironmentData
(
req
,
res
)
{
let
reqConf
=
{
regionGroup
:
'String'
,
regionType
:
'String'
,
regionKey
:
'Number'
,
deviceId
:
'String'
};
const
NotMustHaveKeys
=
[
"regionGroup"
,
"regionType"
,
"regionKey"
,
"deviceId"
];
let
{
regionGroup
,
regionType
,
regionKey
,
deviceId
}
=
eccReqParamater
(
reqConf
,
req
.
body
,
NotMustHaveKeys
);
const
result
=
await
deviceBiz
.
getEnvironmentData
(
regionGroup
,
regionType
,
regionKey
,
deviceId
);
res
.
success
(
result
);
}
...
...
src/service/mqttInit.ts
View file @
37602267
import
{
processDeviceData
}
from
"../biz/mqttClient"
;
import
{
processDeviceData
,
customerDeviceData
}
from
"../biz/mqttClient"
;
import
{
systemConfig
}
from
"../config/serverConfig"
;
const
mqtt
=
require
(
'mqtt'
);
...
...
@@ -21,12 +21,20 @@ export async function startMqttClient() {
client
.
on
(
'connect'
,
()
=>
{
console
.
log
(
'MQTT客户端已连接,正在订阅主题...'
);
// 订阅网关的上行主题
client
.
subscribe
(
systemConfig
.
mqttsrv
.
topic
,
(
err
)
=>
{
client
.
subscribe
(
systemConfig
.
mqttsrv
.
topic
_env
,
(
err
)
=>
{
if
(
err
)
{
console
.
error
(
'订阅失败:'
,
err
);
console
.
error
(
'
环境
订阅失败:'
,
err
);
}
else
{
console
.
log
(
`成功订阅主题:
${
systemConfig
.
mqttsrv
.
topic
}
`
);
console
.
log
(
'等待设备数据...'
);
console
.
log
(
`成功订阅环境主题:
${
systemConfig
.
mqttsrv
.
topic_env
}
`
);
console
.
log
(
'等待环境设备数据...'
);
}
});
client
.
subscribe
(
systemConfig
.
mqttsrv
.
topic_crowd
,
(
err
)
=>
{
if
(
err
)
{
console
.
error
(
'客流订阅失败:'
,
err
);
}
else
{
console
.
log
(
`成功订阅客流主题:
${
systemConfig
.
mqttsrv
.
topic_crowd
}
`
);
console
.
log
(
'等待客流设备数据...'
);
}
});
});
...
...
@@ -34,9 +42,12 @@ export async function startMqttClient() {
// 当收到消息时触发处理
client
.
on
(
'message'
,
(
topic
,
message
)
=>
{
// 只处理配置的上行主题
if
(
topic
===
systemConfig
.
mqttsrv
.
topic
)
{
if
(
topic
===
systemConfig
.
mqttsrv
.
topic
_env
)
{
processDeviceData
(
message
);
}
if
(
topic
===
systemConfig
.
mqttsrv
.
topic_crowd
)
{
customerDeviceData
(
message
);
}
});
client
.
on
(
'error'
,
(
err
)
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment