· 8 years ago · Jul 19, 2018, 01:56 PM
1#Region Project Attributes
2 #ApplicationLabel: LiteIP Light
3 #VersionCode: 1
4 #VersionName:
5 'SupportedOrientations possible values: unspecified, landscape or portrait.
6 #SupportedOrientations: portrait
7 #CanInstallToExternalStorage: False
8 #BridgeLogger: True
9#End Region
10
11#Region Activity Attributes
12 #FullScreen: False
13 #IncludeTitle: False
14#End Region
15
16Sub Process_Globals
17 'These global variables will be declared once when the application starts.
18 'These variables can be accessed from all modules.
19 Type NameMac (Name As String, MAC As String)
20 Dim Serial1 As Serial
21 Dim myDB As SQL
22 Dim postcodeDB As SQL
23 Dim Auth As FirebaseAuth
24 Dim mGPS As GPS
25End Sub
26
27Sub Globals
28 ' These global variables will be redeclared each time the activity is created.
29 ' These variables can only be accessed from this module.
30 Dim FoundDevices As List
31 Dim Admin As BluetoothAdmin
32 Dim AStream As AsyncStreams
33 Dim BTConnected As Boolean
34 Dim CommandQueue As List
35 Dim LastCommand As String
36 Dim FailureCount As Int
37 Dim EditingProfile As Int
38 Dim LastProfile As Int
39 Dim LastDeviceRow As Int
40 Dim ProfileOrDevice As String
41 Dim ForbiddenChars As List
42 Dim InitialDeviceName As String
43 Dim InitialProfileName As String
44
45 Dim Header As Panel
46 Dim Table As Panel
47 Dim NumberOfColumns, RowHeight As Int
48 Dim HeaderColor, TableColor, HeaderFontColor As Int
49 Dim FontSize As Float
50 Type RowCol (Row As Int, Col As Int)
51 Dim Alignment As Int
52 Dim SelectedRowColor As Int
53
54 ' Table settings
55 HeaderColor = Colors.Gray
56 RowHeight = 40dip
57 TableColor = Colors.White
58 HeaderFontColor = Colors.White
59 FontSize = 14
60 Alignment = Gravity.CENTER
61 SelectedRowColor = Colors.ARGB(255, 255, 255, 150)
62
63 ' Dialog settings for devices.
64 Private DeviceDialog As CustomLayoutDialog
65 Private DialogProfileID As Spinner
66 Private DialogDaylightLink As Spinner
67
68 ' Dialog settings for profile name only.
69 Private ProfileNameDialog As CustomLayoutDialog
70 Private ProfileNameLabel As Label
71 Private ProfileNameET As EditText
72
73 Private ScrollView1 As ScrollView
74 Private NewProfileButton As Button
75 Private ConnectButton As Button
76 Private Label1 As Label
77 Private DialogDeviceName As EditText
78 Private LeftArrow As Button
79 Private RightArrow As Button
80
81 ' Huge profile dialog.
82 Private ProfileDialog As CustomLayoutDialog
83 Private DaylightModeSpinner As Spinner
84 Private DayET As EditText
85 Private LowET As EditText
86 Private HighET As EditText
87 Private SensorET As EditText
88 Private LampMinET As EditText
89 Private LampMaxET As EditText
90 Private HoldTimeET As EditText
91 Private DayMinET As EditText
92
93 Private SplashPanel As Panel
94 Private SplashLogo As ImageView
95 Private LiteIP_Label As Label
96 Private SearchButton As Button
97 Private btn_SignIn As Button
98
99 Private Email As String
100 Private Latitude As String
101 Private Longitude As String
102
103End Sub
104
105Sub Activity_Create(FirstTime As Boolean)
106 Activity.LoadLayout("Main")
107 If FirstTime Then
108 postcodeDB.Initialize(File.DirInternal, "postcodeDB.db", True)
109 mGPS.Initialize("gps")
110 Auth.Initialize("auth")
111 End If
112
113 If Auth.CurrentUser.IsInitialized Then
114 Auth_SignedIn(Auth.CurrentUser)
115 End If
116
117
118
119 ' TableView related things
120 Table = ScrollView1.Panel
121 Table.Color = TableColor
122 LastProfile = 0
123 LastDeviceRow = 0
124
125 ' Initializing all required objects
126 FoundDevices.Initialize
127 CommandQueue.Initialize
128 ForbiddenChars.Initialize
129 ForbiddenChars.AddAll(Array As String("'", "&", ";", ",", "=", QUOTE))
130 Latitude = "None"
131 Longitude = "None"
132 Admin.Initialize("Admin")
133 Serial1.Initialize("Serial1")
134End Sub
135
136Sub Activity_Resume
137End Sub
138
139Sub Activity_Pause (UserClosed As Boolean)
140End Sub
141
142Sub CreateTables
143 myDB.ExecNonQuery("CREATE TABLE IF NOT EXISTS Devices (DeviceID INTEGER PRIMARY KEY, DeviceName TEXT UNIQUE, ProfileID INTEGER DEFAULT 101, DaylightLink INTEGER DEFAULT 2000, InSync INTEGER, RSSI INTEGER)")
144 myDB.ExecNonQuery("CREATE TABLE IF NOT EXISTS Profiles (ProfileID INTEGER PRIMARY KEY, ProfileName TEXT UNIQUE DEFAULT 'P101', LDRTargetDay INTEGER DEFAULT 0, LDRTargetLow INTEGER DEFAULT 0, LDRTargetHigh INTEGER DEFAULT 0, SensorDelay INTEGER DEFAULT 0, LampMin INTEGER DEFAULT 0, LampMax INTEGER DEFAULT 0, HoldTime INTEGER DEFAULT 0, DaylightMin INTEGER DEFAULT 0, DaylightMode INTEGER DEFAULT 0)")
145 myDB.ExecNonQuery("CREATE TABLE IF NOT EXISTS Storage (StorageID INTEGER PRIMARY KEY, LastConnect TEXT DEFAULT 'None')")
146 myDB.ExecNonQuery("INSERT OR IGNORE INTO Profiles (ProfileID, ProfileName, LDRTargetDay, LDRTargetLow, LDRTargetHigh, SensorDelay, LampMin, LampMax, HoldTime, DaylightMin, DaylightMode) VALUES (101, 'P101', 700, 100, 600, 2, 0, 100, 30, 0, 0)")
147 myDB.ExecNonQuery("INSERT OR IGNORE INTO Storage VALUES (1, 'None')")
148 postcodeDB.ExecNonQuery("CREATE TABLE IF NOT EXISTS Storage (StorageID INTEGER PRIMARY KEY, LastLogin TEXT DEFAULT 'None', Postcode TEXT DEFAULT 'None')")
149 postcodeDB.ExecNonQuery("INSERT OR IGNORE INTO Storage VALUES (1, 'None', 'None')")
150End Sub
151
152' -------------------------------------------- MENU BUTTONS STUFF START ------------------------------------------
153
154Sub NewProfileButton_Click
155 ' Getting 1 higher than the highest ProfileID in the array.
156 Dim NewProfileID As Int = 1 + myDB.ExecQuerySingleResult("SELECT MAX(ProfileID) FROM Profiles")
157 myDB.ExecNonQuery("INSERT INTO Profiles (ProfileID, ProfileName, LDRTargetDay, LDRTargetLow, LDRTargetHigh, SensorDelay, LampMin, LampMax, HoldTime, DaylightMin, DaylightMode) VALUES (" & NewProfileID & ", " & "'P" & NewProfileID & "', 700, 100, 600, 2, 0, 100, 30, 0, 0)")
158 LoadProfiles_Click
159End Sub
160
161' When the magnifying glass is clicked.
162Sub SearchButton_Click
163 ' If we have a bluetooth connection
164 If BTConnected Then
165 ' Tell the user we're searching for lights and ask the LiteIP Mate for lights.
166 LogAndToast("Searching for lights...", True)
167 AddToQueue("Find,1000,N," & SignalStrength_To_RSSIHex(30) & ",GreaterThan,0,0;:")
168 ExecuteNext
169 Else
170 LogAndToast("Please connect to a LiteIP Mate first.", False)
171 End If
172End Sub
173
174' LongClick on the magnifying glass.
175Sub SearchButton_LongClick
176 ' Simply tell the user the function of the button.
177 ToastMessageShow("Search for lights", False)
178End Sub
179
180Sub ConnectButton_Click
181 ' If we're already connected then
182 If BTConnected Then
183 ' Get the MAC we're connected to.
184 Dim lastConnect As String = myDB.ExecQuerySingleResult("SELECT LastConnect FROM Storage")
185 LogAndToast("Already connected to: " & lastConnect, False)
186 ' Tell the user we're already connected to that MAC address.
187 Else
188 ' Otherwise, disconnect from everything.
189 Disconnect
190 Dim lastConnect As String = "None"
191 ' See if the database is populated with the most recent device we connected to.
192 Try
193 lastConnect = myDB.ExecQuerySingleResult("SELECT IFNULL (LastConnect, 'None') FROM Storage")
194 If lastConnect = Null Then lastConnect = "None"
195 Catch
196 Log("lastConnect is " & lastConnect)
197 End Try
198 ' If there isn't a MAC address in the database, try establish a new connection.
199 If lastConnect = "None" Then
200 If Admin.StartDiscovery = False Then
201 ' If the discovery failed it's because bluetooth is off.
202 LogAndToast("Please enable bluetooth on your phone.", True)
203 Else
204 ' If the discovery succeeds, clear all devices we already have and tell the user we're searching.
205 FoundDevices.Clear
206 LogAndToast("Searching for LiteIP Mate...", False)
207 End If
208 Else
209 LogAndToast("Last connected MAC is: " & lastConnect, False)
210 ' If there is a MAC address in the database, immediately try and connect to that.
211 LogAndToast("Connecting to LiteIP Mate: " & lastConnect, False)
212 Serial1.Connect(lastConnect)
213 End If
214 End If
215End Sub
216
217Sub ConnectButton_LongClick
218 ' Disconnect from the BlueBridge.
219 If BTConnected = True Then
220 Disconnect
221 myDB.ExecNonQuery("UPDATE Storage SET LastConnect = 'None'")
222 LogAndToast("Disconnected from LiteIP Mate.", False)
223 End If
224End Sub
225
226Sub LoadDevices_Click
227 ' Clear the table of all existing views.
228 Table.RemoveAllViews
229 ' Set the number of columns to 5, and set the width automatically.
230 NumberOfColumns = 5
231 ' Setting a storage variable in the database. We use this later when clicking a cell.
232 ' It lets the cell know if it is part of the Profile or Device table.
233 ProfileOrDevice = "Device"
234 ' Set the headers to each column and then query the SQL database.
235 SetHeader(Array As String("Device", "Profile", "Daylight Link", "Sync", "Ident"))
236 Dim Cursor As Cursor = myDB.ExecQuery("SELECT DeviceName, ProfileID, DaylightLink, InSync FROM Devices ORDER BY RSSI ASC")
237 ' For each object we find, feed it into the table.
238 For i = 0 To Cursor.RowCount - 1
239 Cursor.Position = i
240 Dim DeviceName As String = Cursor.GetString("DeviceName")
241 Dim ProfileID As Int = Cursor.GetInt("ProfileID")
242 Dim ProfileName As String = myDB.ExecQuerySingleResult("SELECT ProfileName FROM Profiles WHERE ProfileID = " & ProfileID)
243 Dim DaylightLink As Int = Cursor.GetInt("DaylightLink")
244 Dim DaylightName As String = myDB.ExecQuerySingleResult("SELECT DeviceName FROM Devices WHERE DeviceID = " & DaylightLink)
245 If DaylightName = Null Then DaylightName = "L2000"
246 Dim InSync As String
247 ' Rather than displaying 0 or 1 to the user, they should see No/Yes.
248 If Cursor.GetInt("InSync") = 0 Then
249 InSync = "NO"
250 Else
251 InSync = "YES"
252 End If
253 SetTableView(Array As String(DeviceName, ProfileName, DaylightName, InSync, "OFF"))
254 Next
255 ' Want to scroll to the last device they had selected.
256 NewProfileButton.Visible = False
257 If LastDeviceRow > 0 Then
258 SelectRow(LastDeviceRow)
259 Sleep(0)
260 ScrollView1.ScrollToNow(LastDeviceRow*40dip-80dip)
261 End If
262 LeftArrow.Visible = False
263 RightArrow.Visible = True
264End Sub
265
266Sub LoadProfiles_Click
267 ' Same as above but for profile.
268 ' We're only interested in the ID and name of a profile so only 2 columns.
269 Table.RemoveAllViews
270 NumberOfColumns = 2
271 ' Setting a storage variable in the database. We use this later when clicking a cell.
272 ' It lets the cell know if it is part of the Profile or Device table.
273 ProfileOrDevice = "Profile"
274 SetHeader(Array As String("Profile ID", "Profile Name"))
275 Dim Cursor As Cursor = myDB.ExecQuery("SELECT ProfileID, ProfileName FROM Profiles ORDER BY ProfileID ASC")
276 For i = 0 To Cursor.RowCount - 1
277 Cursor.Position = i
278 Dim ProfileID As String = Cursor.GetInt("ProfileID")
279 Dim ProfileName As String = Cursor.GetString("ProfileName")
280 SetTableView(Array As String(ProfileID, ProfileName))
281 Next
282 NewProfileButton.Visible = True
283 ' Scrolling to the profile of the light.
284 If LastProfile > 0 Then
285 Dim CorrectRow As Int = LastProfile - 101
286 SelectRow(CorrectRow)
287 Sleep(0)
288 ScrollView1.ScrollToNow(CorrectRow*40dip-80dip)
289 End If
290 LeftArrow.Visible = True
291 RightArrow.Visible = False
292End Sub
293
294' For debugging purposes only
295Sub Recreate_Click
296 LastDeviceRow = 0
297 LastProfile = 0
298 myDB.ExecNonQuery("DROP TABLE IF EXISTS Devices")
299 myDB.ExecNonQuery("DROP TABLE IF EXISTS Profiles")
300 myDB.ExecNonQuery("DROP TABLE IF EXISTS Storage")
301 CreateTables
302 Populate_Click
303End Sub
304
305' For debugging purposes only
306Sub Populate_Click
307 myDB.ExecNonQuery("INSERT OR IGNORE INTO Profiles (ProfileID, ProfileName, LDRTargetDay, LDRTargetLow, LDRTargetHigh, SensorDelay, LampMin, LampMax, HoldTime, DaylightMin) VALUES (101, 'Default Profile', 700, 100, 600, 2, 0, 100, 30, 0)")
308 LoadDevices_Click
309End Sub
310
311' -------------------------------------------- MENU BUTTONS STUFF END -------------------------------------------
312' -------------------------------------------- CONNECTION STUFF START -------------------------------------------
313
314Sub Disconnect
315 BTConnected = False
316 Serial1.Disconnect
317 ConnectButton.SetBackgroundImage(LoadBitmap(File.DirAssets, "bluetooth_notconnected1.png"))
318End Sub
319
320Sub Admin_DeviceFound(name As String, MAC As String)
321 ' If it finds a device beginning with RNBT then it is a BlueBridge.
322 Log("Found " & name)
323 If name.Length > 4 And name.Trim.SubString2(0, 4) = "RNBT" Then
324 Dim myNameMac As NameMac
325 myNameMac.Name = name
326 myNameMac.MAC = MAC
327 ' Add it to the list of found devices and stop searching.
328 Log("Found LiteIP Mate: " & MAC)
329 FoundDevices.Add(myNameMac)
330 Admin.CancelDiscovery
331 End If
332End Sub
333
334Sub Admin_DiscoveryFinished
335 ' When the search is finished if the size is 0 we found no BlueBridge.
336 If FoundDevices.Size = 0 Then
337 LogAndToast("No LiteIP Mate was found.", False)
338 Else
339 ' Otherwise create a object to store the Name and MAC address, then connect to that MAC address.
340 Dim myNameMac As NameMac = FoundDevices.Get(0)
341 LogAndToast("Connecting to: " & myNameMac.MAC, False)
342 Serial1.Connect(myNameMac.MAC)
343 End If
344End Sub
345
346Sub Serial1_Connected(Success As Boolean)
347 ' If the connection was a success and we found at least 1 device:
348 If Success Then
349 If FoundDevices.Size > 0 Then
350 ' Get its name and MAC address, also store it in the database as the most recent connection.
351 Dim myNameMac As NameMac = FoundDevices.Get(0)
352 myDB.ExecNonQuery("UPDATE Storage SET LastConnect = '" & myNameMac.MAC & "'")
353 Log("Last connected MAC set to: " & myNameMac.MAC)
354 Else
355 ' If found devices has size 0 it's because we never searched.
356 ' That means we must have connected to the MAC address in the database, thus set that as our MAC address.
357 Dim myNameMac As NameMac
358 myNameMac.MAC = myDB.ExecQuerySingleResult("SELECT LastConnect FROM Storage")
359 End If
360 ' If the AStream isn't initialized initialize it.
361 If Not(AStream.IsInitialized) Then
362 Log("Initializing AStream.")
363 AStream.InitializePrefix(Serial1.InputStream, True, Serial1.OutputStream, "AStream")
364 Else
365 Log("AStream already initialized.")
366 End If
367 ' Log the connected MAC address of the BlueBridge and set our connected flag to True.
368 LogAndToast("LiteIP Mate connected: " & myNameMac.MAC, False)
369 BTConnected = True
370 ConnectButton.SetBackgroundImage(LoadBitmap(File.DirAssets, "bluetooth_connected1.png"))
371 Else
372 ' Otherwise the connection failed. Close the AStream and disconnect from everything.
373 LogAndToast("LiteIP Mate connection failed.", False)
374 Disconnect
375 ' Also clear the database, otherwise we get into a dead-end of connecting to the same out of reach device.
376 myDB.ExecNonQuery("UPDATE Storage SET LastConnect = 'None'")
377 End If
378End Sub
379
380' -------------------------------------------- CONNECTION STUFF END ----------------------------------------------
381' -------------------------------------------- SENDING AND RECEIVING COMMANDS START ------------------------------
382
383' Sends a command to the BlueBridge. Refer to the booklet for commands.
384Sub ExecuteNext
385 If BTConnected And AStream.IsInitialized Then
386 If CommandQueue.Size > 0 Then
387 Dim myCommand As String = CommandQueue.Get(0)
388 LastCommand = myCommand
389 Log("Sending myCommand: " & myCommand)
390 AStream.Write(myCommand.GetBytes("UTF8"))
391 CommandQueue.RemoveAt(0)
392 Else
393 Log("Command queue empty.")
394 End If
395 Else
396 LogAndToast("Please try reconnecting to the LiteIP Mate.", False)
397 End If
398End Sub
399
400' Adds a command to the queue.
401Sub AddToQueue(Command As String)
402 CommandQueue.Add(Command)
403End Sub
404
405Sub AStream_NewData(Buffer() As Byte)
406 ' Dimming variables at the start.
407 Dim myResponse As String
408 Dim FailureFlag As Boolean = False
409 ' Taking the response and cutting it down into an array.
410 myResponse = BytesToString (Buffer,0, Buffer.Length,"UTF8")
411 Log(DateTime.Time(DateTime.Now) & " Response: " & myResponse)
412 myResponse = myResponse.SubString2(0,myResponse.Length - 2)
413 Log(DateTime.Time(DateTime.Now) & " Response: " & myResponse)
414 Dim ResponseList As List
415 ResponseList = Regex.Split(",",myResponse)
416 Log("Response: " & ResponseList)
417 ' All responses by default should include command, sequence and success. If not then the command was invalid.
418 If ResponseList.Size < 3 Then
419 Log("Invalid response.")
420 ' If success was 0 then the command failed.
421 Else if ResponseList.Get(2) = "0" Then
422 Log(ResponseList.Get(0) & ": Command failed")
423 ' Start a failure counter and set the failure flag to true.
424 ' Also add the command back to the queue to be retried.
425 If FailureCount < 3 Then
426 Log("Adding " & LastCommand & " back to the queue.")
427 AddToQueue(LastCommand)
428 FailureFlag = True
429 FailureCount = FailureCount + 1
430 Log("Failure count is: " & FailureCount)
431 Else
432 ' If FailureCount is >= 3 then stop trying and give up on the command. Refresh the corresponding flags.
433 Log("Too many successive failures. Giving up on command.")
434 FailureFlag = False
435 FailureCount = 0
436 End If
437 Else
438 ' Otherwise, if the response was valid:
439 ' Get the command type (always the first variable in the response array)
440 Dim myCommandType As String = ResponseList.Get(0)
441 ' Mark the flags and counter as 0 and False as we did not fail.
442 FailureCount = 0
443 FailureFlag = False
444 Select myCommandType
445 ' If it was a find command:
446 Case "Find"
447 Dim FoundCount As Int
448 ' Trim the first 3 and divide by 10 to find out how many devices we got.
449 FoundCount = Round((ResponseList.Size-3)/10)
450 Log("Found " & FoundCount & " Devices")
451 If FoundCount > 0 Then
452 ' Remove all devices with ID less than 2000 (as these are fake devices).
453 myDB.ExecNonQuery("DELETE FROM Devices WHERE DeviceID < 2000")
454 For i = 0 To FoundCount - 1
455 ' For every device we found, if it wasn't a wall switch:
456 If Not((HexToInt(ResponseList.Get(3+i*10+2))) = 14) Then
457 ' Get the devices ID and RSSI, located at the zeroth and first positions in the response per device respectively.
458 Dim DeviceID As Int
459 Dim DeviceRSSI As Int
460 DeviceID = HexToInt(ResponseList.Get(3+i*10))
461 DeviceRSSI = HexToInt(ResponseList.Get(3+i*10+1))
462 ' Add a Link read command to the queue for that specific light to get its daylight link.
463 AddToQueue("Link,1001,R," & ResponseList.Get(3+i*10) & ";:")
464 ' Insert it into the database.
465 myDB.ExecNonQuery("INSERT OR IGNORE INTO Devices (DeviceID, DeviceName, RSSI) VALUES (" & DeviceID & ", " & "'L" & DeviceID & "', " & DeviceRSSI & ")")
466 End If
467 Next
468 ' Send out a find more command after doing the find new. This will fail if no lights return.
469 AddToQueue("Find,1000,M," & SignalStrength_To_RSSIHex(30) & ",GreaterThan,0,0;:")
470 End If
471
472 ' If it was a link command:
473 Case "Link"
474 If LastCommand.Contains("Link,1001,L,") Then
475 ' If the last command contains this string then it was a write.
476 ' A write will have a different response to a read so trying to process it the same way will give an error.
477 Log("ResponseList size is: " & ResponseList.Size)
478 Log("Success bit is: " & ResponseList.Get(2))
479 Else
480 ' Otherwise, it was a read:
481 Log("Recieved link response.")
482 ' Get the ID and link in interpretable integer format.
483 Dim DeviceID As Int
484 Dim DaylightLink As Int
485 DeviceID = HexToInt(ResponseList.Get(3))
486 DaylightLink = HexToInt(ResponseList.Get(5))
487 ' Update that light with the corresponding daylight link.
488 myDB.ExecNonQuery("UPDATE OR IGNORE Devices SET DaylightLink = " & DaylightLink & " WHERE DeviceID = " & DeviceID)
489 End If
490
491 ' If it was a config command:
492 Case "Conf"
493 ' Get the ID and whether it was a success or not.
494 Log("Received conf response.")
495 Dim DeviceID As Int
496 Dim Success As Int
497 DeviceID = HexToInt(ResponseList.Get(3))
498 Success = HexToInt(ResponseList.Get(2))
499 ' Set the InSync value to 1 or 0 (success or fail) for that device.
500 myDB.ExecNonQuery("UPDATE OR IGNORE Devices SET InSync = " & Success & " WHERE DeviceID = " & DeviceID)
501
502 Case Else
503 Log("Unknown Command: " & myCommandType)
504 End Select
505 End If
506
507 ' Finally redrawing the page to show the new devices.
508 ' No need to redraw if it was a failure because nothing will have changed.
509 If FailureFlag = False Then LoadDevices_Click
510 ' Execute next to keep the queue going.
511 ExecuteNext
512End Sub
513
514Sub AttemptToSync(DeviceID As Int)
515 ' Take in DeviceID. Look up DeviceID in the database and get its profileID.
516 ' Config write to that device ID using all the fields in profileID.
517 Dim ProfileID As Int = myDB.ExecQuerySingleResult("SELECT ProfileID From Devices WHERE DeviceID = " & DeviceID)
518 Dim Cursor As Cursor = myDB.ExecQuery("SELECT * FROM Profiles WHERE ProfileID = " & ProfileID)
519 If Cursor.RowCount > 0 Then Cursor.Position = 0
520 Dim LDRTargetDay As Int = Cursor.GetInt("LDRTargetDay")
521 Dim LDRTargetLow As Int = Cursor.GetInt("LDRTargetLow")
522 Dim LDRTargetHigh As Int = Cursor.GetInt("LDRTargetHigh")
523 Dim SensorDelay As Int = Cursor.GetInt("SensorDelay")
524 Dim LampMin As Int = Cursor.GetInt("LampMin")
525 Dim LampMax As Int = Cursor.GetInt("LampMax")
526 Dim HoldTime As Int = Cursor.GetInt("HoldTime")
527 Dim DaylightMin As Int = Cursor.GetInt("DaylightMin")
528 Dim DaylightMode As Int = Cursor.GetInt("DaylightMode")
529 Dim ConfigList As List
530 ConfigList.Initialize
531 ConfigList.Add(IntToHex(828)) ' Resource enable
532 ConfigList.Add(IntToHex(32)) ' Resource option
533 ConfigList.Add(IntToHex(LDRTargetDay)) ' LDR target day
534 ConfigList.Add(IntToHex(LDRTargetLow)) ' LDR target low
535 ConfigList.Add(IntToHex(LDRTargetHigh)) ' LDR target high
536 ConfigList.Add(IntToHex(LDRTargetDay)) ' LDR target night
537 ConfigList.Add(IntToHex(LDRTargetLow)) ' LDR target low, night
538 ConfigList.Add(IntToHex(LDRTargetHigh)) ' LDR target high, night
539 ConfigList.Add(IntToHex(4)) ' Lamp Command
540 ConfigList.Add(IntToHex(3)) ' Rank
541 ConfigList.Add(IntToHex(229)) ' Minimum Tx timeouts
542 ConfigList.Add(IntToHex(SensorDelay)) ' Sensor delay day
543 ConfigList.Add(IntToHex(SensorDelay)) ' Sensor delay night
544 ConfigList.Add(IntToHex(LampMax)) ' Maximum lamp level
545 ConfigList.Add(IntToHex(LampMin)) ' Minimum lamp level
546 ConfigList.Add(IntToHex(LampMax)) ' Maximum lamp level, night
547 ConfigList.Add(IntToHex(LampMin)) ' Minimum lamp level, night
548 ConfigList.Add(IntToHex(30)) ' Fade time
549 ConfigList.Add(IntToHex(HoldTime)) ' Hold time day
550 ConfigList.Add(IntToHex(HoldTime)) ' Hold time night
551 ConfigList.Add(IntToHex(0)) ' Hop - presence
552 ConfigList.Add(IntToHex(5)) ' Hop - daylight
553 ConfigList.Add(IntToHex(30)) ' Daylight rate
554 ConfigList.Add(IntToHex(DaylightMode)) ' Daylight mode
555 ConfigList.Add(IntToHex(0)) ' Application
556 ConfigList.Add(IntToHex(ProfileID)) ' LiteIP Profile
557 ConfigList.Add(IntToHex(DaylightMin)) ' DaylightMin
558 ConfigList.Add(IntToHex(0)) ' ReportInterval
559 ConfigList.Add(IntToHex(120)) ' Emergency driver
560 ConfigList.Add(IntToHex(0)) ' Spares
561 ConfigList.Add(IntToHex(0))
562 ConfigList.Add(IntToHex(0))
563
564 ' Create a string builder to build the command.
565 Dim Builder As StringBuilder
566 Builder.Initialize
567 ' Always start it off with Conf,123,W followed by the DeviceID in hex.
568 Builder.Append("Conf,123,W,")
569 Builder.Append(IntToHex(DeviceID))
570 ' While there are things left in the ConfigList:
571 Do While ConfigList.Size > 0
572 ' Add them to the list after a comma and then remove them.
573 Builder.Append(",")
574 Builder.Append(ConfigList.Get(0))
575 ConfigList.RemoveAt(0)
576 Loop
577 ' Finally put on the ;: and build the string, then add it to the queue and execute.
578 Builder.Append(";:")
579 Dim myCommand As String = Builder.ToString
580 AddToQueue(myCommand)
581 ExecuteNext
582End Sub
583
584' -------------------------------------------- SENDING AND RECEIVING COMMANDS END --------------------------------
585' -------------------------------------------- TABLE VIEW STUFF START --------------------------------------------
586
587Sub SetTableView(Values() As String)
588 ' Setting each view in the table with our corresponding inputs.
589 ' Validation on the amount of inputs to the amount of columns we have.
590 If Values.Length <> NumberOfColumns Then
591 Log("Wrong number of values.")
592 Return
593 End If
594 Dim LastRow As Int
595 LastRow = NumberOfRows
596 For i = 0 To NumberOfColumns - 1
597 Dim l As Label
598 l.Initialize("cell")
599 l.Text = Values(i)
600 l.Gravity = Alignment
601 l.TextSize = FontSize
602 If Values(i) = "NO" Then
603 l.TextColor = Colors.Red
604 Else If Values(i) = "YES" Then
605 l.TextColor = Colors.Green
606 Else
607 l.TextColor = Colors.Black
608 End If
609 Dim rc As RowCol
610 rc.Initialize
611 rc.Col = i
612 rc.Row = LastRow
613 l.Tag = rc
614 Table.AddView(l, CalculateLeft(i), RowHeight * LastRow, CalculateWidth(i), RowHeight)
615 Next
616 Table.Height = NumberOfRows * RowHeight
617End Sub
618
619Sub SetHeader(Values() As String)
620 ' Setting the header. If it is already initialized, overwrite it by removing it first.
621 If Header.IsInitialized Then Header.RemoveAllViews
622 Header.Initialize("")
623 Header.Color = HeaderColor
624 For i = 0 To NumberOfColumns - 1
625 Dim l As Label
626 l.Initialize("header")
627 l.Text = Values(i)
628 l.Gravity = Gravity.CENTER
629 l.TextSize = FontSize-2
630 l.Color = HeaderColor
631 l.TextColor = HeaderFontColor
632 l.Tag = i
633 Header.AddView(l, CalculateLeft(i), 0, CalculateWidth(i), RowHeight)
634 Next
635 Activity.AddView(Header, ScrollView1.Left, ScrollView1.Top - RowHeight, ScrollView1.Width, RowHeight)
636End Sub
637
638Sub NumberOfRows As Int
639 Return Table.NumberOfViews / NumberOfColumns
640End Sub
641
642Sub GetView(Row As Int, Col As Int) As Label
643 Dim l As Label
644 l = Table.GetView(Row * NumberOfColumns + Col)
645 Return l
646End Sub
647
648Sub CalculateWidth(column As Int) As Int
649 Dim ColumnWidth As Int
650 If ProfileOrDevice = "Device" Then
651 Select column
652 Case 0, 1
653 ColumnWidth = 24%x
654 Case 2
655 ColumnWidth = 23%x
656 Case 3, 4
657 ColumnWidth = 12%x
658 End Select
659 Else
660 ColumnWidth = 50%x
661 End If
662 Return ColumnWidth
663End Sub
664
665Sub CalculateLeft(column As Int) As Int
666 Dim Left As Int
667 If ProfileOrDevice = "Device" Then
668 Select column
669 Case 0
670 Left = 0%x
671 Case 1
672 Left = 24%x
673 Case 2
674 Left = 48%x
675 Case 3
676 Left = 71%x
677 Case 4
678 Left = 83%x
679 End Select
680 Else If ProfileOrDevice = "Profile" Then
681 Select column
682 Case 0
683 Left = 0%x
684 Case 1
685 Left = 50%x
686 End Select
687 End If
688 Return Left
689End Sub
690
691Sub Cell_Click
692 Dim rc As RowCol
693 Dim l As Label
694 l = Sender
695 rc = l.Tag
696 SelectRow(rc.Row)
697
698 ' If we're connected then:
699 If BTConnected = True Then
700 ' If we're on the device table:
701 If ProfileOrDevice = "Device" Then
702 Dim DeviceID As Int = myDB.ExecQuerySingleResult("SELECT DeviceID FROM Devices WHERE DeviceName = '" & GetCell(rc.Row, 0) & "'")
703 Select rc.Col
704 ' If they click one of the first 3 columns, take them to the profile for the device.
705 Case 0, 1, 2
706 LastDeviceRow = rc.Row
707 LastProfile = myDB.ExecQuerySingleResult("SELECT ProfileID FROM Profiles WHERE ProfileName = '" & GetCell(rc.Row, 1) & "'")
708 LoadProfiles_Click
709 ' If they click the third column, try to sync the device to the LiteIP mate.
710 Case 3
711 AttemptToSync(DeviceID)
712 SetCell(rc.Row, 3, 0)
713 ' 4th column is turning a light off for 5 seconds to identify it.
714 Case 4
715 ' IMPORTANT: Current row, zeroth column is always the device ID when on the device page. ----------------------
716 AddToQueue("Ident,123,0," & IntToHex(DeviceID) & ",0A,100," & IntToHex(5) & ";:")
717 ExecuteNext
718 End Select
719
720 Else If ProfileOrDevice = "Profile" Then
721 ' Set the profile we're editing. IMPORTANT: Zeroth column is always profile ID when on the profile page. --------------
722 EditingProfile = GetCell(rc.Row, 0)
723 ' Create a dialog to allow for changing of the profile's properties:
724 Dim EditingProfileName As String = myDB.ExecQuerySingleResult("SELECT ProfileName FROM Profiles WHERE ProfileID = " & EditingProfile)
725 Dim sf As Object = ProfileDialog.ShowAsync("Editing Profile " & EditingProfile & ": " & EditingProfileName, "Confirm", "Cancel", "", Null, True)
726 ProfileDialog.SetSize(100%x, 92%y)
727 Wait For (sf) Dialog_Ready(pnl As Panel)
728 pnl.LoadLayout("ProfileDialogN")
729 DaylightModeSpinner.AddAll(Array As String("No", "Yes"))
730 Dim DaylightMode As Int = myDB.ExecQuerySingleResult("SELECT DaylightMode FROM Profiles WHERE ProfileID = " & EditingProfile)
731 If DaylightMode = 2 Then
732 DaylightModeSpinner.SelectedIndex = 1
733 End If
734 ' Set the confirm button to disabled by default.
735 ProfileDialog.GetButton(DialogResponse.POSITIVE).Enabled = True
736 ' Getting all column headers from the Profiles database and values.
737 ProfileDialogInit
738 ' Waiting for their response.
739 Wait For (sf) Dialog_Result(Res As Int)
740 If Res = DialogResponse.POSITIVE Then
741 SetProfileValues
742 myDB.ExecNonQuery("UPDATE Devices SET InSync = 0 WHERE ProfileID = " & EditingProfile)
743 ' Update the screen.
744 LoadProfiles_Click
745 End If
746 End If
747 Else
748 ToastMessageShow("Please connect to a LiteIP Mate.", False)
749 End If
750End Sub
751
752Sub Cell_LongClick
753 Dim rc As RowCol
754 Dim l As Label
755 l = Sender
756 rc = l.Tag
757 SelectRow(rc.Row)
758
759 ' User should only be able to update the fields if they're connected to the bluetooth device.
760 If BTConnected = True Then
761 ' If we're on the "Device" screen then we want to give them device changing dialogs.
762 If ProfileOrDevice = "Device" Then
763 Dim DeviceID As Int = myDB.ExecQuerySingleResult("SELECT DeviceID FROM Devices WHERE DeviceName = '" & GetCell(rc.Row, 0) & "'")
764 Select rc.Col
765 ' If the column is 0 they are changing the "Device Name" column.
766 Case 0
767 Dim sf As Object = DeviceDialog.ShowAsync("Change Device Name", "Confirm", "Cancel", "", Null, True)
768 DeviceDialog.SetSize(100%x, 250dip)
769 Wait for (sf) Dialog_Ready(pnl As Panel)
770 ' Create a dialog and manipulate hiding of buttons to change what the user sees.
771 pnl.LoadLayout("DeviceDialog")
772 InitialDeviceName = GetCell(rc.Row, 0)
773 Label1.Text = "Device Name: "
774 DialogProfileID.Visible = False
775 DialogDaylightLink.Visible = False
776 ' When changing name, we only want the name box to be visible.
777 DialogDeviceName.Visible = True
778 ' Set the text to the current name by default for visibility's sake.
779 DialogDeviceName.Text = GetCell(rc.Row, 0)
780 Wait For (sf) Dialog_Result(Res As Int)
781 If Res = DialogResponse.POSITIVE Then
782 ' When they confirm, set the cell to the new name.
783 SetCell(rc.Row, rc.Col, DialogDeviceName.Text)
784 End If
785
786 ' If the column is 1 they are changing the 'Profile' column.
787 Case 1
788 Dim sf As Object = DeviceDialog.ShowAsync("Change Profile", "Confirm", "Cancel", "", Null, True)
789 DeviceDialog.SetSize(100%x, 250dip)
790 Wait For (sf) Dialog_Ready(pnl As Panel)
791 pnl.LoadLayout("DeviceDialog")
792 ' Get all profiles from the profile database.
793 ' Make a special note of the current profile as we want to have that be the initial option shown.
794 Dim CurrentID As Int = myDB.ExecQuerySingleResult("SELECT ProfileID FROM Devices WHERE DeviceName = '" & GetCell(rc.Row, 0) & "'")
795 Dim CurrentProfile As String = myDB.ExecQuerySingleResult("SELECT ProfileName FROM Profiles WHERE ProfileID = " & CurrentID)
796 Dim CorrectIndex As Int
797 Dim Cursor As Cursor = myDB.ExecQuery("SELECT ProfileName FROM Profiles")
798 ' Add them to a spinner and display it to the user.
799 Label1.Text = "Profile Name: "
800 DialogDaylightLink.Visible = False
801 DialogDeviceName.Visible = False
802 DialogProfileID.Visible = True
803 For i = 0 To Cursor.RowCount - 1
804 Cursor.Position = i
805 ' First set the cursor's gotten value to a variable.
806 Dim CursorProfile As String = Cursor.GetString("ProfileName")
807 ' As we iterate, check if the gotten value is equal to the stored database value. When it is, get the index of that value.
808 If CursorProfile = CurrentProfile Then CorrectIndex = i
809 ' Add it to the ProfileID list.
810 DialogProfileID.Add(CursorProfile)
811 Next
812 ' Set the index to the correct one by default.
813 DialogProfileID.SelectedIndex = CorrectIndex
814 Wait For (sf) Dialog_Result(Res As Int)
815 If Res = DialogResponse.POSITIVE Then
816 Dim NewID As Int = myDB.ExecQuerySingleResult("SELECT ProfileID FROM Profiles WHERE ProfileName = '" & DialogProfileID.SelectedItem & "'")
817 SetCell(rc.Row, rc.Col, NewID)
818 LastProfile = NewID
819 ' Telling the user they're out of sync.
820 SetCell(rc.Row, 3, 0)
821 End If
822
823 ' If the column is 2 then they are changing the 'Daylight Link' column.
824 Case 2
825 Dim sf As Object = DeviceDialog.ShowAsync("Edit Daylight Link", "Confirm", "Cancel", "", Null, True)
826 DeviceDialog.SetSize(100%x, 250dip)
827 Wait For (sf) Dialog_Ready(pnl As Panel)
828 pnl.LoadLayout("DeviceDialog")
829 Dim CurrentDayLink As Int = myDB.ExecQuerySingleResult("SELECT DaylightLink FROM Devices WHERE DeviceName = '" & GetCell(rc.Row, 0) & "'")
830 ' Get all profiles from the profile database.
831 Dim Cursor As Cursor = myDB.ExecQuery("SELECT Devices.DeviceID, Devices.DeviceName, Devices.ProfileID, Profiles.ProfileID, Profiles.DaylightMode FROM Devices INNER JOIN Profiles ON Devices.ProfileID=Profiles.ProfileID")
832 ' Add them to a spinner and display it to the user.
833 Label1.Text = "Daylight Link: "
834 DialogProfileID.Visible = False
835 DialogDeviceName.Visible = False
836 DialogDaylightLink.Visible = True
837 For i = 0 To Cursor.RowCount - 1
838 Cursor.Position = i
839 Dim CursorDayMode As Int = Cursor.GetInt("DaylightMode")
840 If CursorDayMode = 2 Then
841 Dim CursorDayLink As Int = Cursor.GetInt("DeviceID")
842 If CursorDayLink = CurrentDayLink Then CorrectIndex = i
843 DialogDaylightLink.Add(Cursor.GetString("DeviceName"))
844 End If
845 Next
846 DialogDaylightLink.SelectedIndex = CorrectIndex
847 Wait For (sf) Dialog_Result(Res As Int)
848 If Res = DialogResponse.POSITIVE Then
849 Dim DaylightLinkDevice As Int = myDB.ExecQuerySingleResult("SELECT DeviceID FROM Devices WHERE DeviceName = " & DialogDaylightLink.SelectedItem)
850 SetCell(rc.Row, rc.Col, DaylightLinkDevice)
851 AddToQueue("Link,1001,L," & IntToHex(DeviceID) & "," & IntToHex(DaylightLinkDevice) & ";:")
852 ExecuteNext
853 End If
854
855 ' If they click the third column, try to sync the device to the LiteIP mate.
856 Case 3
857 AttemptToSync(DeviceID)
858 SetCell(rc.Row, 3, 0)
859 ' 4th column is turning a light off for 5 seconds to identify it.
860 Case 4
861 AddToQueue("Ident,123,0," & IntToHex(DeviceID) & ",0A,100," & IntToHex(5) & ";:")
862 ExecuteNext
863 End Select
864
865 ' If we're on the "Profile" screen we want to give them a profile name changing dialog on long click.
866 Else If ProfileOrDevice = "Profile" Then
867 Dim sf As Object = ProfileNameDialog.ShowAsync("Change Profile Name", "Confirm", "Cancel", "", Null, True)
868 ProfileNameDialog.SetSize(100%x, 250dip)
869 Wait for (sf) Dialog_Ready(pnl As Panel)
870 ' Create a dialog and manipulate hiding of buttons to change what the user sees.
871 pnl.LoadLayout("ProfileNameDialog")
872 InitialProfileName = GetCell(rc.Row, 1)
873 ProfileNameLabel.Text = "Profile Name: "
874 ' Set the text to the current name by default for visibility's sake.
875 ProfileNameET.Text = myDB.ExecQuerySingleResult("SELECT ProfileName FROM Profiles WHERE ProfileID = " & GetCell(rc.Row, 0))
876 Wait For (sf) Dialog_Result(Res As Int)
877 If Res = DialogResponse.POSITIVE Then
878 ' When they confirm, set the cell to the new name.
879 SetCell(rc.Row, rc.Col, ProfileNameET.Text)
880 End If
881 End If
882 Else
883 ToastMessageShow("Please connect to a LiteIP Mate.", False)
884 End If
885End Sub
886
887' Highlighting a row.
888Sub SelectRow(Row As Int)
889 ' Go through the table and set everything to transparent.
890 For Each v As View In Table.GetAllViewsRecursive
891 v.Color = Colors.Transparent
892 Next
893 For col = 0 To NumberOfColumns - 1
894 GetView(Row, col).Color = SelectedRowColor
895 Next
896 ' If we're on the device page:
897 If ProfileOrDevice = "Device" Then
898 ' Set the selected row and get the device's profile (2nd column (including zero)).
899 LastDeviceRow = Row
900 LastProfile = myDB.ExecQuerySingleResult("SELECT ProfileID FROM Profiles WHERE ProfileName = '" & GetCell(Row, 1) & "'")
901 Else If ProfileOrDevice = "Profile" Then
902 ' If we're on the profile page then get the zeroth column for LastProfile instead.
903 LastProfile = GetView(Row, 0).Text
904 End If
905End Sub
906
907Sub SetCell(Row As Int, Col As Int, Value As String)
908 ' We only have the row and column index but ideally we want the row and column name.
909 Dim ColumnString As String
910 Dim DeviceName As String = GetCell(Row, 0)
911 Dim QuoteSet As String = ""
912 ' Figure out if the table is the Devices or Profiles table.
913 If ProfileOrDevice = "Device" Then
914 ' Find the column they clicked. There is no Case 0 because we don't want people to be able to change DeviceID.
915 Select Col
916 Case 0
917 ColumnString = "DeviceName"
918 QuoteSet = "'"
919 Case 1
920 ColumnString = "ProfileID"
921 Case 2
922 ColumnString = "DaylightLink"
923 Case 3
924 ColumnString = "InSync"
925 End Select
926 ' Quote set is by default blank. We set it to "'" when we need to manipulate strings, as SQL can only read strings surrounded by '.
927 myDB.ExecNonQuery("UPDATE Devices SET " & ColumnString & " = " & QuoteSet & Value & QuoteSet & " WHERE DeviceName = '" & DeviceName & "'")
928 ' If the column is the InSync we should update the text to No/Yes rather than 0 or 1.
929 If ColumnString = "InSync" Then
930 If Value = 1 Then
931 GetView(Row, Col).TextColor = Colors.Green
932 GetView(Row, Col).Text = "YES"
933 Else If Value = 0 Then
934 GetView(Row, Col).TextColor = Colors.Red
935 GetView(Row, Col).Text = "NO"
936 End If
937 Else If ColumnString = "ProfileID" Then
938 GetView(Row, Col).Text = myDB.ExecQuerySingleResult("SELECT ProfileName FROM Profiles WHERE ProfileID = " & Value)
939 Else
940 GetView(Row, Col).Text = Value
941 End If
942 LoadDevices_Click
943 Else If ProfileOrDevice = "Profile" Then
944 ' Find the column they clicked. No Case 0 because we don't want people to be able to change ProfileID.
945 Select Col
946 Case 1
947 ColumnString = "ProfileName"
948 End Select
949 Dim ProfileID As String = GetCell(Row, 0)
950 myDB.ExecNonQuery("UPDATE Profiles SET " & ColumnString & " = '" & Value & "' WHERE ProfileID = " & ProfileID)
951 GetView(Row, Col).Text = Value
952 End If
953End Sub
954
955Sub GetCell(Row As Int, Col As Int) As String
956 Return GetView(Row, Col).Text
957End Sub
958
959' -------------------------------------------- TABLE VIEW STUFF END ----------------------------------------------
960' -------------------------------------------- MISC FUNCTIONS ----------------------------------------------------
961
962Sub IntToHex(myint As Int) As String
963 Return Bit.ToHexString(myint).ToUpperCase
964End Sub
965
966Sub HexToInt(myHex As String) As Int
967 Return Bit.ParseInt(myHex,16)
968End Sub
969
970Sub SignalStrength_To_RSSIHex (mySignalStrength As Int) As String
971 'RSSI = 100 - (60 * SS)/100
972 Dim myRSSIInt As Int
973 myRSSIInt = 100 - ((60*mySignalStrength) / 100)
974 Dim myRSSI As String
975 myRSSI = IntToHex(myRSSIInt)
976 Return myRSSI
977End Sub
978
979Sub DialogDeviceName_TextChanged(Old As String, New As String)
980 Dim InvalidCharFlag As Boolean = False
981 For i = 0 To ForbiddenChars.Size - 1
982 If New.Contains(ForbiddenChars.Get(i)) Then InvalidCharFlag = True
983 Next
984 DeviceDialog.GetButton(DialogResponse.POSITIVE).Enabled = Not(InvalidCharFlag)
985 If InvalidCharFlag = False Then
986 Dim Cursor As Cursor = myDB.ExecQuery("SELECT * FROM Devices WHERE DeviceName = '" & New & "'")
987 If Cursor.RowCount > 0 Then DeviceDialog.GetButton(DialogResponse.POSITIVE).Enabled = False
988 End If
989 If New = "" Then DeviceDialog.GetButton(DialogResponse.POSITIVE).Enabled = True
990 If New = InitialDeviceName Then DeviceDialog.GetButton(DialogResponse.POSITIVE).Enabled = True
991End Sub
992
993Sub ProfileNameET_TextChanged(Old As String, New As String)
994 Dim InvalidCharFlag As Boolean = False
995 For i = 0 To ForbiddenChars.Size - 1
996 If New.Contains(ForbiddenChars.Get(i)) Then InvalidCharFlag = True
997 Next
998 ProfileNameDialog.GetButton(DialogResponse.POSITIVE).Enabled = Not(InvalidCharFlag)
999 If InvalidCharFlag = False Then
1000 Dim Cursor As Cursor = myDB.ExecQuery("SELECT * FROM Profiles WHERE ProfileName = '" & New & "'")
1001 If Cursor.RowCount > 0 Then ProfileNameDialog.GetButton(DialogResponse.POSITIVE).Enabled = False
1002 End If
1003 If New = InitialProfileName Then ProfileNameDialog.GetButton(DialogResponse.POSITIVE).Enabled = True
1004End Sub
1005
1006Sub SetProfileValues
1007 myDB.ExecNonQuery("UPDATE Profiles SET LDRTargetDay = " & DayET.Text & " WHERE ProfileID = " & EditingProfile)
1008 myDB.ExecNonQuery("UPDATE Profiles SET LDRTargetLow = " & LowET.Text & " WHERE ProfileID = " & EditingProfile)
1009 myDB.ExecNonQuery("UPDATE Profiles SET LDRTargetHigh = " & HighET.Text & " WHERE ProfileID = " & EditingProfile)
1010 myDB.ExecNonQuery("UPDATE Profiles SET SensorDelay = " & SensorET.Text & " WHERE ProfileID = " & EditingProfile)
1011 myDB.ExecNonQuery("UPDATE Profiles SET LampMin = " & LampMinET.Text & " WHERE ProfileID = " & EditingProfile)
1012 myDB.ExecNonQuery("UPDATE Profiles SET Lampmax = " & LampMaxET.Text & " WHERE ProfileID = " & EditingProfile)
1013 myDB.ExecNonQuery("UPDATE Profiles SET HoldTime = " & HoldTimeET.Text & " WHERE ProfileID = " & EditingProfile)
1014 myDB.ExecNonQuery("UPDATE Profiles SET DaylightMin = " & DayMinET.Text & " WHERE ProfileID = " & EditingProfile)
1015 If DaylightModeSpinner.SelectedItem = "Yes" Then
1016 myDB.ExecNonQuery("UPDATE Profiles SET DaylightMode = 2 WHERE ProfileID = " & EditingProfile)
1017 Else
1018 myDB.ExecNonQuery("UPDATE Profiles SET DaylightMode = 0 WHERE ProfileID = " & EditingProfile)
1019 End If
1020
1021End Sub
1022
1023Sub ProfileDialogInit
1024 Dim Cursor As Cursor = myDB.ExecQuery("SELECT * FROM Profiles WHERE ProfileID = " & EditingProfile)
1025 Cursor.Position = 0
1026 DayET.Text = Cursor.GetInt("LDRTargetDay")
1027 LowET.Text = Cursor.GetInt("LDRTargetLow")
1028 HighET.Text = Cursor.GetInt("LDRTargetHigh")
1029 SensorET.Text = Cursor.GetInt("SensorDelay")
1030 LampMinET.Text = Cursor.GetInt("LampMin")
1031 LampMaxET.Text = Cursor.GetInt("LampMax")
1032 HoldTimeET.Text = Cursor.GetInt("HoldTime")
1033 DayMinET.Text = Cursor.GetInt("DaylightMin")
1034 DayET.InputType = DayET.INPUT_TYPE_NUMBERS
1035 LowET.InputType = LowET.INPUT_TYPE_NUMBERS
1036 HighET.InputType = HighET.INPUT_TYPE_NUMBERS
1037 SensorET.InputType = SensorET.INPUT_TYPE_NUMBERS
1038 LampMinET.InputType = LampMinET.INPUT_TYPE_NUMBERS
1039 LampMaxET.InputType = LampMaxET.INPUT_TYPE_NUMBERS
1040 HoldTimeET.InputType = HoldTimeET.INPUT_TYPE_NUMBERS
1041 DayMinET.InputType = DayMinET.INPUT_TYPE_NUMBERS
1042End Sub
1043
1044Sub ValidateProfileDialog As Boolean
1045 If DayET.Text = "" Then Return False
1046 If LowET.Text = "" Then Return False
1047 If HighET.Text = "" Then Return False
1048 If SensorET.Text = "" Then Return False
1049 If LampMinET.Text = "" Then Return False
1050 If LampMaxET.Text = "" Then Return False
1051 If HoldTimeET.Text = "" Then Return False
1052 If DayMinET.Text = "" Then Return False
1053 If (DayET.Text < 0 Or DayET.Text > 1000) Then Return False
1054 If (LowET.Text < 0 Or LowET.Text > 1000) Then Return False
1055 If (HighET.Text < 0 Or HighET.Text > 1000) Then Return False
1056 If (SensorET.Text < 0 Or SensorET.Text > 10) Then Return False
1057 If (LampMinET.Text < 0 Or LampMinET.Text > 100) Then Return False
1058 If (LampMaxET.Text < 0 Or LampMaxET.Text > 100) Then Return False
1059 If (HoldTimeET.Text < 0 Or HoldTimeET.Text > 255) Then Return False
1060 If (DayMinET.Text < 0 Or DayMinET.Text > 100) Then Return False
1061 Return True
1062End Sub
1063
1064Sub DayET_TextChanged(Old As String, New As String)
1065 If Not(Old = "") Then ProfileDialog.GetButton(DialogResponse.POSITIVE).Enabled = ValidateProfileDialog
1066End Sub
1067Sub LowET_TextChanged(Old As String, New As String)
1068 If Not(Old = "") Then ProfileDialog.GetButton(DialogResponse.POSITIVE).Enabled = ValidateProfileDialog
1069End Sub
1070Sub HighET_TextChanged(Old As String, New As String)
1071 If Not(Old = "") Then ProfileDialog.GetButton(DialogResponse.POSITIVE).Enabled = ValidateProfileDialog
1072End Sub
1073Sub SensorET_TextChanged(Old As String, New As String)
1074 If Not(Old = "") Then ProfileDialog.GetButton(DialogResponse.POSITIVE).Enabled = ValidateProfileDialog
1075End Sub
1076Sub LampMinET_TextChanged(Old As String, New As String)
1077 If Not(Old = "") Then ProfileDialog.GetButton(DialogResponse.POSITIVE).Enabled = ValidateProfileDialog
1078End Sub
1079Sub LampMaxET_TextChanged(Old As String, New As String)
1080 If Not(Old = "") Then ProfileDialog.GetButton(DialogResponse.POSITIVE).Enabled = ValidateProfileDialog
1081End Sub
1082Sub HoldTimeET_TextChanged(Old As String, New As String)
1083 If Not(Old = "") Then ProfileDialog.GetButton(DialogResponse.POSITIVE).Enabled = ValidateProfileDialog
1084End Sub
1085Sub DaylightMinET_TextChanged(Old As String, New As String)
1086 If Not(Old = "") Then ProfileDialog.GetButton(DialogResponse.POSITIVE).Enabled = ValidateProfileDialog
1087End Sub
1088
1089Sub LogAndToast(Input As String, Length As Boolean)
1090 Log(Input)
1091 ToastMessageShow(Input, Length)
1092End Sub
1093
1094Sub MakeAllVisible
1095 NewProfileButton.Visible = True
1096 ConnectButton.Visible = True
1097 LiteIP_Label.Visible = True
1098 SearchButton.Visible = True
1099 LeftArrow.Visible = True
1100 RightArrow.Visible = True
1101 ScrollView1.Visible = True
1102End Sub
1103
1104Sub LeftArrow_Click
1105 If ProfileOrDevice = "Profile" Then LoadDevices_Click
1106End Sub
1107
1108Sub LeftArrow_LongClick
1109 If ProfileOrDevice = "Profile" Then ToastMessageShow("Show devices", False)
1110End Sub
1111
1112Sub RightArrow_Click
1113 If ProfileOrDevice = "Device" Then LoadProfiles_Click
1114End Sub
1115
1116Sub RightArrow_LongClick
1117 If ProfileOrDevice = "Device" Then ToastMessageShow("Show profiles", False)
1118End Sub
1119
1120Sub LiteIP_Label_LongClick
1121 Recreate_Click
1122End Sub
1123
1124Sub btn_SignIn_Click
1125 If Starter.GPS1.GPSEnabled = False Then
1126 ToastMessageShow("Please enable GPS on your phone.", False)
1127 Else
1128 Auth.SignInWithGoogle
1129 End If
1130End Sub
1131
1132Sub Auth_SignedIn (User As FirebaseUser)
1133 Log("Signed in: " & User.Email)
1134 Email = User.Email
1135 CallSubDelayed(Starter, "StartGps")
1136 btn_SignIn.Visible = False
1137 LogAndToast("Obtaining location. Please wait...", True)
1138End Sub
1139
1140Sub LocationChanged(Location1 As Location)
1141 Log(Location1.Latitude)
1142 Log(Location1.Longitude)
1143 Latitude = Location1.Latitude
1144 Longitude = Location1.Longitude
1145 CallSubDelayed(Starter, "StopGps")
1146 Sleep(2000)
1147 SplashPanel.SetVisibleAnimated(1000, False)
1148 Sleep(1000)
1149 MakeAllVisible
1150 Log(Email & " // " & Latitude & " // " & Longitude)
1151 FakeJobDone
1152 LoadDevices_Click
1153End Sub
1154
1155Sub PhoneLogin
1156 If Not(Latitude = "None") Then
1157 Dim Job1 As HttpJob
1158 Job1.Initialize("JobPhoneLogin", Me)
1159 Job1.PostString("Http://sync.liteip.com/PhoneLogin.aspx", Email & "," & Latitude & "," & Longitude)
1160 Else
1161 ToastMessageShow("Location not set.", False)
1162 End If
1163End Sub
1164
1165Sub JobDone(Job As HttpJob)
1166 Select Job.JobName
1167 Case "JobPhoneLogin"
1168 If Job.Success Then
1169 ' Do it all here
1170 Else
1171 LogAndToast("JobGetPostcode went wrong somewhere along the line.", False)
1172 End If
1173 End Select
1174End Sub
1175
1176Sub FakeJobDone
1177 Dim postcode As String = "SO31_8AP"
1178 If myDB.IsInitialized = False Then
1179 myDB.Initialize(File.DirInternal, postcode & ".db", True)
1180 End If
1181 CreateTables
1182End Sub