一条报警消息的旅程:用华为云 IoTDA + FunctionGraph 做注塑机停机告警闭环

举报
yd_245773411 发表于 2026/11/03 08:08:01 2026/11/03
【摘要】 老注塑机没有网口,报警只能靠人盯。这次把继电器信号采出来接到 IoTDA,再用 FunctionGraph 做去重、分级和推送,把停机响应时间从半小时压到三分钟,记录整条链路和四个坑。

车间里最贵的不是电费,是停机。转盘机报警之后如果没人听见,机器就那么干等着,等班组长发现、等师傅从另一个车间过来。这次做的事情很简单:让报警自己找人,而不是等人找报警。

一、先把信号采出来,别急着上平台

老机器没有网口,PLC 也没有对外接口。能用的是两样东西:故障指示灯的输出触点,和继电器动作时的那一路 24V 信号。方案是用一块带干接点输入的采集网关,把三色灯和继电器各接一路进去,网关自己跑 MQTT 客户端。

这一步最关键的不是协议,是接哪一路。三色灯的黄灯和红灯代表不同级别:黄灯是缺料、模温不到这类可以自恢复的;红灯是机械卡死、液压超压这类必须停机处理的。分级必须在采集端就分好,否则后面所有逻辑都在猜。

{
  "device_id": "htf160-cavity4",
  "alarm_code": "E207",
  "level": "red",
  "ts": 1759452122000,
  "note": "转盘定位超时"
}

二、IoTDA 接入:用自定义 Topic,别用物模型

设备侧接华为云 IoTDA,最省事的做法是自定义 Topic 上报,格式定成 $oc/devices/{device_id}/sys/messages/up,payload 就是上面那段 JSON。物模型(属性上报)当然更规范,但老机器每次报警的字段结构不一样,硬套物模型要频繁改模型定义,反而不好维护。

接入时有两个参数必须确认:一是设备密钥的鉴权方式(推荐密钥认证 + 一机一密),二是 QoS 用 1,保证报警至少到一次。MQTT over 1883 在厂区内网直连没问题;跨公网记得换 8883 + TLS。

三、规则引擎转发到 FunctionGraph:这里做三件事

IoTDA 的规则动作配成「转发到 FunctionGraph」,函数收到原始报警后做三件事,都不复杂但都必要:

  • 去重:同一台机同一报警码 60 秒内只推一次。现场的抖动非常频繁,继电器会连跳三四下,不去重就是报警风暴。
  • 分级路由:红灯直接推到值班群 + 语音电话;黄灯只进群,不打电话。
  • 落地:写一条记录到数据库,字段是机台、报警码、开始时间、恢复时间。没有这张表,事后想算停机率只能靠回忆。
import json, os, time
import requests

def handler(event, context):
    body = json.loads(event.get("body", "{}") or "{}")
    dev, code, level = body.get("device_id"), body.get("alarm_code"), body.get("level")
    key = "%s:%s" % (dev, code)
    # 去重:用函数实例的临时缓存不够可靠,正式环境建议换成 Redis
    now = int(time.time())
    if now - CACHE.get(key, 0) < 60:
        return {"statusCode": 200, "body": "dup"}
    CACHE[key] = now

    text = "【%s】%s 报警 %s" % ("停机" if level == "red" else "提示", dev, code)
    if level == "red":
        requests.post(os.environ["WEBHOOK"], json={"text": text}, timeout=5)
        requests.post(os.environ["CALL_API"], json={"text": text}, timeout=5)
    else:
        requests.post(os.environ["WEBHOOK"], json={"text": text}, timeout=5)
    return {"statusCode": 200, "body": "ok"}

CACHE = {}

函数的超时时间设 10 秒就够,但要注意冷启动:第一次调用可能要 1 到 3 秒。报警推送对这几秒不敏感,把它当实时系统设计反而会过度工程。

四、通知渠道:群里发一条,比什么大屏都管用

试过做大屏,结论是没人看。最后落在企业微信机器人的 webhook 上:一条消息里带机台号、报警码、发生时间,红灯加一个「已确认」的按钮链接。谁来处理就点一下,点完写回数据库,这条记录才闭合。

这里有个容易忽略的细节:恢复也要推。只推报警不推恢复,群里最后全是未闭合的告警,三天之后所有人都开始无视它。

五、四个坑,按踩到的顺序

  • 时钟漂移:网关没有 NTP,跑一个月快了四分钟。报警时间和实际差四分钟,事后对齐停机记录全乱。解决办法是网关开机必须校时,服务端再按接收时间兜底。
  • 报警风暴:一个传感器接触不良,一小时推了 200 多条。去重窗口从此变成硬需求,并且加了一条「同机台 5 分钟内超过 10 条报警 → 合并成一条汇总」。
  • 离线判定:设备断网和机器正常运行在平台上看起来一样。加了心跳,5 分钟收不到心跳单独推一条「设备离线」,这条比报警更值得看。
  • 规则引擎的匹配串写错一个字符就静默失效:不报错、不告警,只是消息不进来。上线前一定要用真实设备打一条报文,确认函数日志里有记录。

六、效果

上线两个月,平均停机响应从 28 分钟降到 3 分钟出头,主要是夜班受益——夜班只有一个人看十几台机,以前纯粹靠运气。真正省下来的不是修机时间,是「等发现」的那段时间。

这套链路没有用到任何高级能力:一个采集网关、一个 IoTDA 实例、一个函数、一个 webhook。复杂度全在细节里,而不在架构里。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。