Posts Tagged ‘vb2008’

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!

Advertisements

So after weeks of playing,printing, and busting buttons  I think what I ended up is with some acceptable buttons, here are the layout of my first KeyPad Linc

These were done using a InkJet, I still need to try using a Color Laser to see.  Since I got this one off of ebay it was only the 6 key’s which I got the conversion kit off of SmartHome for $5 to 8 bottons.

The Etched buttons do look better but a bit costly.  Here is the breakdown

8 Button Keypadlinc

Color Kit, which changes the color of the LED behind the button

6 to 8 Button Conversion kit or new buttons if you break one. 🙂

Here is the low down,

1st  – Controls the load on the switch which is in my hallway

2nd – The Kitchen Main light

3rd – The Lights inside the Garage

4th – A group which controls all outside lights, (Garage, flood lights, back lights, entrance etc.)

5th- Not linked to any device but when pressed the PC will turn off all the lights in 2 min’s and set the house state to off, which includes bumping up the thermostat to 80 Degrees.

6th- Linked to my I/O Link to open/monitor the garage.

7th -My Children s room both have a main light and a night light switch, this button is linked to both of them, only thing is the Main Switch has a on – level of  0 which causes only the night light to turn on. The best way for this is to link them manually then go back the the program for Smarthomenet’s and change the turn on code to 0.

8th -Linked to my T1700 Thermostat.  Its linked by setting your thermostat to the desiered state then link like any other switch.  Very simple and clean.  I also link this button back to my PLC so I know its been pressed.

One of the questions ive been asked is how to I put my flash script to grab data from the SQL database and provide updates if the device is on or off etc.

Well the awnser is, I dont. Like mentioned before to have your flash talk directly to a sql database you will need additional components which I dont want to install $$$, such as cold fusion or some advanced Flash stuff.  Again I want speed and functionality, especially if its only for a few users.

So what I did was use a internal web server which is installed with VB 2008, to do all the talking for me, more like a middle man.  for example my flash program talks to this web page using the ‘load’ function which sends data using the POST commands (example http://192.168.0.101/finddata.aspx&IN=14) and the code runs and returns the values needed in a specific variable in this case ‘VALUE’. you can also use the LoadVariables command which explain that in this article.

Flash:Loading Variables from files into Flash

So here is a high level of what is being done in the background.

All all times the Insteon Server is updating the SQL Server with the status of the devices as they are turned on or off, so we dont need to connect there. Also note that the Local .net, SQL database and insteon server are all on the same box!

For example lets say I want to pull the status of device #14. (Fan in master bedroom)  This is what I would do from the Flash Program

Example in FLASH CLIENT;

Prepare: In Flash you will need to create a empty movie clip called ‘fan_master’.  Also have images already in your webpage in the location mentioned below. I call it right of the same page you can use your local library if you like.

Here are my images I use in my Flash program,  you may use them if you like (Just right click on them and use SAVE AS)

Light_bulb_off.png

Light_bulb_on.png

Off Button (small_button_on.png)

On Button (small_button_off.png)

In my actionScript, I would put on one of the frames;

//--------------------- SETUP A NEW VARIABLE TO GRAB MY DATA THIS FUNCTION WILL RUN WHEN THE BELOW SITE IS OPENED
var mfan:LoadVars = new LoadVars();
    mfan.onLoad = function() {

//------ Here I check the return value that is returned back as 'value' if its is ON then replace the fan_master 'movie' to the bulb on image
          if (mfan.value=="ON"){
            loadMovie("http://192.168.0.101/images/small_button_on.png", fan_master);
        } else {
            loadMovie("http://192.168.0.101/images/small_button_off.png", fan_master);
        }
    };
//---------------- do the actual opening of the webpage and pass the variable IN and the device im asking for
mfan.load("http://192.168.0.101/finddata.aspx?in=14");
stop();

BLUE BOX (SERVER .NET SIDE)

A description of my Devices Database is found here

‘————————— VB 2008 / WEBPAGE filename finddata.aspx

On my Server side I would grab the value on “IN” using the

 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      '------- Device will hold the value of in 'IN' which is #14
      device = Context.Request.Params("IN")
      value = Lg_Get_Device_Status(device)
      Response.Write("value=" + value)
 End Sub

This will return to my program the following text
“value=ON” or “value=OFF”

‘——– Function to grab the device data by the device #

    Public Function Lg_Get_Device_Status(ByVal Marker As String) As String

        Dim sqlConnection10 As New System.Data.SqlClient.SqlConnection(ConnectionSTring) ' Set your connectionstring accordingly.
        Dim Cmd10 As New System.Data.SqlClient.SqlCommand

        '-------- We'll use the SqlDataReader to get the values of the table 
        Dim Reader As SqlClient.SqlDataReader

        Cmd10.CommandText = "SELECT * FROM Devices where Marker= '" + Marker + "'"
        Cmd10.Connection = sqlConnection10
        sqlConnection10.Open()
        Reader = Cmd10.ExecuteReader()

        ' check for data, if not return 'FALSE'
        If Reader.HasRows = False Then
            Lg_Get_Device_Status = False
            Exit Function
        End If
        Reader.Read()
        '-------- RETURN THE VALUE FROM THE DATABASE SUCH AS ON OR OFF OF %
        Lg_Get_Device_Status = Reader.Item("status")
        sqlConnection10.Close()

    End Function

And there you have it, I do use the same file (finddata.aspx) for other stuff and you can easily query what is being passed and eventually act on it like this,

For example if I pass(showall=1) it would run another function, but that is another article.

        '------------------- SHOW ALL DEVICES
        If Context.Request.Params("showall") <> "" Then Show_insteon_devices() : Exit Sub

        '------------------- SHOW ALL DEVICES by MAC address
        If Context.Request.Params("showmacs") <> "" Then Show_insteon_devices_mac() : Exit Sub

        '------------------- SHOW ALL CONFIGS
        If Context.Request.Params("show_all_configs") <> "" Then Show_all_configs() : Exit Sub

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,