VisualHMI - 告警记录

image-20231129090729848

在工业自动化的人机界面(HMI)应用场景中,当单个HMI上位机需连接多个PLC设备时,若各PLC产生的告警数量庞大且内容一致,使用VisualHMI软件内置的图形化告警配置界面会显得效率低下、操作繁琐且灵活性不足。

为解决此问题,可通过编写LUA脚本的方式来实现告警的集中管理。该方法的核心优势在于:利用脚本读取来自不同PLC的告警数据源,触发解触,并解析告警信息,从而绕过可视化配置的限制,大幅提升配置效率与系统的可维护性。

使用范围:VisualHMI - HMI&M系列&Dx系列

入门应用:VisualHMI - 告警记录(点击下载)

1.应用背景

假设基于Modbus RTU通讯的应用中,HMI通过串行总线连接8台PLC设备(站地址1~8),每台PLC均定义100个同构告警点(地址连续,例如每个PLC的告警起始地址为4x1000,连续6个地址,每个地址的一个bit对应一个告警状态)

image-20260120091652900

2.API说明

2.1.warning_set_mode(en)

告警触发模式控制函数warning_set_mode(en) 是 HMI 脚本告警系统的全局使能开关,用于启用后,需要 warning_set 函数的告警触发

📊 参数说明

参数 类型 说明
en number 告警模式使能标志
1:开启Lua解析告警模式
0:关闭Lua解析告警模式

2.2.warning_set(warning_id,value,count)

批量告警状态设置函数warning_set() 是 HMI 脚本告警系统的核心操作接口,用于按位批量触发或清除连续的告警条目。该函数将 value 视为一个位掩码(bitmap),其低 count 位分别对应从 warning_id 开始的 count 个告警的状态(1=触发,0=清除)。

🔑 前提条件:必须先调用 warning_set_mode(1) 启用脚本告警模式,否则本函数无效。

📊 参数说明

参数 类型 说明
warning_id number 起始告警 ID(从 0 开始)
value number 告警状态位图(16 位)
• 最低位(bit 0)对应 warning_id
• bit 1 对应 warning_id + 1,依此类推
• 每BIT:1 = 触发告警,0 = 清除告警
count number 连续操作的告警数量
• 取值范围:1 ~ 16

5.3.on_parse_warning(id, text, screen_id, control_id, p0, p1, p2, p3)

告警内容动态解析回调函数,on_parse_warning 是 HMI 系统提供的告警文本自定义生成接口,开发者根据告警 ID、画面信息,生成自定义的告警描述字符串。

📊 参数说明

参数 类型 说明
id number 告警 ID*
• 对应 warning_set 中使用的 warning_id
• 用于区分不同类型的告警
text string 原始告警文本
• 此处可以忽略,因为本回调中,拼接新的字符串返回
screen_id number 当前画面 ID
control_id number 当前控件 ID
p0p3 number 告警参数(0~3)
• 仅在工程中为该告警启用了参数功能时有效
• 实际值由 on_get_warning_param 回调提供,详细参考API说明

返回值

