Announcement

Collapse
No announcement yet.

Script parameters without using events?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Script parameters without using events?

    Hello,
    I'd like to first start by saying that I am new to VB.net, an I am very grateful to Tenholder for writing tenScripting3 and recording such great intro videos so that novices such as myself can actually tinker, your contribution is appreciated and I am grateful!

    I'm working on a script that will provide some missing functionality. I want to be able to fine tune the volume controls of a device by whatever increment I choose. When I try to run the script via HSTouch I receive the following error:

    Running script ChangeVolume.vb :Exception has been thrown by the target of an invocation.->Does entry point Main exist in script? at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Obj ect obj, Object[] parameters, Object[] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at Scheduler.clsRunVBNetScript.ExecuteScript()


    My script is as follows:

    Code:
    Public Class ChangeVolume
        Public Sub Main(ByVal Parms As Object)
            Dim ParmArray(10) As String
    
            ' Extract script parameters into ParmArray()
            ' Parms(0) Device ID
            ' Parms(1) String representing action type (i.e. inc or dec)
            ' Parms(2) Integer indicating incremental step (i.e. 1, 2, 5 etc) 
    
            If Parms.ToString.Contains("|") Then
                ParmArray = Parms.ToString.Split(Convert.ToChar("|"))
            Else
                hs.WriteLog("Change Volume:", "No delimiter found, parsing skipped.")
    
            End If
    
            hs.WriteLog("Before IF", ParmArray(0) + " " + ParmArray(1) + " " + ParmArray(2))    '@DONOTEXPORT
    
            '' Get the current device volume level
            Dim theStatus As Integer = hs.DeviceValueEx(ParmArray(0))
            hs.WriteLog("theStatus declared: ", ParmArray(0) + " " + ParmArray(1) + " " + ParmArray(2) + " " + theStatus.ToString) '@DONOTEXPORT
    
            '' Check requested command and incremental level and perform requested action
            If ParmArray(1).Contains("inc") Then
                theStatus += ParmArray(2)
                hs.CAPIControlHandler(hs.CAPIGetSingleControl(ParmArray(0), True, "Vol " & theStatus, False, False))
                hs.WriteLog("Changed Volume +: ", ParmArray(0) + " " + ParmArray(1) + " " + ParmArray(2) + " " + theStatus.ToString) '@DONOTEXPORT
            Else
                theStatus -= ParmArray(2)
                hs.CAPIControlHandler(hs.CAPIGetSingleControl(ParmArray(0), True, "Vol " & theStatus, False, False))
                hs.WriteLog("Changed Volume -: ", ParmArray(0) + " " + ParmArray(1) + " " + ParmArray(2) + " " + theStatus.ToString) '@DONOTEXPORT
            End If
    
        End Sub
    End Class
    I have 4 audio zones, and my goal is to create 4 volume buttons per zone. 2 buttons for single volume increments/decrements, and 2 buttons for increments/decrements in steps of 5. If I use events, that would require 16 events. I would prefer to send parameters using HSTouch.

    I wrote this script using tenScripting3 and tested it with the same, using parameters delimited by the pipe "|". After successfully importing the script into HS3, I tested again using a button and a few text elements, using "Homeseer: Run a Homeseer script with values from elements" by setting the text values and then calling the script with the values from the text elements as parameters. However the above error always shows up in the log when I press the button in HSTouch.

    I suspect that the parameters are not being parsed correctly since I am not able to send a pipe "|" using HSTouch. My main issue is that I do not know what format the parameters are getting to the script, let alone how to parse them, since the Parms variable is an Object, not a string. I did try Parms(0), Parms(1), and Parms(2), but Visual Studio Express 2017 throws an error "Late bound resolution; runtime errors could occur."

    Can anyone provide some insight on how I would be able to properly receive and parse the parameters being sent in HSTouch?

    Thank you in advance!

    #2
    There's another thread started today with the same topic: https://forums.homeseer.com/forum/de...32-weird-error
    HS 4.2.8.0: 2134 Devices 1252 Events
    Z-Wave 3.0.10.0: 133 Nodes on one Z-Net

    Comment


      #3
      Yes, HomeSeer Events and HsTouch handle script parameters differently. HomeSeer Events will pass only a single string to the script as a parameter, that is why many folks use the | delimiter to separate actual paramters passed to a script from an event. However, HsTouch passes multiple parameters as members of an array of strings.

      That is why tenScripting has a checkbox for you to select if you are testing a script for HS Events or HsTouch. If you UNCHECK Process as HS parms, then tenScripting will pass to your script an array of strings. You separate individual parameters by a comma(,).
      tenholde

      Comment


        #4
        Yes I read through it, but there is no real solution. The thread does mention that HSTouch will provide a string array containing one or more strings, so I wrote this little script below to see what HSTouch is actually passing to the script. I get the same error.

        Perhaps I am not passing the parameters correctly from HSTouch?

        Here is the test script, and a screenshot of how I have setup the actions for when the button is released. Any suggestions?

        Code:
        Public Class GetParams
            Public Sub Main(ByVal Parms As String)
                For Each param As String In Parms
                    hs.WriteLog("GetParams: ", param)
                Next
            End Sub
        End Class
        Click image for larger version

