184 lines
7.0 KiB
Plaintext
184 lines
7.0 KiB
Plaintext
// 告警消息解析工具
|
||
// 参考 doc_eldercare/alert.md 设计
|
||
|
||
export type AlertParseResult {
|
||
type : string; // 解析后的类型,如 'SOS', '健康数据', '定位', '通知', '计步', '围栏', '语音', '睡眠', '手表', '未知'
|
||
title : string; // 简要标题
|
||
content : string; // 展示内容
|
||
time ?: string; // 时间
|
||
raw : any; // 原始数据
|
||
level ?: 'normal' | 'warn' | 'danger'; // 可选,紧急等级
|
||
mid ?: string; // 设备ID
|
||
smid ?: string; // 消息ID
|
||
extra ?: UTSJSONObject; // 其它解析字段
|
||
}
|
||
|
||
/**
|
||
* 解析推送消息主入口
|
||
* @param msg 传入ps_push_msg_raw的raw_data对象或完整record
|
||
*/
|
||
export const parseAlertMessage = (msg : UTSJSONObject) : AlertParseResult => {
|
||
// 兼容 record/raw_data
|
||
let data : UTSJSONObject = msg.getJSON('raw_data') ?? {};
|
||
|
||
|
||
const pushType = data.getNumber('pushType') ?? 0;
|
||
const action = data.getNumber('actionRaw') ?? 0;
|
||
const time = data.getString('Time') ?? data.getString('time') ?? data.getString('created_at') ?? '';
|
||
// 1. SOS
|
||
if (pushType === 1) {
|
||
return {
|
||
type: 'SOS',
|
||
title: 'SOS求救',
|
||
content: `${data.getString('Name') ?? ''}(${data.getString('MID') ?? ''}) 向您发出求救`,
|
||
time,
|
||
raw: msg,
|
||
level: 'danger',
|
||
mid: data.getString('MID') ?? data.getString('mid'),
|
||
smid: data.getString('SMID') ?? data.getString('smid'),
|
||
extra: { lon: data.getNumber('Lon'), lat: data.getNumber('Lat'), address: data.getString('Str') }
|
||
};
|
||
}
|
||
// 2. 健康数据
|
||
if (pushType === 2) {
|
||
let arr : string[] = [];
|
||
const h = data.getNumber('H');
|
||
const o = data.getNumber('O');
|
||
const w = data.getNumber('W');
|
||
const x = data.getNumber('X');
|
||
const y = data.getNumber('Y');
|
||
if (h != null) arr.push(`心率:${h}`);
|
||
if (o != null) arr.push(`血氧:${o}`);
|
||
if (w != null) arr.push(`体温:${w}`);
|
||
if (x != null) arr.push(`高压:${x}`);
|
||
if (y != null) arr.push(`低压:${y}`);
|
||
return {
|
||
type: '健康数据',
|
||
title: '健康数据推送',
|
||
content: arr.length > 0 ? arr.join(',') : JSON.stringify(data),
|
||
time,
|
||
raw: msg,
|
||
level: 'normal',
|
||
mid: data.getString('MID') ?? data.getString('mid'),
|
||
smid: data.getString('SMID') ?? data.getString('smid'),
|
||
extra: { mid: data.getString('MID') ?? data.getString('mid') }
|
||
};
|
||
}
|
||
// 3. 定位
|
||
if (pushType === 3) {
|
||
return {
|
||
type: '定位',
|
||
title: '定位推送',
|
||
content: `${data.getString('Pro') ?? ''}${data.getString('City') ?? ''}${data.getString('Dist') ?? ''}${data.getString('Str') ?? ''} (${data.getNumber('Lon')},${data.getNumber('Lat')})`,
|
||
time: data.getString('CT') ?? data.getString('UT') ?? time,
|
||
raw: msg,
|
||
level: 'normal',
|
||
mid: data.getString('MID') ?? data.getString('mid'),
|
||
smid: data.getString('SMID') ?? data.getString('smid'),
|
||
extra: { lon: data.getNumber('Lon'), lat: data.getNumber('Lat') }
|
||
};
|
||
}
|
||
// 4. 通知
|
||
if (pushType === 4) {
|
||
const actionMapObj = {
|
||
'-1': '设备在线离线', '4': '围栏内停留', '5': '离开围栏', '6': '进入围栏', '9': '低电报警', '11': '跌倒报警', '23': '高温报警',
|
||
'26': '断开wifi', '28': 'wifi离线', '36': '防盗报警', '42': '布防告警', '44': '在家布防告警', '7': 'SOS报警', '10': '摘除报警',
|
||
'22': '低温报警', '24': '更换SIM卡', '27': '连接wifi', '35': '社区养老报警', '37': '状态通知', '43': '撤防告警', '45': '八件套报警',
|
||
'47': 'wifi不一致报警', '49': '红外报警', '50': 'NB按键报警', '51': 'NB防拆报警', '52': 'NB报警复位', '61': 'NB设备报警',
|
||
'63': '人体存在报警', '67': 'NB测试报警', '85': '网关上线', '87': '删除子设备', '114': '烟感/气感/门磁事件', '116': 'SCA事件',
|
||
'118': '防跌倒雷达', '121': '智能胸牌告警', '84': '网关离线', '86': '添加子设备', '113': '门磁事件', '115': '拉绳SOS',
|
||
'117': '4G视频门磁', '119': 'd5网关子设备报警', '122': 'NB温湿度报警', '123': '气感报警', '125': '水浸报警', '127': '跌倒报警',
|
||
'129': '燃气报警', '131': '对讲SOS', '134': 'AI智能报警', '124': '烟感报警', '126': '摄像头报警', '128': '井盖报警',
|
||
'130': '红外报警', '132': 'ZML_SOS报警', '200': '设备信息变更'
|
||
};
|
||
let actionStr:string = actionMapObj.getString(action.toString()) ?? `通知类型:${action}`;
|
||
return {
|
||
type: '通知',
|
||
title: actionStr,
|
||
content: `${data.getString('Name') ?? ''} ${data.getString('Content') ?? ''}`.trim() ?? JSON.stringify(data),
|
||
time,
|
||
raw: msg,
|
||
level: (action === 9 || action === 11 || action === 23 || action === 7) ? 'danger' : 'warn',
|
||
mid: data.getString('MID') ?? data.getString('mid'),
|
||
smid: data.getString('SMID') ?? data.getString('smid'),
|
||
extra: { action }
|
||
};
|
||
}
|
||
// 5. 计步/翻转(pushType=5 或有 Step/Roll 字段)
|
||
if (pushType === 6) {
|
||
return {
|
||
type: '计步',
|
||
title: '计步/翻转',
|
||
content: `步数:${data.getNumber('Step') ?? '-'} 翻转:${data.getNumber('Roll') ?? '-'}`,
|
||
time,
|
||
raw: msg,
|
||
level: 'normal',
|
||
mid: data.getString('MID') ?? data.getString('mid'),
|
||
smid: data.getString('SMID') ?? data.getString('smid'),
|
||
extra: { step: data.getNumber('Step'), roll: data.getNumber('Roll'), mid: data.getString('MID') ?? data.getString('mid'), smid: data.getString('SMID') ?? data.getString('smid') }
|
||
};
|
||
}
|
||
// 6. 围栏(进出围栏、进入围栏、离开围栏等)
|
||
if (pushType === 7 || (pushType === 4 && (action === 6 || action === 5))) {
|
||
let actionStr = '';
|
||
if (pushType === 4) {
|
||
if (action === 6) actionStr = '进入围栏';
|
||
else if (action === 5) actionStr = '离开围栏';
|
||
else actionStr = '围栏事件';
|
||
} else {
|
||
actionStr = '进出围栏';
|
||
}
|
||
return {
|
||
type: '围栏',
|
||
title: actionStr,
|
||
content: data.getString('Content') ?? JSON.stringify(data),
|
||
time,
|
||
raw: msg,
|
||
level: 'warn',
|
||
mid: data.getString('MID') ?? data.getString('mid'),
|
||
smid: data.getString('SMID') ?? data.getString('smid'),
|
||
extra: { lon: data.getNumber('Lon'), lat: data.getNumber('Lat'), action }
|
||
};
|
||
}
|
||
// 7. 微聊语音
|
||
if (pushType === 8) {
|
||
let msgType = data.getNumber('msgType') ?? data.getNumber('MType') ?? 0;
|
||
let typeStr = msgType === 2 ? '语音' : '文字';
|
||
return {
|
||
type: '微聊',
|
||
title: `微聊${typeStr}消息`,
|
||
content: data.getString('content') ?? JSON.stringify(data),
|
||
time,
|
||
raw: msg,
|
||
level: 'normal',
|
||
mid: data.getString('MID') ?? data.getString('mid'),
|
||
smid: data.getString('SMID') ?? data.getString('smid'),
|
||
extra: { msgType }
|
||
};
|
||
}
|
||
// 8. 睡眠带报警
|
||
if (pushType === 9) {
|
||
return {
|
||
type: '睡眠报警',
|
||
title: '睡眠带报警',
|
||
content: data.getString('Content') ?? JSON.stringify(data),
|
||
time,
|
||
raw: msg,
|
||
level: 'warn',
|
||
mid: data.getString('MID') ?? data.getString('mid'),
|
||
smid: data.getString('SMID') ?? data.getString('smid'),
|
||
extra: { action }
|
||
};
|
||
}
|
||
// 9. 其它类型可继续补充...
|
||
// 默认
|
||
return {
|
||
type: '未知',
|
||
title: '未知推送',
|
||
content: JSON.stringify(data),
|
||
time,
|
||
raw: msg,
|
||
mid: data.getString('MID') ?? data.getString('mid'),
|
||
smid: data.getString('SMID') ?? data.getString('smid')
|
||
};
|
||
}; |