Announcement

Collapse
No announcement yet.

Can someone please check this script... Thanks!

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

    Can someone please check this script... Thanks!

    I have this script for EZIO running. I modded it slightly so that it correctly updates status when the device triggers, but sometimes HS misses a status change. So I run the script with "EZIOPollDevices" to get a device status update. This works great 1 time. After that it always says "the script is already running waiting for it to end before running again." I do not know why this is. Also despite my config setting, this script never seems to time out.

    Any help would be greatly appreciated.

    Regards,
    CodeMonkey




    Code:
    '
    ' LAST UPDATE: 19 Oct 2007, Jeffry Dwight
    '
    ' This script assumes you are using the EZIO2x4 as follows:
    '
    '   1. The EZIO2x4 is configured with the default settings, except that
    '      relays 1 and 2 each have timers set to 2, the timers are enabled,
    '      and the timers are set to mean seconds. Configure these settings
    '      using SimpleHomeNet's utility.
    '
    '   2. Relays 1 and 2 are wired in parallel with garge door opener
    '      switches, so that actuating a relay is the same as pushing the
    '      opener button (and the auto-off timer from assumption 1 therefore
    '      provides releasing the opener button).
    '
    '   3. Inputs 1 and 2 are being used with dry contacts to monitor the
    '      status of garage doors operated by relays 1 and 2.
    '
    ' TO USE THIS SCRIPT:
    '
    '   1. Plug in your own EZIO2x4's Insteon address in g_szEZIO_Address
    '      below.
    '
    '   2. Place this script in your HomeSeer's scripts folder.
    '
    '   3. Add the this line:
    '
    '        hs.RunEx("EZIO2x4-Garage.vb","RegisterDevices",parm)
    '
    '      to your existing Insteon_ExtDevSupport.vb script's RegisterDevices
    '      routine (right after the Try is a good place).
    '
    '   4. You may use the HomeSeer devices this script creates in any of your
    '      HomeSeer scripts or events.
    '
    '   5. Your scripts/events may call EZIOPollDevices at any time to force a
    '      poll of inputs 1-4 and update status (not necessary if Insteon
    '      broadcasts are reliable in your home, but nice to have for times
    '      when things get out of sync).
    '
    '   6. Your scripts/events may call EZIOOperateRelay to switch on one of
    '      the relays (pass 1 or 2 as the parm to specify which relay).
    
    Const Private g_szScriptName		As String	= "EZIO2x4-Garage.vb"
    Const Private g_szEZIO_Address 		As String 	= "01.70.82"	' The Insteon address of the EZIO controller
    Const Private g_szEZIO_DevName 		As String 	= "EZIO1"	' A unique name for the EZIO device.
    Const Private g_szEZIO_DevLocation 	As String 	= "Garage"	' The location for the EZIO HomeSeer device info
    Const Private g_szEZIO_HouseCode 	As String 	= "G"           ' We are going to use this House Code
    Const Private g_dwEZIO_FirstDeviceCode	As Integer 	= 1		' The Device Code (DC) that will hold the first EZIO device
    Const Private g_bEZIO_Enabled		As Boolean 	= True          ' Set to True to enable EZIO2x4 support, False to disable
    Dim   Private g_bEZIO_Busy		As Boolean 	= False		' We need to know if EZIO device change messages are caused by our own functions
    Dim   Private g_bDebug 			As Boolean	= 0		' Enable for lots of nice logging in HomeSeer's log
    
    '
    ' ----- Call this method from the RegisterDevices() of Insteon_ExtDevSupport.vb
    '
    
    Public Sub RegisterDevices(ByVal parm As Object)
       Try
          g_bEZIO_Busy = False
    
          If g_bEZIO_Enabled Then
             hs.plugin("Insteon").ExtDev_RegisterExternalDeviceSupport(g_szEZIO_DevName,g_szEZIO_Address,g_szScriptName,"EZIOReceiveData")
             EZIOCreateDevices()
             hs.plugin("Insteon").ExtDev_TransmitToExternalDevice(g_szEZIO_DevName,&H7,&H46,0)	' turn off relay one
             hs.plugin("Insteon").ExtDev_TransmitToExternalDevice(g_szEZIO_DevName,&H7,&H46,1)	' turn off relay two
             EZIOPollDevices(vbNull)	' refresh with actual values reported by device
             EZIOProcessStatus(&hF0)	' we just set the relays off, so assume openers NOT operating
          End If
    
          hs.RegisterStatusChangeCB(g_szScriptName,"EZIOStatusChangeCallback")
    
        Catch ex As Exception
            hs.WriteLog(g_szScriptName, "Error in RegisterDevices " & ex.ToString)
        End Try
    End Sub
    
    '
    ' ----- The Insteon plug-in calls this routine every time a device changes
    '
    
    Public Sub EZIOStatusChangeCallback(ByVal parms)
       Dim hc	As String
       Dim dc	As Integer
       Dim Status 	As Integer
    
       Try
          If g_bEZIO_Enabled Then
    
             hc 	= parms(0)
             dc 	= parms(1)
             Status 	= parms(2)
    
             If (hc = g_szEZIO_HouseCode) AND (dc >= g_dwEZIO_FirstDeviceCode) AND (dc <= g_dwEZIO_FirstDeviceCode + 1) AND (g_bEZIO_Busy = False) Then
                If Status = 2 Then ' Turn On
                   hs.plugin("Insteon").ExtDev_TransmitToExternalDevice(g_szEZIO_DevName,&H7,&H45,(dc - g_dwEZIO_FirstDeviceCode))
                ElseIf Status = 3 Then ' Turn Off
                   hs.plugin("Insteon").ExtDev_TransmitToExternalDevice(g_szEZIO_DevName,&H7,&H46,(dc - g_dwEZIO_FirstDeviceCode))
                End If
             End If
    
          End If	' end if g_bEZIO_Enabled
    
       Catch ex As Exception
          hs.WriteLog(g_szScriptName,"Error in StatusChangeCallback:" & ex.ToString)
       End Try
    End Sub
    
    '
    ' ----- Operate EZIO relay x (may be called from external scripts or from within HomeSeer)
    '
    
    Public Sub EZIOOperateRelay(parms as object)
       Dim iDevice as Integer
    
       Try
          If g_bEZIO_Enabled Then
             iDevice = parms
             If iDevice >= 1 AND iDevice <= 2 Then
                hs.plugin("Insteon").ExtDev_TransmitToExternalDevice(g_szEZIO_DevName,&H7,&H45,iDevice - 1)
                if g_bDebug Then hs.WriteLog(g_szScriptname,"EZIOOperateRelay: Sending 0x45 for unit " & iDevice)
             Else
                hs.WriteLog(g_szScriptname,"EZIOOperateRelay: Was expecting 1 or 2 as parameter")
             End If
          End If
    
       Catch ex As Exception
          hs.WriteLog(g_szScriptName,"Error in EZIOOperateRelay: " & ex.ToString)
       End Try
      
    End Sub
    
    '
    ' ----- Poll EZIO (may be called from external scripts or from within HomeSeer)
    '
    
    Public Sub EZIOPollDevices(parms as object)
       Try
          If g_bEZIO_Enabled Then
             hs.plugin("Insteon").ExtDev_TransmitToExternalDevice(g_szEZIO_DevName,&H7,&H49,0)
                if g_bDebug Then hs.WriteLog(g_szScriptname,"EZIOPollDevices: Sending 0x49 to request report")
          End If
    
       Catch ex As Exception
          hs.WriteLog(g_szScriptName,"Error in EZIOPollDevices: " & ex.ToString)
       End Try
    End Sub
    
    '
    ' ----- The Insteon plug-in calls this routine every time there's data from our device
    '
    
    Public Sub EZIOReceiveData(ByVal InsteonData As String)
       Dim Data()		As String
       Dim Flags		As Long
       Dim Status		As Long
       Dim MsgType		As Long
    
       Try
          If g_bDebug Then hs.WriteLog(g_szScriptName,"Received Insteon Data: " & InsteonData)
          Data = Split(InsteonData, " ")
          
    
    
          If Data(0) = "ACK" Then ' This was an ACK response to a prior command. There is extra data here. The standard ACK will also be sent
    
             Select Case Val("&h" & Data(1))
                Case &H49 ' Ack was to a Sensor Report command
                   if g_bDebug Then EZIOSensorReport(Val("&h" & Data(2)), Val("&h" & Data(12)))
             End Select
    
          Else ' This is a standard Insteon message
    
             Flags = CLng("&H" & Data(7))
             If g_bDebug Then hs.WriteLog(g_szScriptName,"FlagsRaw=" & Hex$(Flags) & ", masked=" & Hex$(Flags AND &hE0))
    
             Select Case (Flags AND &hE0)
    
                Case &h80	' Broadcast transmissions from our device
                   MsgType = CLng("&h" & Data(8))	' 0x27 means input sensor status change
                   Status  = CLng("&h" & Data(9))	' bit-mapped, 0=all off, 1=1 on, 2=2 on, 3=1 and 2 on, etc.
                   If g_bDebug Then hs.WriteLog(g_szScriptName,"Got broadcast from our device: MsgType=" & Hex$(MsgType) & ", BitMap=" & Hex$(Status))
                   If MsgType = &H27 Then
                      EZIOProcessStatus(Status) ' Input sensor change status report
                   End If
    
                Case &h20	' Ack replies from our device to any other device
                   MsgType = CLng("&h" & Data(8))
                   Status  = CLng("&h" & Data(9))	' bit-mapped, 0=all off, 1=1 on, 2=2 on, 3=1 and 2 on, etc.
                   If g_bDebug Then hs.WriteLog(g_szScriptName,"Got ACK from command to our device: MsgType=" & Hex$(MsgType) & ", BitMap=" & Hex$(Status))
                   If MsgType = &H49 Or MsgType = &h45 OR MsgType = &h46 Then
                      EZIOProcessStatus(Status) ' Input sensor change status report
                   End If
    
                Case &hC0	' Group control broadcast commands from our device
                   EZIOProcessBroadcast(Val("&h" & Data(5)), Val("&h" & Data(7)))
    
                Case &hA0	' Nak replies from our device to any other device
                   If g_bDebug Then hs.WriteLog(g_szScriptName,"NAK from our device to some other device")
                Case &h00	' Direct commands from our device to any other device
                   If g_bDebug Then hs.WriteLog(g_szScriptName,"Direct from our device to some other device")
                Case &h40	' Group control clean-up commands from our device
                   If g_bDebug Then hs.WriteLog(g_szScriptName,"Group Cleanup from our device")
    
          EZIOPollDevices(vbNull)	' refresh with actual values reported by device
    
    
                Case &h60	' Ack replies from our device to group clean-up commands from any device
                   If g_bDebug Then hs.WriteLog(g_szScriptName,"ACK to group cleanup")
                Case &hE0	' Nak replies from our device to group clean-up commands from any device
                   If g_bDebug Then hs.WriteLog(g_szScriptName,"NAK to group cleanup")
             End Select
    
          End If
    
       Catch ex As Exception
          hs.WriteLog(g_szScriptName,"Error in EzIOReceiveData: " & ex.ToString)
       End Try
    End Sub
    
    '
    ' ------ Create input and output virtual devices (only if they don't already exist)
    '
    
    Private Sub EZIOCreateDevices()
       Dim Lp     	As Integer
       Dim Ref    	As Long
       Dim dv     	As Object
       Dim dc     	As String
       Dim DevName	As String
       Dim Button   As String
       Dim Label    As String
    
       if g_bDebug Then hs.WriteLog(g_szScriptName,"EZIOCreateDevices(): Starting")
    
       Try
          g_bEZIO_Busy = True
    
          For Lp = 0 To 5
             dc = (g_dwEZIO_FirstDeviceCode + Lp).ToString
             If hs.DeviceExists(g_szEZIO_HouseCode & dc) = -1 Then
                Select Case Lp
                   Case 0,1
                      DevName = "Garage Opener " & (Lp + 1).ToString
                      Button  = g_szScriptName & "(""EZIOOperateRelay"",""" & Lp + 1 & """)"
                      Label   = "Operate"
                   Case Else
                      DevName = "Garage Door " & (Lp - 2 + 1).ToString
                      Button  = g_szScriptName & "(""EZIOPollDevices"",""0"")"
                      Label   = " Verify  "
                End Select
                Ref			= hs.NewDeviceRef  (DevName)
                dv  		= hs.GetDeviceByRef(Ref)
                dv.hc		= g_szEZIO_HouseCode
                dv.dc		= dc
                dv.can_dim		= False
                dv.location		= g_szEZIO_DevLocation
                dv.location2	= "auto-created"
                dv.misc     	= &h10
                dv.dev_type_string 	= "Status Only"
                hs.SetDeviceValue   (DevName,0)
                hs.SetDeviceString  (DevName,"Unverified",False)
                hs.SetDeviceStatus  (DevName,3)
                hs.SaveEventsDevices()
                hs.DeviceButtonAdd  (g_szEZIO_HouseCode & dc,Button,Label)
    	    hs.WriteLog         (g_szScriptName,"Created device " & DevName & " as " & g_szEZIO_HouseCode & dc)
             End If
          Next
    
       Catch ex As Exception
          hs.WriteLog(g_szScriptName,"Error in EZIOCreateDevices: " & ex.ToString)
       End Try
    
       g_bEZIO_Busy = False
       if g_bDebug Then hs.WriteLog(g_szScriptName,"EZIOCreateDevices(): Finished")
    End Sub
    
    '
    ' ----- helper function: returns numeric code meaning "on" or "off"
    '
    
    Private Function EZIOOnOffCode (ByVal Code as Byte) as Byte
       If Code Then
          EZIOOnOffCode = 2	' on
       Else
          EZIOOnOffCode = 3	' off
       End If
    End Function
    
    '
    ' ----- helper function: returns string representing device status
    '
    
    Private Function EZIODevStatus (ByVal Code as Byte,ByVal DC as Integer) as String
       Select Case DC	' NOTE: This is the DC, which is one more than the "real" device number!
          Case 1,2	' relays
             Select Case Code
                Case 2:    EZIODevStatus = "Moving"
                Case 3:    EZIODevStatus = "Stopped"
                Case Else: EZIODevStatus = "Unknown"
             End Select
    
          Case Else	' garage door sensors and fence gate sensors
             Select Case Code
                Case 2:    EZIODevStatus = "Closed"
                Case 3:    EZIODevStatus = "Open"
                Case Else: EZIODevStatus = "Unknown"
             End Select
       End Select
    End Function
    
    Private Function EZIODevValue (ByVal Code as Byte) As Long
       If Code = 2 Then
         EZIODevValue = 1
       ElseIf Code = 3 Then
         EZIODevValue = 0
       'ElseIf Code = 4 Then
       '  EZIODevValue = 50
       Else
         EZIODevValue = 999
       End If
    End Function
    
    Private Function EZIODevString(ByVal Code as Byte,DC as Integer) As String
       Select Case DC	' NOTE: This is the DC, which is one more than the "real" device number!
          Case 1,2	' relays
             Select Case Code
                Case 2:     EZIODevString = "Moving"
                Case 3:     EZIODevString = "Stopped"
                Case Else:  EZIODevString = "Unknown"
             End Select
          Case 3	' garage door sensors
             Select Case Code
                Case 2:     EZIODevString = "<font color=GREEN><b>Door Closed</b></font> at " & Now
                Case 3:     EZIODevString = "<font color=RED><b>Door Open</b></font> at " & Now
                Case Else:  EZIODevString = "<font color=BLUE><b>Unknown Status</b></font> at " & Now
             End Select
    	Case 4	' Car Sensor
             Select Case Code
                Case 2:     EZIODevString = "<font color=GREEN><b>Car in Garage</b></font> at " & Now
                Case 3:     EZIODevString = "<font color=RED><b>Garage Empty</b></font> at " & Now
                Case Else:  EZIODevString = "<font color=BLUE><b>Unknown Status</b></font> at " & Now
             End Select
          Case Else ' fence gate sensors
             Select Case Code
                Case 2:     EZIODevString = "<font color=GREEN><b>Gate Closed</b></font> at " & Now
                Case 3:     EZIODevString = "<font color=RED><b>Gate Open</b></font> at " & Now
                Case Else:  EZIODevString = "<font color=BLUE><b>Unknown Status</b></font> at " & Now
             End Select
       End Select
    End Function
    
    '
    ' ----- helper routine: changes virtual devices (only if new value differs from old value)
    '
    
    Private Sub EZIOSetIfChanged(ByVal HC as String,ByVal DC as String,ByVal NewCode as Byte)
       Dim OldCode    as Byte
       Dim OldStatus  as String
       Dim NewStatus  as String
       Dim NewValue   as Long
       Dim NewString  as String
    
       OldCode    = hs.DeviceStatus(HC & DC)
       OldStatus  = EZIODevStatus  (OldCode,DC)
    
       If OldCode <> NewCode Then
          NewStatus  = EZIODevStatus  (NewCode,DC)
          NewValue   = EZIODevValue   (NewCode)
          NewString  = EZIODevString  (NewCode,DC)
    
          hs.WriteLog(g_szScriptName,"EZIO " & HC & DC & " changed from " & OldStatus & " to " & NewStatus)
          hs.SetDeviceStatus(HC & DC,NewCode)
          hs.SetDeviceString(HC & DC,NewString,False)
          hs.SetDeviceValue (HC & DC,NewValue)
       ElseIf g_bDebug Then 
          hs.WriteLog(g_szScriptName,"EZIO " & HC & DC & " was already " & OldStatus & "; no change")
       End If
    End Sub
    
    '
    ' ----- helper routine: processes EZIO device change status messages
    '
    
    Private Sub EZIOProcessStatus(ByVal Status As Byte)
       If g_bDebug Then hs.WriteLog(g_szScriptName,"EZIOProcessStatus(): " & Hex$(Status))
    
       Try
          g_bEZIO_Busy = True
    
          If (Status > 127) Then
             EZIOSetIfChanged(g_szEZIO_HouseCode,(g_dwEZIO_FirstDeviceCode + 0).ToString,EZIOOnOffCode(Status AND 1))
             EZIOSetIfChanged(g_szEZIO_HouseCode,(g_dwEZIO_FirstDeviceCode + 1).ToString,EZIOOnOffCode(Status AND 2))
          Else
             EZIOSetIfChanged(g_szEZIO_HouseCode,(g_dwEZIO_FirstDeviceCode + 2).ToString,EZIOOnOffCode(Status AND 1))
             EZIOSetIfChanged(g_szEZIO_HouseCode,(g_dwEZIO_FirstDeviceCode + 3).ToString,EZIOOnOffCode(Status AND 2))
             EZIOSetIfChanged(g_szEZIO_HouseCode,(g_dwEZIO_FirstDeviceCode + 4).ToString,EZIOOnOffCode(Status AND 4))
             EZIOSetIfChanged(g_szEZIO_HouseCode,(g_dwEZIO_FirstDeviceCode + 5).ToString,EZIOOnOffCode(Status AND 8))
          End If
    
       Catch ex As Exception
          hs.WriteLog(g_szScriptName,"Error in EZIOProcessStatus: " & ex.ToString)
       End Try
    
       g_bEZIO_Busy = False
    End Sub
    
    '
    ' ----- helper routine: logs so-called "sensor reports"
    '
    
    Private Sub EZIOSensorReport(ByVal Sensor As Byte, ByVal Value As Byte)
       Try
          hs.WriteLog(g_szScriptName,"EZIOSensorReport: Unit=" & Sensor.ToString & ", State=" & Value.ToString)
    
       Catch ex As Exception
          hs.WriteLog(g_szScriptName,"Error in EZIOSensorReport: " & ex.ToString)
       End Try
    End Sub
    
    '
    ' ----- helper routine: processes EZIO device broadcasts
    '
    
    Private Sub EZIOProcessBroadcast(ByVal GroupNum As Byte, ByVal CmdNum As Byte)
       Dim dc	As String
    
       Try
          If g_bDebug Then hs.WriteLog(g_szScriptName,"EZIOProcessBroadcast: " & GroupNum.ToString & ", " & CmdNum.ToString)
          If GroupNum >= 1 AND GroupNum <= 4 Then	' makes SILLY assumption that sensor 1 is sending group 1, 2 sends 2, and so forth!
             dc = (g_dwEZIO_FirstDeviceCode + 2 + GroupNum).ToString
             Select Case CmdNum
                Case &H11: hs.SetDeviceStatus(g_szEZIO_HouseCode & dc, 2) ' Set to on
                Case &H13: hs.SetDeviceStatus(g_szEZIO_HouseCode & dc, 3) ' Set to off
             End Select
          End If
    
       Catch ex As Exception
          hs.WriteLog(g_szScriptName,"Error in EZIOProcessBroadcast: " & ex.ToString)
       End Try
    End Sub
    HomeSeer Version: HS3 Pro Edition
    Operating System: Microsoft Windows 10 Pro
    Processor Type and Speed: i7 - 3.26 GHz
    Total Physical Memory: 16Gig

    Plugins: BlBackup | EasyTrigger | FitbitSeer | HSTouchServer | Insteon | WeatherXML

    #2
    Have you tried running this through tenholde's tenscripting module?

    This would allow you to debug running scripts so you can better see what is going on.
    Nicolai L

    Comment


      #3
      CM, The "the script is already running waiting for it to end before running again" just started showing up for my similar scripts for the ezflora when I initialize my script in the insteon plugin. It might be something the plugin is doing, but I don't know that for sure.

      However, the "already running" messages come, but all of the correct communication and responses with the ezfloras happen.

      I think you'll need to put debugging code at the highest level and then deeper until you find where its missing. I had work on the Public Sub EZIOReceiveData(ByVal InsteonData As String). I don't remember the specifics, but the logic wasn't always right for me. There may be values coming across that are meaningful but don't fit the fit the case statements. Have a message write to the console for each message that comes back. I used msgbox or something like it. Its ugly, but the answer is revealed relatively quickly.

      Paul
      Paul

      Comment


        #4
        Thanks, I will see what I can do. I only know the very basics when it comes to scripting so it's kind of like getting dropped off in a foreign country and then trying to learn the language.

        CM
        HomeSeer Version: HS3 Pro Edition
        Operating System: Microsoft Windows 10 Pro
        Processor Type and Speed: i7 - 3.26 GHz
        Total Physical Memory: 16Gig

        Plugins: BlBackup | EasyTrigger | FitbitSeer | HSTouchServer | Insteon | WeatherXML

        Comment

        Working...
        X