如何获取Wincc报警控件当前报警数量

1 篇文章 0 订阅
1 篇文章 0 订阅

一、背景

        大家在做开发Wincc项目时应该会遇到这样的要求,通过一个I/O域显示当前的一个报警数量值,这样更能直观的体现当前是否存在报警,而不是用户切换到报警窗口查看才知道有报警。以前我的处理方式一般是通过上位机的全局脚本进行报警数量计数,或者在下位机PLC中做数量统计。但是这总方式对于小项目而言确实是一个比较好的方法,但是当我们的报警数量达到成千上万条时,这样的统计方式工作量将非常大,脚本也非常的多,所以很麻烦。

二、解决思路

        我们在使用Wincc报警控件时,大家都发现在控件的右下角有这样一行状态栏,状态栏中有一行显示的是当前报警控件所显示的行数,比如当前报警控件显示有100行告警,那么他会显示:列表:100。那么我们是否可以读取该值呢,这样不就可以知道当前报警数量了吗。打开报警控件的属性列表里,我们找到StatusbarElementId和StatusbarElementText这两个属性。当属性StatusbarElementId的值为2时,此时StatusbarElementText所表示的值为当前报警列表数值,如下图所示。

三、实现方式

        基于以上思路,我们可以通过全局VB脚本的方式获取该属性的值,代码如下。但是在实现该代码的过程中又产生了一个新的问题,就是该全局脚本在读取对应控件对应属性值时由于该控件并未在当前我们所运行的画面中,所以在我们并未将画面切换至报警控件画面时,该脚本并无法获取到该属性值。如何处理该尴尬的一幕呢,我们可以这样做。

Option Explicit
Function action
Dim a1,a2,a3
'一级报警控件列表数量读取
'一级报警控件在“Alarm1”窗体控件下的“Query_Alarm1”画面中的“控件1”
Set a1=HMIRuntime.Screens("Alarm1:Query_Alarm1").ScreenItems("控件1")
'首先将控件的StatusbarElementId属性值置2
a1.StatusbarElementId=2
'读出控件属性StatusbarElementText的值,注意该属性的数据类型是String型,所以对应的AlarmCount1变量
'应该为“文本变量 16 位字符集”才行
HMIRuntime.Tags ("AlarmCount1").Write a1.StatusbarElementText

'二级报警控件列表数量读取
Set a2=HMIRuntime.Screens("Alarm2:Query_Alarm2").ScreenItems("控件1")
a2.StatusbarElementId=2
HMIRuntime.Tags ("AlarmCount2").Write a2.StatusbarElementText

'三级报警控件列表数量读取
Set a3=HMIRuntime.Screens("Alarm3:Query_Alarm3").ScreenItems("控件1")
a3.StatusbarElementId=2
HMIRuntime.Tags ("AlarmCount3").Write a3.StatusbarElementText

End Functi

        一般我们开发Wincc画面,我么肯定是有一个主画面的,这个主画面主体是始终不动的。那么我们可以在主画面上通过一个窗体控件将我们所要读取报警属性的报警画面直接加载出来。由于主画面不论什么情况只要Wincc激活运行他就始终是运行状态,从而使得我们的报警画面一直是加载状态,我们的全局脚本也能直接读取到该报警控件的属性值,而不需要我切换到报警画面的时候才进行报警属性值的读取。

        如下图所示,为方便大家观看,我将三个加载报警画面的窗体控件进行了放大,正常使用时为了不影响我们主画面的外观,我们可以将该窗体控件大小调至最小,层级调至最低,这样画面运行起来时我们根本看不到该主画面上还有其他画面在运行。

四、优化处理

        以上方法已经是可以获取到该报警控件当前报警数量值的,但是我们最终获取的值是一个String的字符串类型的数据,我们可不可以将“列表:”给去掉,得到后面的数值,最终把他赋值给一个Int型的数据里去。解决方法肯定是有的,鉴于鄙人VB实在是不是太懂,所以以下方法我通过Wincc全局C脚本来实现。C脚本实现这个逻辑实际上就很简单了,就是通过对字符串的简单处理即可代码如下:

#include "apdefap.h"

int gscAction( void )
{
  int count[3],i;       //定义for循环遍历变量i,以及转化之后的报警数量count,count定义为一个int型的数组变量,长度为3,因为我这里只有三级报警,读出每一级报警的报警数量
  char *string[3];      //定义一个字符指针,长度为3,用来承接从Wincc内定义的变量
  string[0]=GetTagChar("AlarmCount1");    //将Wincc定义的AlarmCount1变量读取出来,赋值给string[0],因为AlarmCount1变量数据类型为一个字符串,直接将AlarmCount1读取出来的值赋值给字符串变量编译会报错,需要用指针型字符串变量进行承接                                  
  string[1]=GetTagChar("AlarmCount2");
  string[2]=GetTagChar("AlarmCount3");

  for(i;i<3;i++)                          //for循环进行遍历,通过New_Function函数将传入的字符串中含有数字的字符分离出来,并转化成int的数据
  count[i]=New_Function(string[i]);       //New_Function函数为自定义函数,在项目函数中进行定义

  SetTagDWord("AlarmNum1",count[0]);	
  SetTagDWord("AlarmNum2",count[1]);	
  SetTagDWord("AlarmNum3",count[2]);	
return 0; 
}

        上面C脚本我使用到了一个自定义函数New_Function,关于该函数的定义程序如下:

int New_Function(char* str)
{
int i,j,Value;
    for (i = 0, j = 0; str[i] != '\0'; i++)
    {
        if (isdigit(str[i]))      //函数isdigit()为C语言内部函数,该函数的功能为判断一个字符串中当前字符是否为数字,如果为数字则返回值为“True”,否则为“False”
        {
            str[j] = str[i];      //if判断当前遍历字符是否为数字,如果是,则把数字从新放入字符串中
            j++;
        }
    }
    str[j] = '\0';  // 添加字符串结尾的 null 字符
    Value=atoi(str);              //函数atoi()为C语言内部函数,该函数的功能是将传进来的字符串中的数值转化成int型的数
    return Value;
}

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值