Archive for the ‘Software Setup’ Category

So I have been working hard over the last few month trying to consolidate many pieces of what I hope to be the decorations master piece for 2010.

Here is how it started.  For 2009 I had already created a simple programs that would randomly play small 5-10 second sequences such as fading on / fading off, lighting bolts etc. And even in Halloween/Christmas starting I start projecting some images and clips on the window using my laptop and a projector. But wouldn’t it be nice to have it all sync together?  This is where this ‘project’ came up.

For starters I considered dropping these boxes and going with the Light-o-rama product.   Which I am sure you have seen 1000 times before and that same Transiberian Orchestra song!  But after downloading the demo software I found there was no way I could insert code or run a program before or after.   Don’t get me wrong its a excellent product and insteon devices will NEVER match the speed those device can achieve!   But another limitation ‘I’ didn’t like was that its all in central controllers. With the lamplincs I can and have had devices inside the home and some outside at the same time, also if one device dies you replace it and your done, here if you controller dies you are down 16 ‘channels’ .  BUT Downside for me is each device needs to be  programmed individually but once its set your ready to go!.  Another big plus for me was that I could use existing Insteon devices over and over and even mix with the ones in the home.  For example in Halloween I would kill the kitchen lights inside for the lighting bolts outside.   So in true ‘me’ spirit I decided to stick with Insteon and do something different!

Here are some of the LampLincs I’ve picked up over 2009/2010.  Each are identified by unique #

The Show Manager

So “Show Manager” is basically the conductor that start and stop these individual programs.  Here is a high level chart of what it consist of.

For example the ‘Show Manager’ will start and stop the ‘Randomizer’, ‘Sequencer’ as well as accept input from the internet.  Like in 2009 I will provide a button from our community website/ internet users to ‘bump’ the decorations. 🙂  Try that Lightorama.

The program is a simple program that will start and stop programs using VB program looking as the processes in memory.

The “Sequencer” Program (New for 2010)

Different from 2009 is the ‘Sequencer’ program which is what allows me to sync video/audio to commands to the devices.  The screen is very simple and clear.  You have a time line which is broken down in .25 seconds with the devices down the left.  Each color is a different command sent via the serial interface.

Closeup of the Time line board.

Close up of the commands screen

Synchronizing the video between the two computers was a ‘TASK’ .   I had to get down to the milliseconds so the video would sync correctly,

For this I had to use VB 2008/2010 Windows presentation format (WPF) in the remote laptop since you can change the rate of play of the video. I never found a right way to do this in VB 2008 or less. So the main sequencer would send a heartbeat to the laptop everysecond with its time sync so the player could go slower or faster.

The way I put them to talk is a previous entry here, how to Communicate using ports / TCP.   HERE

To be continued….

Hi, so I know ive been disconnected for a while.  But always trying to provide some goodies.

One of the cool things of the PLC is that if you know serial commands you can actually talk to it bypassing the SDM software.  My reason being that X10 motion sensors are cheeper than the Insteon and smaller which I can hide in different places but I would run in to the problem of the x10 signals not making it back to my main computer.  So what If you can have something on another computer which can transalate it to Insteon ?:)

So what I was right on the back of the PLC I have a transceiver and use the PLC with this small code to convert it to Insteon.  This way I basically have a x10 receiver on the other leg of my home.

So below is a small little program I use to  ‘convert’ X10 signals to a Insteon signal.  In my case the PLC will sending a ON  or OFF command to the PLM and depending the rate is the house code for example (B5,B6).   For the example im using VB 2005.  2008 and 2010 will work fine as well.  Note that i am bypassing entirely the SDM software.  if you don’t call it in your code it wont load, but you do have the port locked and isn’t sharable  🙂

A very good starting point is this site and I basically started from here http://www.madreporite.com/insteon/insteon.html which will show you how read bytes, which is how the plc will respond as well.

Basically the PLC talks at 4800,8,N,1.  The program consist of a simple form with  just one button to exit.


Option Strict Off
Option Explicit On
Imports VB = Microsoft.VisualBasic
Imports System.IO
Imports System.IO.Ports
Imports System.Net

Public Class Form1
 Public WithEvents PLC As New IO.Ports.SerialPort
 Public X10_House_Code As String
 Public X10_House_VALUE As Integer
 Public X10_Command As String
 Public PLC_Queue As String
 Public handler As New mySerialDelegate(AddressOf Process_Queue)  ' Once we read the data process it in a separate thread.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 '------ OPEN PLC SERIAL CONNECTION SETUP PLC AND LEAVE READY - 
 PLC.PortName = "COM1"
 PLC.BaudRate = 4800
 PLC.DataBits = 8
 PLC.Parity = Parity.None
 PLC.StopBits = StopBits.One
 If PLC.IsOpen = False Then PLC.Open()

