I updated the script to skip the wall thermastate. I did it based on the address (in my case 621272). But I think there are better ways to do this? I tried with the device type C_type but the table does not match the numer of the device in this section.
I remove the unkown device messageby adding a Case "03". (The wall themostate can work directly, no need for it in homeseer).
I added the command temp to set a radiator thermoste to a value from another device (in my case T2 in farenheid*100).
I quoted out some double debug writelogs.
I removed the coding to restore the temperature to the homeseer setting (because I can override with the wall thermostate, and also directly on the radiator thermostate?)
Arrays were defined with Tcnt = 20 and in the coding there was a check on 100.... (only causing trouble with devicetype other than 00 an 01...)
Code: Select all
' Script : max_monitor script
' Purpose: communication with Max! Gateway
' Author : BLB
' Version: 02p 20130211 Some bugfixes to temp setting via listboxes by storing / comparing required temp in INI file
' Version: 02o 20130120 changed device type with MAX part (Cube or RT), Serial number/address/Firmware version/[device number];
' removed seperate device with Serial number/address/Firmware version/[device number]
' changed MAX!RT device value "Mode/Setpnt/Valve%/EndDateTime" to Setpoint value
' added MAX!RT device "Current Temperature" (Corrected with Offset). The current temperature is not always available, the device value/string stay untouched in that case
' added option to hide status IF status = OK and hide Temperatures via .ini file
' added WaitSec option in .ini file to set the waittime (for response from cube) in the .ini file. Too short time can lead to out of array error as found by Fischi
' modified Firmware version output to Decimal (and not HEX)
' added listboxes for temperature control for each Radiator Termostat, setpoint can be set via this listbox
' Version: 02n 20121219 added latest update time Thermostat Status after change device string
' Version: 02m 20121025 added firmware version Thermostats
' Version: 02l 20121004 added comment for solution for out of array error found by Fischi
' Version: 02k 20120504 improved C: response decoding, now response from other devices (wall switch, wall Thermostat) will be skipped properly
' Version: 02j 20120109 adapted debug setup. debug levels 0 (no), 1 (all full decoded info), 2 (1 + all base64 decoded info)
' Version: 02i 20120108 improved L: response decoding, now response from other devices (wall switch, wall Thermostat) with other response lenght will be skipped properly
' Version: 02h 20120108 added DevLocationswitched parameter in ini file to interchange location1 and location2
' Version: 02g 20111107 added Valve setting in device value (XXxYYY, XXx=temp zetting, YYY is valve opening in %) and sending Boost command
' Version: 02f 20111103 added additional options for end time in s: command
' Version: 02e 20111102 corrected room & device allocation, added timezone info for Cube
' Version: 02d 20111026 added s: command & Cube time (check)
' Version: 02c 20111002 added l: command and started with implementation s: command
' Version: 02b 20111002 added Tvalve() (current valve opening)
' Version: 02a 20110930 initial release
' usage:
' run script without parameters: update all devices, if devices don't exist in HS already they will be created
' run script with parameters:
' ("Main","s:|<room>|<temperature>[|<mode>[|<enddate&time>]]")
' room roomnumber. if room = 0 then update for all rooms
' temperature can be the temperature (xx degrees or xx,5 degrees in range 4,5..30,5), auto (back to week schedule),
' com (comfort temp), eco (eco temp) and win (window open temp) are also allowed
' mode a (Auto) or "" (ommited): back to weekschedule on the first weekschedule change time
' b (Boost) : only boost activation, independent from temp
' p (permanent) : temperature will stay until next (manual) change
' t (Temporary) : temperature will be set until the given date & time
' enddate&time YYYYMMDDHHMM : the end date & time
' DDHHMM : days, hours and minutes later than current time
' import required modules
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Const INI_FILE As String = "hssi_BLB_Max_monitor.ini" ' name ini file
Const swversion = "0.2p" ' the version of this file
Sub Main(ByVal varParameters)
'define variables
Dim Tcnt As Integer = 20
Dim Client As New TcpClient()
Dim strHC As String = hs.GetINISetting("Startup", "HouseCode", "", INI_FILE) ' house code
Dim DevLocation As String = hs.GetINISetting("Startup", "DevLocation", "", INI_FILE)
Dim RemoteIP As String = hs.GetINISetting("Startup", "TCPAddress", "", INI_FILE)
Dim PortNumber As Integer = Val(hs.GetINISetting("Startup", "TCPPort", "", INI_FILE))
Dim WaitSec As Integer = Val(hs.GetINISetting("Startup", "WaitSec", "3", INI_FILE))
Dim DevLocsw As Boolean = hs.GetINISetting("Startup", "DevLocationswitched", "", INI_FILE)
Dim Debug As Integer = Val(hs.GetINISetting("Startup", "Debug", "3", INI_FILE))
Dim HideStatusOK As Boolean = hs.GetINISetting("Startup", "HideStatusOK", "FALSE", INI_FILE)
Dim HideTemps As Boolean = hs.GetINISetting("Startup", "HideTemperatures", "FALSE", INI_FILE)
Dim strDC As String = hs.GetINISetting("Cube", "FirstDeviceCode", "", INI_FILE)
Dim strDV As String = strHC & strDC
Dim Temp As String
Dim Message As String
Dim SetSetpoint As Boolean = True
Dim ResponseH, ResponseM, ResponseC(Tcnt),ResponseL As String
Dim ResponseH_SN, ResponseH_Ad,ResponseH_Fw, ResponseH_P4, ResponseH_P5, ResponseH_P6, ResponseH_P7, ResponseH_P8, ResponseH_P9 As String
Dim ResponseH_Ye, ResponseH_Mo, ResponseH_Da, ResponseH_Ho, ResponseH_Mi, ResponseH_Date As String
Dim Date_error_Mi
Dim ResponseM_P1, ResponseM_P2, ResponseM_P3
Dim PositionH, PositionM, PositionC(Tcnt), PositionL As String
Dim Seperator(Tcnt) as Integer
Dim Counter As Integer = 0
Dim M_Rnumber(Tcnt), M_Rname(Tcnt), M_Raddress(Tcnt) , M_D_Type(Tcnt), M_Daddress(Tcnt), M_D_SN(Tcnt) As String
Dim M_D_room(Tcnt) , M_DName(Tcnt), M_DRoom(Tcnt) As String
Dim Name_Length, M_pointer, M_R_count, M_D_count, M_Rooms, M_Devices, Mi As Integer
Dim Caddress(Tcnt), C_type(Tcnt), C_SN(Tcnt), C_Firmware(Tcnt), C_Week(Tcnt) As String
Dim C_Cube_WT, C_Cube_ST As String
Dim C_Cube_TV As Long
Dim C_Com_Temp(Tcnt), C_Eco_Temp(Tcnt), C_Max_Temp(Tcnt), C_Min_Temp(Tcnt), C_Off_Temp(Tcnt), C_Win_Temp(Tcnt) As single
Dim C_Win_Dura(Tcnt), C_Dur_Boos(Tcnt), C_Val_Boos(Tcnt), C_Dti_deca(Tcnt), C_max_Valv(Tcnt), C_off_Valv(Tcnt) As String
Dim C_Wk(7) As String
Dim Taddress(Tcnt), Tvalid(Tcnt), Terror(Tcnt), Tanswer(Tcnt), Tstatus(Tcnt), TstatusT(Tcnt) As String
Dim Tbattery(Tcnt), Tlinkstatus(Tcnt), Tpanel(Tcnt), Tgateway(Tcnt), Tdts(Tcnt), Tmode1(Tcnt), Tmode2(Tcnt) As String
Dim TTemp(Tcnt), Tvalve(Tcnt) As Single
Dim Tdate(Tcnt), Ttime(Tcnt), TdateTime(Tcnt), Tist(Tcnt) As String
Dim MaxCommand, s_roomc, s_mode, s_enddt As String
Dim s_room As Integer
Dim Tyy, Tmm, Tdd, Tda, Thh, IST As String
dim dv2 as Object
If debug > 0 Then hs.WriteLog("Max_debug1", "SWversion: " & swversion)
If varParameters = "" Or varParameters = "l:" Then
MaxCommand = varParameters
ElseIf Left(varParameters,2) = "s:"
' IF s:, 1st parameter = command (always "s:")
' 2nd parameter = roomnumber. If 0 all rooms
' 3rd parameter = temperature. auto, com (comfort temp), eco (eco temp), win (window open temp)
' and bst (boost command) are also allowed
' optional 4rd parameter = mode. A (Auto), B (Boost), P (Permanent), T (Temporary). If T then 5th parameter
' is also required
' optional 5th parameter = end date & time. yymmddhhmm
Maxcommand = hs.stringitem(varParameters, 1, "|")
s_room = hs.stringitem(varParameters, 2, "|")
s_roomc = hs.stringitem(varParameters, 3, "|")
s_mode = LCase(hs.stringitem(varParameters, 4, "|"))
s_enddt = hs.stringitem(varParameters, 5, "|")
If debug > 1 Then hs.WriteLog("Max_debug2", "s: command: " & Maxcommand & " room: " & s_room & " roomcmd: " & s_roomc & " mode: " & s_mode)
Else
hs.WriteLog("Error", "Max Monitor; Unknown command: " & varParameters)
End If
'Device Names for Cube (n1) and Thermostats (n2)
Dim n1(3), n2(5)
n1(1)= "System date & Time"
n1(2)= "Timezone"
n2(1)= "Temperatures"
n2(2)= "Status"
n2(3)= "Program Today (Temp/Time)"
n2(4)= "Mode/Setpnt/Valve%/EndDateTime"
n2(5)= "Current Temperature"
Try
' Connect to the remote
Client.Connect(IPAddress.Parse(RemoteIP), PortNumber)
Dim NetStream As NetworkStream = Client.GetStream()
' Receive reply. After initial Connect, the Cube gives always an initial response with all?? info
hs.WaitSecs(WaitSec)
Dim Reply As String = ReadString(Client)
If debug > 1 Then hs.WriteLog("Max_debug2", "Full Reply: " & Reply) ' full reply to logfile
' Search seperators (:) in initial response string and put all fields in seperate variables Seperator()
Seperator(Counter) = 1
Do Until Seperator(Counter) = 0
Seperator(Counter+1) = InStr(Seperator(Counter)+1,Reply,":")
Counter += 1 ' counter hold number of fields in the reply
Loop
' Search the different responses from the initial response string and split them in all known parameters
Dim i As Integer ' i = counter to the number of fields in reply
Dim dev As Integer = 1
For i = 1 To counter-1
If i = counter-1 Then Seperator(i+1) = Reply.length
Select Case Mid(Reply,Seperator(i)-1,2)
Case "H:" ' The H response contains information about the Cube.
ResponseH = Mid(Reply,Seperator(i)+1,Seperator(i+1)-Seperator(i)-2)
If debug > 1 Then hs.WriteLog("Max_debug2", "H: " & ResponseH)
ResponseH_SN = hs.StringItem(ResponseH,1,",")
ResponseH_Ad = Hex2Dec(hs.StringItem(ResponseH,2,","))
ResponseH_Fw = Hex2Dec(hs.StringItem(ResponseH,3,","))
ResponseH_P4 = hs.StringItem(ResponseH,4,",")
ResponseH_P5 = hs.StringItem(ResponseH,5,",")
ResponseH_P6 = hs.StringItem(ResponseH,6,",")
ResponseH_P7 = hs.StringItem(ResponseH,7,",")
ResponseH_P8 = hs.StringItem(ResponseH,8,",")
ResponseH_P9 = hs.StringItem(ResponseH,9,",")
ResponseH_Ye = Hex2Dec(Mid(ResponseH_P8,1,2))+2000
ResponseH_Mo = Hex2Dec(Mid(ResponseH_P8,3,2))
ResponseH_Da = Hex2Dec(Mid(ResponseH_P8,5,2))
ResponseH_Ho = Hex2Dec(Mid(ResponseH_P9,1,2))
ResponseH_Mi = Hex2Dec(Mid(ResponseH_P9,3,2))
ResponseH_Date = CDate(ResponseH_Ye & "-" & ResponseH_Mo & "-" &ResponseH_Da & " " & ResponseH_Ho & ":" & ResponseH_Mi)
Date_error_Mi = DateDiff("n",ResponseH_Date,now())
hs.WriteLog("Info", "H: Cubedate: " & ResponseH_Date & " systemtime: " & now() & " Datediff: " & DateDiff("n",ResponseH_Date,now()))
If debug > 0 Then hs.WriteLog("Max_debug1", "H: Cube Serial number: " & ResponseH_SN & " Cube Address: " & ResponseH_Ad & " Cube Firmware: " & ResponseH_Fw & " Cube Date: " & ResponseH_Date)
Case "M:" ' The M response contains Metadata; rooms, device names etc
ResponseM = Mid(Reply,Seperator(i)+1,Seperator(i+1)-Seperator(i)-2)
If debug > 1 Then hs.WriteLog("Max_debug2", "M: " & ResponseM)
ResponseM_P1 = hs.StringItem(ResponseM,1,",")
ResponseM_P2 = hs.StringItem(ResponseM,2,",")
ResponseM_P3 = Base64ToHex(hs.StringItem(ResponseM,3,","))
If debug > 1 Then hs.WriteLog("Max_debug2", "M: " & ResponseM_P1 & " " & ResponseM_P2 & " " & ResponseM_P3)
M_pointer = 5
M_R_count = 1
M_Rooms = Val("&H" & Mid(ResponseM_P3,M_pointer,2))
M_pointer += 2
For Mi = 1 To M_Rooms
M_Rnumber(Mi) = Val("&H" & Mid(ResponseM_P3,M_pointer,2))
M_pointer += 2
Name_Length = Val("&H" & Mid(ResponseM_P3,M_pointer,2)) * 2
M_pointer += 2
M_RName(Mi) = Hex2asc(Mid(ResponseM_P3,M_pointer,Name_Length))
M_pointer += Name_Length
M_Raddress(Mi) = Hex2Dec(Mid(ResponseM_P3,M_pointer,6))
M_pointer += 6
If debug > 0 Then hs.WriteLog("Max_debug1", "M: #rooms: " & CStr(M_rooms) & " RoomNumber: " & CStr(M_Rnumber(Mi)) & " RoomName: " & _
M_RName(Mi) & " 1stAddressInRoom: " & M_Raddress(Mi))
Next
M_R_count = 1
M_Devices = Val("&H" & Mid(ResponseM_P3,M_pointer,2))
M_pointer += 2
For Mi = 1 To M_Devices
M_D_type(Mi) = Mid(ResponseM_P3,M_pointer,2)
M_pointer += 2
M_Daddress(Mi) = Hex2Dec(Mid(ResponseM_P3,M_pointer,6))
M_pointer += 6
M_D_SN(Mi) = Hex2asc(Mid(ResponseM_P3,M_pointer,20))
M_pointer += 20
Name_Length = Val("&H" & Mid(ResponseM_P3,M_pointer,2)) * 2
M_pointer += 2
M_DName(Mi) = Hex2asc(Mid(ResponseM_P3,M_pointer,Name_Length))
M_pointer += Name_Length
M_DRoom(Mi) = Val("&H" & Mid(ResponseM_P3,M_pointer,2))
M_pointer += 2
If debug > 0 Then hs.WriteLog("Max_debug1", "M: #Devices: " & CStr(M_Devices) & " DeviceType: " & M_D_type(Mi) & _
" DeviceAddress: " & M_Daddress(Mi) & " SN: " & M_D_SN(Mi) & " DeviceName: " & M_DName(Mi) & _
" DeviceRoom: " & M_DRoom(Mi))
Next
Case "L:"
ResponseL = Base64ToHex(Mid(Reply,Seperator(i)+1,Seperator(i+1)-Seperator(i)-2))
If debug > 1 Then hs.WriteLog("Max_debug2", "L: lenght: " & CStr(ResponseL.length) & " L: response: " & ResponseL)
Dim t As Integer = 1
Dim L(Tcnt) As String
Dim LLength as Integer
Dim L_Pointer As Integer = 1
Do until L_pointer > ResponseL.length
LLength = Val("&H" & Mid(ResponseL,L_Pointer,2))
If LLength = 11 'Lenght = 11 means Thermostat
L(t) = Mid(ResponseL,L_Pointer,(LLength+1)*2)
If debug > 1 Then hs.WriteLog("Max_debug2", "L: Device " & CStr(t) & ": " & L(t))
Taddress(t) = Hex2Dec(Mid(L(t),3,6))
Temp = Hex2Bin(Mid(L(t),11,2)) 'convert byte 6 to binary status bits
Tvalid(t) = Mid(Temp,4,1)
If Tvalid(t) = "0" Then TstatusT(t) = "invalid info"
Terror(t) = Mid(Temp,5,1)
If Terror(t) = "1" Then Tstatus(t) += " error occurred"
Tanswer(t) = Mid(Temp,6,1)
If Tanswer(t) = "1" Then TstatusT(t) += " not an answer to a Command"
Tstatus(t) = Mid(Temp,7,1)
If Tstatus(t) = "0" Then TstatusT(t) += " not initialized"
Temp = Hex2Bin(Mid(L(t),13,2)) 'convert byte 7 to binary status bits
Tbattery(t) = Mid(Temp,1,1)
If Tbattery(t) = "1" Then TstatusT(t) += " low battery"
Tlinkstatus(t) = Mid(Temp,2,1)
If Tlinkstatus(t) = "1" Then TstatusT(t) += " link error"
Tpanel(t) = Mid(Temp,3,1)
If Tpanel(t) = "1" Then TstatusT(t) += " panel locked"
Tgateway(t) = Mid(Temp,4,1)
If Tgateway(t) = "0" Then TstatusT(t) += " gateway unknown"
Tdts(t) = Mid(Temp,5,1)
If Tdts(t) = "0" Then TstatusT(t) += " DST inactive"
If TstatusT(t) = "" Then TstatusT(t) = "OK"
Tmode1(t) = Mid(Temp,7,2)
Select Case Tmode1(t)
Case "00"
'auto/week schedule
Tmode2(t) = "Auto"
Case "01"
'Manual
Tmode2(t) = "Manual"
Case "10"
'Party/Vacation
Tmode2(t) = "Party/Vacation"
Case "11"
'Boost
Tmode2(t) = "Boost"
Case Else
'something wrong'
End Select
Tvalve(t) = Val("&h" & Mid(L(t),15,2)) ' current valve opening in %
Ttemp(t) = Val("&h" & Mid(L(t),17,2)) / 2 ' Temperature setpoint
Dim DateISThex As Double = Val("&h" & Mid(L(t),19,4)) ' date or Actual Temperature
if Debug > 0 Then hs.WriteLog("Max_debug1","L: " & L(t) & " IST: " & DateISThex/10 & " Mode: " & Tmode1(t) & " HEX: " & Mid(L(t),19,4))
If Tmode1(t) = "10" ' temporary Temp setting, =>Date
Tdate(t) = DateSerial(2000 + (DateISThex And &h0F),((DateISThex And &hE000) >> 12)+((DateISThex And &h80) >> 7),(DateISThex And &h1F00) >> 8)
Ttime(t) = TimeSerial(Int(Val("&h" & Mid(L(t),23,2))/2),(Val("&h" & Mid(L(t),23,2))/2 - int(Val("&h" & Mid(L(t),23,2))/2))*60,0)
TdateTime(t) = FormatDateTime(Tdate(t) & " " & Ttime(t))
Tist(t) = "0"
Else If DateISThex <> 0 ' Actual Temperature
Tist(t) = DateISThex/10
TdateTime(t) = "--"
Else
TdateTime(t) = "--"
End If
If debug > 0 Then hs.WriteLog("Max_debug1","L: address: " & Taddress(t) & " tvalid: " & Tvalid(t) & " Terror: " & Terror(t)& " Tanswer: " & Tanswer(t) & " mode: " & Tmode2(t) & " Valve: " & CStr(Tvalve(t)) & "% Temp: " & CStr(Ttemp(t)) & " date: " & TdateTime(t))
Else
If debug > 0 Then hs.WriteLog("Max_debug1","L: no Thermostat, Length L: command= " & LLength & "!")
End If
L_pointer += (LLength+1)*2
t += 1
Loop
Case "C:"
ResponseC(dev) = Mid(Reply,Seperator(i)+1,Seperator(i+1)-Seperator(i)-2)
Dim j1, j2, j3 As Integer
Dim WP, WP2, WP3, WP4 As String
Caddress(dev) = Hex2Dec(hs.StringItem(ResponseC(dev),1,","))
Temp = Base64ToHex(hs.StringItem(ResponseC(dev),2,","))
C_type(dev) = Mid(Temp,9,2)
C_SN(dev) = hex2asc(Mid(Temp,17,20))
If debug > 0 Then hs.WriteLog("Max_debug1", "C" & CStr(dev) & ": " & "address: " & Caddress(dev) & " type: " & C_type(dev) & " SerialNR: " & C_SN(dev))
Select Case C_Type(dev)
Case "00"
' Cube
If debug > 1 Then hs.WriteLog("Max_debug2", "C: C response: " & Temp)
C_Cube_TV = Val("&h" & Trim(Mid(Temp,429,6)))
C_Cube_WT = Hex2asc(Trim(Mid(Temp,429,10)))
C_Cube_ST = Hex2asc(Trim(Mid(Temp,453,10)))
If debug > 1 Then hs.WriteLog("Max_debug2", "C: C Cube response: " & C_Cube_WT & " " & C_Cube_ST)
Case "01"
' Thermostate
C_Firmware(dev) = Hex2Dec(Mid(Temp,13,2)) ' Firmware version
C_Com_Temp(dev) = Val("&h" & Mid(Temp,37,2)) / 2 ' comfort temperature
C_Eco_Temp(dev) = Val("&h" & Mid(Temp,39,2)) / 2 ' Eco Temperature
C_Max_Temp(dev) = Val("&h" & Mid(Temp,41,2)) / 2 ' Max Temperature
C_Min_Temp(dev) = Val("&h" & Mid(Temp,43,2)) / 2 ' Min Temperature
C_Off_Temp(dev) = Val("&h" & Mid(Temp,45,2)) / 2 - 3.5 ' offset possible is -3,5 to 3,5 degrees, 3,5 = 0
C_Win_Temp(dev) = Val("&h" & Mid(Temp,47,2)) / 2 ' window open temperature
C_Win_Dura(dev) = Mid(Temp,49,2) ' window open duration
C_Dur_Boos(dev) = Bin2Dec(Left(Hex2Bin(Mid(Temp,51,2)),3)) ' Boost duration
If C_Dur_Boos(dev) = "7" Then C_Dur_Boos(dev) = "30"
C_Val_Boos(dev) = Bin2Dec(Mid(Hex2Bin(Mid(Temp,51,2)),4,5))*5 & "%" ' Boost Valve Value (%)
C_Dti_deca(dev) = WeekdayName(Bin2Dec(Left(Hex2Bin(Mid(Temp,53,2)),3))+1,True,7) & " " & _
Bin2Dec(Mid(Hex2Bin(Mid(Temp,53,2)),4,5)) & ":00u" ' Decalcification: Day of week and Time
C_max_Valv(dev) = Val("&h" & Mid(Temp,55,2))*100/255 ' Maximum Valve setting; *(100/255) to get in %
C_off_Valv(dev) = Val("&h" & Mid(Temp,57,2))*100/255 ' Valve Offset ; *(100/255) to get in %
For j1 = 1 To 7 ' days of the week
WP = Mid(Temp, 7 + 52 * j1, 52) ' string with (13) values for the selected day
C_Wk(j1)=""
j2 = 1
Do
WP2 = Bin2Dec(Mid(Hex2Bin(Mid(WP,1+(j2-1)*4,4)),2,6))/2 ' temperature
WP3 = Bin2Dec(Mid(Hex2Bin(Mid(WP,1+(j2-1)*4,4)),8,9))*5 ' time in minutes
WP4 = FormatDateTime(TimeSerial(0,Wp3,0),4) ' formatted time (in hours)
C_Wk(j1) = C_Wk(j1) & "("&j2 & ") " & WP2 & "/" & WP4 & " "
j2 += 1
Loop until wp3 = "1440" Or j2 = 13
If j1 = Weekday(Now(),7) Then C_Week(dev) = C_Wk(j1) ' copy current day to C_Week() variable
If debug > 0 Then hs.WriteLog("Max_debug1","C" & CStr(dev) & ": " & WeekdayName(J1,True,7) & " " & Weekday(Now(),7) & " " & C_Wk(j1))
Next
If debug > 0 Then hs.WriteLog("Max_debug1","C" & CStr(dev) & ": " & "ComT: " & C_Com_Temp(dev) & " EcoT: " & C_Eco_Temp(dev) & " MaxT: " & C_Max_Temp(dev) & " MinT: " & C_Min_Temp(dev) & " OffT: " & C_Off_Temp(dev) & " WinT: " & C_Win_Temp(dev) & " WinDur: " & C_Win_Dura(dev) & " Boostdur: " & C_Dur_Boos(dev) & " BoostVal: " & C_Val_Boos(dev) & " datetime_decal: " & C_Dti_deca(dev)&" Valve_Max: "&C_max_Valv(dev)& " Valve_off: "& C_off_Valv(dev) & " Firmware: "& C_Firmware(dev))
Case "03" 'JK avoind unknown device message
Case Else
' unknown device
hs.WriteLog("Error","Max Monitor; C" & CStr(dev) & ": " & " unknown device: " & C_Type(dev))
End Select
If debug > 1 Then hs.WriteLog("Max_debug2","C" & CStr(dev) & ": " & "response: " & Temp)
dev +=1
Case else
hs.WriteLog("Error", "Max Monitor; unknown command: " & CStr(dev) & Mid(Reply,Seperator(i)-1,2))
End Select
Next
' all initial fields are read and processed
' update all Max Devices. If MaxDevices don't exist, they will be created
Dim dv, C1, C2, C3, CRef, Lref, Mref
Dim DevTypeName, DevLocation2 As String
If MaxCommand = "" ' If no MaxCommand then Check Setpoint setting via Listbox
MaxCommand = "s:"
End If
Select Case MaxCommand
Case "s:"
Dim s_roomc2 As String
Dim s_roomct As String = ""
Dim s_roomct2 As String = ""
Select Case s_mode ' check mode
Case "" ' if mode = "" (Default) or "a" then 2 MSB = 00 (dec 0)
s_mode = 0
Case "a" ' if mode = "a" then 2 MSB = 00 (dec 0)
s_mode = 0
Case "p" ' if mode = "P" then 2 MSB = 01 (dec 64)
s_mode = 64
Case "t" ' if mode = "t" then 2 MSB = 10 (dec 128)
s_mode = 128
Case "b" ' if mode = "b" then 2 MSB = 11 (dec 192)
s_mode = 192
If Len(s_enddt) = 12 Then ' if 12 then end date is given
Tyy = Dec2Bin2(Val(Left(s_enddt,4))-2000,6)
Tmm = Dec2Bin2(Val(Mid(s_enddt,5,2)),4)
Tdd = Dec2Bin2(Val(Mid(s_enddt,7,2)),5)
Tda = Dec2Hex(Bin2Dec(Left(Tmm,3) & Tdd & Right(Tmm,1) & "0" & Tyy),4)
Thh = Dec2Hex(Val(Mid(s_enddt,9,2))*2 + Int(Val(Mid(s_enddt,9,2))/30),2)
Else If Len(s_enddt) = 6 Then 'if 6 then given info is ddhhmm in the future
Dim tempdaytime = ResponseH_Date
tempdaytime = DateAdd("d",Val(Left(s_enddt,2)) ,tempdaytime)
tempdaytime = DateAdd("h",Val(Mid(s_enddt,3,2)),tempdaytime)
tempdaytime = DateAdd("n",Val(Mid(s_enddt,5,2)),tempdaytime)
Tyy = Dec2Bin2( Year(tempdaytime)-2000,6)
Tmm = Dec2Bin2(Month(tempdaytime),4)
Tdd = Dec2Bin2( Day(tempdaytime),5)
Tda = Dec2Hex(Bin2Dec(Left(Tmm,3) & Tdd & Right(Tmm,1) & "0" & Tyy),4)
Thh = Dec2Hex(Hour(tempdaytime)*2 + Int(Minute(tempdaytime)/30),2)
If debug > 1 Then hs.WriteLog("Max_debug2","enddatetime: "& ResponseH_Date & " new " & tempdaytime)
End If
s_roomct2 = Tda & Thh
If debug > 1 Then hs.WriteLog("Max_debug2", "s: date: " & Tda & " yy: " & Tyy & " mm: " & Tmm & " dd: " & Tdd & " tt: " & Thh)
Case else
hs.WriteLog("Error", "Max Monitor; wrong mode command: " & s_mode)
End Select
Dim sc As Integer
Dim s_loop_s As Integer
Dim s_loop_e As Integer
If s_room = 0 Then
C1 = 1
s_loop_s = 1
s_loop_e = M_Rooms
Else
' lookup M response
Mref = 1
Do until s_room = M_Rnumber(Mref) Or Mref = M_Rooms
Mref+=1
Loop
s_loop_s = Mref
s_loop_e = Mref
End if
For sc = s_loop_s To s_loop_e ' loop all Thermostats
C1 = sc
Dim s_roomn As String = Dec2Hex(M_Raddress(C1),6) & Dec2Hex(M_Rnumber(C1),2)
' lookup C response
Cref = 1
Do until Caddress(Cref) = M_Raddress(C1) Or Cref = Tcnt ' JK 100 -> Tcnt
Cref+=1
Loop
' lookup L response
Lref = 1
Do until Taddress(Lref) = M_Daddress(C1) Or Lref = Tcnt ' JK 100 -> Tcnt
Lref+=1
Loop
' write room name in ini file
If hs.GetINISetting("Thermostat" & CStr(C1), "DeviceName", "", INI_FILE) <> M_DName(C1) Then hs.SaveINISetting("Thermostat" & CStr(C1), "DeviceName",M_DName(C1), INI_FILE)
If debug > 0 Then hs.WriteLog("debugn4 s:", CStr(Cref) & Caddress(Cref) & C_Com_Temp(Cref))
' look up & (encode room) command (temperature setting)
If s_roomc = "auto" Or s_roomc = "00"
s_roomC2 = "00"
ElseIf LCase(s_roomc) = "com"
s_roomc2 = Dec2Hex(C_Com_Temp(Cref) * 2 + s_mode,2)
ElseIf LCase(s_roomc) = "eco"
s_roomc2 = Dec2Hex(C_Eco_Temp(Cref) * 2 + s_mode,2)
ElseIf LCase(s_roomc) = "win"
s_roomc2 = Dec2Hex(C_Win_Temp(Cref) * 2 + s_mode,2)
ElseIf LCase(s_roomc) = "temp" ' JK extra command
s_roomc2 = Dec2Hex(Math.Round(hs.devicevalue("T2")/100,1) * 2 + s_mode,2) ' JK extra command (T@ holds the desired temperture in F*100
ElseIf Val(s_roomc) < 31 And Val(s_roomc) > 4
If debug > 0 Then hs.WriteLog("debugn4b s:", CDbl(s_roomc) )
s_roomc2 = Dec2Hex(CDbl(s_roomc) * 2 + s_mode,2)
ElseIf s_roomc = "" 'roomtemp per individual room temp setting (listbox)
strDC = hs.GetINISetting("Thermostat" & CStr(C1), "FirstDeviceCode", "", INI_FILE)
strDV = strHC & strDC+3
If hs.devicevalue(strDV) <> hs.GetINISetting("Thermostat" & CStr(C1), "Settemp", "0", INI_FILE) Then
hs.SaveINISetting("Thermostat" & CStr(C1), "Settemp",hs.devicevalue(strDV), INI_FILE)
'If Ttemp(Lref) <> hs.devicevalue(strDV)/10 Then 'setpoint must be changed
'hs.WriteLog("Max_debug0", "SetSetpoint, Thermostat" & CStr(C1) & " Current Setpoint: " & Ttemp(Lref) & " Required setpoint: " & strDV & " " & hs.devicevalue(strDV)/10) ' JK ???
's_roomc2 = Dec2Hex(CDbl(hs.devicevalue(strDV)/10) * 2 + s_mode,2) ' JK ?????
'Ttemp(Lref) = hs.devicevalue(strDV)/10
'Else
SetSetpoint = False
'End If
Else
SetSetpoint = False
End If
Else
hs.WriteLog("Error", "Max Monitor; unknown room command: " & s_roomc)
End If
If SetSetpoint Then
MaxCommand = "000440000000"
MaxCommand += s_roomn & s_roomc2 & s_roomct2
If debug > 1 Then hs.WriteLog("Max_debug2","s: " & MaxCommand )
'hs.WriteLog("Max_debug2","s: " & MaxCommand ) ' JK double writelog
MaxCommand = "s:" & HexToBase64(MaxCommand)
SendString(NetStream, MaxCommand & vbCrLf)
hs.WaitSecs(WaitSec)
Reply = ReadString(Client)
If debug > 1 Then hs.WriteLog("Max_debug2", "s: " & Reply)
'hs.WriteLog("Max_debug2", "s: " & Reply) ' JK double writelog
End If
SetSetpoint = True
Next
Case ""
'
Case Else
hs.WriteLog("Error", "Max Monitor; unknown command: " & MaxCommand)
End Select
'update all existing or create new
strDC = hs.GetINISetting("Cube", "FirstDeviceCode", "", INI_FILE)
strDV = strHC & strDC
If hs.DeviceExistsRef(strDV) = -1 Then ' check if Cube exist. if not, create devices
DevTypeName = hs.GetINISetting("Startup", "CubeName", "", INI_FILE)
DevLocation2 = hs.GetINISetting("Cube", "DevLocation2", "", INI_FILE)
For C1 = 1 To 2
dv = hs.GetDeviceByRef(hs.NewDeviceRef(n1(C1)))
dv.dc = CStr(C1+ Int(strDC)-1)
dv.hc = strHC
dv.can_dim = False
if DevLocsw
dv.location = DevLocation
dv.location2 = DevLocation2
else
dv.location = DevLocation2
dv.location2 = DevLocation
End If
dv.dev_type_string = DevTypeName & "-" & CStr(ResponseH_SN) & "/" & CStr(ResponseH_Ad)& "/" & CStr(ResponseH_FW)
dv.misc = &h10
Next
End If
' update Cube Device
hs.SetDeviceValue(strHC & CStr(Int(strDC)+0),Val(ResponseH_Ye & ResponseH_Mo & ResponseH_Da))
If Date_error_Mi > 10 Or Date_error_Mi < -10 Then
hs.SetDeviceString(strHC & CStr(Int(strDC)+0),"<img src='/images/Off-Line.gif'> " & ResponseH_Date)
Else
hs.SetDeviceString(strHC & CStr(Int(strDC)+0),"<img src='/images/On-Line.gif'> " & ResponseH_Date)
End If
hs.SetDeviceValue(strHC & CStr(Int(strDC)+1),C_Cube_TV)
hs.SetDeviceString(strHC & CStr(Int(strDC)+1),C_Cube_WT & "/" & C_Cube_ST)
'thermostats
For C2 = 1 To M_Devices 'M_Devices holds the number of Thermostats
If M_Daddress(C2) <> "610272" ' JK address of the wall thermoste, just scip it.
strDC = hs.GetINISetting("Thermostat" & CStr(C2), "FirstDeviceCode", "", INI_FILE)
If strDC = "" Then hs.WriteLog("Error","Max Monitor; Thermostat setting in INI file incorrect")
strDV = strHC & strDC
If hs.DeviceExistsRef(strDV) = -1 Then ' check if Thermostat exist. if not, create devices
hs.WriteLog("Max_debug0", "Create Radiator Thermostat Device: " & strDV)
DevTypeName = hs.GetINISetting("Startup", "ThermostatName", "", INI_FILE)
'lookup M response Room
Mref = 1
Do until M_Raddress(Mref) = M_Daddress(C2) Or Mref = Tcnt ' JK 100 -> Tcnt
Mref+=1
Loop
' lookup C response
Cref = 1
Do until Caddress(Cref) = M_Daddress(C2) Or Cref = Tcnt ' JK 100 -> Tcnt
Cref+=1
Loop
hs.WriteLog("Max_debug1", "Firmware: " & C_Firmware(C2))
'hs.WriteLog("Max_debug1", "Firmware: " & C_Firmware(C2)) ' JK double writelog
DevLocation2 = M_RName(Mref)
For C3 = 1 To 5
dv = hs.GetDeviceByRef(hs.NewDeviceRef(n2(C3)))
dv.dc = CStr(C3+ Int(strDC)-1)
dv.hc = strHC
dv.can_dim = False
if DevLocsw
dv.location = DevLocation
dv.location2 = DevLocation2
else
dv.location = DevLocation2
dv.location2 = DevLocation
End If
dv.dev_type_string = DevTypeName & "-" & CStr(M_D_SN(Mref)) & "/" & CStr(M_Daddress(Mref)) & "/" & CStr(C_Firmware(Cref)) & "/" & CStr(M_DRoom(Mref))
dv.misc = &h10
If C3 = 4 Then 'create listbox
hs.DeviceValuesAdd(strHC & CStr(C3+ Int(strDC)-1), _
"OFF" & chr(2) & "45" & chr(1) & _
"12.0" & chr(2) & "120" & chr(1) & _
"13.0" & chr(2) & "130" & chr(1) & _
"14.0" & chr(2) & "140" & chr(1) & _
"15.0" & chr(2) & "150" & chr(1) & _
"16.0" & chr(2) & "160" & chr(1) & _
"17.0" & chr(2) & "170" & chr(1) & _
"18.0" & chr(2) & "180" & chr(1) & _
"18.5" & chr(2) & "185" & chr(1) & _
"19.0" & chr(2) & "190" & chr(1) & _
"19.5" & chr(2) & "195" & chr(1) & _
"20.0" & chr(2) & "200" & chr(1) & _
"20.5" & chr(2) & "205" & chr(1) & _
"21.0" & chr(2) & "210" & chr(1) & _
"21.5" & chr(2) & "215" & chr(1) & _
"22.0" & chr(2) & "220" & chr(1) & _
"22.5" & chr(2) & "225" & chr(1) & _
"23.0" & chr(2) & "230" & chr(1) & _
"23.5" & chr(2) & "235" & chr(1) & _
"24.0" & chr(2) & "240" & chr(1) & _
"24.5" & chr(2) & "245" & chr(1) & _
"25.0" & chr(2) & "250" & chr(1) & _
"ON" & chr(2) & "300" & chr(1) & _
"Any Value" & chr(2) & "999", true)
End If
If Debug > -1 Then hs.WriteLog("Max_debug0", "dev: " & n2(C3))
Next
End If
'update Thermostats
' lookup C response
Cref = 1
Do until Caddress(Cref) = M_Daddress(C2) Or Cref = Tcnt ' JK 100 -> Tcnt
Cref+=1
Loop
Dim Temps As String
If C_Off_Temp(Cref) = 0 Then
Temps = "C" & CStr(C_Com_Temp(Cref)) & " E" & C_Eco_Temp(Cref) & " W" & C_Win_Temp(Cref) & " +" & CStr(C_Max_Temp(Cref)) & " -" & C_Min_Temp(Cref)
Else
Temps = "C" & CStr(C_Com_Temp(Cref)) & " E" & C_Eco_Temp(Cref) & " W" & C_Win_Temp(Cref) & " +" & CStr(C_Max_Temp(Cref)) & " -" & C_Min_Temp(Cref) & " O" & C_Off_Temp(Cref)
End If
hs.SetDeviceValue(strHC & CStr(Int(strDC)+0),C_Off_Temp(Cref)*10) ' Offset Temperatrue
hs.SetDeviceString(strHC & CStr(Int(strDC)+0),Temps)
dv2 = hs.GetDeviceByRef(hs.GetDeviceRef(strHC & CStr(Int(strDC)+0)))
IF HideTemps Then
dv2.misc = (dv2.misc OR &H20)
Else
dv2.misc = (dv2.misc AND (NOT &H20))
End If
hs.SetDeviceValue(strHC & CStr(Int(strDC)+2),Weekday(Now(),7)) 'Auto Day schedule
hs.SetDeviceString(strHC & CStr(Int(strDC)+2),C_Week(Cref))
' lookup L response
Lref = 1
Do until Taddress(Lref) = M_Daddress(C2) Or Lref = Tcnt ' JK 100 -> Tcnt
Lref+=1
Loop
If instr(hs.DeviceString(strHC & CStr(Int(strDC)+1)),TstatusT(Lref)) = 0 Then hs.SetDeviceLastChange(strHC & CStr(Int(strDC)+1),now)
dv2 = hs.GetDeviceByRef(hs.GetDeviceRef(strHC & CStr(Int(strDC)+1)))
If TstatusT(Lref) = "OK" Then
hs.SetDeviceValue(strHC & CStr(Int(strDC)+1),2) ' Status ok
hs.SetDeviceString(strHC & CStr(Int(strDC)+1),"<img src='/images/On-Line.gif'> " & TstatusT(Lref))
IF HideStatusOK Then dv2.misc = (dv2.misc OR &H20)
Else
hs.SetDeviceValue(strHC & CStr(Int(strDC)+1),1) ' Status error
hs.SetDeviceString(strHC & CStr(Int(strDC)+1),"<img src='/images/Off-Line.gif'> " & TstatusT(Lref))
IF HideStatusOK Then dv2.misc = (dv2.misc AND (NOT &H20))
End If
hs.SetDeviceValue(strHC & CStr(Int(strDC)+3), Ttemp(Lref)*10) 'Setpoint * 10
hs.SetDeviceString(strHC & CStr(Int(strDC)+3),"<img src='/images/Temperatures/" & CStr(Int(Ttemp(Lref))) & ".gif'> " & Tmode2(Lref)&"/"&CStr(Ttemp(Lref))&"/"&CStr(TValve(Lref))&"/"&TdateTime(Lref))
If Tist(Lref) <> "" Then
hs.SetDeviceValue(strHC & CStr(Int(strDC)+4), Tist(Lref)*10 - hs.DeviceValue(strHC & CStr(Int(strDC)+0))) 'Current Temperature * 10
hs.SetDeviceString(strHC & CStr(Int(strDC)+4),"<img src='/images/Temperatures/" & CStr(Int(Tist(Lref) - hs.DeviceValue(strHC & CStr(Int(strDC)+0))/10)) & ".gif'> " & Tist(Lref) - hs.DeviceValue(strHC & CStr(Int(strDC)+0))/10)
End If
End If ' JK skip of unwanted devices
Next
' Disconnect at the end
Client.Close()
Catch ex As Exception
If ex.Message = "De index ligt buiten de matrixgrenzen." Then
hs.WriteLog("Error","Max Monitor: " & ex.Message & " You probably need to increase the WaitSec value in the .ini file.")
Else
hs.WriteLog("Error","Max Monitor: " & ex.Message)
End If
End Try
End Sub
Private Function ReadString(ByVal Client As System.Net.Sockets.TcpClient) As String
Dim Stream As NetworkStream = Client.GetStream
Dim Buffersize As Integer = Client.ReceiveBufferSize
Dim Data(Buffersize -1) As Byte
If Stream.CanTimeout Then
Stream.ReadTimeout = 1000 * 15
End If
Dim BytesRead As Integer = Stream.Read(Data, 0, Buffersize)
Return Encoding.ASCII.GetString(Data, 0, BytesRead)
End Function
Private Function SendString(ByVal Stream As NetworkStream, ByVal Data As String) As Boolean
Dim Bytes As [Byte]() = Encoding.ASCII.GetBytes(Data)
If Stream.CanTimeout Then
Stream.WriteTimeout = 1000 * 5
End If
Stream.Write(Bytes, 0, Bytes.Length)
Return True
End Function
Private Function Base64ToHex(base64string As String) As String
Dim result As String
Dim b64bytes() As Byte = System.Convert.FromBase64String(base64string)
For Each b As Byte In b64bytes
result &= Hex(b).PadLeft(2, "0"c)
Next
Return result
End Function
Private Function HexToBase64(ByVal HexText As String) As String
Dim HexTextBytes As Integer = HexText.Length \ 2 -1
Dim result(HexTextBytes) As Byte
Dim i As Integer
For i = 0 To HexTextBytes
result(i) = Convert.ToByte(HexText.Substring(i * 2, 2), 16)
Next
Return Convert.ToBase64String(result)
End Function
Private Function Hex2Bin(ByVal dwHex As String) As String
dwHex = CStr(dwHex)
Dim sTemp As String
Dim I As Integer
For I = 1 To Len(dwHex)
sTemp = Mid(dwHex, I, 1)
Select Case sTemp
Case "0": Hex2Bin = Hex2Bin & "0000"
Case "1": Hex2Bin = Hex2Bin & "0001"
Case "2": Hex2Bin = Hex2Bin & "0010"
Case "3": Hex2Bin = Hex2Bin & "0011"
Case "4": Hex2Bin = Hex2Bin & "0100"
Case "5": Hex2Bin = Hex2Bin & "0101"
Case "6": Hex2Bin = Hex2Bin & "0110"
Case "7": Hex2Bin = Hex2Bin & "0111"
Case "8": Hex2Bin = Hex2Bin & "1000"
Case "9": Hex2Bin = Hex2Bin & "1001"
Case "A": Hex2Bin = Hex2Bin & "1010"
Case "B": Hex2Bin = Hex2Bin & "1011"
Case "C": Hex2Bin = Hex2Bin & "1100"
Case "D": Hex2Bin = Hex2Bin & "1101"
Case "E": Hex2Bin = Hex2Bin & "1110"
Case "F": Hex2Bin = Hex2Bin & "1111"
End Select
Next I
End Function
Private Function Hex2Dec(Hextext As String) As String
Dim result As String = Convert.ToInt32(Hextext,16)
Return result
End Function
Private Function Hex2asc(Hextext As String) As String
Dim result As String
Dim i As Integer
For i = 0 To HexText.Length \ 2 -1
result &= Chr(Val("&h" & Mid(HexText,i*2+1,2)))
Next
Return result
End Function
Private Function Bin2Dec(Binary As String) As long
Dim result As Long
Dim s As Integer
For s = 1 To Len(Binary)
result += (Mid(Binary, Len(Binary) - s + 1, 1) * (2 ^ (s - 1)))
Next s
Return result
End Function
Private Function Dec2Bin(DecimalNum As Long) As String
Dim tmp As String
Dim n As Long
n = DecimalNum
tmp = Trim(Str(n Mod 2))
n = n \ 2
Do While n <> 0
tmp = Trim(Str(n Mod 2)) & tmp
n = n \ 2
Loop
Return tmp
End Function
' function which converts dec value into bin (string) left padded with 0 upto length
Private Function Dec2Bin2(DecimalNum As Long, length As Integer) As String
Dim result As String
Dim n As Long
n = DecimalNum
result = Trim(Str(n Mod 2))
n = n \ 2
Do While n <> 0
result = Trim(Str(n Mod 2)) & result
n = n \ 2
Loop
Dim lgth As Integer = Len(result)
Dim m As Integer
For m = 1 To length - lgth
result = "0" & result
Next
Return result
End Function
' function which converts dec value into hex (string) left padded with 0 upto length
Private Function Dec2Hex(Dec As Integer, length As Integer) As String
Dim result As String
Dim n As Integer
result = Hex(Dec)
Dim lgth As Integer = Len(result)
For n = 1 To length - lgth
result = "0" & result
Next
Return result
End Function