ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

声光告警也需要生命周期管理:单次、周期、无限循环与恢复闭环设计

2026/8/25 5:31:02 拓冰建站 浏览量
声光告警也需要生命周期管理:单次、周期、无限循环与恢复闭环设计 很多项目接入语音通知终端时只完成了一个动作监控平台发现异常后调用接口让设备播报一条告警。这个动作可以证明接口已经打通却不代表告警系统已经具备生产可用性。例如同一个故障被监控平台重复推送严重告警只播放一次很快被现场噪声淹没无限循环告警创建后故障恢复却没有停止播报队列不断积压恢复通知半小时后才被播放值班人员跳过当前语音但后台周期任务仍然存在设备重启或调用服务重启后系统找不到原来的告警任务。这些问题本质上都属于“告警生命周期管理”。本文以博灵 Q 系列语音通知终端为例讨论如何组合单次告警、周期告警、无限循环告警、队列控制和恢复通知构建一套完整的智能声光告警闭环。本文侧重架构与代码思路。接口路径和字段应以实际设备版本及官方文档为准。一、不要把所有告警都当成一次性消息不同类型的事件应该采用不同的播报策略。事件类型推荐策略示例普通状态通知单次告警备份任务执行完成一般警告单次告警重复12次磁盘使用率达到80%持续性故障周期告警空调温度持续超限紧急且必须处理无限循环告警水浸、消防、安全门异常故障恢复删除重复任务单次恢复通知数据库重新上线如果把所有告警都设置成无限循环现场很快会陷入噪声如果所有告警都只播放一次又可能错过真正紧急的故障。合理方案应该根据严重程度、持续时间和业务影响选择告警模式。二、告警生命周期状态机推荐将每一个告警事件建模为状态机首次检测到异常 │ ▼ ┌──────────┐ ┌────────────────┐ │ NORMAL │ ───▶ │ PENDING确认中 │ └──────────┘ └───────┬────────┘ ▲ │ 连续异常达到阈值 │ ▼ │ ┌────────────────┐ │ │ FIRING告警中 │ │ └───────┬────────┘ │ │ │ 创建周期/循环告警 │ 保存设备返回的cid │ │ │ ▼ │ ┌────────────────┐ │ │ ACK已人工确认 │ │ └───────┬────────┘ │ │ 状态恢复 │ ▼ │ ┌────────────────┐ └────────── │ RESOLVED已恢复 │ └────────────────┘其中最重要的是两条规则从NORMAL进入FIRING时只创建一次告警任务从FIRING进入RESOLVED时必须删除对应任务并发送恢复通知。监控平台应该为每个事件生成稳定的event_id例如机房A:空调01:回风温度过高同一故障的重复检测必须使用相同event_id否则告警网关无法判断它是新事件还是旧事件的重复通知。三、Q 系列的几类告警接口根据 Q 系列接口文档可以将主要能力归纳如下。单次告警POST /api/api/send_msg适用于一次性的声光语音播报可设置LED 样式LED 颜色灯光参数TTS 文本语速提示音重复次数播报时长。周期性告警POST /api/api/set_api_repeat_alarm主要参数notify_desc通知组 tts_text语音内容成功后返回cid。通知组中的播报间隔等配置会影响实际提醒方式。无限循环告警POST /api/api/not_stop_repeat_alarm适用于需要持续提醒、直至人工处置或故障恢复的事件同样会返回cid。删除重复告警POST /api/home/del_repeat_alarm通过创建告警时返回的cid删除周期性或无限循环播报。获取等待队列长度GET /api/api/get_play_queue_size返回等待播报的请求数量当前正在播放的内容不计算在内。跳过当前播报POST /api/api/play_next用于停止当前内容并播放下一条。需要注意跳过当前播报和删除整个周期任务不是同一个概念。四、推荐的告警控制架构告警生命周期不应该完全由监控平台或语音终端单独承担而应增加告警控制服务┌──────────────────────────────────────┐ │ Zabbix / Alertmanager / 云监控 / PLC │ └──────────────────┬───────────────────┘ │ Webhook ▼ ┌──────────────────────────────────────┐ │ 告警控制服务 │ │ │ │ 事件标准化 告警去重 级别映射 │ │ 状态机管理 cid保存 恢复处理 │ │ 队列保护 调用审计 失败重试 │ └─────────┬─────────────────┬──────────┘ │ │ │ API调用 │ 状态存储 ▼ ▼ ┌──────────────────┐ ┌────────────────┐ │ 博灵Q系列通知终端│ │ Redis/数据库 │ │ │ │ │ │ 声光、TTS、队列 │ │ event_id→cid │ └──────────────────┘ └────────────────┘状态存储至少需要保存{ event_id: room-a:ac-01:temperature, status: firing, alarm_mode: repeat, cid: 658529f458d39, severity: critical, created_at: 2026-08-24T10:30:0008:00 }如果没有保存cid恢复时就无法准确删除对应循环任务。五、用 Python 封装告警生命周期下面提供一个简化示例演示如何创建周期告警、保存cid并在恢复时删除任务。示例使用内存保存状态只适合接口调试。正式环境应改用 Redis、SQLite、PostgreSQL 等持久化存储。import hashlib import os import time from dataclasses import dataclass import requests DEVICE_URL os.environ.get( Q_DEVICE_URL, http://192.168.0.66 ) API_KEY os.environ[Q_API_KEY] dataclass class ActiveAlarm: event_id: str cid: str mode: str text: str active_alarms: dict[str, ActiveAlarm] {} class QTerminalClient: def __init__(self, base_url: str, api_key: str): self.base_url base_url.rstrip(/) self.api_key api_key def _sign(self, payload: dict[str, str]) - str: sign_values dict(payload) sign_values[token] self.api_key sign_text .join( f{key}{sign_values[key]} for key in sorted(sign_values) ) return hashlib.md5( sign_text.encode(utf-8) ).hexdigest() def _post( self, path: str, payload: dict[str, str] ) - dict: request_data dict(payload) request_data[time] str(int(time.time())) request_data[sign] self._sign(request_data) response requests.post( f{self.base_url}{path}, datarequest_data, timeout5 ) response.raise_for_status() result response.json() if result.get(code) ! 200: raise RuntimeError( f设备调用失败{result} ) return result def create_repeat_alarm( self, notify_group: str, text: str ) - str: result self._post( /api/api/set_api_repeat_alarm, { notify_desc: notify_group, tts_text: text } ) return result[data][cid] def create_infinite_alarm( self, notify_group: str, text: str ) - str: result self._post( /api/api/not_stop_repeat_alarm, { notify_desc: notify_group, tts_text: text } ) return result[data][cid] def delete_repeat_alarm(self, cid: str): self._post( /api/home/del_repeat_alarm, {id: cid} ) def send_recovery(self, text: str): self._post( /api/api/send_msg, { text: text, tts_speed: 5, repeat_count: 1 } ) terminal QTerminalClient( DEVICE_URL, API_KEY )文档说明不同版本和安全设置可能影响鉴权要求。正式对接前应使用当前设备版本验证参与签名的字段和数据序列化方式。六、处理“故障”和“恢复”事件创建告警时先检查event_id是否已经存在def handle_firing( event_id: str, severity: str, text: str ): if event_id in active_alarms: print(重复事件忽略再次创建) return if severity critical: cid terminal.create_infinite_alarm( notify_group严重告警, texttext ) mode infinite else: cid terminal.create_repeat_alarm( notify_group一般警告, texttext ) mode repeat active_alarms[event_id] ActiveAlarm( event_idevent_id, cidcid, modemode, texttext ) print( f已创建告警event_id{event_id}, fcid{cid} )故障恢复后根据保存的cid删除重复任务def handle_resolved( event_id: str, recovery_text: str ): alarm active_alarms.get(event_id) if alarm is None: print(未找到活动告警直接发送恢复通知) terminal.send_recovery(recovery_text) return terminal.delete_repeat_alarm(alarm.cid) terminal.send_recovery(recovery_text) del active_alarms[event_id] print( f告警已恢复并关闭event_id{event_id} )调用示例event_id room-a:ac-01:temperature handle_firing( event_idevent_id, severitycritical, text机房A空调一号回风温度过高请立即检查 ) # 故障恢复后调用 handle_resolved( event_idevent_id, recovery_text恢复通知机房A空调一号温度已经恢复正常 )完整流程为第一次故障事件 → 创建无限循环告警 → 保存cid 相同故障再次推送 → 根据event_id去重 → 不再创建任务 收到恢复事件 → 根据cid删除循环任务 → 播放一次恢复通知 → 清理本地状态七、如何防止播报队列失控语音播报是串行资源。同一时刻通常只能清晰地播放一条内容因此告警系统必须考虑背压。1. 在进入设备前去重推荐去重键source host metric status例如zabbix:db-01:mysql-connect:firing在一定时间窗口内相同去重键只允许进入一次。2. 合并同类告警如果十台非核心设备同时离线不一定需要逐台播报。告警网关可以合并为一般警告分支机房共有十台非核心设备离线请登录监控平台查看详情。3. 控制语音长度语音内容应优先包含级别位置对象问题动作例如严重告警二号机房核心交换机离线请检查供电和网络连接。不要把完整日志、堆栈信息或数百字符的错误描述直接放入 TTS。4. 定期检查队列长度如果等待队列持续增长通常说明上游发生告警风暴去重逻辑失效播报文本过长设备离线后告警积压告警产生速度超过播放速度。队列长度可以作为告警网关的自我保护指标。八、人工确认应该如何设计“跳过当前播报”不代表故障已经恢复。可以将人工操作分为三类操作含义后台动作跳过暂时不听当前内容播放下一条确认已有人处理停止重复提醒但保留故障状态恢复故障已经消除删除任务并关闭事件如果设备按键支持 Webhook 回调可以把人工按键动作发送给告警控制服务记录操作时间设备地址当前播报文本事件 ID确认人员或值班班次。这样可以形成从“发现—通知—确认—恢复”的完整记录。九、设备或控制服务重启后怎么办只使用内存字典保存event_id和cid存在明显风险服务重启后映射全部丢失。生产环境至少应完成将活动告警写入持久化存储服务启动时重新加载未恢复事件定期核对本地状态与设备状态对无法确认的旧任务执行人工检查保存所有创建和删除接口的响应为同一事件设置唯一约束删除任务失败时进入重试队列。数据库表可以设计为CREATE TABLE active_alarm ( event_id VARCHAR(200) PRIMARY KEY, cid VARCHAR(100) NOT NULL, alarm_mode VARCHAR(20) NOT NULL, severity VARCHAR(20) NOT NULL, alarm_text VARCHAR(500) NOT NULL, status VARCHAR(20) NOT NULL, created_at TIMESTAMP NOT NULL, resolved_at TIMESTAMP NULL );十、典型应用场景机房环境告警温度过高使用周期播报水浸或烟雾使用无限循环告警。传感器恢复后删除任务并播放绿色恢复通知。生产线停机PLC 检测到停机后触发持续提醒操作人员按下确认按钮后停止语音但事件继续保持告警状态直至设备恢复运行。视频监控异常NVR 检测到核心摄像机掉线后创建周期告警。普通摄像机批量离线时先聚合再播报离线数量避免逐条占用队列。关键业务中断数据库、支付、ERP 或 MES 服务中断时使用高优先级通知组。恢复事件必须与原故障使用相同event_id确保可以关闭正确的循环任务。十一、上线检查清单正式使用前建议验证单次、周期和无限循环告警是否符合预期周期告警是否能够获得并保存cid恢复事件能否删除正确任务重复 Webhook 是否会创建多个循环告警跳过当前播报是否影响周期任务设备离线时接口调用如何重试控制服务重启后能否恢复活动告警播报队列积压时是否触发保护API Key 是否已修改并安全保存设备接口是否限制在受控网段是否存在短信、电话或即时通信备用渠道。结语智能声光告警不仅是一次 API 调用更是一个有开始、有持续状态、有人工确认、也必须有结束条件的任务。博灵 Q 系列语音通知终端提供单次告警、周期告警、无限循环告警、队列查询和任务删除等能力可以作为机房、生产线、视频监控和业务系统的现场语音告警节点。但要真正投入生产还需要在上游完成事件 ID、去重、cid持久化、恢复处理和队列保护。只有建立完整生命周期网络报警灯才能在关键时刻持续提醒同时又不会因为告警风暴成为新的噪声来源。参考资料博灵 Q 系列产品介绍单次告警 API重复告警 API基础功能 API接口签名快速入门