The files contained in this repository can be downloaded to your computer using a svn client.
On Linux you simply type the command displayed below.
This URL has Read-Only access.
root / trunk / DomotiGaServer / CCUL.class @ 636
History | View | Annotate | Download (17.8 kB)
| 1 | ' Gambas class file |
|---|---|
| 2 | |
| 3 | ' Description: |
| 4 | ' CCUL.class |
| 5 | ' Connect to CULFW interface via tcp socket or serial port. |
| 6 | |
| 7 | ' Development Status: |
| 8 | ' Just started. |
| 9 | |
| 10 | ' DomotiGa - an open source home automation program. |
| 11 | ' Copyright(C) 2008-2011 Ron Klinkien |
| 12 | |
| 13 | ' Read file called COPYING for license details. |
| 14 | |
| 15 | PROPERTY TCPHost AS String |
| 16 | PROPERTY TCPPort AS Integer |
| 17 | PROPERTY Interface AS String |
| 18 | PROPERTY SerPort AS String |
| 19 | PROPERTY Baud AS String |
| 20 | PROPERTY CULDebug AS Boolean |
| 21 | PROPERTY Model AS Integer |
| 22 | |
| 23 | PRIVATE sTCPHost AS String |
| 24 | PRIVATE iTCPPort AS Integer |
| 25 | PRIVATE sInterface AS String |
| 26 | PRIVATE sSerPort AS String |
| 27 | PRIVATE sBaud AS String |
| 28 | PRIVATE bCULDebug AS Boolean |
| 29 | PRIVATE iModel AS Integer |
| 30 | |
| 31 | PUBLIC hCUL AS NEW Socket |
| 32 | PUBLIC hCULSer AS NEW SerialPort |
| 33 | PUBLIC bSimulate AS Boolean = FALSE |
| 34 | |
| 35 | PRIVATE bFirstByte AS Boolean = TRUE |
| 36 | PRIVATE RecBuf AS Byte[255] |
| 37 | PRIVATE bMessage AS Boolean = FALSE |
| 38 | PRIVATE iByteCount AS Integer = 0 |
| 39 | |
| 40 | CONST FS20_OFF AS Byte = &H00 |
| 41 | CONST FS20_DIM1 AS Byte = &H01 |
| 42 | CONST FS20_DIM2 AS Byte = &H02 |
| 43 | CONST FS20_DIM3 AS Byte = &H03 |
| 44 | CONST FS20_DIM4 AS Byte = &H04 |
| 45 | CONST FS20_DIM5 AS Byte = &H05 |
| 46 | CONST FS20_DIM6 AS Byte = &H06 |
| 47 | CONST FS20_DIM7 AS Byte = &H07 |
| 48 | CONST FS20_DIM8 AS Byte = &H08 |
| 49 | CONST FS20_DIM9 AS Byte = &H09 |
| 50 | CONST FS20_DIM10 AS Byte = &H0A |
| 51 | CONST FS20_DIM11 AS Byte = &H0B |
| 52 | CONST FS20_DIM12 AS Byte = &H0C |
| 53 | CONST FS20_DIM13 AS Byte = &H0D |
| 54 | CONST FS20_DIM14 AS Byte = &H0E |
| 55 | CONST FS20_DIM15 AS Byte = &H0F |
| 56 | CONST FS20_DIM16 AS Byte = &H10 |
| 57 | CONST FS20_ON AS Byte = &H11 |
| 58 | CONST FS20_TOGGLE AS Byte = &H12 |
| 59 | CONST FS20_DIMUP AS Byte = &H13 |
| 60 | CONST FS20_DIMDOWN AS Byte = &H14 |
| 61 | CONST FS20_DIMSWITCH AS Byte = &H15 |
| 62 | CONST FS20_TIMER AS Byte = &H16 |
| 63 | CONST FS20_SENDSTATE AS Byte = &H17 |
| 64 | CONST FS20_OFFFORTIMER AS Byte = &H18 |
| 65 | CONST FS20_ONFORTIMER AS Byte = &H19 |
| 66 | CONST FS20_ONOLDFORTIMER AS Byte = &H1A |
| 67 | CONST FS20_RESET AS Byte = &H1B |
| 68 | CONST FS20_RAMPONTIME AS Byte = &H1C |
| 69 | CONST FS20_RAMPOFFTIME AS Byte = &H1D |
| 70 | |
| 71 | CONST FHT_SYNCTIME AS Byte = &H2C |
| 72 | CONST FHT_MODE AS Byte = &H3D |
| 73 | CONST FHT_DESIREDTEMP AS Byte = &H41 |
| 74 | CONST FHT_STATUS AS Byte = &H44 |
| 75 | CONST FHT_DAYTEMP AS Byte = &H82 |
| 76 | CONST FHT_NIGHTTEMP AS Byte = &H84 |
| 77 | CONST FHT_WINDOWOPENTEMP AS Byte = &H8A |
| 78 | |
| 79 | PUBLIC SUB CUL_Ready() |
| 80 | |
| 81 | Main.WriteLog(("CUL TCP socket connected."))
|
| 82 | Init() |
| 83 | |
| 84 | END |
| 85 | |
| 86 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 87 | ' connect to the host:port |
| 88 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 89 | PUBLIC FUNCTION ConnectTCP() AS Boolean |
| 90 | |
| 91 | ' try to close the connection |
| 92 | TRY hCUL.Close |
| 93 | |
| 94 | ' get a new one |
| 95 | hCUL = NEW Socket AS "CUL" |
| 96 | hCUL.Connect(sTCPHost, iTCPPort) |
| 97 | |
| 98 | ' all ok |
| 99 | RETURN TRUE |
| 100 | |
| 101 | CATCH ' some errors |
| 102 | Main.WriteLog(("CUL Error: ") & ERROR.Text)
|
| 103 | RETURN FALSE |
| 104 | |
| 105 | END |
| 106 | |
| 107 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 108 | ' connect to the serial port |
| 109 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 110 | PUBLIC FUNCTION ConnectSerial() AS Boolean |
| 111 | |
| 112 | ' try to close the connection |
| 113 | TRY hCULSer.Close |
| 114 | |
| 115 | ' get a new one |
| 116 | hCULSer = NEW Serialport AS "CULSer" |
| 117 | WITH hCULSer |
| 118 | .PortName = sSerPort |
| 119 | .Speed = sBaud |
| 120 | .Parity = 0 |
| 121 | .DataBits = 8 |
| 122 | .StopBits = 1 |
| 123 | .FlowControl = 0 |
| 124 | .Open() |
| 125 | END WITH |
| 126 | |
| 127 | Init() |
| 128 | |
| 129 | ' all ok |
| 130 | RETURN TRUE |
| 131 | |
| 132 | CATCH ' some errors |
| 133 | Main.WriteLog(("CUL Error: ") & ERROR.Text)
|
| 134 | RETURN FALSE |
| 135 | |
| 136 | END |
| 137 | |
| 138 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 139 | ' disconnect from the host |
| 140 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 141 | PUBLIC FUNCTION Disconnect() AS Boolean |
| 142 | |
| 143 | ' try to close the connection |
| 144 | TRY hCUL.Close |
| 145 | TRY hCULSer.Close |
| 146 | IF InStr(sInterface, "tcp") THEN |
| 147 | Main.WriteLog(("CUL TCP socket close."))
|
| 148 | ELSE |
| 149 | Main.WriteLog(("CUL serial port close."))
|
| 150 | END IF |
| 151 | ' all ok |
| 152 | RETURN TRUE |
| 153 | |
| 154 | CATCH ' some errors |
| 155 | Main.WriteLog(("CUL Error: ") & ERROR.Text)
|
| 156 | RETURN FALSE |
| 157 | |
| 158 | END |
| 159 | |
| 160 | PUBLIC SUB CUL_Error() |
| 161 | |
| 162 | DIM sString AS String = "CUL: " |
| 163 | |
| 164 | ' handle error |
| 165 | SELECT CASE hCUL.Status |
| 166 | CASE Net.CannotCreateSocket |
| 167 | Main.WriteLog(sString & ("The system does not allow to create a socket."))
|
| 168 | CASE Net.HostNotFound |
| 169 | Main.WriteLog(sString & ("Host '") & sTCPHost & ("' not found."))
|
| 170 | CASE Net.ConnectionRefused |
| 171 | Main.WriteLog(sString & ("Unable to connect. Connection refused."))
|
| 172 | CASE Net.CannotRead |
| 173 | Main.WriteLog(sString & ("Error reading data."))
|
| 174 | CASE Net.CannotWrite |
| 175 | Main.WriteLog(sString & ("Error writing data."))
|
| 176 | END SELECT |
| 177 | |
| 178 | END |
| 179 | |
| 180 | PUBLIC SUB CUL_Read() |
| 181 | |
| 182 | DIM bData AS Byte |
| 183 | |
| 184 | TRY READ #hCUL, bData |
| 185 | IF ERROR THEN Main.WriteDebugLog(("[CUL] Error reading data from the TCP port! -> ") & Error.Text)
|
| 186 | ProcessReceivedChar(bData) |
| 187 | |
| 188 | END |
| 189 | |
| 190 | PUBLIC SUB CULSer_Read() |
| 191 | |
| 192 | DIM bData AS Byte |
| 193 | |
| 194 | TRY READ #hCULSer, bData |
| 195 | IF ERROR THEN Main.WriteDebugLog(("[CUL] Error reading data from the serial port! -> ") & Error.Text)
|
| 196 | ProcessReceivedChar(bData) |
| 197 | |
| 198 | END |
| 199 | |
| 200 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 201 | ' initialize interface |
| 202 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 203 | PUBLIC FUNCTION Init() |
| 204 | |
| 205 | SendCommand("X21")
|
| 206 | IF bCULDebug THEN Main.WriteRFXDebugLog("[CUL] > X21\n")
|
| 207 | |
| 208 | END |
| 209 | |
| 210 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 211 | ' initialize interface |
| 212 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 213 | PUBLIC FUNCTION GetVersion() |
| 214 | |
| 215 | SendCommand("V")
|
| 216 | IF bCULDebug THEN Main.WriteRFXDebugLog("[CUL] > V\n")
|
| 217 | |
| 218 | END |
| 219 | |
| 220 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 221 | ' inject packet into parser. |
| 222 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 223 | PUBLIC SUB Simulate(sPacket AS String) |
| 224 | |
| 225 | DIM iCnt AS Integer |
| 226 | |
| 227 | bFirstByte = TRUE |
| 228 | IF bCULDebug THEN Main.WriteRFXDebugLog(("[CUL] CUL receiver Simulate String: ") & sPacket & "\n")
|
| 229 | |
| 230 | FOR iCnt = 1 TO Len(sPacket) |
| 231 | ProcessReceivedChar(Asc(Mid(sPacket, iCnt, 1))) |
| 232 | NEXT |
| 233 | ProcessReceivedChar(&HA) |
| 234 | bSimulate = FALSE |
| 235 | |
| 236 | END SUB |
| 237 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 238 | ' send a command to the interface |
| 239 | '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 240 | PUBLIC FUNCTION SendCommand(sBuffer AS String) |
| 241 | |
| 242 | IF sInterface = "tcp" THEN |
| 243 | ' send the message to the tcp stream |
| 244 | TRY WRITE #hCUL, sBuffer |
| 245 | IF ERROR THEN Main.WriteRFXDebugLog(("[CUL] Unable to write to TCP port! -> ") & Error.Text)
|
| 246 | ELSE |
| 247 | ' send the message to the serial port |
| 248 | TRY WRITE #hCULSer, sBuffer |
| 249 | IF ERROR THEN Main.WriteRFXDebugLog(("[CUL] Unable to write to serial port! -> ") & Error.Text)
|
| 250 | ENDIF |
| 251 | |
| 252 | END |
| 253 | |
| 254 | PRIVATE SUB ProcessReceivedChar(bTemp AS Byte) |
| 255 | |
| 256 | IF bFirstByte = TRUE THEN |
| 257 | bFirstByte = FALSE |
| 258 | iByteCount = 0 |
| 259 | IF bCULDebug THEN Main.WriteRFXDebugLog("[CUL] < ", 0)
|
| 260 | END IF |
| 261 | |
| 262 | ' IF bCULDebug THEN Main.WriteRFXDebugLog(Hex(bTemp, 2), 1) |
| 263 | Main.ControlLed("CUL", "On")
|
| 264 | |
| 265 | RecBuf[iByteCount] = bTemp |
| 266 | IF bTemp = &HA THEN |
| 267 | bMessage = TRUE |
| 268 | ELSE |
| 269 | IF bCULDebug THEN Main.WriteRFXDebugLog(Chr(bTemp), 1) |
| 270 | INC iByteCount |
| 271 | ENDIF |
| 272 | |
| 273 | IF bMessage THEN |
| 274 | Display_Message() |
| 275 | END IF |
| 276 | |
| 277 | END |
| 278 | |
| 279 | PRIVATE SUB Display_Message() |
| 280 | |
| 281 | DIM iDeviceId, iCnt AS Integer |
| 282 | DIM sHouseCode, sAddress, sCmd, sValue, sEMType, sEMCumulValue, sEMPeakValue, sMsgCounter, sELVAddress, sCde, sVal, sId, sSval, sFv AS String |
| 283 | DIM aEMType AS String[] = ["", "EM1000-S", "EM1000-EM", "EM1000-GZ"] |
| 284 | DIM aFHTc2m AS String[] = ["auto", "manual", "holiday", "holiday-short"] |
| 285 | |
| 286 | DIM bConfirm AS Boolean |
| 287 | |
| 288 | bMessage = FALSE |
| 289 | bFirstByte = TRUE |
| 290 | |
| 291 | IF bCULDebug THEN Main.WriteRFXDebugLog("\n", 1)
|
| 292 | |
| 293 | SELECT CASE Chr(RecBuf[0]) |
| 294 | CASE "F" |
| 295 | ' F <Hex> |
| 296 | ' FS20 message. <Hex> is a hex string with the following format: |
| 297 | ' hhhhaacc or hhhhaaccee, where |
| 298 | ' hhhh is the FS20 housecode |
| 299 | ' aa is the FS20 device address |
| 300 | ' cc is the FS20 command |
| 301 | ' ee is the FS20 timespec. Note that cc must have the extension bit set. |
| 302 | ' Example: F12340111 |
| 303 | ' find device id |
| 304 | sHouseCode = Chr(RecBuf[1]) & Chr(RecBuf[2]) & Chr(RecBuf[3]) & Chr(RecBuf[4]) |
| 305 | sAddress = Chr(RecBuf[5]) & Chr(RecBuf[6]) |
| 306 | sELVAddress = Hex2Four(sHouseCode & sAddress) |
| 307 | sCmd = Chr(RecBuf[7]) & Chr(RecBuf[8]) |
| 308 | |
| 309 | SELECT CASE Val(sCmd) |
| 310 | CASE FS20_OFF |
| 311 | sValue = "Off" |
| 312 | CASE FS20_ON |
| 313 | sValue = "On" |
| 314 | CASE FS20_DIM1, FS20_DIM2, FS20_DIM3, FS20_DIM4, FS20_DIM5, FS20_DIM6, FS20_DIM7, FS20_DIM8, FS20_DIM9, FS20_DIM10, FS20_DIM11, FS20_DIM12, FS20_DIM13, FS20_DIM14, FS20_DIM15, FS20_DIM16 |
| 315 | sValue = "Dim " & Format(100 / Val(sCmd), "#") |
| 316 | CASE FS20_DIMUP |
| 317 | sValue = "DimUp" |
| 318 | CASE FS20_DIMDOWN |
| 319 | sValue = "DimDown" |
| 320 | CASE ELSE |
| 321 | sValue = "??" |
| 322 | END SELECT |
| 323 | |
| 324 | IF bCULDebug THEN Main.WriteDebugLog(("[CUL] FS20 message received with address: ") & sHouseCode & sAddress & " (" & sELVAddress & (") command: ") & sValue)
|
| 325 | |
| 326 | iDeviceId = Devices.Find(sHouseCode & sAddress, Devices.FindInterface("CUL Interface"), "FS20")
|
| 327 | ' update value |
| 328 | IF iDeviceId THEN Devices.ValueUpdate(iDeviceId, sValue, "", "", "") |
| 329 | |
| 330 | CASE "T" |
| 331 | ' T <Hex> |
| 332 | ' FHT message. |
| 333 | ' ThhhhNNNNNN |
| 334 | sAddress = Chr(RecBuf[1]) & Chr(RecBuf[2]) & Chr(RecBuf[3]) & Chr(RecBuf[4]) & Chr(RecBuf[5]) & Chr(RecBuf[6]) |
| 335 | sCde = Chr(RecBuf[7]) & Chr(RecBuf[8]) |
| 336 | sCmd = FHTCode(sCde) |
| 337 | |
| 338 | IF iByteCount > 9 THEN |
| 339 | sVal = Chr(RecBuf[9]) & Chr(RecBuf[10]) |
| 340 | ELSE IF iByteCount < 9 THEN |
| 341 | sCmd = "FHT short message" |
| 342 | ELSE IF iByteCount > 11 THEN |
| 343 | ' signal |
| 344 | ENDIF |
| 345 | |
| 346 | IF NOT Len(sVal) OR IF sCmd = "report1" OR IF sCmd = "report2" THEN bConfirm = TRUE |
| 347 | |
| 348 | sVal = Val("&H" & sVal)
|
| 349 | |
| 350 | IF InStr(sCmd, "-from") OR IF InStr(sCmd, "-to") THEN |
| 351 | sVal = Format(Val(sVal) / 6, "0#") & ":" & Format((Val(sVal) MOD 6) * 10, "0#") |
| 352 | ELSE IF sCmd = "mode" |
| 353 | sVal = aFHTc2m[sVal] |
| 354 | ELSE IF InStr(sCmd, "actuator") |
| 355 | |
| 356 | sId = Chr(RecBuf[6]) |
| 357 | sSval = Chr(RecBuf[7]) & Chr(RecBuf[8]) |
| 358 | sFv = 100 * Val(sVal) / 255 + 0.5 |
| 359 | PRINT sId |
| 360 | PRINT sSval |
| 361 | PRINT sFv |
| 362 | IF sSval = "A0" OR IF sSval = "B0" THEN |
| 363 | sVal = sSval ' sync in the summer |
| 364 | ELSE IF Right(sSval, 1) = "0" THEN |
| 365 | sVal = "syncnow" |
| 366 | ELSE IF Right(sSval, 1) = "1" THEN |
| 367 | sVal = "99%" ' FHT set to 30.5, FHT80B=="ON" |
| 368 | ELSE IF Right(sSval, 1) = "2" THEN |
| 369 | sVal = "0%" ' FHT set to 5.5 |
| 370 | ELSE IF Right(sSval, 1) = "6" THEN |
| 371 | sVal = sFv |
| 372 | ELSE IF Right(sSval, 1) = "8" THEN |
| 373 | sVal = "offset: " & sFv |
| 374 | ELSE IF Right(sSval, 1) = "A" THEN |
| 375 | sVal = "lime-protection" |
| 376 | ELSE IF Right(sSval, 1) = "C" THEN |
| 377 | sVal = "synctime: " & (Val(sVal) / 2) - 1 |
| 378 | ELSE IF Right(sSval, 1) = "E" THEN |
| 379 | sVal = "test" |
| 380 | ELSE IF Right(sSval, 1) = "F" THEN |
| 381 | sVal = "pair" |
| 382 | ELSE |
| 383 | sVal = "unknown" |
| 384 | ENDIF |
| 385 | ' If(preg_match("/[AB]0/i", $sval)){ $val = $fv; } #
|
| 386 | ' elseif(preg_match("/.0/", $sval)){ $val = "syncnow"; }
|
| 387 | ' elseif(preg_match("/.1/", $sval)){ $val = "99%"; } # FHT set to 30.5, FHT80B=="ON"
|
| 388 | ' elseif(preg_match("/.2/", $sval)){ $val = "0%"; } # FHT set to 5.5
|
| 389 | ' elseif(preg_match("/.6/", $sval)){ $val = "$fv"; }
|
| 390 | ' elseif(preg_match("/.8/", $sval)){ $val = "offset: $fv"; }
|
| 391 | ' elseif(preg_match("/.A/", $sval)){ $val = "lime-protection"; }
|
| 392 | ' elseif(preg_match("/.C/", $sval)){ $val = sprintf("synctime: %d", int($val/2)-1); }
|
| 393 | ' elseif(preg_match("/.E/", $sval)){ $val = "test"; }
|
| 394 | ' elseif(preg_match("/.F/", $sval)){ $val = "pair"; }
|
| 395 | ' ELSE { $val = "unknown_$sval: $fv"; }
|
| 396 | ' |
| 397 | ' $pos = strpos($val, "%"); |
| 398 | ' IF (!($pos == = FALSE)){
|
| 399 | ' IF ($id == "0"){
|
| 400 | ' SetValue($varids[ 'Position']['id'],$val); |
| 401 | ' } ELSE {
|
| 402 | ' $pid == getVid( 'Position'.$id,IPS_GetParent($varids['ID']['id'])); |
| 403 | ' IF (!$pid == FALSE){
|
| 404 | ' SetValue($pid, $val); |
| 405 | ' } |
| 406 | ' } |
| 407 | ' } |
| 408 | ELSE IF sCmd = "TFK" |
| 409 | sVal = Chr(RecBuf[7]) & Chr(RecBuf[8]) |
| 410 | sVal = FHTTKCode(sVal) |
| 411 | IF iByteCount > 9 THEN |
| 412 | 'signal |
| 413 | ENDIF |
| 414 | ENDIF |
| 415 | |
| 416 | IF bCULDebug THEN Main.WriteDebugLog(("[CUL] FHT message received with address: ") & sAddress & (" command: ") & sCmd & " " & sVal)
|
| 417 | |
| 418 | CASE "E" |
| 419 | ' E <Hex> |
| 420 | ' EM message. <Hex> is a hex string with the following format: |
| 421 | ' Ettaacc111122223333 |
| 422 | ' tt: type 01 = EM-1000S, 02 = EM-1000EM, 03 = EM-1000GZ |
| 423 | ' aa: address, depending on the type above 01: 01-04, 02: 05-08, 03: 09-12 |
| 424 | ' cc: counter, will be incremented by one for each message |
| 425 | ' 1111: cumulated value |
| 426 | ' 2222: last value(not set for type 2) |
| 427 | ' 3333: top value(not set for type 2) |
| 428 | sEMType = Chr(RecBuf[1]) & Chr(RecBuf[2]) |
| 429 | sAddress = Chr(RecBuf[3]) & Chr(RecBuf[4]) |
| 430 | sEMCumulValue = Chr(RecBuf[7]) & Chr(RecBuf[8]) & Chr(RecBuf[9]) & Chr(RecBuf[10]) |
| 431 | sMsgCounter = Chr(RecBuf[5]) & Chr(RecBuf[6]) |
| 432 | TRY sValue = Chr(RecBuf[11]) & Chr(RecBuf[12]) & Chr(RecBuf[13]) & Chr(RecBuf[14]) |
| 433 | TRY sEMPeakValue = Chr(RecBuf[15]) & Chr(RecBuf[16]) & Chr(RecBuf[17]) & Chr(RecBuf[18]) |
| 434 | |
| 435 | IF bCULDebug THEN Main.WriteDebugLog(("[CUL] EM message received for sensor type: ") & aEMType[Val(sEMType)] & " (" & sEMType & ")" & (" address: ") & sAddress & (" cumulated value: ") & sEMCumulValue & (" last value: ") & sValue & (" top value: ") & sEMPeakValue & (" msg counter: ") & Val("&H" & sMsgCounter))
|
| 436 | |
| 437 | iDeviceId = Devices.Find(sAddress, Devices.FindInterface("CUL Interface"), aEMType[Val(sEMType)])
|
| 438 | ' update value |
| 439 | IF iDeviceId THEN Devices.ValueUpdate(iDeviceId, sEMCumulValue, sValue, sEMPeakValue, "") |
| 440 | |
| 441 | CASE ELSE |
| 442 | Main.WriteDebugLog(("[CUL] Unknown/unsupported message format received!"))
|
| 443 | END SELECT |
| 444 | Main.ControlLed("CUL", "Off")
|
| 445 | |
| 446 | ' CATCH |
| 447 | ' Main.WriteDebugLog(("ERROR: Parsing CUL data packet: ") & DisplayPacket(RecBuf) & " " & Error.Text & " at " & Error.Where)
|
| 448 | |
| 449 | END |
| 450 | |
| 451 | ' converting CUL Hex IDs into ELV-4-Ids |
| 452 | PRIVATE SUB Hex2Four(sHex AS String) AS String |
| 453 | |
| 454 | DIM iCnt AS Integer |
| 455 | DIM sELV AS String |
| 456 | |
| 457 | FOR iCnt = 1 TO Len(sHex) |
| 458 | sELV &= Left(Str((Val("&H" & Mid(sHex, iCnt, 1)) / 4) + 1), 1)
|
| 459 | sELV &= (Val("&H" & Mid(sHex, iCnt, 1)) MOD 4) + 1
|
| 460 | NEXT |
| 461 | RETURN sELV |
| 462 | |
| 463 | END |
| 464 | |
| 465 | PRIVATE SUB FHTCode(sCode AS String) AS String |
| 466 | |
| 467 | SELECT CASE sCode |
| 468 | CASE "00" |
| 469 | RETURN "actuator" |
| 470 | CASE "01" |
| 471 | RETURN "actuator1" |
| 472 | CASE "02" |
| 473 | RETURN "actuator2" |
| 474 | CASE "03" |
| 475 | RETURN "actuator3" |
| 476 | CASE "04" |
| 477 | RETURN "actuator4" |
| 478 | CASE "05" |
| 479 | RETURN "actuator5" |
| 480 | CASE "06" |
| 481 | RETURN "actuator6" |
| 482 | CASE "07" |
| 483 | RETURN "actuator7" |
| 484 | CASE "08" |
| 485 | RETURN "actuator8" |
| 486 | CASE "14" |
| 487 | RETURN "mon-from1" |
| 488 | CASE "15" |
| 489 | RETURN "mon-to1" |
| 490 | CASE "16" |
| 491 | RETURN "mon-from2" |
| 492 | CASE "17" |
| 493 | RETURN "mon-to2" |
| 494 | CASE "18" |
| 495 | RETURN "tue-from1" |
| 496 | CASE "19" |
| 497 | RETURN "tue-to1" |
| 498 | CASE "1A" |
| 499 | RETURN "tue-from2" |
| 500 | CASE "1B" |
| 501 | RETURN "tue-to2" |
| 502 | CASE "1C" |
| 503 | RETURN "wed-from1" |
| 504 | CASE "1D" |
| 505 | RETURN "wed-to1" |
| 506 | CASE "1E" |
| 507 | RETURN "wed-from2" |
| 508 | CASE "1F" |
| 509 | RETURN "wed-to2" |
| 510 | CASE "20" |
| 511 | RETURN "thu-from1" |
| 512 | CASE "21" |
| 513 | RETURN "thu-to1" |
| 514 | CASE "22" |
| 515 | RETURN "thu-from2" |
| 516 | CASE "23" |
| 517 | RETURN "thu-to2" |
| 518 | CASE "24" |
| 519 | RETURN "fri-from1" |
| 520 | CASE "25" |
| 521 | RETURN "fri-to1" |
| 522 | CASE "26" |
| 523 | RETURN "fri-from2" |
| 524 | CASE "27" |
| 525 | RETURN "fri-to2" |
| 526 | CASE "28" |
| 527 | RETURN "sat-from1" |
| 528 | CASE "29" |
| 529 | RETURN "sat-to1" |
| 530 | CASE "2A" |
| 531 | RETURN "sat-from2" |
| 532 | CASE "2B" |
| 533 | RETURN "sat-to2" |
| 534 | CASE "2C" |
| 535 | RETURN "sun-from1" |
| 536 | CASE "2D" |
| 537 | RETURN "sun-to1" |
| 538 | CASE "2E" |
| 539 | RETURN "sun-from2" |
| 540 | CASE "2F" |
| 541 | RETURN "sun-to2" |
| 542 | CASE "3E" |
| 543 | RETURN "mode" |
| 544 | CASE "3F" |
| 545 | RETURN "holiday1" |
| 546 | CASE "40" |
| 547 | RETURN "holiday2" |
| 548 | CASE "41" |
| 549 | RETURN "desired-temp" |
| 550 | CASE "42" |
| 551 | RETURN "measured-low" |
| 552 | CASE "43" |
| 553 | RETURN "measured-high" |
| 554 | CASE "44" |
| 555 | RETURN "warnings" |
| 556 | CASE "45" |
| 557 | RETURN "manu-temp" |
| 558 | CASE "4B" |
| 559 | RETURN "ack" |
| 560 | CASE "53" |
| 561 | RETURN "can-xmit" |
| 562 | CASE "54" |
| 563 | RETURN "can-rcv" |
| 564 | CASE "60" |
| 565 | RETURN "year" |
| 566 | CASE "61" |
| 567 | RETURN "month" |
| 568 | CASE "62" |
| 569 | RETURN "day" |
| 570 | CASE "63" |
| 571 | RETURN "hour" |
| 572 | CASE "64" |
| 573 | RETURN "minute" |
| 574 | CASE "65" |
| 575 | RETURN "report1" |
| 576 | CASE "66" |
| 577 | RETURN "report2" |
| 578 | CASE "69" |
| 579 | RETURN "ack2" |
| 580 | CASE "7D" |
| 581 | RETURN "start-xmit" |
| 582 | CASE "7E" |
| 583 | RETURN "end-xmit" |
| 584 | CASE "82" |
| 585 | RETURN "day-temp" |
| 586 | CASE "84" |
| 587 | RETURN "night-temp" |
| 588 | CASE "85" |
| 589 | RETURN "lowtemp-offset" |
| 590 | CASE "8A" |
| 591 | RETURN "windowopen-temp" |
| 592 | CASE "B9" |
| 593 | RETURN "TFK" |
| 594 | CASE ELSE |
| 595 | RETURN "unknown" |
| 596 | END SELECT |
| 597 | |
| 598 | END |
| 599 | |
| 600 | PRIVATE SUB FHTTKCode(bCode AS Byte) AS String |
| 601 | |
| 602 | SELECT CASE bCode |
| 603 | CASE &H01, &H82 |
| 604 | RETURN "Window:Closed" |
| 605 | CASE &H02, &H81 |
| 606 | RETURN "Window:Open" |
| 607 | CASE &H11, &H91 |
| 608 | RETURN "Window:Open, Low Batt" |
| 609 | CASE &H12 |
| 610 | RETURN "Window:Closed, Low Batt" |
| 611 | CASE &H0C |
| 612 | RETURN "Sync:Syncing" |
| 613 | CASE &H0F |
| 614 | RETURN "Test:Success" |
| 615 | CASE ELSE |
| 616 | RETURN "unknown" |
| 617 | END SELECT |
| 618 | |
| 619 | END |
| 620 | |
| 621 | PRIVATE SUB DisplayPacket(bBuf AS Byte[]) AS String |
| 622 | |
| 623 | DIM sMsg AS String |
| 624 | DIM iCnt AS Integer |
| 625 | |
| 626 | FOR iCnt = 0 TO iByteCount |
| 627 | sMsg &= Hex(bBuf[iCnt], 2) |
| 628 | NEXT |
| 629 | RETURN sMsg |
| 630 | |
| 631 | ' CATCH |
| 632 | ' Main.WriteDebugLog(("ERROR: Display data packet: ") & Error.Text & " at " & Error.Where)
|
| 633 | |
| 634 | END |
| 635 | |
| 636 | ' implement properties |
| 637 | PRIVATE FUNCTION TCPHost_Read() AS String |
| 638 | |
| 639 | RETURN sTCPHost |
| 640 | |
| 641 | END |
| 642 | |
| 643 | PRIVATE SUB TCPHost_Write(Value AS String) |
| 644 | |
| 645 | sTCPHost = Value |
| 646 | |
| 647 | END |
| 648 | |
| 649 | PRIVATE FUNCTION TCPPort_Read() AS Integer |
| 650 | |
| 651 | RETURN iTCPPort |
| 652 | |
| 653 | END |
| 654 | |
| 655 | PRIVATE SUB TCPPort_Write(Value AS Integer) |
| 656 | |
| 657 | iTCPPort = Value |
| 658 | |
| 659 | END |
| 660 | |
| 661 | PRIVATE FUNCTION Interface_Read() AS String |
| 662 | |
| 663 | RETURN sInterface |
| 664 | |
| 665 | END |
| 666 | |
| 667 | PRIVATE SUB Interface_Write(Value AS String) |
| 668 | |
| 669 | sInterface = Value |
| 670 | |
| 671 | END |
| 672 | |
| 673 | PRIVATE FUNCTION Baud_Read() AS String |
| 674 | |
| 675 | RETURN sBaud |
| 676 | |
| 677 | END |
| 678 | |
| 679 | PRIVATE SUB Baud_Write(Value AS String) |
| 680 | |
| 681 | sBaud = Value |
| 682 | |
| 683 | END |
| 684 | |
| 685 | PRIVATE FUNCTION SerPort_Read() AS String |
| 686 | |
| 687 | RETURN sSerPort |
| 688 | |
| 689 | END |
| 690 | |
| 691 | PRIVATE SUB SerPort_Write(Value AS String) |
| 692 | |
| 693 | sSerPort = Value |
| 694 | |
| 695 | END |
| 696 | |
| 697 | PRIVATE FUNCTION CULDebug_Read() AS Boolean |
| 698 | |
| 699 | RETURN bCULDebug |
| 700 | |
| 701 | END |
| 702 | |
| 703 | PRIVATE SUB CULDebug_Write(Value AS Boolean) |
| 704 | |
| 705 | bCULDebug = Value |
| 706 | |
| 707 | END |
| 708 | |
| 709 | PRIVATE FUNCTION Model_Read() AS Integer |
| 710 | |
| 711 | RETURN iModel |
| 712 | |
| 713 | END |
| 714 | |
| 715 | PRIVATE SUB Model_Write(Value AS Integer) |
| 716 | |
| 717 | iModel = Value |
| 718 | |
| 719 | END |