Name:	ActionType.png
Views:	399
Size:	25.9 KB
ID:	1281857

        Comment


          #5
          I would try removing the initial "class" statement, as it might be causing problems (and the "end class" of course).

          Your Main() declaration indicates that you will be receiving only one string, whereas HSTouch passes more than one. I would change the declaration to "object" instead of "string",

          Note that the Vertical bar or comma or whatever that is used to separate parameters is utilized so that only one string is passed. You want multiple strings, so delimiters are not relevant.

          Comment


            #6
            What I would do is combine all of your parameters into one, using a delimiter. In the example below, I am using a period to separate the parameters. The following does work when called by HS or HStouch:

            Code:
            Public Sub Main(parms As Object)
              Dim uid As String = ""
              If parms isNot nothing Then uid = parms.ToString
              If Trim(uid) = "" Then uid = "0.0.0.0"
              Dim parm() As String = Split(uid,".") ' Input like "9.120.100.100"
              ...
            End Sub

            Comment


              #7
              Originally posted by tenholde View Post
              Yes, HomeSeer Events and HsTouch handle script parameters differently. HomeSeer Events will pass only a single string to the script as a parameter, that is why many folks use the | delimiter to separate actual paramters passed to a script from an event. However, HsTouch passes multiple parameters as members of an array of strings.

              That is why tenScripting has a checkbox for you to select if you are testing a script for HS Events or HsTouch. If you UNCHECK Process as HS parms, then tenScripting will pass to your script an array of strings. You separate individual parameters by a comma(,).
              Thank you tenholde. You're suggestion to uncheck the box allowed me to further experiment and find a solution. I ended up using a For Each to loop through the Parms Object to put put each parameter in an array, and then assign them to more appropriately named string variables, as below. Is there a more efficient way to get them into the string variables? I suspect I am doing double the work by first parsing them and then assigning, but I don't know of a way to reference a specific string in the For Each statement?

              Code:
              Dim ParmArray(10) As String
              
                      '' Retrieve parameters
                      '' Parms(0) Device ID
                      '' Parms(1) String representing action type (i.e. inc or dec)
                      '' Parms(2) Integer indicating incremental step (i.e. 1, 2, 5 etc) 
                      Dim strDeviceRef As String
                      Dim strAction As String
                      Dim strIncrement As String
              
                      Dim index As Integer = 0
                      For Each param As String In Parms
                          ParmArray(index) = param
                          index += 1
                      Next
              
                      strDeviceRef = ParmArray(0)
                      strAction = ParmArray(1)
                      strIncrement = ParmArray(2)

              Comment


                #8
                I think something like this should work. Cannot test, as I do not use HsTouch:

                Code:
                 Public Sub Main(ByVal ParmArray() As String)
                        '' Retrieve parameters
                        '' Parms(0) Device ID
                        '' Parms(1) String representing action type (i.e. inc or dec)
                        '' Parms(2) Integer indicating incremental step (i.e. 1, 2, 5 etc) 
                        Dim strDeviceRef As String
                        Dim strAction As String
                        Dim strIncrement As String
                        strDeviceRef = ParmArray(0)
                        strAction = ParmArray(1)
                        strIncrement = ParmArray(2)
                    End Sub
                tenholde

                Comment


                  #9
                  Okay, I admit to being a little confused by the comments above. What am I missing?

                  In post #4, it appears that the OP is trying to pass literal values to the script. The fields instead should be HS touch element names (with the actual parameter found in that element's text). As far as I can see, there is no way to pass literal parameters to HS script calls (with this particular HS Touch action) without the use of additional elements. Is this not true?

                  In VB, objects can contain strings or arrays of strings. If your script is expecting the possibility of arrays of string, you could use code something like:

                  Code:
                  Public Sub Main(ByVal parms As Object)
                    Dim buff As String = ""
                    If parms.GetType().ToString = "System.String" Then ' Simple string
                      buff = parms.ToString
                    Else ' parms.GetType().ToString contains "System.String[]"
                      buff = parms(0).ToString
                    End If
                    ...
                  End Sub
                  From what I can tell, HS Touch will pass a simple non-array string if there are zero or one parameters. I have not verified this, but I assume that more than one parameter will cause HS Touch to pass a string array.

                  Comment


                    #10
                    Originally posted by aa6vh View Post
                    Okay, I admit to being a little confused by the comments above. What am I missing?

                    In post #4, it appears that the OP is trying to pass literal values to the script. The fields instead should be HS touch element names (with the actual parameter found in that element's text). As far as I can see, there is no way to pass literal parameters to HS script calls (with this particular HS Touch action) without the use of additional elements. Is this not true?

                    In VB, objects can contain strings or arrays of strings. If your script is expecting the possibility of arrays of string, you could use code something like:

                    Code:
                    Public Sub Main(ByVal parms As Object)
                    Dim buff As String = ""
                    If parms.GetType().ToString = "System.String" Then ' Simple string
                    buff = parms.ToString
                    Else ' parms.GetType().ToString contains "System.String[]"
                    buff = parms(0).ToString
                    End If
                    ...
                    End Sub
                    From what I can tell, HS Touch will pass a simple non-array string if there are zero or one parameters. I have not verified this, but I assume that more than one parameter will cause HS Touch to pass a string array.
                    Could you try verifying your last assertion please.
                    tenholde

                    Comment


                      #11
                      Originally posted by tenholde View Post
                      Could you try verifying your last assertion please.
                      What part do you want me to verify again?

                      Comment


                        #12
                        Originally posted by tenholde View Post
                        I think something like this should work. Cannot test, as I do not use HsTouch:

                        Code:
                        Public Sub Main(ByVal ParmArray() As String)
                        '' Retrieve parameters
                        '' Parms(0) Device ID
                        '' Parms(1) String representing action type (i.e. inc or dec)
                        '' Parms(2) Integer indicating incremental step (i.e. 1, 2, 5 etc)
                        Dim strDeviceRef As String
                        Dim strAction As String
                        Dim strIncrement As String
                        strDeviceRef = ParmArray(0)
                        strAction = ParmArray(1)
                        strIncrement = ParmArray(2)
                        End Sub
                        Thank you and tenholde for your replies!

                        I think I prefer the example quoted above as it is clearer to me and allows me to visually understand that I am picking each passed parameter and saving into a variable.

                        I will try that asap and report back.

                        Comment


                          #13
                          Originally posted by nuttynet View Post

                          Thank you and tenholde for your replies!

                          I think I prefer the example quoted above as it is clearer to me and allows me to visually understand that I am picking each passed parameter and saving into a variable.

                          I will try that asap and report back.
                          Fair enough. There are a lot of different ways in coding to accomplish the same thing, and they are not wrong.

                          It probably is not an issue for you, but be aware that if you want to use that same function in a HS event, you will get a run time error because of the incompatibility between an array of strings and a simple string. Using an Object like I described will prevent that run time error. (You could even get that run time error from HS Touch should it decide to pass a simple string instead of the array of strings, which I have seen it do).

                          Comment


                            #14
                            Originally posted by aa6vh View Post

                            Fair enough. There are a lot of different ways in coding to accomplish the same thing, and they are not wrong.

                            It probably is not an issue for you, but be aware that if you want to use that same function in a HS event, you will get a run time error because of the incompatibility between an array of strings and a simple string. Using an Object like I described will prevent that run time error. (You could even get that run time error from HS Touch should it decide to pass a simple string instead of the array of strings, which I have seen it do).
                            Thanks for the warning. I will keep it in mind. in fact I will try it both ways now, just to test the waters

                            Comment


                              #15
                              Originally posted by aa6vh View Post

                              What part do you want me to verify again?
                              That HsTouch passed parameters differently if you have only one, versus more than one.
                              tenholde

                              Comment

                              Working...
                              X