返回值 类型 说明
str string 告警描述字符串
• 支持拼接变量、单位、状态等 • 示例:"电机#3 温度 98°C 超过阈值 95°C!",带参配合on_get_warning_param `实现
encode number 字符编码标识(可选)
1:表示返回字符串为 UTF-8 编码(默认)
• 0:GBK-8 编码

3.应用

3.1.告警设置

“工程”→“告警设置”配置如下所示:

假设HMI接8个PLC,1个PLC有96个告警,则设置告警条数768(该参数,不能小于实际告警条数)

image-20260120094822492

3.2.告警显示

“告警控件”属性配置如下所示:

image-20260120095046007

3.3.编辑Lua

3.3.1.初始化

在Lua脚本on_init里,启用Lua告警解析,并初始化读8个从机的告警寄存器

function on_init()

    warning_set_mode(1) --启用Lua告警解析

    set_auto_read(0)  --脚本控制读取
    create_resp_que() --队列发送,使能回调 on_cmd_resp

    for i = 0, 7
    do
        select_slave(i)
        start_read(i+1, VT_4x, 0x1000, 6) --读取从机1~8的告警
    end

end

3.3.2.触发/解除告警

读取每个从机告警,在系统回调on_cmd_resp函数里面,依次解析每个从机、每个寄存器(0x1000~0x1005),每个位(bit0~bit15)的状态

_warningTb = {
--4x1000, bit0~bit15
    '相序保护',--bit0
    '水流开关保护',
    '水位开关保护',
    '制热出水温度过高',
    '下水流开关断开',
    '1#电流故障',
    '2#电流故障',
    '线控器通讯故障',
    '进水传感器故障',
    '出水传感器故障',
    '水箱传感器故障',
    '环境传感器故障',
    '1#盘管传感器故障',
    '2#盘管传感器故障',
    '1#排气传感器故障',
    '2#排气传感器故障',--bit15

--4x1001, bit0~bit15
    '下回水传感器故障',--bit0
    '1#回气传感器故障',
    '2#回气传感器故障',
    '1#高压开关保护',
    '2#高压开关保护',
    '1#低压开关保护',
    '2#低压开关保护',
    '冬季防冻保护',
    '制冷进出水温度过低保护',
    '进出水温差过大保护',
    '1#制热环境与盘管温差过大保护',
    '2#制热环境与盘管温差过大保护',
    '3#制热环境与盘管温差过大保护',
    '4#制热环境与盘管温差过大保护',
    '3#电流故障',
    '4#电流故障',--bit15

--4x1002, bit0~bit15
    '1#增焓进口传感器故障',--bit0
    '2#增焓进口传感器故障',
    '预留',
    '子设备掉线',
    '1#增焓出口传感器故障',
    '2#增焓出口传感器故障',
    '3#增焓出口传感器故障',
    '4#增焓出口传感器故障',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',--bit15

--4x1003, bit0~bit15
    '压机1过载保护',--bit0
    '压机2过载保护',
    '压机3过载保护',
    '压机4过载保护',
    '内风机1过载保护',
    '内风机2过载保护',
    '内风机3过载保护',
    '内风机4过载保护',
    '外风机1过载保护',
    '外风机2过载保护',
    '外风机3过载保护',
    '外风机4过载保护',
    '电辅热1过载保护',
    '电辅热2过载保护',
    '电辅热3过载保护',
    '电辅热4过载保护',--bit15

--4x1004, bit0~bit15
    '系统1高压保护',--bit0
    '系统2高压保护',
    '系统3高压保护',
    '系统4高压保护',
    '系统1低压保护',
    '系统2低压保护',
    '系统3低压保护',
    '系统4低压保护',
    '系统1排气过高保护',
    '系统2排气过高保护',
    '系统3排气过高保护',
    '系统4排气过高保护',
    '系统1电流保护',
    '系统2电流保护',
    '系统3电流保护',
    '系统4电流保护',--bit15

--4x1005, bit0~bit15
    '室内翅片1探头故障',--bit0
    '室内翅片2探头故障',
    '室内翅片3探头故障',
    '室内翅片4探头故障',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',
    '预留',--bit15

}

function on_cmd_resp(slave,vtype,addr,count,ret,wr)

    if ret == 0 and wr == 0
    then
        if  vtype == VT_4x and addr == 0x1000 and count == 6
        then
            select_slave(slave) -- 从机1~8
            for i = 0, 5 --6个告警寄存器
            do
                local val = get_uint16(VT_4x, 0x1000 + i)
                for j = 0, 15 --16个bit
                do
                    local idx = i*16 + j + 1
                    if idx ~= 35 and (not (idx >= 41 and idx <= 48)) and (not (idx >= 85 and idx <= 96)) --跳过“预留”bit
                    then
                         --1~100:从机1告警ID
                         --101~200:从机2告警ID
                         --201~300:从机3告警ID
                         --301~400:从机4告警ID
                         --401~500:从机5告警ID
                         --501~600:从机6告警ID
                         --601~700:从机7告警ID
                         --701~800:从机8告警ID
                         warning_set(idx + slave*100 ,((val >> j) & 0x01), 1)
                    end
                end
            end
        end
    end
end

3.3.3.解析告警

根据告警id范围,区分那个从机触发的告警,在返回的字符串拼接上前缀“从机X”

function on_parse_warning(id, text, screen_id, control_id, p0, p1, p2, p3)
--1~100:从机1告警ID
--101~200:从机2告警ID
--201~300:从机3告警ID
--301~400:从机4告警ID
--401~500:从机5告警ID
--501~600:从机6告警ID
--601~700:从机7告警ID
--701~800:从机8告警ID

    local slaveId = (id // 96) + 1 --第几个从机
    local msgId = id % 96          --告警类型ID
    local curWarnMsg = ''          --告警字符

    if msgId == 0 then msgId = 96 end

    curWarnMsg = '从机'..string.format('%02d', slaveId).. ': '.._warningTb[msgId]
    return curWarnMsg, 1 --返回GBK编码

end

3.3.4.运行预览

运行虚拟屏,和Modbus slave 连接,如下所示:

Video_2026-01-20_105954 00_00_00-00_00_30

Copyright ©Dacai all right reserved,powered by Gitbook该文件修订时间: 2026-02-10 10:03:45

results matching ""

    No results matching ""