Announcement

Collapse
No announcement yet.

X10 Script.. timing issue, maybe? [Issue closed]

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

    X10 Script.. timing issue, maybe? [Issue closed]

    I have been fighting an X10 issue for a while now and can not figure out what I am doing wrong. When my freezer is opened, a DS10 calls an event that turns on an X10 status light and then calls a script. When the script gets control, the status light does NOT appear to be on, and of course any test for an on status fails. Why? What am I missing here?

    Thanks
    Gary

    Last edited by mfisher; April 17, 2018, 08:43 AM.

    #2
    Your script is properly reporting the status device C3 at the instant it is being called, which is Off. Although your log entries make it appear that the device was turned on before your freezer script reports, in my experience you cannot trust the order of log entries that occur within a very short time span of one another.

    When dealing with X10 you'll want to remember that it takes a long time (in computer time) to send data over the power line. The issue here is that the device status in HS is not updated when you send the command, but after the X10 plugin receives an acknowledge from the X10 hardware that the command was actually sent. Since it takes slightly under a second for the 'C3 CON' command to get sent on the power line by the X10 hardware, plus a little time for the X10 plugin to receive the ack and update the device in hs, you'll want to wait for all of this to occur before checking the device status.

    In this case you are calling the first script to turn the device on, your script sends the C3 CON command and immediately exits, then your second script is called before the X10 data has been sent and the device in HS is updated.

    There are several possible solutions to this:
    1) Add a 1-2 second delay between the two script calls to allow time for the X10 data to be sent.

    2) In your FreezerOpen code, watch the HS device for a status change to ON before proceeding (include a timeout in case the X10 transmission never gets through.)

    3) In your event that calls Exec10() in the X10 plugin, set the 'Wait for script to complete' (or whatever its called, I don't have access to my HS system this moment) so that HS waits until your script finishes. Then in your script, use ExecX10Wait() instead instead of ExecX10() when calling into the X10 plugin to send your X10 data. This will cause the X10 plugin to wait until it receives an ack from the hardware before returning to your script.


    Here are the details of what I suspect is happening:

    1) FreezerOpen event calls your script Main(EXECX10)
    2) --Main(EXECX10) calls into the X10 plugin (assuming you're calling using PluginFunction(ExecX10,...))
    3) ----The X10 plugin compiles the X10 codes, sends them to the X10 interface and exits.
    4) ------X10 interface begins to transmit data on power line. (for C3 CON this takes about 0.8 seconds @ 60Hz.)
    5) ----X10 plugin returns. (Note that it does not update the device status in HS at this point!)
    6) --Main(EXECX10) exits
    7) FreezerOpen event calls script Main(FreezerOpen)
    8) --FreezerOpen sub checks the device in HS, which has not yet been updated by the X10 plugin, and calls hs.WriteLog() with the results.
    9) X10 hardware completes transmission of data on the powerline and acknowledges transmission to the X10 plugin
    10) X10 plugin validates the previously sent command, then calls into HS using CAPI to update the status of the device in HS. Note that CAPI() calls hs.WriteLog() (or another internal HS log routine) to create a log entry.
    11) X10 plugin checks for any triggers for this device and exits
    12) The log entries for the CAPI call and your FeezerOpen script happen close to each other (within the same second) and get logged in the wrong order.

    Hope this helps to clear things up!
    Best regards,
    -Mark-

    If you're not out on the edge, you're taking up too much room!
    Interested in 3D maps? Check out my company site: Solid Terrain Modeling

    Comment


      #3
      Interesting Mark, thanks much for the detailed insight. You have given me renewed direction in several areas.

      Originally posted by mfisher View Post
      There are several possible solutions to this: ...

      3) In your event that calls Exec10() in the X10 plugin, set the 'Wait for script to complete' (or whatever its called, I don't have access to my HS system this moment) so that HS waits until your script finishes. Then in your script, use ExecX10Wait() instead instead of ExecX10() when calling into the X10 plugin to send your X10 data. This will cause the X10 plugin to wait until it receives an ack from the hardware before returning to your script.
      As a test, to see how long it really takes for (HS3/X10 plug-in) to REALLY turn on the device, I inserted this code into the FreezerOpen function (after the Dim bDebug...)

      Code:
                  Do Until lngX = 100
                      If hs.DeviceValue(DvRef("C3")) > 0 Then Exit Do
                      Threading.Thread.Sleep(1)               ' Sleep for 1 millisecond
                      lngX = lngX + 1
                  Loop
                  hs.WriteLog(strPgm, strSub & "->intX Loop Count =" & CStr(lngX))
      I ended up with the 1 millisecond, in the Thread.Sleep, after trying larger values. To this point, I have not seen a loop count greater that 2 milliseconds and many have been only 1. I concede there are many ways to view this condition. But my question is why is CAPI returning to the caller before the device status is set to the value requested by the caller? It just seems that CAPI would be the superior location to insert the wait. I mean, providing for a return code (or something) in case the ack does not happen within X milliseconds.

      2) --Main(EXECX10) calls into the X10 plugin (assuming you're calling using PluginFunction(ExecX10,...))
      No, I am calling hs.CAPIControlHandler (see code below), which may have something to do with this problem. However, I am not testing the CAPIControlResponse, because I am not sure what the response values really mean. I had commented out the call to the PluginFunction several years back, when I was having other issues with X10 in the early days of HS3. I don't remember the details of what issues or for sure that NOT calling the PluginFunction fixed the problem. Would calling the PluginFunction instead negate the need for the wait in my code?

      Code:
          [B]Public Function EXECX10(ByVal ParamArray aParms() As String) As Boolean ' Turn X10 Device ON/OFF, two Parameters Required[/B]
              'aParms(0) = X10 device code (hc/dc)
              'aParms(1) = ON or OFF
              Const strSub As String = ":EXECX10 "            ' Define Subroutine name
              Dim objCAPIControl As CAPIControlResponse       ' Define CAPIControl Response object
              Dim intRef As Integer                           ' Device Reference Integer
              Const prmDv As Integer = 0                      ' Device Index into Param array
              Const prmOnOff As Integer = 1                   ' Device Index into Param array
              Try
                  If bDebug Then hs.WriteLog(strPgm, strSub & "->Entered #1, UBound(aParms)=" & UBound(aParms)) ' Write Entry to Log
                  If UBound(aParms) <> 1 Then Throw New System.Exception("Wrong number of parameters passed, 2 Required! " & UBound(aParms) & " was Passed!") ' Q. Were two parms passed A. No, then throw exception
                  intRef = hs.DeviceExistsCode(aParms(prmDv)) ' Get the Device Reference for the X10 Code passed
                  If intRef <= 0 Then Throw New System.Exception("Device Reference to " & aParms(prmDv) & " was NOT Found!") ' Q. Valid Reference A. No, then throw exception
                  If UCase(aParms(prmOnOff)) = "OFF" Then             ' Q. Is the caller requesting a Device OFF A. Yes, then...
                      objCAPIControl = hs.CAPIControlHandler(hs.CAPIGetSingleControl(intRef, True, "Off", False, False)) ' Set the Device ON
                      If objCAPIControl.ToString <> "All_Success" Then Throw New System.Exception("CAPI X10 Response Exception: " & vbCrLf & objCAPIControl.ToString & vbCrLf & "Device parm = " & aParms(prmDv) & ", Function = " & aParms(prmOnOff) & "!") ' Q. Valid CAPI Response A. No, then throw exception
                      ' hs.PluginFunction("X10", "", "ExecX10", {aParms(prmDv), "Off", 0, 0, True}) ' Set the Device OFF
                  ElseIf UCase(aParms(prmOnOff)) = "ON" Then          ' Q. Is the caller requesting a Device ON A. Yes, then...
                      objCAPIControl = hs.CAPIControlHandler(hs.CAPIGetSingleControl(intRef, True, "On", False, False)) ' Set the Device OFF
                      If objCAPIControl.ToString <> "All_Success" Then Throw New System.Exception("CAPI X10 Response Exception: " & vbCrLf & objCAPIControl.ToString & vbCrLf & "Device parm = " & aParms(prmDv) & ", Function = " & aParms(prmOnOff) & "!") ' Q. Valid CAPI Response A. No, then throw exception
                      ' hs.PluginFunction("X10", "", "ExecX10", {aParms(prmDv), "On", 0, 0, True}) ' Set the Device OFF
                  Else                                        ' A. None of the above, then...
                      Throw New System.Exception("Invalid ON/OFF parameter for " & aParms(prmDv) & "!") ' Throw invalid ON/OFF parm passed exception
                  End If                                      ' endif testing the ON/OFF parm passed
                  EXECX10 = True                              ' Set Return code to successful
                  If bDebug Then hs.WriteLog(strPgm, strSub & "->Exit #1") ' Write Entry to Log
              Catch ex As Exception                           ' Exception Handling routine
                  hs.WriteLog(strPgm, strSub & "->Execution Exception = " & ex.ToString) ' Log error Message
                  EXECX10 = False                             ' Set Return Code to failure
              End Try                                         ' End Try/Catch
      
          End Function

      Comment


        #4
        Which X10 interface are you using?
        What OS is the plugin running under?

        If you are using the X10 plugin (and not the CM15a plugin) you might try calling ExecX10 in the plugin instead of using CAPI and setting the 'wait' flag so that the plugin waits for the ack before returning. Here's the definition of that sub in the plugin:
        Code:
        Public Function ExecX10(ByVal code As String, ByVal cmd As String, Optional ByVal dimv As Integer = 0, Optional ByVal data2 As Integer = 0, Optional ByVal wait As Boolean = False) As String
        Also note that you cannot use hs.PluginFunction() in HS3. See the first post in this thread for details on how to call functions in the X10 plugin.
        Best regards,
        -Mark-

        If you're not out on the edge, you're taking up too much room!
        Interested in 3D maps? Check out my company site: Solid Terrain Modeling

        Comment


          #5
          Originally posted by mfisher View Post
          Which X10 interface are you using?
          What OS is the plugin running under?
          Sorry should have included this info (see below) in my original post.

          If you are using the X10 plugin (and not the CM15a plugin) you might try calling ExecX10 in the plugin instead of using CAPI and setting the 'wait' flag so that the plugin waits for the ack before returning.
          Yes, I am using the X10 plugin, using a CM11a. Is calling the X10 plug-in ExecX10 function with the wait what you recommend/use?

          Thanks
          Gary

          Current Date/Time: 3/28/2018 12:27:34 PM
          HomeSeer Version: HS3 Pro Edition 3.0.0.423
          Operating System: Microsoft Windows 8.1 Pro with Media Center - Work Station
          System Uptime: 2 Days 20 Hours 26 Minutes 53 Seconds
          IP Address: 192.168.1.83
          Number of Devices: 249
          Number of Events: 68
          Available Threads: 800
          HSTouch Enabled: True
          Event Threads: 0
          Event Trigger Eval Queue: 0
          Event Trigger Priority Eval Queue: 0
          Device Exec Queue: 0
          HSTouch Event Queue: 0
          Email Send Queue: 0
          Anti Virus Installed: Windows Defender Malwarebytes

          Enabled Plug-Ins
          2.0.54.0: BLOnkyo
          2.18.0.3: MCSSPRINKLERSP
          30.0.0.36: RFXCOM
          3.0.6551.16959: UltraGCIR3
          3.0.0.40: X10
          3.0.1.190: Z-Wave

          Comment


            #6
            Thanks for the interface and OS info. As an experiment, instead of using CAPI I would try calling ExecX10() in the X10 plugin with the wait flag set and see what happens. Be sure to review how to call ExecX10() before doing this: https://forums.homeseer.com/showthread.php?t=178701
            Best regards,
            -Mark-

            If you're not out on the edge, you're taking up too much room!
            Interested in 3D maps? Check out my company site: Solid Terrain Modeling

            Comment


              #7
              Thanks much for the feedback Mark. For now, mainly for stability, I think I will continue to use my EXECX10 script function. I added the thread.Sleep(1) loop (above) to it with an optional WAIT parameter, so the default (false or missing) will continue to "speed" through. The few instances where an X10 device is tested immediately after being set such as this one, I set the wait parameter to true and it goes though the sleep loop. So far so good, so we will see. Thanks for all your help.

              Gary

              Comment

              Working...
              X