End Sub

 '---- THIS IS THE EVENT THAT WILL FIRE EACH TIME DATA IS RECEIVED BASICALLY WE CAPTURE ALL THE DATA AND
 '---- CALL THE OTHER THEAD TO CONVERT IT.
 Private Sub PLC_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles PLC.DataReceived
 Dim A, Bytes_to_read As Integer
 Dim rcvBuf(4096) As Byte
 Bytes_to_read = PLC.BytesToRead
 Do While PLC.BytesToRead > 0
 PLC.Read(rcvBuf, 0, rcvBuf.Length)
 For A = 0 To Bytes_to_read - 1
 PLC_Queue = PLC_Queue + Hex(rcvBuf(A)).PadLeft(2, "0") + " "
 Next
 Bytes_to_read = PLC.BytesToRead

 Loop

 Me.BeginInvoke(handler)
 End Sub

 Public Delegate Sub mySerialDelegate()
 Public Sub Process_Queue()

 'CONVERT STEAM TO X10 HOUSE CODES and the VALUE THAT WILL BE PASS TO THE OTHER DEVICE
 ' SO WHEN IT SEEN B2 IT WILL SEND TO THE OTHER SIDE A VALUE OF 18 ON THE RATE OR 'ON' VALUE
 ' Im only converting the B Code nothing else. 

 If PLC_Queue.Contains("02 4A 00 EE ") Then X10_House_Code = "B2" : X10_House_VALUE = 18
 If PLC_Queue.Contains("02 4A 00 E2 ") Then X10_House_Code = "B3" : X10_House_VALUE = 19
 If PLC_Queue.Contains("02 4A 00 EA ") Then X10_House_Code = "B4" : X10_House_VALUE = 20
 If PLC_Queue.Contains("02 4A 00 E1 ") Then X10_House_Code = "B5" : X10_House_VALUE = 21
 If PLC_Queue.Contains("02 4A 00 E9 ") Then X10_House_Code = "B6" : X10_House_VALUE = 22
 If PLC_Queue.Contains("02 4A 00 E5 ") Then X10_House_Code = "B7" : X10_House_VALUE = 23
 If PLC_Queue.Contains("02 4A 00 E4 ") Then X10_House_Code = "B8" : X10_House_VALUE = 24
 If PLC_Queue.Contains("02 4A 00 E7 ") Then X10_House_Code = "B9" : X10_House_VALUE = 25
 If PLC_Queue.Contains("02 4A 00 EF ") Then X10_House_Code = "B10" : X10_House_VALUE = 26
 If PLC_Queue.Contains("02 4A 00 E3 ") Then X10_House_Code = "B11" : X10_House_VALUE = 27
 If PLC_Queue.Contains("02 4A 00 EB ") Then X10_House_Code = "B12" : X10_House_VALUE = 28
 If PLC_Queue.Contains("02 4A 00 E0 ") Then X10_House_Code = "B13" : X10_House_VALUE = 30
 If PLC_Queue.Contains("02 4A 00 E8 ") Then X10_House_Code = "B14" : X10_House_VALUE = 31
 If PLC_Queue.Contains("02 4A 00 E4 ") Then X10_House_Code = "B15" : X10_House_VALUE = 32
 If PLC_Queue.Contains("02 4A 00 EC ") Then X10_House_Code = "B16" : X10_House_VALUE = 32

 '- ON OR OFF
 If PLC_Queue.Contains("02 4A 01 E2 ") Then X10_Command = "ON" : Send_Bytes(X10_House_VALUE, True) : Debug.Print(X10_House_Code) : X10_House_Code = "" : X10_Command = ""
 If PLC_Queue.Contains("02 4A 01 E3 ") Then X10_Command = "OFF" : Send_Bytes(X10_House_VALUE, False) : Debug.Print(X10_House_Code) : X10_House_Code = "" : X10_Command = ""

 Debug.Print(PLC_Queue)

 ' Clear and start again
 PLC_Queue = ""
 End Sub

Public Function Send_Bytes(ByVal value As Integer, ByVal State As Boolean) As Boolean
 Dim RECEIVER() As String = Split("0D.FE.9E", ".")  '-- THIS CONTAINS WHO WE ARE SENDING THE MESSAGE TO CHANGE AS NECESSARY
 '-- MAGIC CODE TO SEND TO PLC (I'LL EXPLAIN THEM LATER)
 Dim xmtbuf() As Byte = {&H2, &H40, &H1, &HA1, &H0, &H9, &HFD, &HE4, &H0, &H0, &H0, &HD, &HB, &H44, &H5, &H11, &H1}

 '-- HERE WE WILL REPLACE THE BYTES ABOVE IN BOLD TO WANT TO SEND TO,
 xmtbuf(11) = System.Convert.ToInt32(RECEIVER(0), 16)
 xmtbuf(12) = System.Convert.ToInt32(RECEIVER(1), 16)
 xmtbuf(13) = System.Convert.ToInt32(RECEIVER(2), 16)

 '- DEPENDING ON THE DEVICE BEING ON OR OFF WE SWAP ONE OF THE BYTES
 If State = True Then xmtbuf(15) = 17 Else xmtbuf(15) = 19 ' If on then push 17 if off push 19

 '--- HERE WE INSERT THE VALUE / X10 HOUSE CODE WE HAVE PREDIFINED 
 xmtbuf(16) = value

 '--- CALL OUR LITTLE FUNCTION TO WRITE THE BYTES TO THE SERIAL PORT
 PLC_Write(xmtbuf)

 '--- SETUP SOME MORE BYTES (THIS DOENST CHANGE) AND WRITE THEM, THIS TELLS THE PLC TO PROCESS THE BYTES WE SENT
 '--- BEFORE
 Dim xmtBuf2() As Byte = {&H2, &H46, &H1, &H42, &H10, &H9F}
 PLC_Write(xmtBuf2)
 End Function

 '--- THIS FUNCTION BASICALY WRITES ALL BYTES TO THE SERIAL PORT WE HAVE PREVIOUSLY DEFINED
 Public Function PLC_Write(ByVal XmtBuf As Object) As Boolean
 Try
 PLC.Write(XmtBuf, 0, XmtBuf.Length)
 Catch
 Debug.Print("COULDNT SEND DATA CHECK PORT")
 End Try

 End Function

 '--- SIMPLE BUTTON ON OUR FORM TO EXIT THE PROGRAM
 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 End
 End Sub
