|
龍海兒
關注《電氣外傳》公眾號,知乎,CSDN等同號
級別: 論壇先鋒
|
圖片:
圖片:
圖片:
圖片:
圖片:
1111MicrosoftInternetExplorer402DocumentNotSpecified7.8 磅Normal0如題,聲音報警我們用的很多,但是如何實現差異化的語音報警呢?直接先看圖看效果。 那語音報警都好理解,差異化又具體體現在哪里呢? 因為市面上已經有前輩開發出了語音報警,但是不能靈活單獨的應用到每一條報警上面。比如我只想要一條或者兩條重要信息實現語音播報,其它報警靜默顯示就行。那么通過本例可輕松解決。 特別說明!開發不易,本例所用腳本原件放在文章末尾,小額支持即可下載!感謝理解,歡迎交流。 第一步,打開WinCC創建內部變量(alarmComing)二進制類型與(alarmText)(prevAlarmText1)(prevAlarmText2)三個16位文本類型。(如需要多個報警可多建立兩個Text變量) 第二步,用Win+r輸入services.msc然后找到Windows Audio服務,啟動它(一般都啟動著)。 第三步,把gmsgfunc.fct腳本放到C:\Program Files (x86)\SIEMENS\WinCC\aplib\Alarm中替換掉以前的。 第四步,把Voice腳本vbs放到wincc項目ScriptAct文件夾中。 第五步,打開報警記錄找到想要播報的變量勾選屬性里面觸發動作如圖(不勾選的變量不會播報)。 通過以上操作就可以實現單獨變量的聲音報警,其它變量依然按照普通設置呈現。如果想觸發報警之后一直播報,直到人員點擊消音按鈕才消失。那請看之下進階操作。 將剛才第二步的Voice替換成cycle腳本(注意一定要替換,不可以都保留),然后在報警控件中將事件里面的OnToolbarButtonClicked屬性加上記事本中的c腳本用于取消循環,也可以自己外加按鈕來實現。 記得拷貝進去的每個腳本都打開再次保存一下,否則可能不能發聲。以下是本例用到的腳本,各位也可以再次優化腳本生成更多功能。 更過截圖和腳本鏈接請移步同名公眾號查看 |
|
|---|---|---|
|
|
qwerty_123
www
級別: 略有小成
|
//wincc聲音報警C腳本版,和wincc自身的報警沒有任何關系,所以不要和wincc自帶的報警相關聯 //曾經用于工程中的語音報警,事先將語音先錄好,然后將變量和語音關聯起來 #include "apdefap.h" //播放聲音的函數聲明 #pragma code("winmm.dll") VOID WINAPI PlaySoundA(char *,char *,DWORD); #pragma code() struct datainfo //變量名和聲音文件名的對應關系 { const char * const tagname; //變量名 const char * const soundname; //聲音文件名 }; struct statusdatainfo //保存報警變量的狀態信息 { int prevStatus; int playing; }; //所有的報警變量和聲音文件名對應關系表 //注意:變量名和文件名要和實際的變量名、文件名完全一致 //注意:聲音文件只支持wav文件 //注意:變量越靠前,則優先級越高,在同時發生多個報警時,優先級最高的聲音優先播放,而且任一時刻只能播放一個聲音 static struct datainfo data[]= { {"www","Windows XP 啟動.wav"}, {"testalarm","ringin.wav"}, {"qqq","Windows XP 關機.wav"}, {"eee","Windows XP 注銷音.wav"} }; static struct statusdatainfo statusdata[sizeof(data)/sizeof(data[0])]; //////////////////////////////////// int gscAction( void ) { int totalnum=0; //總的報警變量數量,也等于總的報警聲音數量 int index=0; //循環變量 int hasfound=0; //已找到優先級最高的報警變量 char * filename=NULL; //當前要播放聲音的文件名 char * dirname="D:\\WINDOWS\\Media\\"; //聲音文件存放的目錄 static char * currfilename=NULL; //當前正在播放聲音的文件名,注意:該變量是靜態變量 static char FullName[200]; //當前正在播放聲音的文件全名,注意:文件名全名不能太長,該變量是靜態變量 char * ack_name="ack"; //報警確認變量的名字,一次只能確認優先級最高的報警 int ack_status=0; //當前確認變量的狀態 totalnum=sizeof(data)/sizeof(struct datainfo); //報警變量的數量 ack_status=GetTagBit(ack_name); for(index=0;index<totalnum;index++) //查找當前第一個報警的變量所對應的聲音文件名,搜索的順序決定了優先級 { if (statusdata[index].playing) { statusdata[index].prevStatus=GetTagBit(data[index].tagname); if (ack_status) //確認報警變量 { ack_status=0; statusdata[index].playing=0; } else { if (0==hasfound) { hasfound=1; filename=data[index].soundname; } } } else { statusdata[index].playing=!statusdata[index].prevStatus && GetTagBit(data[index].tagname); statusdata[index].prevStatus=GetTagBit(data[index].tagname); if (statusdata[index].playing) { if(0==hasfound) { filename=data[index].soundname; hasfound=1; } } } } SetTagBit(ack_name,0); if (filename!=currfilename) //當要播放的聲音文件和當前正在播放的聲音文件不同時才播放新的聲音 { currfilename=filename; //修改當前正在播放的聲音文件名 if (NULL==currfilename) //如果沒有報警則停止播放聲音 { FullName[0]=0x0; PlaySoundA(NULL,NULL,0x2000|1|8); //停止播放聲音 } else //循環播放新的聲音文件 { strcpy(FullName,dirname); //復制目錄名 strcat(FullName,currfilename); //合成聲音文件全名 PlaySoundA(FullName,NULL,0x2000|1|8); //播放聲音 } } return 0; } |
|---|---|
|
|