Announcement

Collapse
No announcement yet.

Serial Communication Question

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

    Serial Communication Question

    I've got my existing iTach devices working happily.

    Now I'm jumping into a new project... zoned lighting. I've acquired some Wattstopper LMRC-222 (2 load universal dimming room controllers). They can be chained together to create their own network of controllers and you can interface to them with a LMDI-100, a serial connection. Yay... maybe.

    I'm looking into buying a Global Cache GC-100-12 and hooking into the serial port on it from the LMDI-100. (yes this is overkill for this project, I'm planning on using it for another project as well - replacing some wireless security switches and an arduino project should I ever find time).

    GC-100-12 Serial Port Spec

    LMDI-100 Serial Data Interface

    LMDI-100 Serial Data Interface Host Commands


    That bit should be easy. The question is, can I (from what information I've given so far) receive the output from the LMDI-100 with the GC-100-12 serial port AND process it via this plugin?

    The commands coming from the LMDI-100 appear to be all ASCII
    The most basic command is:

    ECHO <text>
    Purpose Troubleshooting tool. The LMDI-100 interface will simply send back to the Host whatever text it receives.
    Parameters <text> Most printable text (no special characters allowed)
    Example Command ECHO are you there [CR]
    Response R: ECHO are you there [CR]

    From what I've seen on the forum it might be possible to base events on data coming in (parsing it and taking some action and then setting virtual devices to reflect system changes from the WattStopper switches making the actual changes). And finally actually send commands to the controllers to make changes without having to use the wall switches at all.

    I know this isn't an elegant solution but I think it might work - comments? Questions? etc? If this doesn't work I'll code up a serial port program to monitor and send commands to the LMDI-100 I guess.

    #2
    Not sure if the GC plugin will do what you want, but you should be able to use this plugin: http://board.homeseer.com/showthread.php?t=169754.

    The GC serial port will just map to the ip address and either port 4999 or 5000 (by default).

    Cheers
    Al
    HS 4.2.8.0: 2134 Devices 1252 Events
    Z-Wave 3.0.10.0: 133 Nodes on one Z-Net

    Comment


      #3
      That looks promising, I will give it a shot later and see!

      Comment


        #4
        Hi,

        Were you success in integrating the Watt Stopper to Homeseer? How did you eventually do it?

        Comment


          #5
          Short answer yes. And the system works just fine.

          The only problem is there is no "real time" update. I have an event that polls the LMDI-100 (Wattstopper) constantly, OK every couple minutes, because I don't need instant notification in HS about what the various load states are. But I do need to know what they are eventually.

          There is a script that takes input from a series of events (multiple events per load that basically pass in parameters to the script telling the script what commands to issue out on the COM port tied to the LMDI-100). Buttons in HSTouch call the various events.

          At least that's how I recall setting it up...

          The system works fine, if I remember right I had to step through all the loads and toggle them on/off because someone didn't document how the loads were wired originally.

          Comment


            #6
            Below is the script to control the lighting loads, it's self documented for the most part (thank god I did that much!)

            PHP Code:
            'Send Parameters in the form 
            '    
            targetsmanualz1...z20
            '    commands: get, set, or a valid command for the WattStopper LMDI 100 used with manual target
            '    
            value0-100, for future use, set to empty 
            'examples:
            '    
            manual|SCENE 1|empty
            '    get|z1|empty
            '    
            set|z4|empty
            '    set|z18|eventname
            '   
            manual|VERSION|empty
            '    manual|FORCEON 1 100|empty
            '    
            manual|FORCEONCANCEL 1|empty
            '    manual|CLEAN 1 100|empty
            '    
            manual|CLEANCANCEL 1|empty
            'Input is converted to lower case automatically
            '
            Future use:
            '    STATUS LOAD
            '        
            Force LMDI-100 to report all status changes instead of polling with GETLOAD 
            '        (could be less reliable if a status is missed thus using GETLOAD at 5min intervals
            '        
            to report changes from light switches or other events outside of the automation
            '        system)

            Text Strings 
            Imports System
            .Text

            ' Sleep / Timing
            Imports System.Threading

            Command Port Controls
            Imports System
            .IO.Ports
            Imports System
            .Object
            Public COMPort As New SerialPort()

            ' Global Debug Flag = 0 Off (default), 1 = On 
            Public Shared wfDebug As Integer = 1

            '
            ------------------------------------------------------------------------------
            ' WattStopper LMDI-100 Control 
            SubroutineMain
            ' Inputs: string, parameters separated with at pipe '|' character
            Parameter Meaning
            '    0 / target
            '    
            command
            '    2 / value
            Outputsreturns nothing
            '------------------------------------------------------------------------------
            Public Sub Main(ByVal oParms as Object)
                If wfDebug>0 Then
                    ' 
            info
                    hs
            .writelog("Info""WattStopper entered Main() LMDI-100 Control")
                
            End If

                
            ' Parameter Array 
                Dim aParam(2) As String
                aParam = oParms.ToString.Split("|")
                Dim sTarget As String = LCase(aParam(0))
                Dim sCommand As String = LCase(aParam(1))
                Dim sValue As String = LCase(aParam(2))
                Dim sEventName As String = ""
                Dim iValue As Integer = 0
                Dim sLightRef As String = ""
                Dim sLightSliderRef As String = ""
                Dim sLightZone As String = ""
                Dim iDimable As Integer = 0
                Dim oCOMString As Object
                Dim rxBuff As String = ""
                Dim txBuff As String = ""

                ' 
            Define the Communication Port we will use
                
            COMPort.PortName "COM2"
                
            COMPort.BaudRate 19200
                COMPort
            .Parity System.IO.Ports.Parity.None
                COMPort
            .DataBits 8
                COMPort
            .StopBits System.IO.Ports.StopBits.One
                Comport
            .ReadTimeout 5000
                
                
            If wfDebug>0 Then
                    
            ' info
                    hs.writelog("Info", "WattStopper Parameter received: '"& Convert.ToString(oParms) & "'")
                    hs.writelog("Info", "WattStopper Parameters converted: '"& sTarget & "', '" & sCommand & "', '" & sValue & "'")
                End If

                Select Case sTarget ' 
            Target Zone
                    
            Case "z1"
                        
            sLightZone "Stairwell Lights, No Dim"
                        
            iDimable 0
                        txBuff 
            txBuff "1"
                        
            sLightRef "857"
                    
            Case "z2"
                        
            sLightZone "Entrance Chandler, No Dim"
                        
            iDimable 0
                        txBuff 
            txBuff "2"
                        
            sLightRef "856"
                    
            Case "z3"
                        
            sLightZone "Basement Bar Lights, Supports Dimming"
                        
            iDimable 1
                        txBuff 
            txBuff "3"
                        
            sLightRef "854"
                        
            sLightSliderRef "855"
                    
            Case "z4"
                        
            sLightZone "Entertainment Wall Scones, Supports Dimming"
                        
            iDimable 1
                        txBuff 
            txBuff "4"
                        
            sLightRef "852"
                        
            sLightSliderRef "853"
                    
            Case "z5"
                        
            sLightZone "Kitchen Island Hanging Lights, Supports Dimming"
                        
            iDimable 1
                        txBuff 
            txBuff "5"
                        
            sLightRef "850"
                        
            sLightSliderRef "851"
                    
            Case "z6"
                        
            sLightZone "Kitchen Counter-top (Under Cupboards) Accent Lights, No Dim"
                        
            iDimable 0
                        txBuff 
            txBuff "6"
                        
            sLightRef "849"
                    
            Case "z7"
                        
            sLightZone "Basement Hallway Lights, Supports Dim"
                        
            iDimable 1
                        txBuff 
            txBuff "7"
                        
            sLightRef "847"
                        
            sLightSliderRef "848"
                    
            Case "z8"
                        
            sLightZone "Basement Bar Seating Hanging Lights, Supports Dim"
                        
            iDimable 1
                        txBuff 
            txBuff "8"
                        
            sLightRef "845"
                        
            sLightSliderRef "846"
                    
            Case "z9"
                        
            sLightZone "Kitchen Cabinet Interior Light (top), No Dim"
                        
            iDimable 0
                        txBuff 
            txBuff "9"
                        
            sLightRef "844"
                    
            Case "z10"
                        
            sLightZone "Deck Not Connected"
                        
            iDimable 1
                        txBuff 
            txBuff "10"
                        
            sLightRef "842"
                        
            sLightSliderRef "843"
                    
            Case "z11"
                        
            sLightZone "Great Room Pot Lights, Supports Dim"
                        
            iDimable 1
                        txBuff 
            txBuff "11"
                        
            sLightRef "840"
                        
            sLightSliderRef "841"
                    
            Case "z12"
                        
            sLightZone "Kitchen Pot Lights, Supports Dim"
                        
            iDimable 1
                        txBuff 
            txBuff "12"
                        
            sLightRef "838"
                        
            sLightSliderRef "839"
                    
            Case "z13"
                        
            sLightZone "Exterior South Eaves Lights, Supports Dim"
                        
            iDimable 1
                        txBuff 
            txBuff "13"
                        
            sLightRef "836"
                        
            sLightSliderRef "837"
                    
            Case "z14"
                        
            sLightZone "Exterior South Deck Eaves Lights, Supports Dim"
                        
            iDimable 1
                        txBuff 
            txBuff "14"
                        
            sLightRef "834"
                        
            sLightSliderRef "835"
                    
            Case "z15"
                        
            sLightZone "Kitchen Floor Accent Lights, No Dim"
                        
            iDimable 0
                        txBuff 
            txBuff "15"
                        
            sLightRef "832"
                    
            Case "z16"
                        
            sLightZone "Dining Room Chandler, Supports Dim"
                        
            iDimable 1
                        txBuff 
            txBuff "16"
                        
            sLightRef "830"
                        
            sLightSliderRef "831"
                    
            Case "z17"
                        
            sLightZone "Basement Pool Table Lights, Supports Dim"
                        
            iDimable 1
                        txBuff 
            txBuff "17"
                        
            sLightRef "828"
                        
            sLightSliderRef "829"
                    
            Case "z18"
                        
            sLightZone "Basement Dart Board Light, Supports Dim"
                        
            iDimable 1
                        txBuff 
            txBuff "18"
                        
            sLightRef "821"
                        
            sLightSliderRef "823"
                    
            Case "z19"
                        
            sLightZone "Basement Main Lights, Supports Dim"
                        
            iDimable 1
                        txBuff 
            txBuff "19"
                        
            sLightRef "824"
                        
            sLightSliderRef "825"
                    
            Case "z20"
                        
            sLightZone "Basement TV Area Lights, Supports Dim"
                        
            iDimable 1
                        txBuff 
            txBuff "20"
                        
            sLightRef "826"
                        
            sLightSliderRef "827"
                    
            Case "manual"
                        
            txBuff ""
                    
            Case Else
                        
            ' Unrecognised target supplied, report error and exit
                        If wfDebug>0 Then
                            ' 
            Error
                            hs
            .writelog("Error""WattStopper target not found '"sTarget "'")
                        
            End If
                        Exit 
            Sub
                End Select

                
            If wfDebug>and sTarget<>"manual" Then
                    
            ' info
                    hs.writelog("Info", "WattStopper Zone (" & txBuff & ") " & sLightZone)
                    hs.writelog("Info", "WattStopper HomeSeer Reference ID = '" & sLightRef)
                    hs.writelog("
            Info", "WattStopper Dimming Enabled ='" & Convert.ToString(iDimable) & "' Ref ID '" & sLightSliderRef & "'")
                End If
                
                'Get or Set:    Get - Update virtual device with load/zone value
                '                Set - Set the actual device with the virtual load/zone value
                If sCommand = "
            get" or sCommand = "set" Then
                    sEventName = sValue
                    ' Disable Event(s) to stop them from re-triggering during execution
                    If wfDebug>0 Then 
                        ' info
                        hs.writelog("
            Info", "WattStopper disable event '" & sEventName & "'")
                    End If
                    hs.DisableEvent(sEventName)
                    If Right(sEventName,1) = "
            s" Then
                        ' Disable Events
                        If wfDebug>0 Then 
                            ' info
                            hs.writelog("
            Info", "WattStopper disable event '" & Left(sEventName, Len(sEventName)-1) & "'")
                        End If
                        hs.DisableEvent(Left(sEventName, Len(sEventName)-1))
                    ElseIf iDimable>0 Then
                        ' Disable Events
                        If wfDebug>0 Then 
                            ' info
                            hs.writelog("
            Info", "WattStopper disable event '" & sEventName & "s" & "'")
                        End If
                        hs.DisableEvent(sEventName & "
            s")
                    End If
                End If

                Select Case sCommand
                    Case "
            get"
                        txBuff = "
            GETLOAD " & txBuff
                    Case "
            set"
                        If Right(sEventName,1) = "
            s" Then
                            ' Use the Slider Value to set light level (1-100)
                            iValue = Convert.ToInt32(hs.DeviceValue(Convert.ToInt32(sLightSliderRef)))
                            If wfDebug>0 Then 
                                ' info
                                hs.writelog("
            Info", "WattStopper using slider value '" & Convert.ToString(iValue) & "'")
                            End If
                        Else
                            ' Use the Button Value to set light level (on / off)
                            iValue = Convert.ToInt32(hs.DeviceValue(Convert.ToInt32(sLightRef)))
                        End If
                        If (iValue < 1) Or (iValue = 255) Then
                            sValue = "
            0"
                        ElseIf (iValue > 99) And (iValue < 255) Then
                            sValue = "
            100"
                        ElseIf (iValue > 0) And (iValue < 100) Then
                            sValue = Convert.ToString(iValue)
                        Else
                            ' Invalid Lighting Value
                            If wfDebug>0 Then
                                ' info
                                hs.writelog("
            Error", "WattStopper target zone (" & txBuff & "value invalid '"& Convert.ToString(iValue) & "'")
                            End If
                            ' Force Light to Valid Value (off), both Device and Hardware
                            hs.SetDeviceValueByRef(sLightRef, 0, True)
                            sValue = "
            0"
                        End If
                        txBuff = "
            LOAD " & txBuff & " " & sValue
                    Case Else
                        If sTarget = "
            manual"
                            txBuff = sCommand
                        Else
                            ' Unrecognised command supplied, report error and exit
                            If wfDebug>0 Then
                                ' Error
                                hs.writelog("
            Error", "WattStopper command not foundParameters"& sTarget & "|" & sCommand & "|" & sValue)
                            End If
                            Exit Sub
                        End If
                End Select

                If COMPort.IsOpen = False Then 
                    COMPort.Open() 
                Else
                    If wfDebug>0 Then
                        ' Error
                        hs.writelog("
            Error", "WattStopper COM Port already openPort" & COMPort.PortName)
                        COMPort.Close()
                        System.Threading.Thread.Sleep(Comport.ReadTimeout)
                        COMPort.Open() 
                        If COMPort.IsOpen = False Then 
                            ' Error
                            hs.writelog("
            Error", "WattStopper could not re-open COM Port " & COMPort.PortName)
                            Exit Sub
                        End If
                    End If
                End If
                
                On Error GoTo ErrorHandling
                
                ' Append a CR (terminator) to the end of the Tx message to the LMDI-100 (CR is the default)
                oCOMString = txBuff & vbCR
                
                If wfDebug>0 Then 
                    hs.writelog("
            Info", "WattStopper Port" & COMPort.PortName & "BaudRate"& COMPort.BaudRate & " '8N1'")
                    hs.writelog("
            Info", "WattStopper tx buffer '" & oCOMString & "'")
                End If

                ' Send Command to WattStopper LMDI-100
                COMPort.Write(oCOMString)
                
                ' Wait for the WattStopper LMDI-100 to respond
                Dim iSleep As Integer = 0
                Dim iCount As Integer = 0
                iSleep = Comport.ReadTimeout / 10
                Do
                    'Read the COM port
                    rxBuff = (COMPort.ReadExisting)
                    If rxBuff <> "" Then
                        If wfDebug>0 Then 
                            hs.writelog("
            Info", "WattStopper rxBuff '" & rxBuff & "'")
                        End If
                        Exit Do
                    End If
                    If iCount > Comport.ReadTimeout Then 
                        If wfDebug>0 Then 
                            hs.writelog("
            Error", "WattStopper failed to respondtime-out reached COM port " & COMPort.PortName & " read time-out"& COMPort.ReadTimeout)
                        End If
                        Exit Do
                    End If
                    iCount = iCount + iSleep
                    If wfDebug>0 Then 
                        hs.writelog("
            Info", "WattStopper rxBuff empty sleeping and trying again iCount '" & iCount & "'")
                    End If
                    System.Threading.Thread.Sleep(iSleep)
                Loop

                ' Ensure Communication Port is closed
                COMPort.close()

            ExitWattStopper:
                On Error Resume Next

                ' If there was a response from the LMDI-100 lets update any virtual devices (if necessary)
                If rxBuff <> "" Then
                    If sCommand="
            get" Or sCommand="set" Then
                        Dim sRX As String = Trim(rxBuff)
                        '                                      111111... 
                        '                            123456789012345...
                        'RX contains something like "
            R:GETLOAD 1 100"
                        'RX contains something like "
            R:LOAD 18 0"
                        'based on the above 2 examples the values would be...
                        '                        = 6 or 3
                        Dim startPOS As Integer = InStr(1, sRX, "
            LOAD", CompareMethod.Text)
                        If wfDebug>0 Then hs.writelog("
            Info", "WattStopper startPOS "+Convert.ToString(startPOS))
                        
                        '                       = 11 or 8
                        Dim iOffset As Integer = startPOS + 5
                        If wfDebug>0 Then hs.writelog("
            Info", "WattStopper iOffset="+Convert.ToString(iOffset))
                        
                        '                    = 12 or 10
                        Dim iEnd As Integer = InStr(iOffset, sRX, " ", CompareMethod.Text)
                        If wfDebug>0 Then hs.writelog("
            Info", "WattStopper iEnd="+Convert.ToString(iEnd))
                        
                        '                    = "
            1" or "18"
                        Dim sZone As String = Mid(sRX,iOffset,(iEnd-iOffset))
                        If wfDebug>0 Then hs.writelog("
            Info", "WattStopper sZone="+Convert.ToString(sZone))
                        
                        '              = 100 or 0    13 or 11    3 or 1
                        Dim sLoad As String = Mid(sRX,iEnd+1,Len(sRX)-iEnd)
                        If wfDebug>0 Then hs.writelog("
            Info", "WattStopper sLoad="+Convert.ToString(sLoad))
                        ' Set button value for lighting control
            '            If Right(sEventName,1) = "
            s" Then
                            If Convert.ToInt32(sLoad)>0 Then
                                ' Load is > 0 (on)
                                hs.SetDeviceValueByRef(sLightRef, 100, True)     'Set the Lights Load / Light Level
                            Else
                                ' Load is 0 or less (off)
                                hs.SetDeviceValueByRef(sLightRef, 0, True)         'Set the Lights Load / Light Level
                            End If
            '            Else
            '                hs.SetDeviceValueByRef(sLightRef, Convert.ToInt32(sLoad), True)         'Set the Lights Load / Light Level
            '            End If
                        If iDimable>0 Then
                            hs.SetDeviceValueByRef(sLightSliderRef, Convert.ToInt32(sLoad), True)     'Set the Slider Load / Light Level
                        End If
                        If wfDebug>0 Then 
                            ' info
                            hs.writelog("
            Info", "WattStopper updated " & sLightZone & " Ref ID " & sLightRef)
                            hs.writelog("
            Info", "WattStopper re-enable event '" & sEventName & "'")
                        End If
                        ' Enable Event to stop it from re-triggering during execution
                        hs.RemoveDelayedEvent(0,sEventName)
                        hs.EnableEvent(sEventName)
                        If Right(sEventName,1) = "
            s" Then
                            ' Enable button event (slider event enabled by default above)
                            hs.RemoveDelayedEvent(0, Left(sEventName, Len(sEventName)-1))
                            hs.EnableEvent(Left(sEventName, Len(sEventName)-1))
                            If wfDebug>0 Then 
                                ' info
                                hs.writelog("
            Info", "WattStopper re-enable event '" & Left(sEventName, Len(sEventName)-1) & "'")
                            End If
                        ElseIf iDimable>0 Then
                            ' Re-enable Events
                            If wfDebug>0 Then 
                                ' info
                                hs.writelog("
            Info", "WattStopper re-enable event '" & sEventName & "s" & "'")
                            End If
                            hs.RemoveDelayedEvent(0, sEventName & "
            s")
                            hs.EnableEvent(sEventName & "
            s")
                        End If
                    Else
                        ' Manual event occurred.
                    End If
                End If
                
                If wfDebug>0 Then 
                    ' info
                    hs.writelog("
            Info", "WattStopper exiting Main() LMDI-100 Control")
                End If
                Exit Sub

            ErrorHandling:
                ' Ensure Communication Port is closed
                COMPort.close()
                
                If wfDebug>0 Then 
                    ' info
                    hs.writelog("
            Error", "WattStopper un-handled error encountered in Main() LMDI-100 Control")
                    hs.writelog("
            Error", "WattStopper error" & Err.Description)
                End If
                
                Resume ExitWattStopper
            End Sub 

            Comment


              #7
              Thank you! This is most helpful. A very intricate script. Based on your script, your talking directly through the serial. You're not using the Global Cache interface or IP/serial plug in suggested to you above.

              I notice you disable other events then re-enable them. What happens is you don't disable them?

              How often are you updating the light status? Did you have a different script to update the device status?

              Comment


                #8
                Originally posted by huntley1 View Post
                ...your talking directly through the serial. You're not using the Global Cache interface or IP/serial plug in suggested to you above.
                Yes I can't remember exactly the reason, but I ended up using a USB to Serial cable (COM2 in this case).

                Originally posted by huntley1 View Post
                ...I notice you disable other events then re-enable them. What happens is you don't disable them?
                Not much, its really unlikely the script being triggered twice in the same instance and trying to use the COM port at the same time... but I figured why take that chance. This removes that possibility.

                Originally posted by huntley1 View Post
                ...How often are you updating the light status? Did you have a different script to update the device status?
                Same script and every 5 minutes or there abouts I call this script with a GET for the light load value (1 call per load, theres a better way I just haven't gotten to it because why fix what works...)
                I call the script with a GET command, you'll see the line:
                PHP Code:
                hs.SetDeviceValueByRef(sLightRef100True)     'Set the Lights Load / Light Level 
                Where sLightRef is the name of the HomeSeer light object to update (so HomeSeer shows the correct value (in this case 100% on for a non-dimming load that was switched on)

                Comment

                Working...
                X