End Class

We’ll after receiving back some of my hard earned money thru 2008. I shelved out the $159 for the Insteon T1700 thermostat.
It can be found here.

The device is quite small, which is fine and thinner that my orginary Honeywell one which was a real plus.  To install was also very simple.
And technical support was awesome!!!  Who expects to call a company and receive a live person and be able to troubleshoot on the phone in less that 3 min.  And to top it off the rep even called me back since he had to leave. At the end it was a simple dip switch due to my model.  So if after you install it and when you turn on cool and heat comes out and vice-versa, just turn on dip switch two and your set!  Thats Again Mike from Venstar!!!!


The only thing would be the ‘light’ on the side of the Insteon module.  so in dark areas it does stand out.
Like mentioned above the device is very small and the insteon module even smaller.
For example check out the image in comparison to my hand

Setting Mode, Getting Temperature of Thermostat

Ok, enough Pictures and talk, lets see how to control this device.

First forget about sending ON/OFF commands, for me they didnt work, nor did they do anything.  What we will be using is the 0x02 command instead of 0x11 for on or 0x13 for OFF.  What I has able to find was the higher numbers after that worked. I’ll show you what

Ive got and show examples after.  In my case I couldnt send request using the regular PLC commands so I ended using the low level calls using the sendhex function, that article can be found here

More ways to speak to your Insteon Devices

For the examples my PLC is # “0D 51 32” and my Thermostat is “01 02 03“.

