|
|
Rank: Newbie Groups: Member
Joined: 10/4/2009 Posts: 4
|
I am “rookie” with VBA on PI system I don’t know how to write a macro which allow run sound (e.g. *.wav sound from Windows folder) when the tag (Multistate) will reach specified value. Is it possible?. Thanks in advance
|
|
|
|
|
OSIsoft vCampus is a subscription-based, online offering that consists of providing everything people need to develop applications on the PI System. We invite you to take a "tour" of the OSIsoft Virtual Campus - also feel free to consult the FAQ or contact OSIsoft vCampus for more details.
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
Hi Tombro, Welcome to the forum. You can play a sound in reaction to an event, in this case the StateChanged event of a MultiStated symbol (where you check the currentstate property). You need to use the Win32 function "sndPlaySound32". Code: Declare Function sndPlaySound32 Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long
So you may have something like. Code:
Private Sub MySymbol_StateChanged(bCancelDefault As Boolean) If MySymbol.GetMultiState.CurrentState = 1 Then ' This is the alarm state, play a sound... Call sndPlaySound32("c:\MySoundFile.wav", 0) Else ' This is a normal state so ignore it... End If End Sub
Rhys. Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Newbie Groups: Member
Joined: 10/4/2009 Posts: 4
|
Thank you very much for so quick reply :-) I was proceeded according your suggestion, but something is wrong. Probably it is my incapacity in VB :-). I created the rectangle and attribute MultiState to it.  and put procedure to Module  Could you tell me what I did wrong?
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
The StateChanged event will be raised within "ThisDisplay" so you need to move the code from the "Module1" to "ThisDisplay". If in doubt, in the ThisDisplay VBA window you can select the objects from the left list and then the events for that object from the right hand list. Also, you need to decide which state it is you want to play a sound, I used CurrentState = 1 as an example. Make sure you EnableScripting for the symbol too (right click on the symbol in build mode). Rhys. Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Newbie Groups: Member
Joined: 10/4/2009 Posts: 4
|
The code was moved to "ThisDisplay". Declaration of function "sndPlay..." remain in "Module1" Scripting is enable The MultiState is changing its states but I still not hear the sound. I have checked library "winmm.dll" on system - exist. Speakers work well
I do not know what else should I check?
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
Try using the play sound code in its own method just to ensure the sound works. Something to note when checking your states. In the designer the states start "State 1, State 2..." but the CurrentState property is 0 based. So if you have State 1 (in designer) as your alarm state, you want to check for "If MySymbol.GetMultistate.CurrentState = 0". Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Newbie Groups: Member
Joined: 10/4/2009 Posts: 4
|
Thanks a lot :-) Now is working perfect. Problem was with defined status. I didn't know that is difference between designer mode and normal CurrentState.
By the way, how to set sound continous up to time when the status will change to previous value?
Thanks in advance
|
|
|
Rank: Member Groups: Member
Joined: 10/1/2008 Posts: 22 Location: Romania
|
Hi to all of you.
you can use a "do while " or "do until" - it depends on your conditions Here is my example
"--------------------------- Private Sub Display_DataUpdate() Do While MySymbol.GetMultiState.CurrentState = 0 If MySymbol.GetMultiState.CurrentState = 0 Then ' This is the alarm state, play a sound... Call sndPlaySound32("C:\OSXP\Help\Tours\WindowsMediaPlayer\Audio\Wav\wmpaud4.wav", 0) Else ' This is a normal state so ignore it... Exit Do End If Loop End Sub ".......................................
|
|
|
Rank: Newbie Groups: Member
Joined: 12/21/2009 Posts: 8 Location: Dublin
|
Hi all,
This is great i've used this code to start an alarm when a value changes. How would i now make the value flash when it changes. I was thinking of multistate but its not when a vlue is ablove a ceratin limit, i need it to flash whenever it changes. I then use a button to reset the alarm and flashing.
Thanks.
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
Hi iremark, Just curious, does your value not change often and this is why you want it to flash when it changes? To do this you would (well I would) make use of Multistate. You leave it multistated with no "blinking" then when the value changes, you access the Symbols MultiState and set blinking to True. Then when you click your button you access the MultiState again and set blinking to False. Enjoy! Rhys. Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Newbie Groups: Member
Joined: 12/21/2009 Posts: 8 Location: Dublin
|
Thank for this help.
Yes, the value might only change once per hour.
I was thinking about using multi states, but i wasn't sure how. With multi states i can get the value to blink when it goes above a certain limit, but how do i get it to blick everytime it changes?
|
|
|
Rank: Advanced Member Groups: Member
Joined: 12/3/2009 Posts: 71 Location: Germany/Pennsylvania
|
Hi iremark,
you can use a static or global variable to memorize the last currentstate of the multistate and set the blink property of the MSState if state is changed. Even in DataUpdate procedure or in the Statechanged event procedure of this symbol.
But how long the symbol should blink? You have to set the property blink = false after a certain period.
Another (maybe better) solution: you set blink=true for all states and set it false for the currentstate after the dedicated period. Do not forget to set back to true, once it is not longer the current!!
Hope this helps
Michael
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
Hi Mark, Sorry for the delay, too many mince pies and too much turkey! So you basically just add a Value symbol to your display and EnableScripting. Set the Multistate to just have 2 states (set the tag to be the same tag that you are displaying), both of which just have the same properties (e.g. Black font and NO blinking). Then with some VBA you can set the value to blink when Data is updated for that PI tag and reset the blinking when you click on the value. Code: Private Sub AlarmValue_Click(ByVal lvarX As Long, ByVal lvarY As Long) Call ToggleBlink(Symbols("AlarmValue"), False) End Sub
Private Sub AlarmValue_DataUpdate() Call ToggleBlink(Symbols("AlarmValue"), True) End Sub
Private Sub ToggleBlink(ByVal sym As Symbol, ByVal bBlink As Boolean)
If sym.IsMultiState Then Dim MState As MultiState, State As MSState, iState As Integer Set MState = sym.GetMultiState For iState = 1 To MState.StateCount Set State = MState.GetState(iState) State.blink = bBlink Set State = Nothing Next iState Call sym.SetMultiState(MState) Set MState = Nothing End If
End Sub
If you want some more logic in there, e.g. only blink for a certain State of your MultiState then you just add in that logic to your code. Enjoy. Rhys. Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Newbie Groups: Member
Joined: 12/21/2009 Posts: 8 Location: Dublin
|
Hi,
Thanks for your help on this. I have only managed to get back to this now. I have copied in your code exactly, i just replaced the "AlarmValue" with my value name "value10". When i execure, i get an "Automation Error". Am i doing this correctly?
Call ToggleBlink(Symbols("value10"), False)
|
|
|
Rank: Advanced Member Groups: Member
Joined: 12/3/2009 Posts: 71 Location: Germany/Pennsylvania
|
Hi Mark
There were many reason to get such an automation error.
Set a breakpoint at the update procedure to see when the error occures.
BTW: You configured value10 as Multistate correctly?
Michael
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
Check the case of your symbol name too, it looks like a ProcessBook auto name so likely is "Value10". Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Newbie Groups: Member
Joined: 12/21/2009 Posts: 8 Location: Dublin
|
Sorry, got this working, simply put:
Call ToggleBlink(Value10, True)
Thanks again.
|
|
|
Rank: Administration
 Groups: Administration
Joined: 6/20/2008 Posts: 617 Location: Cheshire, United Kingdom.
|
Mark, Either of these will work Call ToggleBlink(Value10, True) ' Direct reference to the symbol. 'Fully qualified = Call ToggleBlink(ThisDisplay.Value10, True) Call ToggleBlink(Symbols("Value10"), True) ' Reference to the symbol in the Symbols collection. Note, ProcessBook is sensitive over the case of the name. 'Fully qualified = Call ToggleBlink(ThisDisplay.Symbols("Value10"), True) Principal Consultant Real-Time Data Management @ Wipro Technologies
|
|
|
Rank: Newbie Groups: Member
Joined: 12/21/2009 Posts: 8 Location: Dublin
|
While i have you there, as well as having the value blink, i'm looking to set it's color to red, then set it back to black when i click. Struggling a little. Thanks.
|
|
|
Rank: Newbie Groups: Member
Joined: 12/21/2009 Posts: 8 Location: Dublin
|
Sorry, jumped the gun again, had a moment of inspiration, managed to get it working.
|
|
|
|
Guest
|