Posts Tagged ‘XP’

Like many programs there is always more ways to do one thing.

Here is another way I found to talk to my PLC what I’ve been able to get is that i’m sending the direct HEX (PLM) commands to the PLC. Which in turn makes  the processing faster. In my environment it helped a little but had its down sides.

My initial articles using the regular Insteon commands are here.

Turn on a group (SM is your VB PLC Object) Using the PLCHEX command

Im suspecting the first HEX codes are the address and command we are sending to the PLC

Example #1,

My PLC ID is 0D.51.32
Group I want on is “1A
Groups use :C5
Command: Turn on (11=On,12=Fast On,13=Off,14 = Fast Off,19=Poll, 10=Ping)
Power:Full (The last FF for 255 HEX)

Code;

Sm.SendPLCHex("02 40 01 A1 00 09 FD CB 0D 51 32 00 00 1A C5 11 FF)
Sm.SendPLCHex("02 46 01 42 10 9F") ' - Execute Command?

Advantages is that there is no ‘sendtxt’ echo coming back or even a echo of my text going out, which for me makes the command process faster.  And you still get the ‘echo’ in the same format coming in so no change to your program is needed if you are already capturing th text comming back.

Cons:There is no place to define the HOPS?. Sometimes can fail is you send to many commands one right after the other, Im suspecting that since you we are cutting the initial ack on the start it choke after too many commands.  My solution to this was to pause between each command I sent to it.  A good 1 seconds did more than just fine.

* BTW, I like to send the group commands twice since I dont do Group clean-up’s so I basically execute the second line twice.

Turn on a single device (SM is your VB PLC Object) Using the PLCHEX command

Example #2,

My PLC ID is 0D.51.32
Device I want on is :0A.0B.0C
Single Devices use  :05
Command: Turn on (11=On,12=Fast On,13=Off,14 = Fast Off,19=Poll, 10=Ping)
Power:Full (The last FF for 255 HEX)

Code;

Sm.SendPLCHex("02 40 01 A1 00 09 FD CB 0D 51 32 0A 0B 0C  C5 11 FF)
Sm.SendPLCHex("02 46 01 42 10 9F") - ' - Execute Command?

Hope this helps in your development, and drop me a line if this helps you…

Advertisements

Hi, in a previous article I had shown how to monitor & capture data on a specific port using VB. Mainly to allow my server send out notification to the clients, like a Caller ID Alert. That article can be found here

How to monitor and capture data in a specific port in VB / 2005

Below I’ll show the code I use on the server side to actually open and send the information to the clients.

Like mentioned above I will use the example of a caller Id alert , so the program will open a port 81 and send the text ‘callerid’ to the clients (In this case 192.168.0.106). You can use PC names if you have a home router like D-link etc.

Since I have a couple of clients I use VB ‘commandline’ feature to retrieve the IP, port and message that I am going to send.  My utility is called ‘BumpClients’.  For the example lets say this how its called

“Bumpclients.exe 192.168.0.106 callerid 81”

—————— Setting up the imports, make sure you include System.Net and System.net.Sockes, the others may not be needed

Option Strict Off
Option Explicit On
Imports VB = Microsoft.VisualBasic
Imports System.Xml.XPath
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Data
Imports System
Imports System.Drawing
Imports System.Windows.Forms

Public Class Form1

'------------------------------ Create the instance to of the TCP Client (Its the same as receiving)
    Public WithEvents OpenPort As TcpClient  

'------ I use the Form_load event to quickly send the message and exit the program, no user interaction is needed, we grab all paramters from the command line when called.
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.WindowState = FormWindowState.Minimized '- Go hidden
        Me.Hide() '- Go hidden

'------ Next using the Split command I grab the three parameters by looking for the space( This will give me the IP,the command,and port the program will use!)
'------ Data(0)=IP, Data(1)=command, Data(2)=port.

        Dim IP As String
        Dim datA_out
        Dim port As Integer

        data_out = Split(Command$(), " ")
        IP = data_out(0)
        port = data_out(2)

'------ Just a quick check to make I can ping the IP, if not just exit and dont even bother.
        If My.Computer.Network.Ping(IP) = False Then End

'---- The actualy opening of the port un a 'try' statement if it fails exit also
        Try
            OpenPort = New TcpClient(IP, port)
        Catch
            End
        End Try

'------ If all is good then go ahead and convert our text to bytes and send it out using the stream method!
       Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(Trim(data_out(1)))

        Dim stream As NetworkStream = OpenPort.GetStream()
        stream.Write(data, 0, data.Length)

'------ Close and exit!- That's it!
        stream.Close()
        OpenPort.Close()
        End
    End Sub
End Class

A important note, remember that on your client you need to open the port you use in the firewall or it will never see anything, but you dont need to open it on the server since it will be sending.  To test this you will need the two actual computers sine you cant monitor and send data thru the same port.

In my application I actually run a external program using the system.diagnostics,process.start command, to the IP of my PC’s this way, it will run each script and not wait.And each of time will exit accordingly.

data_out=”callerid”
port=81

System.Diagnostics.Process.Start(“C:\vb\Insteon_BumpClients\BumpClients\BumpClients\bin\Release\BumpClients.exe”, ” 192.168.0.102 ” + data_out + ” ” + port) ‘ Laptop
System.Diagnostics.Process.Start(“C:\vb\Insteon_BumpClients\BumpClients\BumpClients\bin\Release\BumpClients.exe”, ” 192.168.0.120 ” + data_out + ” ” + port) ‘
System.Diagnostics.Process.Start(“C:\vb\Insteon_BumpClients\BumpClients\BumpClients\bin\Release\BumpClients.exe”, ” 192.168.0.104 ” + data_out + ” ” + port) ‘

Enjoy!

In one of my  previous post I had shown how to capture the Caller Id info of a modem.  So what do I do this the information??

In my case I notify all the PC in the house a particular caller / number is ringing by sending data on a specific port.  So they know who it is before picking up or even looking at the phone for the caller Id info. Below is the code on how to monitor a port for data.

In this case it will open and monitor port 81.  Since there is no event for the TCPListener Im using the VB timer control, then check the port for any pending data ever 1000ms , if data is pending it will read it and show it in a pop-up in the icon tray. 🙂

To keep it simple here, and Not shown here, I actually FTP back via code (Will setup another post for this) to the server and grab the image of the person which is then displayed on the client on another window.

Like all code here, is all in VB 2005. For setup: Note that for this  to work you do need to open port 81 (TCP) on the client.

Just create a basic form with the following controls (All are default names)

A Notify object called “NotifyIcon1”
A timer object called “Timer1”

‘—————— setup my Import variables, some may not be needed.

Imports System.Web
Imports System.Net
Imports System.Net.Sockets
Imports System.IO
Imports System
Imports System.ComponentModel
Imports System.Threading
Imports Microsoft.VisualBasic

'----------------------- Here is the main class which loads the form.
Public Class Form1
    Public WithEvents OpenPort As TcpListener '--------- I setup the TCPListner object, There really isnt no events for it so I have to check using a timer.

'--------- GET THE CLIENT ip FROM THE ENVIRONMENT This will return ina array the IP of the client in the case of XP the first ip(0) should be fine, in the case
'--------- vista you have to search for it. I just looked for the first octet to be the same as my internal network.

    Public ip() As System.Net.IPAddress = System.Net.Dns.GetHostEntry(Environment.MachineName).AddressList
    Public IPAdresstxt As String

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'ip(0) = IPAddress.Parse(Microsoft.VisualBasic.Interaction.Command()) '---- Un-comment for XP

'------- for Vista the first item of the array can be anything, so I loop thru the values looking for the same network of my home network
        Dim ip_count As Integer
        or ip_count = 0 To ip.Length - 1
            If ip(ip_count).ToString.Contains("192") = True Then
                OpenPort = New TcpListener(ip(ip_count), 81)  '--------- Here we set the IP (My PC) and the port to monitor in this case 81
                IPAdresstxt = ip(ip_count).ToString
            End If
        Next
'-------------------

        OpenPort.Start() ' - Open and monitor
        NotifyIcon1.Visible = True
        NotifyIcon1.BalloonTipTitle = "Caller ID"
        NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info
        NotifyIcon1.BalloonTipText = "Caller ID Running, window will close in 3 seconds"
        NotifyIcon1.ShowBalloonTip(2500)  '----------------- Hide my Icon popup after 2500 MS
        Me.Hide() '----------- This will hide my form and only leave the icon on the tray.  :)

    End Sub

'------------------ This is my main timer1 which is enabled and checked every 1 sec.
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        '-------------- CHECK PORT 81 IF GOT DATA
        If My.Computer.Network.IsAvailable = True Then  '----- If data is present then read data and pharse it.
            If OpenPort.Pending = True Then
                Dim bytes(1024) As Byte
                Dim data As String = Nothing
                Dim client As TcpClient = OpenPort.AcceptTcpClient()
                Dim stream As NetworkStream = client.GetStream()
                Dim i As Int32
                ' Loop to receive all the data sent by the client.
                i = stream.Read(bytes, 0, bytes.Length)
                While (i <> 0)
                    data = data + System.Text.Encoding.ASCII.GetString(bytes, 0, i)
                    data = data.ToUpper()
                    Dim msg As Byte() = System.Text.Encoding.ASCII.GetBytes(data)
                    i = stream.Read(bytes, 0, bytes.Length)
                End While

                data = LCase(data).Trim
                ShowCallerID(data)  '---------------------- Call the function to update the Notify-Icon
                Msgbox "Data received is"+data
         End If
        End If
    End Sub

'---------------------- Function to update the Notify-Icon
    Public Function ShowcallerID(number as Integer) As Boolean
        NotifyIcon1.BalloonTipText = "Incomming call from " + name + vbCrLf + " From # " + number.ToString
        NotifyIcon1.ShowBalloonTip(10)
        IncommingCallWindow.txtName.Text = name
        If number.ToString.StartsWith("1") = True Then
            number = Val(Mid$(number, 2, number.ToString.Length - 1))
        End If

    End Function

End Class

Enjoy!

One of the cool things of the program is to be able to play sounds, and play other formats on-demand.  For this example we will play a chime clock at noon.

There are a couple of ways of doing this (API Calls, command line etc), The way I will show is for me the simplest way, and really only requires that you have windows media player installed.
If you are going to play MP3 files, you will also need to install the codec’s for it, the easiest way to do this is just download and install winamp (Free version).

1st Step is to make sure you Media player is setup and ready to go.

Note: Using the media player in the background allows me pause, get status, use playlists, set the volume and many other things, sure you can probably do this with API calls and other functions but the main purpose of my CPU power I want to dedicate to phrasing the executing Insteon commands.  Also besides being clean and simple, once the player is started you code will continue to run, it will not pause or stop while the media is playing. It will  only stop unless you tell it to, as well if you break the program.

Again using I was using VB2005 / XP, the first thing you will do is reference the object in your code.   Here is a picture of my reference.

We’ll use for our code the variable WMP and reference this,
In this case I refernce it twice so I have one for quick sounds and another for Internet Radio which can be playing all the time if needed, so they dont cancel each other out.

Public WMP As New WMPLib.WindowsMediaPlayer
Public WMP_Radio as New WMPLib.WindowsMediaPlayer

To point the player to the filename it actually called using the WMP.URL=”<full path to filename or source>” this can point to a streaming URL, Wav,.MP3 file even a saved playlist. (f.y.i. Playlist are simple text files which can easily be created if needed)

Here is the function I use to call the Media play and play a specific file, doesnt matter if its .WAV or .MP3, All my sounds are stored locally under C:\voicemail\sounds\ my function also passes the volume which ranges from 1-100. This is for the player not for the Windows Mixer.

Play_wav_file("doorchime.wav",100) - Play doorchime full blast!

    Public Function Play_wav_file(ByVal Filename As String, ByVal vol As Integer)
        WMP.URL = "c:\voicemail\sounds\" + Filename
        WMP.settings.volume = vol
        WMP.controls.play()

    End Function

You can also test to see if the Media player is playing to prevent errors with its WMP.Status
Here are some others

WMP_Radio.controls.stop() - Will stop the player.

Here is my function to play Internet Radio, I can call it using various command such as

PlayMusic(“play80”) or PlayMusic(“stop”) etc…

 Public Function PlayMusic(ByVal cmd As String)
        Dim volume As Integer
        cmd = LCase(cmd)

        If cmd = "play80" Then
            WMP_Radio.URL = "http://planethitsradio.com/streams/80slow.asx"
            WMP_Radio.settings.volume = 30
            WMP_Radio.controls.play()
        End If

        If cmd = "playsoft" Then
            WMP_Radio.URL = "http://planethitsradio.com/streams/smoothhigh.asx"
            WMP_Radio.settings.volume = 20
            WMP_Radio.controls.play()
        End If

        If cmd = "playhits" Then
            WMP_Radio.URL = "http://planethitsradio.com/streams/highband.asx"
            WMP_Radio.settings.volume = 20
            WMP_Radio.controls.play()
        End If

        If cmd = "stop" Then
            WMP_Radio.controls.stop()
        End If

        If cmd = "up" Then
            volume = WMP_Radio.settings.volume
            If volume <= 90 Then WMP_Radio.settings.volume = volume + 10
            WMP_Radio.controls.play()
        End If

        If cmd = "down" Then
            volume = WMP_Radio.settings.volume
            If volume >= 10 Then WMP_Radio.settings.volume = volume - 10
            WMP_Radio.controls.play()
        End If

    End Function

A very good link which I use for some of my sounds is Freesounds.org, you will need to register to download them.

Yes, this is me around 20 years ago.  Enjoy!