0x6b – Bit 2 – Get Thermostat Mode (Returned is 00=off,01=Heat,02=Cool,03=Auto,04=Fan)

 
	'Send

	Sm.SendPLCHex("02 40 01 A1 00 09 FD 9B 0D 51 32 01 02 03 05 6B 02"	Sm.SendPLCHex("02 46 01 42 10 9F") ' Execute my command

	'You should get the reponse on the Last Bit of your reponse.  For example
	04 01 02 03 0D 51 32 26 6B 02

	So in this case 0x02 Means the device is on COOL.

0x6b – Bit 3 – Get Temperature (Returned is the temperature, you convert to decimal and divide by two)

	'Send
	Sm.SendPLCHex("02 40 01 A1 00 09 FD 9B 0D 51 32 01 02 03 05 6B 03")
	Sm.SendPLCHex("02 46 01 42 10 9F") ' Execute my command
	'You should get the reponse on the Last Bit of your reponse.  For example
	04 01 02 03 0D 51 32 26 6B 9A 
	So in this case 0x9A Converted to decimal is 154 divide
        that by two and you get 77 degrees!!

0x6b - Bit 4 - Set to Heat
'Send

Sm.SendPLCHex("02 40 01 A1 00 09 FD 9B 0D 51 32 01 02 03 05 6B 04")

Sm.SendPLCHex("02 46 01 42 10 9F") ' Execute my command

0x6b - Bit 5 - Set to Cool
'Send

Sm.SendPLCHex("02 40 01 A1 00 09 FD 9B 0D 51 32 01 02 03 05 6B 05")

Sm.SendPLCHex("02 46 01 42 10 9F") ' Execute my command
0x6b – Bit 6 – Set to Auto (To switch automatically from Cool to Heat depending on your settings)

	'Send
	Sm.SendPLCHex("02 40 01 A1 00 09 FD 9B 0D 51 32 01 02 03 05 6B 06")
	Sm.SendPLCHex("02 46 01 42 10 9F") ' Execute my command

0x6b – Bit 7 – Fan on

	'Send
	Sm.SendPLCHex("02 40 01 A1 00 09 FD 9B 0D 51 32 01 02 03 05 6B 07")
	Sm.SendPLCHex("02 46 01 42 10 9F") ' Execute my command

0x6b – Bit 8 – Fan off

	'Send
	Sm.SendPLCHex("02 40 01 A1 00 09 FD 9B 0D 51 32 01 02 03 05 6B 08")
	Sm.SendPLCHex("02 46 01 42 10 9F") ' Execute my command

0x6b – Bit 9 – All Off

	'Send
	Sm.SendPLCHex("02 40 01 A1 00 09 FD 9B 0D 51 32 01 02 03 05 6B 09")
	Sm.SendPLCHex("02 46 01 42 10 9F") ' Execute my command

Setting the Cool / Heat Thermostat Temperature

Here insteon of 0x6B we will be using the 0x6C for Cool and 0x6D for HEAT.  So lets say you’ve set your device to Cool and want to lower it to 75 Degrees.  Just like when we read the temperature, when we set it we need to multiply the requested value * 2 and convert it to HEX.  In the sample below the variable Set_Temp holds what we want it to.  The next statement converts it to HEX and *2 and presto!

'This is the temperature we want to set Cool to!
Set_Temp="75"
Dim Temp As String = Hex(Set_Temp * 2)
Sm.SendPLCHex("02 40 01 A1 00 09 FD 9B 0D 51 32 01 02 03 05 6C " + Temp)
Sm.SendPLCHex("02 46 01 42 10 9F")

'This is the temperature we want to set heat to!
Set_Temp="70"
Dim Temp As String = Hex(Set_Temp * 2)
Sm.SendPLCHex("02 40 01 A1 00 09 FD 9B 0D 51 32 01 02 03 05 6D " + Temp)
Sm.SendPLCHex("02 46 01 42 10 9F")

Hope this works for you and its working great for me.  Each hour I poll the temperature and as part of that routine I poll my thermostat to keey the information up to date. I’ll post more as I find out!

Finally my first Insteon Motion sensor arrived!.  The box is average size and has a pretty big label showing SkyLinc and SmartHome technologies.

Out of the box, cool white color.

The device even comes with its own 9V battery so you can start up quickly.  Linking is the done the same was a other devices.

Like most of the Insteon device it has its traditional SET button, In this case the ‘SET” button is inside the battery compartment.

Which also houses the ‘dip’ switch for fine tuning of the device.  I’ve set mine to not show the LED which is a very BIG led. (I tell you what they are for below the image)
For this reason you can see the PIN #2 is on all others are ‘off’ which are not connected or on the top.

According the the 1 page (What looks like a photocopy) the pins are used for the following

Dip Switches

1.Sensitivity, enable to reduce the sensor 33%

2.Turn of LED (It will still flash if there is a incorrect link or the device you link too has been removed.

3.Night-only mode – Only operate when dark

4.On-Only mode, so it doesn’t tell you when the device hasnt seen movement in 1 minute.

5.Not Used.

The linking was very simple, press the link button and press the link of the device you want to turn on/off.  In my case its the PLC so I can see the ON (0x11) and OFF (0x13) commands and act accordingly.    

I haven’t found any way to change the default re-transmition time which is 1 minute, so unlike the Eagle eye which transmits every 10 seconds, this will only t ransmit if the status changes for example from ON to OFF.  So this means if you have movement in the area you will only see ONE – ON command until one minute after when there is no movement. You wont get a message each minute.    Also there is no way to poll the device, but it does seem to have already hard coded its ‘address’.  So its considered a device which status changes from On for occupied to OFF to no motion detected in 1 min.

Among my findings the RANGE is great!. In my case I have 4 access points so even in the back yard the reception is great!.  The white color is a plus, fits in anywhere , this was something I never understood with the eagle eye’s. (brown) Plus includes its own mointing kit which you can swivel the device.  I used double side tape before using the screws this way I can find the best spot before making it permanent.

Here is the VB/SDM strings which come in when the sensor is activated

02 11 8C F0 00 00 01 CB 13 01 - Which is for OFF (No motion for 1 min)
02 11 8C F0 00 00 01 CB 13 01 - Which is for On (Motion)

02 11 8C F0 00 00 01 CB 11 02 - Which is for Dusk start / Dawn end (Dark for 3 Minutes)
02 11 8C F0 00 00 01 CB 13 02 - Which is for Dusk end start / Dawn Start?

More Pics

Mounting Kit not shown.

I placed my first Insteon Sensor in the top middle hallway, and covers the two corners perfectly,
I quickly removed the two eagle Eye’s I had…


Lets say your like me and you wish to check the status of the contact on your garage.    But notice that regular polls only return the device itself not the status of the contact.

For example maybe at a given time you want to make sure the contact is closed.  Here is how

I’m going to use as reference the original articles of getting “Insteon to talking to your PC found below” Part #1,#2,

https://pixiescorner.wordpress.com/2008/06/15/part-2-get-insteon-talking-to-your-pc/
https://pixiescorner.wordpress.com/2008/06/20/part-3-get-insteon-talking-to-your-pc-part-2/

This is using VB .NET and assuming you already have some experience with the SDM/PLC commands.

For the Sensor Poll We are going to use the command #19 and a second command of ’01 to query the device.  For example

For this example Lets say for example my plc is AA.BB.CC
My I/O Linc is : 11.22.33

 

So in VB polling the device using the SDM would be like this,

sm.SendINSTEONRaw(”AA BB CC 11 22 33 05 19 01″, 3)

In return you will get the following bytes, notice the change in the last digit.
If the garage is closed (Contact closed)
 - 04 11 22 33 AA BB CC 25 03 01 

If the garage is closed (Contact OPEN)
 - 04 11 22 33 AA BB CC 25 03 00

If you get FF,FE or other numbers make sure you are using the last 01 on your command #19 as this will give you the state of the device which isnt the contact status.

Enjoy!

 
 

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…

Insteon’s SDM COM object is great for having a preset commands at your disposal but ive ran into issues where I dont want the program to wait for the ACK.  (In this case it will pause for the response), this can be a problem in very large environment, especially if your poll all devices at a certain time.  In my case I like to poll all the devices at least twice a day.

If this is the first article you ready please check out the articles below on how to get started.

Software: Get Insteon / Talking to your PC – Part 1

Software: Get Insteon / Talking to your PC – Part 2

For example

The SDM quick command is sm.GetOnLevelText “11.22.BB”

We will be using the InsteonRaw command Hex #19 like this
sm.SendINSTEONRaw(”00 00 00 11 22 BB 05
19 00″, 3)

Here is a debug of what is sent and what is received. I am polling device (0A.FE.3E) from my PLC (0D.51.32)

8/24/2008 11:38:32 AM sentinsteon=0D 51 32 0A FE 3E 05 19 00
8/24/2008 11:38:33 AM receiveinsteonraw=04 0A FE 3E 0D 51 32 21 00 00

Insteon responds in the same but with the device being queried first

0A FE 3E= Device responding.

OD 51 31 = My PLC, the desitation receiving the response

21 = Is a incremental # which can change among #21-2B, so you have to look for it.

00 = Some type of marker – Changes also

00 = Our value in hex, from 00= OFF to FF = Full all and everything in between

Here is another debug trace of a device query which is on;

8/24/2008 11:43:33 AM sentinsteon=0D 51 32 08 6B 57 05 19 00 (My requesting of status of the device calling command #19)
8/24/2008 11:43:34 AM receiveinsteonraw=04 08 6B 57 0D 51 32 26 1A FF (This one is reporting back as ON!)

Note: What is very tricky of this is that don’t always thing FF is on, I some icon dimmers that on can be ‘FE’, as a rule of thumb anything NOT 00 is consider for me as ‘ON’

Again all these codes are show in “Software: Get Insteon / Talking to your PC – Part 2“. I’ve copied the code from part #1 which will allow us to act upon the events of the SDM when text arrives back

'------- First we setup the SDM object in our code
Class  MainMenu
Friend WithEvents Sm As SDM3Server.SDM3

'-- When I load my mainmenu even I have the following

Public Sub MainMenu_Load(...... )
  Sm =New SDM3Server.SDM3
Try
      Sm.IsResponding()
    Catch
    MsgBox("SDM NOT LOADED try AGAIN")
 End Try
End Sub

Here is the TEXT event that I use for the whole program to break down and read the strings returned to me.

Public Sub sm_OnText(ByVal strInsteonStatus As String) Handles Sm.OnText

var = Split(strInsteonStatus, "=")
Select Case LCase(var(0))

	Case "setonleveltext"
		data = Split(var(1), ",")
		device = data(0)
		value = data(1)

	Case "receiveinsteonraw"
		data = var(1)
		bytes = Split(data," ")
		If LBound(bytes) = 0 And UBound(bytes) = 9 Then
			AddrFrom = bytes(1) & bytes(2) & bytes(3)
			AddrTo = bytes(4) & bytes(5) & bytes(6)
			Flags = bytes(7)
			Command1 = bytes(8)
			Command2 = bytes(9)
			End If

     '------------ GRAB RESPONSES FROM QUERYES (#19) RETURNING
                    If flags = "21" or flags = "24" Or flags = "25" Or flags = "26" Or flags = "2B" Or flags = "22" Or flags = "23" Then
                        If Cmd2 <> "00" Then Msgbox "DEVICE IS ON!!"
                        If Cmd2  = "00" Then Msgbox "Device is OFF!"
                    End If
		End If
	Case Else

End Select

As previously mentioned my main program depends 100% off a SQL database, below is a dump of my “Configuration” database, that holds all the system settings.
Many are loaded into memory the first time, or when I run PollDevices query this way the information is updated when needed.  I know its a lot of information but maybe a developer can use these fields as ideas for their program.

Below are my two main functions I’ve created call (get a value or update a value).

Grabbing a value from the “Config” Database

For example this function will return the value of a specific query for example

lg_get_config("wake_up_time")

 Public Function Lg_Get_config(ByVal field As String) As String

       '------ SETUP CONNECTION TO DATABASE (CONNECTION STRING MAY VARY AMONG SYSTEM OR WHERE you have DB)
        Dim sqlConnection35 As New System.Data.SqlClient.SqlConnection(My.Settings.InsteonConnectionString)
        Dim cmd35 As New System.Data.SqlClient.SqlCommand

        '------ SETUP READER TO GRAB THE NECESSARY DATA
        Dim Reader As SqlClient.SqlDataReader
        cmd35.CommandText = "SELECT * FROM Config where config= '" + field.ToLower.Trim + "'"
        cmd35.Connection = sqlConnection35
        sqlConnection35.Open()

'------ OPEN CONNECTION AND CHECK TO MAKE SURE
        Do While sqlConnection35.State <> ConnectionState.Open
        Loop

        Reader = cmd35.ExecuteReader()

        ' --------- check for data, if not return 'FALSE' AND leave function
        If Reader.HasRows = False Then
            Lg_Get_config = False
            Exit Function
        End If
        Reader.Read()

'---------- return the value and close all connections and exit.
        Lg_Get_config = Reader.Item("value")
        Reader.Close()
        sqlConnection35.Close()

    End Function

Setting a value in the “Config” Database

The next example updates a field, and is very similar just that it uses the SQL update command

For example lets say I want to update the “wake_up_time” to something else

lg_set_config("wake_up_time","9:00:00 AM")

    Public Function Lg_Set_config(ByVal field As String, ByVal value As String) As Boolean

        '------------- SETUP CONNECTION
        Dim sqlConnection4 As New System.Data.SqlClient.SqlConnection(My.Settings.InsteonConnectionString)
        Dim cmd4 As New System.Data.SqlClient.SqlCommand
        cmd4.CommandType = System.Data.CommandType.Text
        cmd4.Connection = sqlConnection4

        '------ The Update Command to modify the field
        cmd4.CommandText = "UPDATE Config SET Value= '" + value + "' WHERE config='" + field.Trim.ToLower + "'"
        sqlConnection4.Open()

        '--------- Since we are not getting anything in return this is a NonQuery Executre
        cmd4.ExecuteNonQuery()
        Lg_Set_config = True
        sqlConnection4.Close()
        Update_TimeStamp()  ' - I update the TimeStamp Value so anytime its queried they know is been updated.

    End Function

Data Dictionary The “Config” Database

marker – Int field
config – nvarchar(128)
value – nvarchar(255)
description – nvarchar(255)

* marker field is my primary key, this is also set to “Identity Specification” which means it will autopopulate with a incremental value, so no record is the same, example (1,2,3,4,5,6 etc)

Below is a dump of all my fields and a quick explanation of what they represent.  Descriptions starting with RST are the ones that are updated by the system automatically. For example if I turn on the outside lights, I update the field at that moment to say it has been turned on.

outdoor_turn_off_time 10:32 PM When will all outdoor lights will turn off

outdoor_turnedon Y RST, If outdoor lights are on?
extractor_girls N RST, If the extractor is on or off
extractor_girls_time 10 In Minutes, Timeout for the girls extractor
timer_randomlights N If the random lights are on
random_lights_min 10 Random lights timer in minutes
time_after_sunset_to_turn_on 12 Time in minutes after sunset the lights outside will turn on
temperature 75% RST, Current temperature
temperature_last_read 6:40:29 AM RST, When was the temperature last read
temperature_text Mostly Cloudy RST, Text from NOAA.GOV
temperature_image http://rssweather.cachefly.net/images/weather-symbols/mcloudyn.png RST, Local image
SunRise 6:59:52 AM RST, SunRise in time
SunSet 7:56:07 PM RST, SunSet in Time
Outdoor_turn_on_time 8:08:07 PM RST from program, Outdoor turn on time
fan_off_low 15 Turn off Fan Threshold
fan_on_high 88 Turn on fan Threshold
voicemails N RST,If Voicemails are present?
master_closet_timer 3 Master Closet Timer in Minutes
master_closet N RST,Master Closet is on?
alarm_clock_status ON Mine, Turn on Alarm clock, M-F
poll_devices_interval 525 Minutes to poll each device
poll_devices_next_poll 8/23/2008 15:28 RST, Next time to poll
master_closet_turn_off_time 8/22/2008 22:39 RST, Master Closet
extractor_girls_turn_off_time 8/22/2008 21:46 RST,Girls Turn off Extractor time
Entrance_turnedon N RST, Is entrance on?
entrace_turn_on_time 8:01:07 PM RST, What time to turn entrance on
time_after_sunset_entrance_turn_on 5 Time to turn on Entrace after SunSet in Minutes
house_state NIGHT House State (E,O,I)
wake_up_time 6:15:00 AM Master Wake up time, M-F only
time_after_sunrise_to_turn_off 10 Time after SunRise to turn off Nook (Sat and sun Only)
incomming_call N CallerID Found? – No Longer Used
incomming_stamp 8/22/2008 17:29 RST, TimeStamp to clear call (No longer used)
incomming_name Luis Garcia RST, Caller ID
incomming_image luis.png RST, Imaged pulled from Contacts DB
incomming_date 8/22/2008 17:29 RST, Incomming Time
incomming_number xxxxxxxxxx RST, Incomming Number
entrance_turn_off_pre -5 Time in minutes before turn off time to turn off the entrance only
entrance_turn_off_pre_time 10:27:00 PM From program result of entracne_Trun_off_pre
motion_hallway N Motion is detected in hallway
extractor_master N If the extractor is on or off
extractor_master_time 10 Timeout for Extrator Master
extractor_master_turn_off_time 8/23/2008 6:18 RST,Master Turn off Extractor time
sensor_hallway N IF Hallway Sensor is on
sensor_hallway_time 6 Timeout Hallway
sensor_hallway_turn_off_time 8/23/2008 6:14 Hallway Timeout
sensor_hallway_bypass N Set to N if normal and Y to ignoreTimer
sensor_entrance_last_seen 8/23/2008 2:48 RST, Last time movement was detected
sensor_entrance_rescan_timeout 3 Minutes before the entrance sends out another signal
sensor_entrance_bypass Y If sensor entrance is bypassed (Y)=dont check (N)=yes check
sensor_master_closet_bypass N If sensor master is bypassed (Y)=dont check (N)=yes check
sensor_hallway_last_seen 8/23/2008 6:08 RST, Last time movement was detected
sensor_master_bathroom_last_seen 8/23/2008 6:09 RST,Last time movement was detected in master batrhoom
sensor_den_last_seen 8/22/2008 23:05 RST,Last time movement was detected in DEN
sensor_garage_last_seen 8/22/2008 20:59 RST,Last time movement was detected in Garage
sensor_hallway_start_time 6:00:00 PM Time that the Sensor will kick in. Usually set 3pm since its day time it wont turn on
sensor_garage_door_state CLOSED Garage door if open
temperature_last_read_wdw 6:40:29 AM Last time temperature was read for WDW
sensor_outside_bathroom_last_seen 8/23/2008 0:25 RST,Last time movement was detected in master batrhoom
sensor_outside_bathroom_timeout 25 Outside bathroom timeout
sensor_outsidebathroom_enabled Y RST, Enabled or not?
music_playing_status N RST, Is Radio Music Playing
sensor_garage_door_state_last 8/22/2008 20:58 RST, Last time Garage was open or closed
sensor_garage_door_timer 6/23/2008 20:48 RST, Time is has been opened
decorations_status OFF Status of all decorations
sensor_den_timer 8/22/2008 23:10 RST, Time the Den will turn off it no movement
sensor_den_timer_timeout 5 Minutes, Den will turn off after no activity
sensor_master_closet_last_seen 8/22/2008 22:36 RST, MasterCloset Last Seen
decorations_on 7:58:07 PM Time Decorations turn on
decorations_off 10:45:00 PM Time Decorations turn off
decorations_after_sunset_on 2 Decorations turn on after sunset
speakers_status OFF RST, if speakers are on
coffee_machine_status TRUE CoffeeMachine timer if on or OFF
coffee_machine_timer 6:20:00 AM CoffeeMachine OnTime
sensor_laundry_last_seen 8/22/2008 21:30 RSt, LAST seen activity in Laundry
sensor_laundry_timeout 3 Minutes before laundry turns off
sensor_laundry_timer 8/22/2008 21:33 RST, When will it turn off
kelly_alarm_on 6:15:00 AM Kelly On_Time
kelly_alarm_status ON IF Kellys alarm is on or off
barbie_alarm_on 7:01:00 AM Barbie OnTime
barbie_alarm_status ON Barbie on-time
back_house_lights_on 9:00:00 PM When will the backlights turn on
back_house_lights_off 9:30:00 PM When will the backlights turn off
guilda_alarm_on 6:15:00 AM Guildas Light will turn on
guilda_alarm_status ON Guildas Alarm status
kelly_alarm_song S:\Mp3\Hanna Montana6 – I Got Nerve.mp3 Kelly AlarmSong
barbie_alarm_song S:\Mp3\Abba\(1994) Thank You For The Music\Disc 1\21 – Abba – My Love, My Life.mp3 Kelly AlarmSong
kelly_artist_songs1 hanna mon Kelly selected artist for Alarm
kelly_artist_songs2 vanessa Kelly selected artist for Alarm
kelly_artist_songs3 ashley tins Kelly selected artist for Alarm
barbie_artist_songs1 cascada Barbie Selected artist for Alarm
barbie_artist_songs2 Abba Barbie Selected artist for Alarm
barbie_artist_songs3 Rick Springfield Barbie Selected artist for Alarm
kelly_alarm_song_title Hanna Montana – I Got Nerve Last song Played
barbie_alarm_song_title ABBA – My Love, My Life Last song Played

The “Devices” data dictionary

I’m always talking about the database this, database that,

So here is the layout of what I have.  This main database ‘Devices table’ that holds all the mac address of each device I have in my home. This makes easy to call devices by number and not by mac.

As mentioned before its a SQL database, you can use what ever you want, This is included in the free version of VB 2008 express. I recommend you download it.

Here is what each field means,

Marker=  is setup as a sequential number which is automatically set so it increments automatically, this is the # of my device, since there can only be one.

Name= The name of device, for example I try to use a standard name, this makes it easier if there is more than one device in a room, for example “Kitchen MainLamp” or “Kitchen Sink lamp”

Mac = The Insteon address, including the dots, for example “01.41.5F” all in caps

Type = “L” for lamp, “F” for fixed I dont know why but I dont use this yet.

Protocol= “I” for Insteon or “X” for X10

Dimmable=”True or False”

Status = Current status of device, if its ON, or OFF, and even % of device such as 50%

Poll = True or false, when I want to check the status of all devices, setting this to True will include it.  For example I don’t want to poll a device which isn’t on line since it will eventually retry 3 times and time out the others.  This is specifically for Christmas decorations.

Last_seen = Last time any change was done to the device, on,off, etc.

randompoll = Sometimes some devices can get pesky so I poll a device every couple of minutes, but only one devices, that is where setting this to True means it will include this on the mix

That’s it, that’s my ‘devices’ database… once they are loaded into memory I reference them by number!

Loading the Insteon Database into Memory

In my code I reference them by using VB structures like this, below is the definition which is defined as public so its available to everyone.

   '----------------------------------- maint structure for insteon devices
    Public Structure Insteon_Device
        Dim MAC As String
        Dim MacSP As String
        Dim MacNP As String
        Dim Name As String
        Dim Type As String
        Dim Protocol As String
        Dim Dimmable As String
    End Structure

Then I call it as a type of variable like this;

'---- I set this to 40 to make space for more. This is set way on top of the program as public so its accessible in all the program.
Public InD(40) As Insteon_Device

This allows me to call the variables like this

debug.print (Ind(1).Mac) ' This will give me the mac of the device by #.. Neat!

Since i come from VB6 Im used to the old classic SQL connection definitions, like all my code there is many ways of doing this so yes you can use the table-adapters and other .NET goodies since I only want Raw power not any fancy tables or colors, I got with my trusty code.

Here is how I load them into the variables itself calling my public function.

Public Function Load_Insteon_devices()
        Dim marker As Integer
        Dim TotalDevices As Integer

        '----------------- SETUP THE SQL CONNECTION AND DATA-READER COMPONENTS
        Dim sqlConnection2 As New System.Data.SqlClient.SqlConnection(My.Settings.InsteonConnectionString)
        Dim cmd2 As New System.Data.SqlClient.SqlCommand
        Dim counter As Integer
        Dim Reader As SqlClient.SqlDataReader

        '---------------- FIRST QUERY CHECKS THE AMOUNT OF DEVICES I HAVE
        cmd2.CommandType = System.Data.CommandType.Text
        cmd2.Connection = sqlConnection2
        cmd2.CommandText = "SELECT COUNT(*) AS CNT FROM Devices"

        sqlConnection2.Open() : Reader = cmd2.ExecuteReader() : Reader.Read()
        TotalDevices = Reader.Item("CNT") '---- TotalDevices will grab to # of devices I have :)
        sqlConnection2.Close()

        '-------------------- NOW THAT I GOT THE AMOUNT GO AHEAD AND READ ALL THE FIELDS
        cmd2.CommandText = "SELECT * FROM Devices"
        sqlConnection2.Open() : Reader = cmd2.ExecuteReader() : Reader.Read()

        '------------------ SCROLL THRU THE DEVICES AND UPDATED EACH STRUCTURE PROPERTY 
        For marker = 1 To TotalDevices
            counter = Reader.Item("Marker")
            InD(counter).MAC = Reader.Item("MAC")

            '-------------- THE VARIABLES MACSP IS THE SAME AS THE MAC ONLY REPLACING THE DOTS FOR SPACES
            InD(counter).MacSP = Trim(InD(counter).MAC.Replace(".", " "))  

            '-------------- THE VARIABLE MAPNP IS THE SMAE AS THE MAC ONLY THAT THERE IS NO SPACES
            InD(counter).MacNP = Trim(InD(counter).MAC.Replace(".", ""))
            InD(counter).Name = Reader.Item("Name")
            InD(counter).Protocol = Reader.Item("Protocol")
            InD(counter).Type = Reader.Item("Type")
            InD(counter).Dimmable = Reader.Item("Dimmable")
            InD(counter).Mastermapping = Reader.Item("Mastermapping")
            Reader.Read()
        Next
        DEBUG.PRINT ("FINISHED LOADING DEVICES")
    End Function

How I update my Devices Database via code

For my own fancy, Here is the code I use to update a device by #.  Like mentioned before when you call a INSTEON group which affects more than one device you dont get individual response from each item so I like to update the DB manually.

So I call another custom function that will update the device using the mac address, and pass the status, such as on or off. For example;

Lg_Update_Device(InD(20).MacNP, "OFF")

Public Function Lg_Update_Device(ByVal ID As String, ByVal value As String) As Boolean

        '------------------------ SETUP CONNECTION AND OTHER GOODIES BEFORE UPDATING ANYTHING
        Dim sqlConnection34 As New System.Data.SqlClient.SqlConnection(My.Settings.InsteonConnectionString)
        Dim cmd34 As New System.Data.SqlClient.SqlCommand
        cmd34.CommandType = System.Data.CommandType.Text
        cmd34.Connection = sqlConnection34

        '------ THIS IS THE ACTUAL SQL COMMAND TO UPDATE THE DEVICE USING THE MAC AS  THE KEY.      

        cmd34.CommandText = "UPDATE Devices SET status= '" + value + "', last_seen='" + Now().ToString + "' WHERE MAC='" + ID + "'"
        If sqlConnection34.State = ConnectionState.Open Then sqlConnection34.Close()
        sqlConnection34.Open()
        cmd34.ExecuteNonQuery()

        '---------------- CLOSE CONNECTION AND EXIT FUNCTION
        sqlConnection34.Close()
        Update_TimeStamp()

    End Function

My Sql database runs on the same box as the ‘server’ and is really fast, SQL caches information in memory so the more you have the better.  It looks like a lot of code but it flyes!.  Hopefully this example will help you on creating your own DB.

Cheers,


Here are my screens so far.  As you can see there is now text that is dynamically populated.
I picked a relative small window, in this case 574.1 x 430.05 and work everthing in that, cleaner and simple.

The Jukebox function basically tells my server to open a HTML page and play a radio URL.
you can find that article here Software:Play WAV,MP3 and Playlists, from your program.

Master Bedroom Screen, I’ve added little dots next to the devices to see if there on or off.
I show how I did this in the next article.

Here I’ve also populated the bottom of the Den,Hallway with the motion sensor data, this way
you can see when there was last activity, also the bulbs show the light status.

Yep, the notification screen, its the only way to unglue them from their PC’s
I wonder where they got it from.  That is done

The Special Features menu.  Also populate the information for the Garage Motion sensors and last time it was opened.