YetAnotherForum
Welcome Guest Search | Active Topics | Log In | Register

Sound with multistate Options · View
tombro
#1 Posted : Monday, October 05, 2009 6:49:16 PM
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
Sponsor  
 

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.
RJK Solutions
#2 Posted : Monday, October 05, 2009 7:41:14 PM
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
tombro
#3 Posted : Tuesday, October 06, 2009 9:38:53 AM
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?
RJK Solutions
#4 Posted : Tuesday, October 06, 2009 10:29:14 AM
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
tombro
#5 Posted : Tuesday, October 06, 2009 12:58:57 PM
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?
RJK Solutions
#6 Posted : Tuesday, October 06, 2009 1:13:34 PM
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
tombro
#7 Posted : Tuesday, October 06, 2009 5:37:56 PM
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
Ana-Maria
#8 Posted : Wednesday, October 14, 2009 11:17:15 AM
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
".......................................
iremark
#9 Posted : Monday, December 21, 2009 2:25:02 PM
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.
RJK Solutions
#10 Posted : Monday, December 21, 2009 4:20:39 PM
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
iremark
#11 Posted : Wednesday, December 23, 2009 1:16:21 PM
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?
Michael
#12 Posted : Saturday, December 26, 2009 8:11:32 PM
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
RJK Solutions
#13 Posted : Sunday, December 27, 2009 8:01:33 PM
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
iremark
#14 Posted : Thursday, March 04, 2010 3:09:50 PM
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)

Michael
#15 Posted : Thursday, March 04, 2010 3:22:05 PM
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
RJK Solutions
#16 Posted : Thursday, March 04, 2010 3:28:30 PM
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
iremark
#17 Posted : Thursday, March 04, 2010 3:49:59 PM
Rank: Newbie
Groups: Member

Joined: 12/21/2009
Posts: 8
Location: Dublin
Sorry, got this working, simply put:

Call ToggleBlink(Value10, True)

Thanks again.
RJK Solutions
#18 Posted : Thursday, March 04, 2010 3:57:45 PM
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
iremark
#19 Posted : Thursday, March 04, 2010 4:01:43 PM
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.
iremark
#20 Posted : Thursday, March 04, 2010 4:05:24 PM
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.
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.